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