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 Collaborator struct {
12 Id int
13 RepoDid syntax.DID
14 Subject syntax.DID
15 AddedBy syntax.DID
16 Created string
17}
18
19func AddCollaborator(q DBTX, c Collaborator) error {
20 _, err := q.Exec(
21 `insert or ignore into collaborators (repo_did, subject_did, added_by_did) values (?, ?, ?)`,
22 c.RepoDid,
23 c.Subject,
24 c.AddedBy,
25 )
26 return err
27}
28
29func IsCollaborator(q DBTX, repoDid, subject syntax.DID) (bool, error) {
30 var exists bool
31 err := q.QueryRow(
32 `select exists (select 1 from collaborators where repo_did = ? and subject_did = ?)`,
33 repoDid,
34 subject,
35 ).Scan(&exists)
36 return exists, err
37}
38
39func RemoveCollaborator(q DBTX, repoDid, subject syntax.DID) error {
40 _, err := q.Exec(
41 `delete from collaborators where repo_did = ? and subject_did = ?`,
42 repoDid,
43 subject,
44 )
45 return err
46}
47
48func (d *DB) ApplyCollaboratorBackfill(ctx context.Context, rows []Collaborator, migrationName string, markApplied bool) error {
49 insert := func(tx *sql.Tx) error {
50 for _, c := range rows {
51 if err := AddDid(tx, c.Subject.String()); err != nil {
52 return err
53 }
54 if err := AddCollaborator(tx, c); err != nil {
55 return err
56 }
57 }
58 return nil
59 }
60
61 if markApplied {
62 conn, err := d.db.Conn(ctx)
63 if err != nil {
64 return err
65 }
66 defer conn.Close()
67 return orm.RunMigration(conn, d.logger, migrationName, insert)
68 }
69
70 tx, err := d.db.BeginTx(ctx, nil)
71 if err != nil {
72 return err
73 }
74 defer tx.Rollback()
75 if err := insert(tx); err != nil {
76 return err
77 }
78 return tx.Commit()
79}
80
81func ListCollaborators(q DBTX, repoDid syntax.DID, p ListPage) ([]Collaborator, *int, error) {
82 return listPaged(q,
83 `select id, repo_did, subject_did, added_by_did, created
84 from collaborators
85 where repo_did = ?`,
86 []any{repoDid}, p,
87 func(r *sql.Rows) (Collaborator, error) {
88 var c Collaborator
89 err := r.Scan(&c.Id, &c.RepoDid, &c.Subject, &c.AddedBy, &c.Created)
90 return c, err
91 },
92 func(c Collaborator) int { return c.Id },
93 )
94}