This repository has no description
3.4 kB
157 lines
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 Created string
17}
18
19func (d *DB) IsMigrationApplied(name string) (bool, error) {
20 var exists bool
21 err := d.db.QueryRow(
22 `select exists (select 1 from migrations where name = ?)`,
23 name,
24 ).Scan(&exists)
25 return exists, err
26}
27
28func (d *DB) ApplyKnotMemberBackfill(ctx context.Context, rows []KnotMember, migrationName string) error {
29 conn, err := d.db.Conn(ctx)
30 if err != nil {
31 return err
32 }
33 defer conn.Close()
34
35 return orm.RunMigration(conn, d.logger, migrationName, func(tx *sql.Tx) error {
36 for _, m := range rows {
37 if err := AddDid(tx, m.Subject.String()); err != nil {
38 return err
39 }
40 if err := AddKnotMemberDirect(tx, m.Did, m.Subject); err != nil {
41 return err
42 }
43 }
44 return nil
45 })
46}
47
48func AddKnotMemberDirect(q DBTX, addedBy, subject syntax.DID) error {
49 _, err := q.Exec(
50 `insert or ignore into knot_members (did, rkey, subject) values (?, NULL, ?)`,
51 addedBy,
52 subject,
53 )
54 return err
55}
56
57func RemoveKnotMemberBySubject(q DBTX, subject syntax.DID) error {
58 _, err := q.Exec(
59 "delete from knot_members where subject = ?",
60 subject,
61 )
62 return err
63}
64
65func RemoveKnotMemberDirect(q DBTX, subject syntax.DID) error {
66 _, err := q.Exec(
67 "delete from knot_members where subject = ? and rkey is null",
68 subject,
69 )
70 return err
71}
72
73func CountKnotMembersBySubject(q DBTX, subject string) (int, error) {
74 var count int
75 err := q.QueryRow(
76 `select count(*) from knot_members where subject = ?`,
77 subject,
78 ).Scan(&count)
79 return count, err
80}
81
82func ListKnotMembers(q DBTX, p ListPage) ([]KnotMember, *int, error) {
83 return listPaged(q,
84 `select id, did, subject, created
85 from knot_members
86 where id in (select min(id) from knot_members group by subject)`,
87 nil, p,
88 func(r *sql.Rows) (KnotMember, error) {
89 var m KnotMember
90 err := r.Scan(&m.Id, &m.Did, &m.Subject, &m.Created)
91 return m, err
92 },
93 func(m KnotMember) int { return m.Id },
94 )
95}
96
97func (d *DB) ApplyKnotMembersBackfill(ctx context.Context, rows []KnotMember, migrationName string) error {
98 conn, err := d.db.Conn(ctx)
99 if err != nil {
100 return err
101 }
102 defer conn.Close()
103
104 return orm.RunMigration(conn, d.logger, migrationName, func(tx *sql.Tx) error {
105 for _, m := range rows {
106 if err := AddDid(tx, m.Subject.String()); err != nil {
107 return err
108 }
109 if _, err := tx.ExecContext(ctx,
110 `insert or ignore into knot_members (did, rkey, subject) values (?, ?, ?)`,
111 m.Did, m.Rkey, m.Subject,
112 ); err != nil {
113 return err
114 }
115 }
116 return nil
117 })
118}
119
120func AddKnotMember(q DBTX, member KnotMember) error {
121 _, err := q.Exec(
122 `insert or ignore into knot_members (did, rkey, subject) values (?, ?, ?)`,
123 member.Did,
124 member.Rkey,
125 member.Subject,
126 )
127 return err
128}
129
130func RemoveKnotMember(q DBTX, ownerDid, rkey string) error {
131 _, err := q.Exec(
132 "delete from knot_members where did = ? and rkey = ?",
133 ownerDid,
134 rkey,
135 )
136 return err
137}
138
139func GetKnotMember(q DBTX, did, rkey string) (*KnotMember, error) {
140 query :=
141 `select id, did, rkey, subject
142 from knot_members
143 where did = ? and rkey = ?`
144
145 var member KnotMember
146 err := q.QueryRow(query, did, rkey).Scan(
147 &member.Id,
148 &member.Did,
149 &member.Rkey,
150 &member.Subject,
151 )
152 if err != nil {
153 return nil, err
154 }
155
156 return &member, nil
157}