~james/core

core/spindle/db/collaborators.go -rw-r--r-- 3.0 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package db

import (
	"fmt"

	"github.com/bluesky-social/indigo/atproto/syntax"
)

type RepoCollaborator struct {
	OwnerDid syntax.DID
	Rkey     syntax.RecordKey
	Subject  syntax.DID
	RepoDid  syntax.DID
}

func (d *DB) AddRepoCollaborator(c RepoCollaborator) error {
	_, err := d.Exec(
		`insert into repo_collaborators (owner_did, rkey, subject, repo_did)
		 values (?, ?, ?, ?)
		 on conflict(owner_did, rkey) do update set
		     subject  = excluded.subject,
		     repo_did = excluded.repo_did`,
		c.OwnerDid.String(), c.Rkey.String(), c.Subject.String(), c.RepoDid.String(),
	)
	return err
}

func (d *DB) AddKnotCollaborator(repoDid, subject syntax.DID) error {
	_, err := d.Exec(
		`insert into repo_collaborators (owner_did, rkey, subject, repo_did)
		 values (?, ?, ?, ?)
		 on conflict(owner_did, rkey) do nothing`,
		repoDid.String(), subject.String(), subject.String(), repoDid.String(),
	)
	return err
}

func scanCollab(row interface{ Scan(...any) error }) (*RepoCollaborator, error) {
	var owner, rkey, subject, repoDid string
	if err := row.Scan(&owner, &rkey, &subject, &repoDid); err != nil {
		return nil, err
	}
	return &RepoCollaborator{
		OwnerDid: syntax.DID(owner),
		Rkey:     syntax.RecordKey(rkey),
		Subject:  syntax.DID(subject),
		RepoDid:  syntax.DID(repoDid),
	}, nil
}

func (d *DB) DeleteRepoCollaboratorBySubjectRepo(subject, repoDid syntax.DID) error {
	_, err := d.Exec(
		`delete from repo_collaborators where repo_did = ? and subject = ?`,
		repoDid.String(), subject.String(),
	)
	if err != nil {
		return fmt.Errorf("delete collaborator %s on %s: %w", subject, repoDid, err)
	}
	return nil
}

func (d *DB) DeleteRepoCollaboratorsByRepoDid(repoDid syntax.DID) error {
	_, err := d.Exec(`delete from repo_collaborators where repo_did = ?`, repoDid.String())
	if err != nil {
		return fmt.Errorf("delete collaborators for %s: %w", repoDid, err)
	}
	return nil
}

func (d *DB) ListCollaboratorsByRepoDid(repoDid syntax.DID) ([]RepoCollaborator, error) {
	rows, err := d.Query(
		`select owner_did, rkey, subject, repo_did from repo_collaborators where repo_did = ?`,
		repoDid.String(),
	)
	if err != nil {
		return nil, fmt.Errorf("list collaborators for %s: %w", repoDid, err)
	}
	defer rows.Close()

	var out []RepoCollaborator
	for rows.Next() {
		c, err := scanCollab(rows)
		if err != nil {
			return nil, err
		}
		out = append(out, *c)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return out, nil
}

func (d *DB) ListKnotCollaboratorsByRepoDid(repoDid syntax.DID) ([]RepoCollaborator, error) {
	rows, err := d.Query(
		`select owner_did, rkey, subject, repo_did from repo_collaborators
		 where repo_did = ? and owner_did = ?`,
		repoDid.String(), repoDid.String(),
	)
	if err != nil {
		return nil, fmt.Errorf("list knot collaborators for %s: %w", repoDid, err)
	}
	defer rows.Close()

	var out []RepoCollaborator
	for rows.Next() {
		c, err := scanCollab(rows)
		if err != nil {
			return nil, err
		}
		out = append(out, *c)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return out, nil
}