Monorepo for Tangled
tangled.org
1package db
2
3import (
4 "context"
5 "database/sql"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8 "tangled.org/core/orm"
9)
10
11type KnotMember struct {
12 Id int
13 Did syntax.DID
14 Rkey string
15 Subject syntax.DID
16}
17
18func (d *DB) IsMigrationApplied(name string) (bool, error) {
19 var exists bool
20 err := d.db.QueryRow(
21 `select exists (select 1 from migrations where name = ?)`,
22 name,
23 ).Scan(&exists)
24 return exists, err
25}
26
27func (d *DB) ApplyKnotMembersBackfill(ctx context.Context, rows []KnotMember, migrationName string) error {
28 conn, err := d.db.Conn(ctx)
29 if err != nil {
30 return err
31 }
32 defer conn.Close()
33
34 return orm.RunMigration(conn, d.logger, migrationName, func(tx *sql.Tx) error {
35 for _, m := range rows {
36 if _, err := tx.ExecContext(ctx,
37 `insert or ignore into known_dids (did) values (?)`,
38 m.Subject,
39 ); err != nil {
40 return err
41 }
42 if _, err := tx.ExecContext(ctx,
43 `insert or ignore into knot_members (did, rkey, subject) values (?, ?, ?)`,
44 m.Did, m.Rkey, m.Subject,
45 ); err != nil {
46 return err
47 }
48 }
49 return nil
50 })
51}
52
53func AddKnotMember(q DBTX, member KnotMember) error {
54 _, err := q.Exec(
55 `insert or ignore into knot_members (did, rkey, subject) values (?, ?, ?)`,
56 member.Did,
57 member.Rkey,
58 member.Subject,
59 )
60 return err
61}
62
63func RemoveKnotMember(q DBTX, ownerDid, rkey string) error {
64 _, err := q.Exec(
65 "delete from knot_members where did = ? and rkey = ?",
66 ownerDid,
67 rkey,
68 )
69 return err
70}
71
72func CountKnotMembersBySubject(q DBTX, subject string) (int, error) {
73 var count int
74 err := q.QueryRow(
75 `select count(*) from knot_members where subject = ?`,
76 subject,
77 ).Scan(&count)
78 return count, err
79}
80
81func GetKnotMember(q DBTX, did, rkey string) (*KnotMember, error) {
82 query :=
83 `select id, did, rkey, subject
84 from knot_members
85 where did = ? and rkey = ?`
86
87 var member KnotMember
88 err := q.QueryRow(query, did, rkey).Scan(
89 &member.Id,
90 &member.Did,
91 &member.Rkey,
92 &member.Subject,
93 )
94 if err != nil {
95 return nil, err
96 }
97
98 return &member, nil
99}