Monorepo for Tangled
tangled.org
1package db
2
3import (
4 "database/sql"
5 "fmt"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8)
9
10type RepoCollaborator struct {
11 OwnerDid syntax.DID
12 Rkey syntax.RecordKey
13 Subject syntax.DID
14 RepoDid syntax.DID
15}
16
17func (d *DB) AddRepoCollaborator(c RepoCollaborator) error {
18 _, err := d.Exec(
19 `insert into repo_collaborators (owner_did, rkey, subject, repo_did)
20 values (?, ?, ?, ?)
21 on conflict(owner_did, rkey) do update set
22 subject = excluded.subject,
23 repo_did = excluded.repo_did`,
24 c.OwnerDid.String(), c.Rkey.String(), c.Subject.String(), c.RepoDid.String(),
25 )
26 return err
27}
28
29func scanCollab(row interface{ Scan(...any) error }) (*RepoCollaborator, error) {
30 var owner, rkey, subject, repoDid string
31 if err := row.Scan(&owner, &rkey, &subject, &repoDid); err != nil {
32 return nil, err
33 }
34 return &RepoCollaborator{
35 OwnerDid: syntax.DID(owner),
36 Rkey: syntax.RecordKey(rkey),
37 Subject: syntax.DID(subject),
38 RepoDid: syntax.DID(repoDid),
39 }, nil
40}
41
42func (d *DB) GetRepoCollaborator(ownerDid syntax.DID, rkey syntax.RecordKey) (*RepoCollaborator, error) {
43 return scanCollab(d.QueryRow(
44 `select owner_did, rkey, subject, repo_did from repo_collaborators where owner_did = ? and rkey = ?`,
45 ownerDid.String(), rkey.String(),
46 ))
47}
48
49func (d *DB) DeleteRepoCollaborator(ownerDid syntax.DID, rkey syntax.RecordKey) error {
50 res, err := d.Exec(`delete from repo_collaborators where owner_did = ? and rkey = ?`, ownerDid.String(), rkey.String())
51 if err != nil {
52 return err
53 }
54 n, err := res.RowsAffected()
55 if err != nil {
56 return err
57 }
58 if n == 0 {
59 return sql.ErrNoRows
60 }
61 return nil
62}
63
64func (d *DB) DeleteRepoCollaboratorsByRepoDid(repoDid syntax.DID) error {
65 _, err := d.Exec(`delete from repo_collaborators where repo_did = ?`, repoDid.String())
66 if err != nil {
67 return fmt.Errorf("delete collaborators for %s: %w", repoDid, err)
68 }
69 return nil
70}
71
72func (d *DB) ListCollaboratorsByRepoDid(repoDid syntax.DID) ([]RepoCollaborator, error) {
73 rows, err := d.Query(
74 `select owner_did, rkey, subject, repo_did from repo_collaborators where repo_did = ?`,
75 repoDid.String(),
76 )
77 if err != nil {
78 return nil, fmt.Errorf("list collaborators for %s: %w", repoDid, err)
79 }
80 defer rows.Close()
81
82 var out []RepoCollaborator
83 for rows.Next() {
84 c, err := scanCollab(rows)
85 if err != nil {
86 return nil, err
87 }
88 out = append(out, *c)
89 }
90 if err := rows.Err(); err != nil {
91 return nil, err
92 }
93 return out, nil
94}