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 Subject syntax.DID
15 Created string
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) ApplyKnotMemberBackfill(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 := AddDid(tx, m.Subject.String()); err != nil {
37 return err
38 }
39 if err := AddKnotMemberDirect(tx, m.Did, m.Subject); err != nil {
40 return err
41 }
42 }
43 return nil
44 })
45}
46
47func AddKnotMemberDirect(q DBTX, addedBy, subject syntax.DID) error {
48 _, err := q.Exec(
49 `insert or ignore into knot_members (did, rkey, subject) values (?, NULL, ?)`,
50 addedBy,
51 subject,
52 )
53 return err
54}
55
56func RemoveKnotMemberBySubject(q DBTX, subject syntax.DID) error {
57 _, err := q.Exec(
58 "delete from knot_members where subject = ?",
59 subject,
60 )
61 return err
62}
63
64func RemoveKnotMemberDirect(q DBTX, subject syntax.DID) error {
65 _, err := q.Exec(
66 "delete from knot_members where subject = ? and rkey is null",
67 subject,
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 ListKnotMembers(q DBTX, p ListPage) ([]KnotMember, *int, error) {
82 return listPaged(q,
83 `select id, did, subject, created
84 from knot_members
85 where id in (select min(id) from knot_members group by subject)`,
86 nil, p,
87 func(r *sql.Rows) (KnotMember, error) {
88 var m KnotMember
89 err := r.Scan(&m.Id, &m.Did, &m.Subject, &m.Created)
90 return m, err
91 },
92 func(m KnotMember) int { return m.Id },
93 )
94}