Monorepo for Tangled
tangled.org
1package db
2
3import (
4 "database/sql"
5 "fmt"
6 "strings"
7 "time"
8
9 "tangled.org/core/appview/models"
10 "tangled.org/core/orm"
11)
12
13func GetRegistrations(e Execer, filters ...orm.Filter) ([]models.Registration, error) {
14 var registrations []models.Registration
15
16 var conditions []string
17 var args []any
18 for _, filter := range filters {
19 conditions = append(conditions, filter.Condition())
20 args = append(args, filter.Arg()...)
21 }
22
23 whereClause := ""
24 if conditions != nil {
25 whereClause = " where " + strings.Join(conditions, " and ")
26 }
27
28 query := fmt.Sprintf(`
29 select id, domain, did, created, registered, needs_upgrade
30 from registrations
31 %s
32 order by created
33 `,
34 whereClause,
35 )
36
37 rows, err := e.Query(query, args...)
38 if err != nil {
39 return nil, err
40 }
41 defer rows.Close()
42
43 for rows.Next() {
44 var createdAt string
45 var registeredAt sql.Null[string]
46 var needsUpgrade int
47 var reg models.Registration
48
49 err = rows.Scan(®.Id, ®.Domain, ®.ByDid, &createdAt, ®isteredAt, &needsUpgrade)
50 if err != nil {
51 return nil, err
52 }
53
54 if t, err := time.Parse(time.RFC3339, createdAt); err == nil {
55 reg.Created = &t
56 }
57
58 if registeredAt.Valid {
59 if t, err := time.Parse(time.RFC3339, registeredAt.V); err == nil {
60 reg.Registered = &t
61 }
62 }
63
64 if needsUpgrade != 0 {
65 reg.NeedsUpgrade = true
66 }
67
68 registrations = append(registrations, reg)
69 }
70
71 return registrations, nil
72}
73
74func MarkRegistered(e Execer, filters ...orm.Filter) error {
75 var conditions []string
76 var args []any
77 for _, filter := range filters {
78 conditions = append(conditions, filter.Condition())
79 args = append(args, filter.Arg()...)
80 }
81
82 query := "update registrations set registered = strftime('%Y-%m-%dT%H:%M:%SZ', 'now'), needs_upgrade = 0"
83 if len(conditions) > 0 {
84 query += " where " + strings.Join(conditions, " and ")
85 }
86
87 _, err := e.Exec(query, args...)
88 return err
89}
90
91func AddKnot(e Execer, domain, did string) error {
92 _, err := e.Exec(`
93 insert into registrations (domain, did)
94 values (?, ?)
95 on conflict (domain, did) do nothing
96 `, domain, did)
97 return err
98}
99
100func DeleteKnot(e Execer, filters ...orm.Filter) error {
101 var conditions []string
102 var args []any
103 for _, filter := range filters {
104 conditions = append(conditions, filter.Condition())
105 args = append(args, filter.Arg()...)
106 }
107
108 whereClause := ""
109 if conditions != nil {
110 whereClause = " where " + strings.Join(conditions, " and ")
111 }
112
113 query := fmt.Sprintf(`delete from registrations %s`, whereClause)
114
115 _, err := e.Exec(query, args...)
116 return err
117}
118
119func AddKnotMember(e Execer, member models.KnotMember) error {
120 _, err := e.Exec(
121 `insert into knot_members (did, rkey, domain, subject)
122 values (?, ?, ?, ?)
123 on conflict (did, domain, subject) do update set rkey = excluded.rkey`,
124 member.Did,
125 member.Rkey,
126 member.Domain,
127 member.Subject,
128 )
129 return err
130}
131
132func RemoveKnotMember(e Execer, filters ...orm.Filter) error {
133 if len(filters) == 0 {
134 return fmt.Errorf("RemoveKnotMember requires at least one filter")
135 }
136
137 var conditions []string
138 var args []any
139 for _, filter := range filters {
140 conditions = append(conditions, filter.Condition())
141 args = append(args, filter.Arg()...)
142 }
143
144 query := fmt.Sprintf(`delete from knot_members where %s`, strings.Join(conditions, " and "))
145
146 _, err := e.Exec(query, args...)
147 return err
148}
149
150func GetKnotMembers(e Execer, filters ...orm.Filter) ([]models.KnotMember, error) {
151 var members []models.KnotMember
152
153 var conditions []string
154 var args []any
155 for _, filter := range filters {
156 conditions = append(conditions, filter.Condition())
157 args = append(args, filter.Arg()...)
158 }
159
160 whereClause := ""
161 if conditions != nil {
162 whereClause = " where " + strings.Join(conditions, " and ")
163 }
164
165 query := fmt.Sprintf(
166 `select id, did, rkey, domain, subject, created
167 from knot_members
168 %s
169 order by created
170 `,
171 whereClause,
172 )
173
174 rows, err := e.Query(query, args...)
175 if err != nil {
176 return nil, err
177 }
178 defer rows.Close()
179
180 for rows.Next() {
181 var member models.KnotMember
182 var createdAt string
183
184 if err := rows.Scan(
185 &member.Id,
186 &member.Did,
187 &member.Rkey,
188 &member.Domain,
189 &member.Subject,
190 &createdAt,
191 ); err != nil {
192 return nil, err
193 }
194
195 member.Created, err = time.Parse(time.RFC3339, createdAt)
196 if err != nil {
197 member.Created = time.Now()
198 }
199
200 members = append(members, member)
201 }
202
203 return members, nil
204}