An implementation of the ATProto statusphere example app but in Go
1package database
2
3import (
4 "database/sql"
5 "fmt"
6 "log/slog"
7
8 "github.com/willdot/statusphere-go"
9)
10
11func createProfileTable(db *sql.DB) error {
12 createProfileTableSQL := `CREATE TABLE IF NOT EXISTS profile (
13 "did" TEXT NOT NULL PRIMARY KEY,
14 "handle" TEXT,
15 "displayName" TEXT
16 );`
17
18 slog.Info("Create profile table...")
19 statement, err := db.Prepare(createProfileTableSQL)
20 if err != nil {
21 return fmt.Errorf("prepare DB statement to create profile table: %w", err)
22 }
23 _, err = statement.Exec()
24 if err != nil {
25 return fmt.Errorf("exec sql statement to create profile table: %w", err)
26 }
27 slog.Info("profile table created")
28
29 return nil
30}
31
32func (d *DB) CreateProfile(profile statusphere.UserProfile) error {
33 sql := `INSERT INTO profile (did, handle, displayName) VALUES (?, ?, ?) ON CONFLICT(did) DO NOTHING;` // TODO: What about when users change their handle or display name???
34 _, err := d.db.Exec(sql, profile.Did, profile.Handle, profile.DisplayName)
35 if err != nil {
36 return fmt.Errorf("exec insert profile: %w", err)
37 }
38
39 return nil
40}
41
42func (d *DB) GetHandleAndDisplayNameForDid(did string) (statusphere.UserProfile, error) {
43 sql := "SELECT did, handle, displayName FROM profile WHERE did = ?;"
44 rows, err := d.db.Query(sql, did)
45 if err != nil {
46 return statusphere.UserProfile{}, fmt.Errorf("run query to get profile': %w", err)
47 }
48 defer rows.Close()
49
50 var profile statusphere.UserProfile
51 for rows.Next() {
52 if err := rows.Scan(&profile.Did, &profile.Handle, &profile.DisplayName); err != nil {
53 return statusphere.UserProfile{}, fmt.Errorf("scan row: %w", err)
54 }
55
56 return profile, nil
57 }
58 return profile, statusphere.ErrorNotFound
59}