tangled
alpha
login
or
join now
back
round
0
view raw
orm: extract orm package from appview
#875
merged
opened by
oppi.li
1 month ago
targeting
master
from
op/zxpquyouulmx
includes query and migration helpers
Signed-off-by: oppiliappan
me@oppi.li
options
unified
split
Changed files
+519
-464
appview
db
artifact.go
collaborators.go
db.go
follow.go
issues.go
label.go
language.go
notifications.go
pipeline.go
profile.go
pulls.go
punchcard.go
reference.go
registration.go
repos.go
spindle.go
star.go
strings.go
timeline.go
ingester.go
issues
issues.go
knots
knots.go
labels
labels.go
middleware
middleware.go
notifications
notifications.go
notify
db
db.go
oauth
handler.go
pipelines
pipelines.go
pulls
opengraph.go
pulls.go
repo
artifact.go
feed.go
index.go
opengraph.go
repo.go
repo_util.go
settings.go
tags.go
serververify
verify.go
spindles
spindles.go
state
gfi.go
knotstream.go
profile.go
spindlestream.go
state.go
strings
strings.go
validator
issue.go
orm
orm.go
+3
-2
appview/db/artifact.go
···
8
8
"github.com/go-git/go-git/v5/plumbing"
9
9
"github.com/ipfs/go-cid"
10
10
"tangled.org/core/appview/models"
11
11
+
"tangled.org/core/orm"
11
12
)
12
13
13
14
func AddArtifact(e Execer, artifact models.Artifact) error {
···
37
38
return err
38
39
}
39
40
40
40
-
func GetArtifact(e Execer, filters ...filter) ([]models.Artifact, error) {
41
41
+
func GetArtifact(e Execer, filters ...orm.Filter) ([]models.Artifact, error) {
41
42
var artifacts []models.Artifact
42
43
43
44
var conditions []string
···
109
110
return artifacts, nil
110
111
}
111
112
112
112
-
func DeleteArtifact(e Execer, filters ...filter) error {
113
113
+
func DeleteArtifact(e Execer, filters ...orm.Filter) error {
113
114
var conditions []string
114
115
var args []any
115
116
for _, filter := range filters {
+4
-3
appview/db/collaborators.go
···
6
6
"time"
7
7
8
8
"tangled.org/core/appview/models"
9
9
+
"tangled.org/core/orm"
9
10
)
10
11
11
12
func AddCollaborator(e Execer, c models.Collaborator) error {
···
16
17
return err
17
18
}
18
19
19
19
-
func DeleteCollaborator(e Execer, filters ...filter) error {
20
20
+
func DeleteCollaborator(e Execer, filters ...orm.Filter) error {
20
21
var conditions []string
21
22
var args []any
22
23
for _, filter := range filters {
···
58
59
return nil, nil
59
60
}
60
61
61
61
-
return GetRepos(e, 0, FilterIn("at_uri", repoAts))
62
62
+
return GetRepos(e, 0, orm.FilterIn("at_uri", repoAts))
62
63
}
63
64
64
64
-
func GetCollaborators(e Execer, filters ...filter) ([]models.Collaborator, error) {
65
65
+
func GetCollaborators(e Execer, filters ...orm.Filter) ([]models.Collaborator, error) {
65
66
var collaborators []models.Collaborator
66
67
var conditions []string
67
68
var args []any
+24
-137
appview/db/db.go
···
3
3
import (
4
4
"context"
5
5
"database/sql"
6
6
-
"fmt"
7
6
"log/slog"
8
8
-
"reflect"
9
7
"strings"
10
8
11
9
_ "github.com/mattn/go-sqlite3"
12
10
"tangled.org/core/log"
11
11
+
"tangled.org/core/orm"
13
12
)
14
13
15
14
type DB struct {
···
584
583
}
585
584
586
585
// run migrations
587
587
-
runMigration(conn, logger, "add-description-to-repos", func(tx *sql.Tx) error {
586
586
+
orm.RunMigration(conn, logger, "add-description-to-repos", func(tx *sql.Tx) error {
588
587
tx.Exec(`
589
588
alter table repos add column description text check (length(description) <= 200);
590
589
`)
591
590
return nil
592
591
})
593
592
594
594
-
runMigration(conn, logger, "add-rkey-to-pubkeys", func(tx *sql.Tx) error {
593
593
+
orm.RunMigration(conn, logger, "add-rkey-to-pubkeys", func(tx *sql.Tx) error {
595
594
// add unconstrained column
596
595
_, err := tx.Exec(`
597
596
alter table public_keys
···
614
613
return nil
615
614
})
616
615
617
617
-
runMigration(conn, logger, "add-rkey-to-comments", func(tx *sql.Tx) error {
616
616
+
orm.RunMigration(conn, logger, "add-rkey-to-comments", func(tx *sql.Tx) error {
618
617
_, err := tx.Exec(`
619
618
alter table comments drop column comment_at;
620
619
alter table comments add column rkey text;
···
622
621
return err
623
622
})
624
623
625
625
-
runMigration(conn, logger, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error {
624
624
+
orm.RunMigration(conn, logger, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error {
626
625
_, err := tx.Exec(`
627
626
alter table comments add column deleted text; -- timestamp
628
627
alter table comments add column edited text; -- timestamp
···
630
629
return err
631
630
})
632
631
633
633
-
runMigration(conn, logger, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error {
632
632
+
orm.RunMigration(conn, logger, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error {
634
633
_, err := tx.Exec(`
635
634
alter table pulls add column source_branch text;
636
635
alter table pulls add column source_repo_at text;
···
639
638
return err
640
639
})
641
640
642
642
-
runMigration(conn, logger, "add-source-to-repos", func(tx *sql.Tx) error {
641
641
+
orm.RunMigration(conn, logger, "add-source-to-repos", func(tx *sql.Tx) error {
643
642
_, err := tx.Exec(`
644
643
alter table repos add column source text;
645
644
`)
···
651
650
//
652
651
// [0]: https://sqlite.org/pragma.html#pragma_foreign_keys
653
652
conn.ExecContext(ctx, "pragma foreign_keys = off;")
654
654
-
runMigration(conn, logger, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error {
653
653
+
orm.RunMigration(conn, logger, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error {
655
654
_, err := tx.Exec(`
656
655
create table pulls_new (
657
656
-- identifiers
···
708
707
})
709
708
conn.ExecContext(ctx, "pragma foreign_keys = on;")
710
709
711
711
-
runMigration(conn, logger, "add-spindle-to-repos", func(tx *sql.Tx) error {
710
710
+
orm.RunMigration(conn, logger, "add-spindle-to-repos", func(tx *sql.Tx) error {
712
711
tx.Exec(`
713
712
alter table repos add column spindle text;
714
713
`)
···
718
717
// drop all knot secrets, add unique constraint to knots
719
718
//
720
719
// knots will henceforth use service auth for signed requests
721
721
-
runMigration(conn, logger, "no-more-secrets", func(tx *sql.Tx) error {
720
720
+
orm.RunMigration(conn, logger, "no-more-secrets", func(tx *sql.Tx) error {
722
721
_, err := tx.Exec(`
723
722
create table registrations_new (
724
723
id integer primary key autoincrement,
···
741
740
})
742
741
743
742
// recreate and add rkey + created columns with default constraint
744
744
-
runMigration(conn, logger, "rework-collaborators-table", func(tx *sql.Tx) error {
743
743
+
orm.RunMigration(conn, logger, "rework-collaborators-table", func(tx *sql.Tx) error {
745
744
// create new table
746
745
// - repo_at instead of repo integer
747
746
// - rkey field
···
795
794
return err
796
795
})
797
796
798
798
-
runMigration(conn, logger, "add-rkey-to-issues", func(tx *sql.Tx) error {
797
797
+
orm.RunMigration(conn, logger, "add-rkey-to-issues", func(tx *sql.Tx) error {
799
798
_, err := tx.Exec(`
800
799
alter table issues add column rkey text not null default '';
801
800
···
807
806
})
808
807
809
808
// repurpose the read-only column to "needs-upgrade"
810
810
-
runMigration(conn, logger, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error {
809
809
+
orm.RunMigration(conn, logger, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error {
811
810
_, err := tx.Exec(`
812
811
alter table registrations rename column read_only to needs_upgrade;
813
812
`)
···
815
814
})
816
815
817
816
// require all knots to upgrade after the release of total xrpc
818
818
-
runMigration(conn, logger, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error {
817
817
+
orm.RunMigration(conn, logger, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error {
819
818
_, err := tx.Exec(`
820
819
update registrations set needs_upgrade = 1;
821
820
`)
···
823
822
})
824
823
825
824
// require all knots to upgrade after the release of total xrpc
826
826
-
runMigration(conn, logger, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error {
825
825
+
orm.RunMigration(conn, logger, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error {
827
826
_, err := tx.Exec(`
828
827
alter table spindles add column needs_upgrade integer not null default 0;
829
828
`)
···
841
840
//
842
841
// disable foreign-keys for the next migration
843
842
conn.ExecContext(ctx, "pragma foreign_keys = off;")
844
844
-
runMigration(conn, logger, "remove-issue-at-from-issues", func(tx *sql.Tx) error {
843
843
+
orm.RunMigration(conn, logger, "remove-issue-at-from-issues", func(tx *sql.Tx) error {
845
844
_, err := tx.Exec(`
846
845
create table if not exists issues_new (
847
846
-- identifiers
···
911
910
// - new columns
912
911
// * column "reply_to" which can be any other comment
913
912
// * column "at-uri" which is a generated column
914
914
-
runMigration(conn, logger, "rework-issue-comments", func(tx *sql.Tx) error {
913
913
+
orm.RunMigration(conn, logger, "rework-issue-comments", func(tx *sql.Tx) error {
915
914
_, err := tx.Exec(`
916
915
create table if not exists issue_comments (
917
916
-- identifiers
···
971
970
//
972
971
// disable foreign-keys for the next migration
973
972
conn.ExecContext(ctx, "pragma foreign_keys = off;")
974
974
-
runMigration(conn, logger, "add-at-uri-to-pulls", func(tx *sql.Tx) error {
973
973
+
orm.RunMigration(conn, logger, "add-at-uri-to-pulls", func(tx *sql.Tx) error {
975
974
_, err := tx.Exec(`
976
975
create table if not exists pulls_new (
977
976
-- identifiers
···
1052
1051
//
1053
1052
// disable foreign-keys for the next migration
1054
1053
conn.ExecContext(ctx, "pragma foreign_keys = off;")
1055
1055
-
runMigration(conn, logger, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error {
1054
1054
+
orm.RunMigration(conn, logger, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error {
1056
1055
_, err := tx.Exec(`
1057
1056
create table if not exists pull_submissions_new (
1058
1057
-- identifiers
···
1106
1105
1107
1106
// knots may report the combined patch for a comparison, we can store that on the appview side
1108
1107
// (but not on the pds record), because calculating the combined patch requires a git index
1109
1109
-
runMigration(conn, logger, "add-combined-column-submissions", func(tx *sql.Tx) error {
1108
1108
+
orm.RunMigration(conn, logger, "add-combined-column-submissions", func(tx *sql.Tx) error {
1110
1109
_, err := tx.Exec(`
1111
1110
alter table pull_submissions add column combined text;
1112
1111
`)
1113
1112
return err
1114
1113
})
1115
1114
1116
1116
-
runMigration(conn, logger, "add-pronouns-profile", func(tx *sql.Tx) error {
1115
1115
+
orm.RunMigration(conn, logger, "add-pronouns-profile", func(tx *sql.Tx) error {
1117
1116
_, err := tx.Exec(`
1118
1117
alter table profile add column pronouns text;
1119
1118
`)
1120
1119
return err
1121
1120
})
1122
1121
1123
1123
-
runMigration(conn, logger, "add-meta-column-repos", func(tx *sql.Tx) error {
1122
1122
+
orm.RunMigration(conn, logger, "add-meta-column-repos", func(tx *sql.Tx) error {
1124
1123
_, err := tx.Exec(`
1125
1124
alter table repos add column website text;
1126
1125
alter table repos add column topics text;
···
1128
1127
return err
1129
1128
})
1130
1129
1131
1131
-
runMigration(conn, logger, "add-usermentioned-preference", func(tx *sql.Tx) error {
1130
1130
+
orm.RunMigration(conn, logger, "add-usermentioned-preference", func(tx *sql.Tx) error {
1132
1131
_, err := tx.Exec(`
1133
1132
alter table notification_preferences add column user_mentioned integer not null default 1;
1134
1133
`)
···
1136
1135
})
1137
1136
1138
1137
// remove the foreign key constraints from stars.
1139
1139
-
runMigration(conn, logger, "generalize-stars-subject", func(tx *sql.Tx) error {
1138
1138
+
orm.RunMigration(conn, logger, "generalize-stars-subject", func(tx *sql.Tx) error {
1140
1139
_, err := tx.Exec(`
1141
1140
create table stars_new (
1142
1141
id integer primary key autoincrement,
···
1180
1179
}, nil
1181
1180
}
1182
1181
1183
1183
-
type migrationFn = func(*sql.Tx) error
1184
1184
-
1185
1185
-
func runMigration(c *sql.Conn, logger *slog.Logger, name string, migrationFn migrationFn) error {
1186
1186
-
logger = logger.With("migration", name)
1187
1187
-
1188
1188
-
tx, err := c.BeginTx(context.Background(), nil)
1189
1189
-
if err != nil {
1190
1190
-
return err
1191
1191
-
}
1192
1192
-
defer tx.Rollback()
1193
1193
-
1194
1194
-
var exists bool
1195
1195
-
err = tx.QueryRow("select exists (select 1 from migrations where name = ?)", name).Scan(&exists)
1196
1196
-
if err != nil {
1197
1197
-
return err
1198
1198
-
}
1199
1199
-
1200
1200
-
if !exists {
1201
1201
-
// run migration
1202
1202
-
err = migrationFn(tx)
1203
1203
-
if err != nil {
1204
1204
-
logger.Error("failed to run migration", "err", err)
1205
1205
-
return err
1206
1206
-
}
1207
1207
-
1208
1208
-
// mark migration as complete
1209
1209
-
_, err = tx.Exec("insert into migrations (name) values (?)", name)
1210
1210
-
if err != nil {
1211
1211
-
logger.Error("failed to mark migration as complete", "err", err)
1212
1212
-
return err
1213
1213
-
}
1214
1214
-
1215
1215
-
// commit the transaction
1216
1216
-
if err := tx.Commit(); err != nil {
1217
1217
-
return err
1218
1218
-
}
1219
1219
-
1220
1220
-
logger.Info("migration applied successfully")
1221
1221
-
} else {
1222
1222
-
logger.Warn("skipped migration, already applied")
1223
1223
-
}
1224
1224
-
1225
1225
-
return nil
1226
1226
-
}
1227
1227
-
1228
1182
func (d *DB) Close() error {
1229
1183
return d.DB.Close()
1230
1184
}
1231
1231
-
1232
1232
-
type filter struct {
1233
1233
-
key string
1234
1234
-
arg any
1235
1235
-
cmp string
1236
1236
-
}
1237
1237
-
1238
1238
-
func newFilter(key, cmp string, arg any) filter {
1239
1239
-
return filter{
1240
1240
-
key: key,
1241
1241
-
arg: arg,
1242
1242
-
cmp: cmp,
1243
1243
-
}
1244
1244
-
}
1245
1245
-
1246
1246
-
func FilterEq(key string, arg any) filter { return newFilter(key, "=", arg) }
1247
1247
-
func FilterNotEq(key string, arg any) filter { return newFilter(key, "<>", arg) }
1248
1248
-
func FilterGte(key string, arg any) filter { return newFilter(key, ">=", arg) }
1249
1249
-
func FilterLte(key string, arg any) filter { return newFilter(key, "<=", arg) }
1250
1250
-
func FilterIs(key string, arg any) filter { return newFilter(key, "is", arg) }
1251
1251
-
func FilterIsNot(key string, arg any) filter { return newFilter(key, "is not", arg) }
1252
1252
-
func FilterIn(key string, arg any) filter { return newFilter(key, "in", arg) }
1253
1253
-
func FilterLike(key string, arg any) filter { return newFilter(key, "like", arg) }
1254
1254
-
func FilterNotLike(key string, arg any) filter { return newFilter(key, "not like", arg) }
1255
1255
-
func FilterContains(key string, arg any) filter {
1256
1256
-
return newFilter(key, "like", fmt.Sprintf("%%%v%%", arg))
1257
1257
-
}
1258
1258
-
1259
1259
-
func (f filter) Condition() string {
1260
1260
-
rv := reflect.ValueOf(f.arg)
1261
1261
-
kind := rv.Kind()
1262
1262
-
1263
1263
-
// if we have `FilterIn(k, [1, 2, 3])`, compile it down to `k in (?, ?, ?)`
1264
1264
-
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
1265
1265
-
if rv.Len() == 0 {
1266
1266
-
// always false
1267
1267
-
return "1 = 0"
1268
1268
-
}
1269
1269
-
1270
1270
-
placeholders := make([]string, rv.Len())
1271
1271
-
for i := range placeholders {
1272
1272
-
placeholders[i] = "?"
1273
1273
-
}
1274
1274
-
1275
1275
-
return fmt.Sprintf("%s %s (%s)", f.key, f.cmp, strings.Join(placeholders, ", "))
1276
1276
-
}
1277
1277
-
1278
1278
-
return fmt.Sprintf("%s %s ?", f.key, f.cmp)
1279
1279
-
}
1280
1280
-
1281
1281
-
func (f filter) Arg() []any {
1282
1282
-
rv := reflect.ValueOf(f.arg)
1283
1283
-
kind := rv.Kind()
1284
1284
-
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
1285
1285
-
if rv.Len() == 0 {
1286
1286
-
return nil
1287
1287
-
}
1288
1288
-
1289
1289
-
out := make([]any, rv.Len())
1290
1290
-
for i := range rv.Len() {
1291
1291
-
out[i] = rv.Index(i).Interface()
1292
1292
-
}
1293
1293
-
return out
1294
1294
-
}
1295
1295
-
1296
1296
-
return []any{f.arg}
1297
1297
-
}
+4
-3
appview/db/follow.go
···
7
7
"time"
8
8
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
13
func AddFollow(e Execer, follow *models.Follow) error {
···
134
135
return result, nil
135
136
}
136
137
137
137
-
func GetFollows(e Execer, limit int, filters ...filter) ([]models.Follow, error) {
138
138
+
func GetFollows(e Execer, limit int, filters ...orm.Filter) ([]models.Follow, error) {
138
139
var follows []models.Follow
139
140
140
141
var conditions []string
···
191
192
}
192
193
193
194
func GetFollowers(e Execer, did string) ([]models.Follow, error) {
194
194
-
return GetFollows(e, 0, FilterEq("subject_did", did))
195
195
+
return GetFollows(e, 0, orm.FilterEq("subject_did", did))
195
196
}
196
197
197
198
func GetFollowing(e Execer, did string) ([]models.Follow, error) {
198
198
-
return GetFollows(e, 0, FilterEq("user_did", did))
199
199
+
return GetFollows(e, 0, orm.FilterEq("user_did", did))
199
200
}
200
201
201
202
func getFollowStatuses(e Execer, userDid string, subjectDids []string) (map[string]models.FollowStatus, error) {
+21
-20
appview/db/issues.go
···
13
13
"tangled.org/core/api/tangled"
14
14
"tangled.org/core/appview/models"
15
15
"tangled.org/core/appview/pagination"
16
16
+
"tangled.org/core/orm"
16
17
)
17
18
18
19
func PutIssue(tx *sql.Tx, issue *models.Issue) error {
···
27
28
28
29
issues, err := GetIssues(
29
30
tx,
30
30
-
FilterEq("did", issue.Did),
31
31
-
FilterEq("rkey", issue.Rkey),
31
31
+
orm.FilterEq("did", issue.Did),
32
32
+
orm.FilterEq("rkey", issue.Rkey),
32
33
)
33
34
switch {
34
35
case err != nil:
···
98
99
return nil
99
100
}
100
101
101
101
-
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...filter) ([]models.Issue, error) {
102
102
+
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...orm.Filter) ([]models.Issue, error) {
102
103
issueMap := make(map[string]*models.Issue) // at-uri -> issue
103
104
104
105
var conditions []string
···
114
115
whereClause = " where " + strings.Join(conditions, " and ")
115
116
}
116
117
117
117
-
pLower := FilterGte("row_num", page.Offset+1)
118
118
-
pUpper := FilterLte("row_num", page.Offset+page.Limit)
118
118
+
pLower := orm.FilterGte("row_num", page.Offset+1)
119
119
+
pUpper := orm.FilterLte("row_num", page.Offset+page.Limit)
119
120
120
121
pageClause := ""
121
122
if page.Limit > 0 {
···
205
206
repoAts = append(repoAts, string(issue.RepoAt))
206
207
}
207
208
208
208
-
repos, err := GetRepos(e, 0, FilterIn("at_uri", repoAts))
209
209
+
repos, err := GetRepos(e, 0, orm.FilterIn("at_uri", repoAts))
209
210
if err != nil {
210
211
return nil, fmt.Errorf("failed to build repo mappings: %w", err)
211
212
}
···
228
229
// collect comments
229
230
issueAts := slices.Collect(maps.Keys(issueMap))
230
231
231
231
-
comments, err := GetIssueComments(e, FilterIn("issue_at", issueAts))
232
232
+
comments, err := GetIssueComments(e, orm.FilterIn("issue_at", issueAts))
232
233
if err != nil {
233
234
return nil, fmt.Errorf("failed to query comments: %w", err)
234
235
}
···
240
241
}
241
242
242
243
// collect allLabels for each issue
243
243
-
allLabels, err := GetLabels(e, FilterIn("subject", issueAts))
244
244
+
allLabels, err := GetLabels(e, orm.FilterIn("subject", issueAts))
244
245
if err != nil {
245
246
return nil, fmt.Errorf("failed to query labels: %w", err)
246
247
}
···
251
252
}
252
253
253
254
// collect references for each issue
254
254
-
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", issueAts))
255
255
+
allReferencs, err := GetReferencesAll(e, orm.FilterIn("from_at", issueAts))
255
256
if err != nil {
256
257
return nil, fmt.Errorf("failed to query reference_links: %w", err)
257
258
}
···
277
278
issues, err := GetIssuesPaginated(
278
279
e,
279
280
pagination.Page{},
280
280
-
FilterEq("repo_at", repoAt),
281
281
-
FilterEq("issue_id", issueId),
281
281
+
orm.FilterEq("repo_at", repoAt),
282
282
+
orm.FilterEq("issue_id", issueId),
282
283
)
283
284
if err != nil {
284
285
return nil, err
···
290
291
return &issues[0], nil
291
292
}
292
293
293
293
-
func GetIssues(e Execer, filters ...filter) ([]models.Issue, error) {
294
294
+
func GetIssues(e Execer, filters ...orm.Filter) ([]models.Issue, error) {
294
295
return GetIssuesPaginated(e, pagination.Page{}, filters...)
295
296
}
296
297
···
298
299
func GetIssueIDs(e Execer, opts models.IssueSearchOptions) ([]int64, error) {
299
300
var ids []int64
300
301
301
301
-
var filters []filter
302
302
+
var filters []orm.Filter
302
303
openValue := 0
303
304
if opts.IsOpen {
304
305
openValue = 1
305
306
}
306
306
-
filters = append(filters, FilterEq("open", openValue))
307
307
+
filters = append(filters, orm.FilterEq("open", openValue))
307
308
if opts.RepoAt != "" {
308
308
-
filters = append(filters, FilterEq("repo_at", opts.RepoAt))
309
309
+
filters = append(filters, orm.FilterEq("repo_at", opts.RepoAt))
309
310
}
310
311
311
312
var conditions []string
···
397
398
return id, nil
398
399
}
399
400
400
400
-
func DeleteIssueComments(e Execer, filters ...filter) error {
401
401
+
func DeleteIssueComments(e Execer, filters ...orm.Filter) error {
401
402
var conditions []string
402
403
var args []any
403
404
for _, filter := range filters {
···
416
417
return err
417
418
}
418
419
419
419
-
func GetIssueComments(e Execer, filters ...filter) ([]models.IssueComment, error) {
420
420
+
func GetIssueComments(e Execer, filters ...orm.Filter) ([]models.IssueComment, error) {
420
421
commentMap := make(map[string]*models.IssueComment)
421
422
422
423
var conditions []string
···
506
507
507
508
// collect references for each comments
508
509
commentAts := slices.Collect(maps.Keys(commentMap))
509
509
-
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts))
510
510
+
allReferencs, err := GetReferencesAll(e, orm.FilterIn("from_at", commentAts))
510
511
if err != nil {
511
512
return nil, fmt.Errorf("failed to query reference_links: %w", err)
512
513
}
···
548
549
return nil
549
550
}
550
551
551
551
-
func CloseIssues(e Execer, filters ...filter) error {
552
552
+
func CloseIssues(e Execer, filters ...orm.Filter) error {
552
553
var conditions []string
553
554
var args []any
554
555
for _, filter := range filters {
···
566
567
return err
567
568
}
568
569
569
569
-
func ReopenIssues(e Execer, filters ...filter) error {
570
570
+
func ReopenIssues(e Execer, filters ...orm.Filter) error {
570
571
var conditions []string
571
572
var args []any
572
573
for _, filter := range filters {
+8
-7
appview/db/label.go
···
10
10
11
11
"github.com/bluesky-social/indigo/atproto/syntax"
12
12
"tangled.org/core/appview/models"
13
13
+
"tangled.org/core/orm"
13
14
)
14
15
15
16
// no updating type for now
···
59
60
return id, nil
60
61
}
61
62
62
62
-
func DeleteLabelDefinition(e Execer, filters ...filter) error {
63
63
+
func DeleteLabelDefinition(e Execer, filters ...orm.Filter) error {
63
64
var conditions []string
64
65
var args []any
65
66
for _, filter := range filters {
···
75
76
return err
76
77
}
77
78
78
78
-
func GetLabelDefinitions(e Execer, filters ...filter) ([]models.LabelDefinition, error) {
79
79
+
func GetLabelDefinitions(e Execer, filters ...orm.Filter) ([]models.LabelDefinition, error) {
79
80
var labelDefinitions []models.LabelDefinition
80
81
var conditions []string
81
82
var args []any
···
167
168
}
168
169
169
170
// helper to get exactly one label def
170
170
-
func GetLabelDefinition(e Execer, filters ...filter) (*models.LabelDefinition, error) {
171
171
+
func GetLabelDefinition(e Execer, filters ...orm.Filter) (*models.LabelDefinition, error) {
171
172
labels, err := GetLabelDefinitions(e, filters...)
172
173
if err != nil {
173
174
return nil, err
···
227
228
return id, nil
228
229
}
229
230
230
230
-
func GetLabelOps(e Execer, filters ...filter) ([]models.LabelOp, error) {
231
231
+
func GetLabelOps(e Execer, filters ...orm.Filter) ([]models.LabelOp, error) {
231
232
var labelOps []models.LabelOp
232
233
var conditions []string
233
234
var args []any
···
302
303
}
303
304
304
305
// get labels for a given list of subject URIs
305
305
-
func GetLabels(e Execer, filters ...filter) (map[syntax.ATURI]models.LabelState, error) {
306
306
+
func GetLabels(e Execer, filters ...orm.Filter) (map[syntax.ATURI]models.LabelState, error) {
306
307
ops, err := GetLabelOps(e, filters...)
307
308
if err != nil {
308
309
return nil, err
···
322
323
}
323
324
labelAts := slices.Collect(maps.Keys(labelAtSet))
324
325
325
325
-
actx, err := NewLabelApplicationCtx(e, FilterIn("at_uri", labelAts))
326
326
+
actx, err := NewLabelApplicationCtx(e, orm.FilterIn("at_uri", labelAts))
326
327
if err != nil {
327
328
return nil, err
328
329
}
···
338
339
return results, nil
339
340
}
340
341
341
341
-
func NewLabelApplicationCtx(e Execer, filters ...filter) (*models.LabelApplicationCtx, error) {
342
342
+
func NewLabelApplicationCtx(e Execer, filters ...orm.Filter) (*models.LabelApplicationCtx, error) {
342
343
labels, err := GetLabelDefinitions(e, filters...)
343
344
if err != nil {
344
345
return nil, err
+5
-4
appview/db/language.go
···
7
7
8
8
"github.com/bluesky-social/indigo/atproto/syntax"
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
12
-
func GetRepoLanguages(e Execer, filters ...filter) ([]models.RepoLanguage, error) {
13
13
+
func GetRepoLanguages(e Execer, filters ...orm.Filter) ([]models.RepoLanguage, error) {
13
14
var conditions []string
14
15
var args []any
15
16
for _, filter := range filters {
···
85
86
return nil
86
87
}
87
88
88
88
-
func DeleteRepoLanguages(e Execer, filters ...filter) error {
89
89
+
func DeleteRepoLanguages(e Execer, filters ...orm.Filter) error {
89
90
var conditions []string
90
91
var args []any
91
92
for _, filter := range filters {
···
107
108
func UpdateRepoLanguages(tx *sql.Tx, repoAt syntax.ATURI, ref string, langs []models.RepoLanguage) error {
108
109
err := DeleteRepoLanguages(
109
110
tx,
110
110
-
FilterEq("repo_at", repoAt),
111
111
-
FilterEq("ref", ref),
111
111
+
orm.FilterEq("repo_at", repoAt),
112
112
+
orm.FilterEq("ref", ref),
112
113
)
113
114
if err != nil {
114
115
return fmt.Errorf("failed to delete existing languages: %w", err)
+14
-13
appview/db/notifications.go
···
11
11
"github.com/bluesky-social/indigo/atproto/syntax"
12
12
"tangled.org/core/appview/models"
13
13
"tangled.org/core/appview/pagination"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
17
func CreateNotification(e Execer, notification *models.Notification) error {
···
44
45
}
45
46
46
47
// GetNotificationsPaginated retrieves notifications with filters and pagination
47
47
-
func GetNotificationsPaginated(e Execer, page pagination.Page, filters ...filter) ([]*models.Notification, error) {
48
48
+
func GetNotificationsPaginated(e Execer, page pagination.Page, filters ...orm.Filter) ([]*models.Notification, error) {
48
49
var conditions []string
49
50
var args []any
50
51
···
113
114
}
114
115
115
116
// GetNotificationsWithEntities retrieves notifications with their related entities
116
116
-
func GetNotificationsWithEntities(e Execer, page pagination.Page, filters ...filter) ([]*models.NotificationWithEntity, error) {
117
117
+
func GetNotificationsWithEntities(e Execer, page pagination.Page, filters ...orm.Filter) ([]*models.NotificationWithEntity, error) {
117
118
var conditions []string
118
119
var args []any
119
120
···
256
257
}
257
258
258
259
// GetNotifications retrieves notifications with filters
259
259
-
func GetNotifications(e Execer, filters ...filter) ([]*models.Notification, error) {
260
260
+
func GetNotifications(e Execer, filters ...orm.Filter) ([]*models.Notification, error) {
260
261
return GetNotificationsPaginated(e, pagination.FirstPage(), filters...)
261
262
}
262
263
263
263
-
func CountNotifications(e Execer, filters ...filter) (int64, error) {
264
264
+
func CountNotifications(e Execer, filters ...orm.Filter) (int64, error) {
264
265
var conditions []string
265
266
var args []any
266
267
for _, filter := range filters {
···
285
286
}
286
287
287
288
func MarkNotificationRead(e Execer, notificationID int64, userDID string) error {
288
288
-
idFilter := FilterEq("id", notificationID)
289
289
-
recipientFilter := FilterEq("recipient_did", userDID)
289
289
+
idFilter := orm.FilterEq("id", notificationID)
290
290
+
recipientFilter := orm.FilterEq("recipient_did", userDID)
290
291
291
292
query := fmt.Sprintf(`
292
293
UPDATE notifications
···
314
315
}
315
316
316
317
func MarkAllNotificationsRead(e Execer, userDID string) error {
317
317
-
recipientFilter := FilterEq("recipient_did", userDID)
318
318
-
readFilter := FilterEq("read", 0)
318
318
+
recipientFilter := orm.FilterEq("recipient_did", userDID)
319
319
+
readFilter := orm.FilterEq("read", 0)
319
320
320
321
query := fmt.Sprintf(`
321
322
UPDATE notifications
···
334
335
}
335
336
336
337
func DeleteNotification(e Execer, notificationID int64, userDID string) error {
337
337
-
idFilter := FilterEq("id", notificationID)
338
338
-
recipientFilter := FilterEq("recipient_did", userDID)
338
338
+
idFilter := orm.FilterEq("id", notificationID)
339
339
+
recipientFilter := orm.FilterEq("recipient_did", userDID)
339
340
340
341
query := fmt.Sprintf(`
341
342
DELETE FROM notifications
···
362
363
}
363
364
364
365
func GetNotificationPreference(e Execer, userDid string) (*models.NotificationPreferences, error) {
365
365
-
prefs, err := GetNotificationPreferences(e, FilterEq("user_did", userDid))
366
366
+
prefs, err := GetNotificationPreferences(e, orm.FilterEq("user_did", userDid))
366
367
if err != nil {
367
368
return nil, err
368
369
}
···
375
376
return p, nil
376
377
}
377
378
378
378
-
func GetNotificationPreferences(e Execer, filters ...filter) (map[syntax.DID]*models.NotificationPreferences, error) {
379
379
+
func GetNotificationPreferences(e Execer, filters ...orm.Filter) (map[syntax.DID]*models.NotificationPreferences, error) {
379
380
prefsMap := make(map[syntax.DID]*models.NotificationPreferences)
380
381
381
382
var conditions []string
···
483
484
484
485
func (d *DB) ClearOldNotifications(ctx context.Context, olderThan time.Duration) error {
485
486
cutoff := time.Now().Add(-olderThan)
486
486
-
createdFilter := FilterLte("created", cutoff)
487
487
+
createdFilter := orm.FilterLte("created", cutoff)
487
488
488
489
query := fmt.Sprintf(`
489
490
DELETE FROM notifications
+6
-5
appview/db/pipeline.go
···
7
7
"time"
8
8
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
12
-
func GetPipelines(e Execer, filters ...filter) ([]models.Pipeline, error) {
13
13
+
func GetPipelines(e Execer, filters ...orm.Filter) ([]models.Pipeline, error) {
13
14
var pipelines []models.Pipeline
14
15
15
16
var conditions []string
···
168
169
169
170
// this is a mega query, but the most useful one:
170
171
// get N pipelines, for each one get the latest status of its N workflows
171
171
-
func GetPipelineStatuses(e Execer, limit int, filters ...filter) ([]models.Pipeline, error) {
172
172
+
func GetPipelineStatuses(e Execer, limit int, filters ...orm.Filter) ([]models.Pipeline, error) {
172
173
var conditions []string
173
174
var args []any
174
175
for _, filter := range filters {
175
175
-
filter.key = "p." + filter.key // the table is aliased in the query to `p`
176
176
+
filter.Key = "p." + filter.Key // the table is aliased in the query to `p`
176
177
conditions = append(conditions, filter.Condition())
177
178
args = append(args, filter.Arg()...)
178
179
}
···
264
265
conditions = nil
265
266
args = nil
266
267
for _, p := range pipelines {
267
267
-
knotFilter := FilterEq("pipeline_knot", p.Knot)
268
268
-
rkeyFilter := FilterEq("pipeline_rkey", p.Rkey)
268
268
+
knotFilter := orm.FilterEq("pipeline_knot", p.Knot)
269
269
+
rkeyFilter := orm.FilterEq("pipeline_rkey", p.Rkey)
269
270
conditions = append(conditions, fmt.Sprintf("(%s and %s)", knotFilter.Condition(), rkeyFilter.Condition()))
270
271
args = append(args, p.Knot)
271
272
args = append(args, p.Rkey)
+6
-5
appview/db/profile.go
···
11
11
12
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
13
"tangled.org/core/appview/models"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
17
const TimeframeMonths = 7
···
44
45
45
46
issues, err := GetIssues(
46
47
e,
47
47
-
FilterEq("did", forDid),
48
48
-
FilterGte("created", time.Now().AddDate(0, -TimeframeMonths, 0)),
48
48
+
orm.FilterEq("did", forDid),
49
49
+
orm.FilterGte("created", time.Now().AddDate(0, -TimeframeMonths, 0)),
49
50
)
50
51
if err != nil {
51
52
return nil, fmt.Errorf("error getting issues by owner did: %w", err)
···
65
66
*items = append(*items, &issue)
66
67
}
67
68
68
68
-
repos, err := GetRepos(e, 0, FilterEq("did", forDid))
69
69
+
repos, err := GetRepos(e, 0, orm.FilterEq("did", forDid))
69
70
if err != nil {
70
71
return nil, fmt.Errorf("error getting all repos by did: %w", err)
71
72
}
···
199
200
return tx.Commit()
200
201
}
201
202
202
202
-
func GetProfiles(e Execer, filters ...filter) (map[string]*models.Profile, error) {
203
203
+
func GetProfiles(e Execer, filters ...orm.Filter) (map[string]*models.Profile, error) {
203
204
var conditions []string
204
205
var args []any
205
206
for _, filter := range filters {
···
441
442
}
442
443
443
444
// ensure all pinned repos are either own repos or collaborating repos
444
444
-
repos, err := GetRepos(e, 0, FilterEq("did", profile.Did))
445
445
+
repos, err := GetRepos(e, 0, orm.FilterEq("did", profile.Did))
445
446
if err != nil {
446
447
log.Printf("getting repos for %s: %s", profile.Did, err)
447
448
}
+21
-20
appview/db/pulls.go
···
13
13
14
14
"github.com/bluesky-social/indigo/atproto/syntax"
15
15
"tangled.org/core/appview/models"
16
16
+
"tangled.org/core/orm"
16
17
)
17
18
18
19
func NewPull(tx *sql.Tx, pull *models.Pull) error {
···
118
119
return pullId - 1, err
119
120
}
120
121
121
121
-
func GetPullsWithLimit(e Execer, limit int, filters ...filter) ([]*models.Pull, error) {
122
122
+
func GetPullsWithLimit(e Execer, limit int, filters ...orm.Filter) ([]*models.Pull, error) {
122
123
pulls := make(map[syntax.ATURI]*models.Pull)
123
124
124
125
var conditions []string
···
229
230
for _, p := range pulls {
230
231
pullAts = append(pullAts, p.AtUri())
231
232
}
232
232
-
submissionsMap, err := GetPullSubmissions(e, FilterIn("pull_at", pullAts))
233
233
+
submissionsMap, err := GetPullSubmissions(e, orm.FilterIn("pull_at", pullAts))
233
234
if err != nil {
234
235
return nil, fmt.Errorf("failed to get submissions: %w", err)
235
236
}
···
241
242
}
242
243
243
244
// collect allLabels for each issue
244
244
-
allLabels, err := GetLabels(e, FilterIn("subject", pullAts))
245
245
+
allLabels, err := GetLabels(e, orm.FilterIn("subject", pullAts))
245
246
if err != nil {
246
247
return nil, fmt.Errorf("failed to query labels: %w", err)
247
248
}
···
258
259
sourceAts = append(sourceAts, *p.PullSource.RepoAt)
259
260
}
260
261
}
261
261
-
sourceRepos, err := GetRepos(e, 0, FilterIn("at_uri", sourceAts))
262
262
+
sourceRepos, err := GetRepos(e, 0, orm.FilterIn("at_uri", sourceAts))
262
263
if err != nil && !errors.Is(err, sql.ErrNoRows) {
263
264
return nil, fmt.Errorf("failed to get source repos: %w", err)
264
265
}
···
274
275
}
275
276
}
276
277
277
277
-
allReferences, err := GetReferencesAll(e, FilterIn("from_at", pullAts))
278
278
+
allReferences, err := GetReferencesAll(e, orm.FilterIn("from_at", pullAts))
278
279
if err != nil {
279
280
return nil, fmt.Errorf("failed to query reference_links: %w", err)
280
281
}
···
295
296
return orderedByPullId, nil
296
297
}
297
298
298
298
-
func GetPulls(e Execer, filters ...filter) ([]*models.Pull, error) {
299
299
+
func GetPulls(e Execer, filters ...orm.Filter) ([]*models.Pull, error) {
299
300
return GetPullsWithLimit(e, 0, filters...)
300
301
}
301
302
302
303
func GetPullIDs(e Execer, opts models.PullSearchOptions) ([]int64, error) {
303
304
var ids []int64
304
305
305
305
-
var filters []filter
306
306
-
filters = append(filters, FilterEq("state", opts.State))
306
306
+
var filters []orm.Filter
307
307
+
filters = append(filters, orm.FilterEq("state", opts.State))
307
308
if opts.RepoAt != "" {
308
308
-
filters = append(filters, FilterEq("repo_at", opts.RepoAt))
309
309
+
filters = append(filters, orm.FilterEq("repo_at", opts.RepoAt))
309
310
}
310
311
311
312
var conditions []string
···
361
362
}
362
363
363
364
func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*models.Pull, error) {
364
364
-
pulls, err := GetPullsWithLimit(e, 1, FilterEq("repo_at", repoAt), FilterEq("pull_id", pullId))
365
365
+
pulls, err := GetPullsWithLimit(e, 1, orm.FilterEq("repo_at", repoAt), orm.FilterEq("pull_id", pullId))
365
366
if err != nil {
366
367
return nil, err
367
368
}
···
373
374
}
374
375
375
376
// mapping from pull -> pull submissions
376
376
-
func GetPullSubmissions(e Execer, filters ...filter) (map[syntax.ATURI][]*models.PullSubmission, error) {
377
377
+
func GetPullSubmissions(e Execer, filters ...orm.Filter) (map[syntax.ATURI][]*models.PullSubmission, error) {
377
378
var conditions []string
378
379
var args []any
379
380
for _, filter := range filters {
···
448
449
449
450
// Get comments for all submissions using GetPullComments
450
451
submissionIds := slices.Collect(maps.Keys(submissionMap))
451
451
-
comments, err := GetPullComments(e, FilterIn("submission_id", submissionIds))
452
452
+
comments, err := GetPullComments(e, orm.FilterIn("submission_id", submissionIds))
452
453
if err != nil {
453
454
return nil, fmt.Errorf("failed to get pull comments: %w", err)
454
455
}
···
474
475
return m, nil
475
476
}
476
477
477
477
-
func GetPullComments(e Execer, filters ...filter) ([]models.PullComment, error) {
478
478
+
func GetPullComments(e Execer, filters ...orm.Filter) ([]models.PullComment, error) {
478
479
var conditions []string
479
480
var args []any
480
481
for _, filter := range filters {
···
542
543
543
544
// collect references for each comments
544
545
commentAts := slices.Collect(maps.Keys(commentMap))
545
545
-
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts))
546
546
+
allReferencs, err := GetReferencesAll(e, orm.FilterIn("from_at", commentAts))
546
547
if err != nil {
547
548
return nil, fmt.Errorf("failed to query reference_links: %w", err)
548
549
}
···
708
709
return err
709
710
}
710
711
711
711
-
func SetPullParentChangeId(e Execer, parentChangeId string, filters ...filter) error {
712
712
+
func SetPullParentChangeId(e Execer, parentChangeId string, filters ...orm.Filter) error {
712
713
var conditions []string
713
714
var args []any
714
715
···
732
733
733
734
// Only used when stacking to update contents in the event of a rebase (the interdiff should be empty).
734
735
// otherwise submissions are immutable
735
735
-
func UpdatePull(e Execer, newPatch, sourceRev string, filters ...filter) error {
736
736
+
func UpdatePull(e Execer, newPatch, sourceRev string, filters ...orm.Filter) error {
736
737
var conditions []string
737
738
var args []any
738
739
···
790
791
func GetStack(e Execer, stackId string) (models.Stack, error) {
791
792
unorderedPulls, err := GetPulls(
792
793
e,
793
793
-
FilterEq("stack_id", stackId),
794
794
-
FilterNotEq("state", models.PullDeleted),
794
794
+
orm.FilterEq("stack_id", stackId),
795
795
+
orm.FilterNotEq("state", models.PullDeleted),
795
796
)
796
797
if err != nil {
797
798
return nil, err
···
835
836
func GetAbandonedPulls(e Execer, stackId string) ([]*models.Pull, error) {
836
837
pulls, err := GetPulls(
837
838
e,
838
838
-
FilterEq("stack_id", stackId),
839
839
-
FilterEq("state", models.PullDeleted),
839
839
+
orm.FilterEq("stack_id", stackId),
840
840
+
orm.FilterEq("state", models.PullDeleted),
840
841
)
841
842
if err != nil {
842
843
return nil, err
+2
-1
appview/db/punchcard.go
···
7
7
"time"
8
8
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
13
// this adds to the existing count
···
20
21
return err
21
22
}
22
23
23
23
-
func MakePunchcard(e Execer, filters ...filter) (*models.Punchcard, error) {
24
24
+
func MakePunchcard(e Execer, filters ...orm.Filter) (*models.Punchcard, error) {
24
25
punchcard := &models.Punchcard{}
25
26
now := time.Now()
26
27
startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
+4
-3
appview/db/reference.go
···
8
8
"github.com/bluesky-social/indigo/atproto/syntax"
9
9
"tangled.org/core/api/tangled"
10
10
"tangled.org/core/appview/models"
11
11
+
"tangled.org/core/orm"
11
12
)
12
13
13
14
// ValidateReferenceLinks resolves refLinks to Issue/PR/IssueComment/PullComment ATURIs.
···
205
206
return err
206
207
}
207
208
208
208
-
func GetReferencesAll(e Execer, filters ...filter) (map[syntax.ATURI][]syntax.ATURI, error) {
209
209
+
func GetReferencesAll(e Execer, filters ...orm.Filter) (map[syntax.ATURI][]syntax.ATURI, error) {
209
210
var (
210
211
conditions []string
211
212
args []any
···
347
348
if len(aturis) == 0 {
348
349
return nil, nil
349
350
}
350
350
-
filter := FilterIn("c.at_uri", aturis)
351
351
+
filter := orm.FilterIn("c.at_uri", aturis)
351
352
rows, err := e.Query(
352
353
fmt.Sprintf(
353
354
`select r.did, r.name, i.issue_id, c.id, i.title, i.open
···
427
428
if len(aturis) == 0 {
428
429
return nil, nil
429
430
}
430
430
-
filter := FilterIn("c.comment_at", aturis)
431
431
+
filter := orm.FilterIn("c.comment_at", aturis)
431
432
rows, err := e.Query(
432
433
fmt.Sprintf(
433
434
`select r.did, r.name, p.pull_id, c.id, p.title, p.state
+4
-3
appview/db/registration.go
···
7
7
"time"
8
8
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
12
-
func GetRegistrations(e Execer, filters ...filter) ([]models.Registration, error) {
13
13
+
func GetRegistrations(e Execer, filters ...orm.Filter) ([]models.Registration, error) {
13
14
var registrations []models.Registration
14
15
15
16
var conditions []string
···
69
70
return registrations, nil
70
71
}
71
72
72
72
-
func MarkRegistered(e Execer, filters ...filter) error {
73
73
+
func MarkRegistered(e Execer, filters ...orm.Filter) error {
73
74
var conditions []string
74
75
var args []any
75
76
for _, filter := range filters {
···
94
95
return err
95
96
}
96
97
97
97
-
func DeleteKnot(e Execer, filters ...filter) error {
98
98
+
func DeleteKnot(e Execer, filters ...orm.Filter) error {
98
99
var conditions []string
99
100
var args []any
100
101
for _, filter := range filters {
+6
-5
appview/db/repos.go
···
11
11
12
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
13
"tangled.org/core/appview/models"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
16
-
func GetRepos(e Execer, limit int, filters ...filter) ([]models.Repo, error) {
17
17
+
func GetRepos(e Execer, limit int, filters ...orm.Filter) ([]models.Repo, error) {
17
18
repoMap := make(map[syntax.ATURI]*models.Repo)
18
19
19
20
var conditions []string
···
294
295
}
295
296
296
297
// helper to get exactly one repo
297
297
-
func GetRepo(e Execer, filters ...filter) (*models.Repo, error) {
298
298
+
func GetRepo(e Execer, filters ...orm.Filter) (*models.Repo, error) {
298
299
repos, err := GetRepos(e, 0, filters...)
299
300
if err != nil {
300
301
return nil, err
···
311
312
return &repos[0], nil
312
313
}
313
314
314
314
-
func CountRepos(e Execer, filters ...filter) (int64, error) {
315
315
+
func CountRepos(e Execer, filters ...orm.Filter) (int64, error) {
315
316
var conditions []string
316
317
var args []any
317
318
for _, filter := range filters {
···
542
543
return err
543
544
}
544
545
545
545
-
func UnsubscribeLabel(e Execer, filters ...filter) error {
546
546
+
func UnsubscribeLabel(e Execer, filters ...orm.Filter) error {
546
547
var conditions []string
547
548
var args []any
548
549
for _, filter := range filters {
···
560
561
return err
561
562
}
562
563
563
563
-
func GetRepoLabels(e Execer, filters ...filter) ([]models.RepoLabel, error) {
564
564
+
func GetRepoLabels(e Execer, filters ...orm.Filter) ([]models.RepoLabel, error) {
564
565
var conditions []string
565
566
var args []any
566
567
for _, filter := range filters {
+6
-5
appview/db/spindle.go
···
7
7
"time"
8
8
9
9
"tangled.org/core/appview/models"
10
10
+
"tangled.org/core/orm"
10
11
)
11
12
12
12
-
func GetSpindles(e Execer, filters ...filter) ([]models.Spindle, error) {
13
13
+
func GetSpindles(e Execer, filters ...orm.Filter) ([]models.Spindle, error) {
13
14
var spindles []models.Spindle
14
15
15
16
var conditions []string
···
91
92
return err
92
93
}
93
94
94
94
-
func VerifySpindle(e Execer, filters ...filter) (int64, error) {
95
95
+
func VerifySpindle(e Execer, filters ...orm.Filter) (int64, error) {
95
96
var conditions []string
96
97
var args []any
97
98
for _, filter := range filters {
···
114
115
return res.RowsAffected()
115
116
}
116
117
117
117
-
func DeleteSpindle(e Execer, filters ...filter) error {
118
118
+
func DeleteSpindle(e Execer, filters ...orm.Filter) error {
118
119
var conditions []string
119
120
var args []any
120
121
for _, filter := range filters {
···
144
145
return err
145
146
}
146
147
147
147
-
func RemoveSpindleMember(e Execer, filters ...filter) error {
148
148
+
func RemoveSpindleMember(e Execer, filters ...orm.Filter) error {
148
149
var conditions []string
149
150
var args []any
150
151
for _, filter := range filters {
···
163
164
return err
164
165
}
165
166
166
166
-
func GetSpindleMembers(e Execer, filters ...filter) ([]models.SpindleMember, error) {
167
167
+
func GetSpindleMembers(e Execer, filters ...orm.Filter) ([]models.SpindleMember, error) {
167
168
var members []models.SpindleMember
168
169
169
170
var conditions []string
+5
-4
appview/db/star.go
···
11
11
12
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
13
"tangled.org/core/appview/models"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
17
func AddStar(e Execer, star *models.Star) error {
···
133
134
134
135
// GetRepoStars return a list of stars each holding target repository.
135
136
// If there isn't known repo with starred at-uri, those stars will be ignored.
136
136
-
func GetRepoStars(e Execer, limit int, filters ...filter) ([]models.RepoStar, error) {
137
137
+
func GetRepoStars(e Execer, limit int, filters ...orm.Filter) ([]models.RepoStar, error) {
137
138
var conditions []string
138
139
var args []any
139
140
for _, filter := range filters {
···
195
196
return nil, nil
196
197
}
197
198
198
198
-
repos, err := GetRepos(e, 0, FilterIn("at_uri", args))
199
199
+
repos, err := GetRepos(e, 0, orm.FilterIn("at_uri", args))
199
200
if err != nil {
200
201
return nil, err
201
202
}
···
225
226
return repoStars, nil
226
227
}
227
228
228
228
-
func CountStars(e Execer, filters ...filter) (int64, error) {
229
229
+
func CountStars(e Execer, filters ...orm.Filter) (int64, error) {
229
230
var conditions []string
230
231
var args []any
231
232
for _, filter := range filters {
···
298
299
}
299
300
300
301
// get full repo data
301
301
-
repos, err := GetRepos(e, 0, FilterIn("at_uri", repoUris))
302
302
+
repos, err := GetRepos(e, 0, orm.FilterIn("at_uri", repoUris))
302
303
if err != nil {
303
304
return nil, err
304
305
}
+4
-3
appview/db/strings.go
···
8
8
"time"
9
9
10
10
"tangled.org/core/appview/models"
11
11
+
"tangled.org/core/orm"
11
12
)
12
13
13
14
func AddString(e Execer, s models.String) error {
···
44
45
return err
45
46
}
46
47
47
47
-
func GetStrings(e Execer, limit int, filters ...filter) ([]models.String, error) {
48
48
+
func GetStrings(e Execer, limit int, filters ...orm.Filter) ([]models.String, error) {
48
49
var all []models.String
49
50
50
51
var conditions []string
···
127
128
return all, nil
128
129
}
129
130
130
130
-
func CountStrings(e Execer, filters ...filter) (int64, error) {
131
131
+
func CountStrings(e Execer, filters ...orm.Filter) (int64, error) {
131
132
var conditions []string
132
133
var args []any
133
134
for _, filter := range filters {
···
151
152
return count, nil
152
153
}
153
154
154
154
-
func DeleteString(e Execer, filters ...filter) error {
155
155
+
func DeleteString(e Execer, filters ...orm.Filter) error {
155
156
var conditions []string
156
157
var args []any
157
158
for _, filter := range filters {
+9
-8
appview/db/timeline.go
···
5
5
6
6
"github.com/bluesky-social/indigo/atproto/syntax"
7
7
"tangled.org/core/appview/models"
8
8
+
"tangled.org/core/orm"
8
9
)
9
10
10
11
// TODO: this gathers heterogenous events from different sources and aggregates
···
84
85
}
85
86
86
87
func getTimelineRepos(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) {
87
87
-
filters := make([]filter, 0)
88
88
+
filters := make([]orm.Filter, 0)
88
89
if userIsFollowing != nil {
89
89
-
filters = append(filters, FilterIn("did", userIsFollowing))
90
90
+
filters = append(filters, orm.FilterIn("did", userIsFollowing))
90
91
}
91
92
92
93
repos, err := GetRepos(e, limit, filters...)
···
104
105
105
106
var origRepos []models.Repo
106
107
if args != nil {
107
107
-
origRepos, err = GetRepos(e, 0, FilterIn("at_uri", args))
108
108
+
origRepos, err = GetRepos(e, 0, orm.FilterIn("at_uri", args))
108
109
}
109
110
if err != nil {
110
111
return nil, err
···
144
145
}
145
146
146
147
func getTimelineStars(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) {
147
147
-
filters := make([]filter, 0)
148
148
+
filters := make([]orm.Filter, 0)
148
149
if userIsFollowing != nil {
149
149
-
filters = append(filters, FilterIn("did", userIsFollowing))
150
150
+
filters = append(filters, orm.FilterIn("did", userIsFollowing))
150
151
}
151
152
152
153
stars, err := GetRepoStars(e, limit, filters...)
···
180
181
}
181
182
182
183
func getTimelineFollows(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) {
183
183
-
filters := make([]filter, 0)
184
184
+
filters := make([]orm.Filter, 0)
184
185
if userIsFollowing != nil {
185
185
-
filters = append(filters, FilterIn("user_did", userIsFollowing))
186
186
+
filters = append(filters, orm.FilterIn("user_did", userIsFollowing))
186
187
}
187
188
188
189
follows, err := GetFollows(e, limit, filters...)
···
199
200
return nil, nil
200
201
}
201
202
202
202
-
profiles, err := GetProfiles(e, FilterIn("did", subjects))
203
203
+
profiles, err := GetProfiles(e, orm.FilterIn("did", subjects))
203
204
if err != nil {
204
205
return nil, err
205
206
}
+25
-24
appview/ingester.go
···
21
21
"tangled.org/core/appview/serververify"
22
22
"tangled.org/core/appview/validator"
23
23
"tangled.org/core/idresolver"
24
24
+
"tangled.org/core/orm"
24
25
"tangled.org/core/rbac"
25
26
)
26
27
···
253
254
254
255
err = db.AddArtifact(i.Db, artifact)
255
256
case jmodels.CommitOperationDelete:
256
256
-
err = db.DeleteArtifact(i.Db, db.FilterEq("did", did), db.FilterEq("rkey", e.Commit.RKey))
257
257
+
err = db.DeleteArtifact(i.Db, orm.FilterEq("did", did), orm.FilterEq("rkey", e.Commit.RKey))
257
258
}
258
259
259
260
if err != nil {
···
350
351
351
352
err = db.UpsertProfile(tx, &profile)
352
353
case jmodels.CommitOperationDelete:
353
353
-
err = db.DeleteArtifact(i.Db, db.FilterEq("did", did), db.FilterEq("rkey", e.Commit.RKey))
354
354
+
err = db.DeleteArtifact(i.Db, orm.FilterEq("did", did), orm.FilterEq("rkey", e.Commit.RKey))
354
355
}
355
356
356
357
if err != nil {
···
424
425
// get record from db first
425
426
members, err := db.GetSpindleMembers(
426
427
ddb,
427
427
-
db.FilterEq("did", did),
428
428
-
db.FilterEq("rkey", rkey),
428
428
+
orm.FilterEq("did", did),
429
429
+
orm.FilterEq("rkey", rkey),
429
430
)
430
431
if err != nil || len(members) != 1 {
431
432
return fmt.Errorf("failed to get member: %w, len(members) = %d", err, len(members))
···
440
441
// remove record by rkey && update enforcer
441
442
if err = db.RemoveSpindleMember(
442
443
tx,
443
443
-
db.FilterEq("did", did),
444
444
-
db.FilterEq("rkey", rkey),
444
444
+
orm.FilterEq("did", did),
445
445
+
orm.FilterEq("rkey", rkey),
445
446
); err != nil {
446
447
return fmt.Errorf("failed to remove from db: %w", err)
447
448
}
···
523
524
// get record from db first
524
525
spindles, err := db.GetSpindles(
525
526
ddb,
526
526
-
db.FilterEq("owner", did),
527
527
-
db.FilterEq("instance", instance),
527
527
+
orm.FilterEq("owner", did),
528
528
+
orm.FilterEq("instance", instance),
528
529
)
529
530
if err != nil || len(spindles) != 1 {
530
531
return fmt.Errorf("failed to get spindles: %w, len(spindles) = %d", err, len(spindles))
···
543
544
// remove spindle members first
544
545
err = db.RemoveSpindleMember(
545
546
tx,
546
546
-
db.FilterEq("owner", did),
547
547
-
db.FilterEq("instance", instance),
547
547
+
orm.FilterEq("owner", did),
548
548
+
orm.FilterEq("instance", instance),
548
549
)
549
550
if err != nil {
550
551
return err
···
552
553
553
554
err = db.DeleteSpindle(
554
555
tx,
555
555
-
db.FilterEq("owner", did),
556
556
-
db.FilterEq("instance", instance),
556
556
+
orm.FilterEq("owner", did),
557
557
+
orm.FilterEq("instance", instance),
557
558
)
558
559
if err != nil {
559
560
return err
···
621
622
case jmodels.CommitOperationDelete:
622
623
if err := db.DeleteString(
623
624
ddb,
624
624
-
db.FilterEq("did", did),
625
625
-
db.FilterEq("rkey", rkey),
625
625
+
orm.FilterEq("did", did),
626
626
+
orm.FilterEq("rkey", rkey),
626
627
); err != nil {
627
628
l.Error("failed to delete", "err", err)
628
629
return fmt.Errorf("failed to delete string record: %w", err)
···
740
741
// get record from db first
741
742
registrations, err := db.GetRegistrations(
742
743
ddb,
743
743
-
db.FilterEq("domain", domain),
744
744
-
db.FilterEq("did", did),
744
744
+
orm.FilterEq("domain", domain),
745
745
+
orm.FilterEq("did", did),
745
746
)
746
747
if err != nil {
747
748
return fmt.Errorf("failed to get registration: %w", err)
···
762
763
763
764
err = db.DeleteKnot(
764
765
tx,
765
765
-
db.FilterEq("did", did),
766
766
-
db.FilterEq("domain", domain),
766
766
+
orm.FilterEq("did", did),
767
767
+
orm.FilterEq("domain", domain),
767
768
)
768
769
if err != nil {
769
770
return err
···
915
916
case jmodels.CommitOperationDelete:
916
917
if err := db.DeleteIssueComments(
917
918
ddb,
918
918
-
db.FilterEq("did", did),
919
919
-
db.FilterEq("rkey", rkey),
919
919
+
orm.FilterEq("did", did),
920
920
+
orm.FilterEq("rkey", rkey),
920
921
); err != nil {
921
922
return fmt.Errorf("failed to delete issue comment record: %w", err)
922
923
}
···
969
970
case jmodels.CommitOperationDelete:
970
971
if err := db.DeleteLabelDefinition(
971
972
ddb,
972
972
-
db.FilterEq("did", did),
973
973
-
db.FilterEq("rkey", rkey),
973
973
+
orm.FilterEq("did", did),
974
974
+
orm.FilterEq("rkey", rkey),
974
975
); err != nil {
975
976
return fmt.Errorf("failed to delete labeldef record: %w", err)
976
977
}
···
1010
1011
var repo *models.Repo
1011
1012
switch collection {
1012
1013
case tangled.RepoIssueNSID:
1013
1013
-
i, err := db.GetIssues(ddb, db.FilterEq("at_uri", subject))
1014
1014
+
i, err := db.GetIssues(ddb, orm.FilterEq("at_uri", subject))
1014
1015
if err != nil || len(i) != 1 {
1015
1016
return fmt.Errorf("failed to find subject: %w || subject count %d", err, len(i))
1016
1017
}
···
1019
1020
return fmt.Errorf("unsupport label subject: %s", collection)
1020
1021
}
1021
1022
1022
1022
-
actx, err := db.NewLabelApplicationCtx(ddb, db.FilterIn("at_uri", repo.Labels))
1023
1023
+
actx, err := db.NewLabelApplicationCtx(ddb, orm.FilterIn("at_uri", repo.Labels))
1023
1024
if err != nil {
1024
1025
return fmt.Errorf("failed to build label application ctx: %w", err)
1025
1026
}
+16
-15
appview/issues/issues.go
···
29
29
"tangled.org/core/appview/reporesolver"
30
30
"tangled.org/core/appview/validator"
31
31
"tangled.org/core/idresolver"
32
32
+
"tangled.org/core/orm"
32
33
"tangled.org/core/rbac"
33
34
"tangled.org/core/tid"
34
35
)
···
113
114
114
115
labelDefs, err := db.GetLabelDefinitions(
115
116
rp.db,
116
116
-
db.FilterIn("at_uri", f.Labels),
117
117
-
db.FilterContains("scope", tangled.RepoIssueNSID),
117
117
+
orm.FilterIn("at_uri", f.Labels),
118
118
+
orm.FilterContains("scope", tangled.RepoIssueNSID),
118
119
)
119
120
if err != nil {
120
121
l.Error("failed to fetch labels", "err", err)
···
314
315
if isIssueOwner || isRepoOwner || isCollaborator {
315
316
err = db.CloseIssues(
316
317
rp.db,
317
317
-
db.FilterEq("id", issue.Id),
318
318
+
orm.FilterEq("id", issue.Id),
318
319
)
319
320
if err != nil {
320
321
l.Error("failed to close issue", "err", err)
···
361
362
if isCollaborator || isRepoOwner || isIssueOwner {
362
363
err := db.ReopenIssues(
363
364
rp.db,
364
364
-
db.FilterEq("id", issue.Id),
365
365
+
orm.FilterEq("id", issue.Id),
365
366
)
366
367
if err != nil {
367
368
l.Error("failed to reopen issue", "err", err)
···
506
507
commentId := chi.URLParam(r, "commentId")
507
508
comments, err := db.GetIssueComments(
508
509
rp.db,
509
509
-
db.FilterEq("id", commentId),
510
510
+
orm.FilterEq("id", commentId),
510
511
)
511
512
if err != nil {
512
513
l.Error("failed to fetch comment", "id", commentId)
···
542
543
commentId := chi.URLParam(r, "commentId")
543
544
comments, err := db.GetIssueComments(
544
545
rp.db,
545
545
-
db.FilterEq("id", commentId),
546
546
+
orm.FilterEq("id", commentId),
546
547
)
547
548
if err != nil {
548
549
l.Error("failed to fetch comment", "id", commentId)
···
652
653
commentId := chi.URLParam(r, "commentId")
653
654
comments, err := db.GetIssueComments(
654
655
rp.db,
655
655
-
db.FilterEq("id", commentId),
656
656
+
orm.FilterEq("id", commentId),
656
657
)
657
658
if err != nil {
658
659
l.Error("failed to fetch comment", "id", commentId)
···
688
689
commentId := chi.URLParam(r, "commentId")
689
690
comments, err := db.GetIssueComments(
690
691
rp.db,
691
691
-
db.FilterEq("id", commentId),
692
692
+
orm.FilterEq("id", commentId),
692
693
)
693
694
if err != nil {
694
695
l.Error("failed to fetch comment", "id", commentId)
···
724
725
commentId := chi.URLParam(r, "commentId")
725
726
comments, err := db.GetIssueComments(
726
727
rp.db,
727
727
-
db.FilterEq("id", commentId),
728
728
+
orm.FilterEq("id", commentId),
728
729
)
729
730
if err != nil {
730
731
l.Error("failed to fetch comment", "id", commentId)
···
751
752
752
753
// optimistic deletion
753
754
deleted := time.Now()
754
754
-
err = db.DeleteIssueComments(rp.db, db.FilterEq("id", comment.Id))
755
755
+
err = db.DeleteIssueComments(rp.db, orm.FilterEq("id", comment.Id))
755
756
if err != nil {
756
757
l.Error("failed to delete comment", "err", err)
757
758
rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "failed to delete comment")
···
840
841
841
842
issues, err = db.GetIssues(
842
843
rp.db,
843
843
-
db.FilterIn("id", res.Hits),
844
844
+
orm.FilterIn("id", res.Hits),
844
845
)
845
846
if err != nil {
846
847
l.Error("failed to get issues", "err", err)
···
856
857
issues, err = db.GetIssuesPaginated(
857
858
rp.db,
858
859
page,
859
859
-
db.FilterEq("repo_at", f.RepoAt()),
860
860
-
db.FilterEq("open", openInt),
860
860
+
orm.FilterEq("repo_at", f.RepoAt()),
861
861
+
orm.FilterEq("open", openInt),
861
862
)
862
863
if err != nil {
863
864
l.Error("failed to get issues", "err", err)
···
868
869
869
870
labelDefs, err := db.GetLabelDefinitions(
870
871
rp.db,
871
871
-
db.FilterIn("at_uri", f.Labels),
872
872
-
db.FilterContains("scope", tangled.RepoIssueNSID),
872
872
+
orm.FilterIn("at_uri", f.Labels),
873
873
+
orm.FilterContains("scope", tangled.RepoIssueNSID),
873
874
)
874
875
if err != nil {
875
876
l.Error("failed to fetch labels", "err", err)
+19
-18
appview/knots/knots.go
···
21
21
"tangled.org/core/appview/xrpcclient"
22
22
"tangled.org/core/eventconsumer"
23
23
"tangled.org/core/idresolver"
24
24
+
"tangled.org/core/orm"
24
25
"tangled.org/core/rbac"
25
26
"tangled.org/core/tid"
26
27
···
72
73
user := k.OAuth.GetUser(r)
73
74
registrations, err := db.GetRegistrations(
74
75
k.Db,
75
75
-
db.FilterEq("did", user.Did),
76
76
+
orm.FilterEq("did", user.Did),
76
77
)
77
78
if err != nil {
78
79
k.Logger.Error("failed to fetch knot registrations", "err", err)
···
102
103
103
104
registrations, err := db.GetRegistrations(
104
105
k.Db,
105
105
-
db.FilterEq("did", user.Did),
106
106
-
db.FilterEq("domain", domain),
106
106
+
orm.FilterEq("did", user.Did),
107
107
+
orm.FilterEq("domain", domain),
107
108
)
108
109
if err != nil {
109
110
l.Error("failed to get registrations", "err", err)
···
127
128
repos, err := db.GetRepos(
128
129
k.Db,
129
130
0,
130
130
-
db.FilterEq("knot", domain),
131
131
+
orm.FilterEq("knot", domain),
131
132
)
132
133
if err != nil {
133
134
l.Error("failed to get knot repos", "err", err)
···
293
294
// get record from db first
294
295
registrations, err := db.GetRegistrations(
295
296
k.Db,
296
296
-
db.FilterEq("did", user.Did),
297
297
-
db.FilterEq("domain", domain),
297
297
+
orm.FilterEq("did", user.Did),
298
298
+
orm.FilterEq("domain", domain),
298
299
)
299
300
if err != nil {
300
301
l.Error("failed to get registration", "err", err)
···
321
322
322
323
err = db.DeleteKnot(
323
324
tx,
324
324
-
db.FilterEq("did", user.Did),
325
325
-
db.FilterEq("domain", domain),
325
325
+
orm.FilterEq("did", user.Did),
326
326
+
orm.FilterEq("domain", domain),
326
327
)
327
328
if err != nil {
328
329
l.Error("failed to delete registration", "err", err)
···
402
403
// get record from db first
403
404
registrations, err := db.GetRegistrations(
404
405
k.Db,
405
405
-
db.FilterEq("did", user.Did),
406
406
-
db.FilterEq("domain", domain),
406
406
+
orm.FilterEq("did", user.Did),
407
407
+
orm.FilterEq("domain", domain),
407
408
)
408
409
if err != nil {
409
410
l.Error("failed to get registration", "err", err)
···
493
494
// Get updated registration to show
494
495
registrations, err = db.GetRegistrations(
495
496
k.Db,
496
496
-
db.FilterEq("did", user.Did),
497
497
-
db.FilterEq("domain", domain),
497
497
+
orm.FilterEq("did", user.Did),
498
498
+
orm.FilterEq("domain", domain),
498
499
)
499
500
if err != nil {
500
501
l.Error("failed to get registration", "err", err)
···
529
530
530
531
registrations, err := db.GetRegistrations(
531
532
k.Db,
532
532
-
db.FilterEq("did", user.Did),
533
533
-
db.FilterEq("domain", domain),
534
534
-
db.FilterIsNot("registered", "null"),
533
533
+
orm.FilterEq("did", user.Did),
534
534
+
orm.FilterEq("domain", domain),
535
535
+
orm.FilterIsNot("registered", "null"),
535
536
)
536
537
if err != nil {
537
538
l.Error("failed to get registration", "err", err)
···
637
638
638
639
registrations, err := db.GetRegistrations(
639
640
k.Db,
640
640
-
db.FilterEq("did", user.Did),
641
641
-
db.FilterEq("domain", domain),
642
642
-
db.FilterIsNot("registered", "null"),
641
641
+
orm.FilterEq("did", user.Did),
642
642
+
orm.FilterEq("domain", domain),
643
643
+
orm.FilterIsNot("registered", "null"),
643
644
)
644
645
if err != nil {
645
646
l.Error("failed to get registration", "err", err)
+5
-4
appview/labels/labels.go
···
16
16
"tangled.org/core/appview/oauth"
17
17
"tangled.org/core/appview/pages"
18
18
"tangled.org/core/appview/validator"
19
19
+
"tangled.org/core/orm"
19
20
"tangled.org/core/rbac"
20
21
"tangled.org/core/tid"
21
22
···
88
89
repoAt := r.Form.Get("repo")
89
90
subjectUri := r.Form.Get("subject")
90
91
91
91
-
repo, err := db.GetRepo(l.db, db.FilterEq("at_uri", repoAt))
92
92
+
repo, err := db.GetRepo(l.db, orm.FilterEq("at_uri", repoAt))
92
93
if err != nil {
93
94
fail("Failed to get repository.", err)
94
95
return
95
96
}
96
97
97
98
// find all the labels that this repo subscribes to
98
98
-
repoLabels, err := db.GetRepoLabels(l.db, db.FilterEq("repo_at", repoAt))
99
99
+
repoLabels, err := db.GetRepoLabels(l.db, orm.FilterEq("repo_at", repoAt))
99
100
if err != nil {
100
101
fail("Failed to get labels for this repository.", err)
101
102
return
···
106
107
labelAts = append(labelAts, rl.LabelAt.String())
107
108
}
108
109
109
109
-
actx, err := db.NewLabelApplicationCtx(l.db, db.FilterIn("at_uri", labelAts))
110
110
+
actx, err := db.NewLabelApplicationCtx(l.db, orm.FilterIn("at_uri", labelAts))
110
111
if err != nil {
111
112
fail("Invalid form data.", err)
112
113
return
113
114
}
114
115
115
116
// calculate the start state by applying already known labels
116
116
-
existingOps, err := db.GetLabelOps(l.db, db.FilterEq("subject", subjectUri))
117
117
+
existingOps, err := db.GetLabelOps(l.db, orm.FilterEq("subject", subjectUri))
117
118
if err != nil {
118
119
fail("Invalid form data.", err)
119
120
return
+3
-2
appview/middleware/middleware.go
···
18
18
"tangled.org/core/appview/pagination"
19
19
"tangled.org/core/appview/reporesolver"
20
20
"tangled.org/core/idresolver"
21
21
+
"tangled.org/core/orm"
21
22
"tangled.org/core/rbac"
22
23
)
23
24
···
217
218
218
219
repo, err := db.GetRepo(
219
220
mw.db,
220
220
-
db.FilterEq("did", id.DID.String()),
221
221
-
db.FilterEq("name", repoName),
221
221
+
orm.FilterEq("did", id.DID.String()),
222
222
+
orm.FilterEq("name", repoName),
222
223
)
223
224
if err != nil {
224
225
log.Println("failed to resolve repo", "err", err)
+5
-4
appview/notifications/notifications.go
···
11
11
"tangled.org/core/appview/oauth"
12
12
"tangled.org/core/appview/pages"
13
13
"tangled.org/core/appview/pagination"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
17
type Notifications struct {
···
53
54
54
55
total, err := db.CountNotifications(
55
56
n.db,
56
56
-
db.FilterEq("recipient_did", user.Did),
57
57
+
orm.FilterEq("recipient_did", user.Did),
57
58
)
58
59
if err != nil {
59
60
l.Error("failed to get total notifications", "err", err)
···
64
65
notifications, err := db.GetNotificationsWithEntities(
65
66
n.db,
66
67
page,
67
67
-
db.FilterEq("recipient_did", user.Did),
68
68
+
orm.FilterEq("recipient_did", user.Did),
68
69
)
69
70
if err != nil {
70
71
l.Error("failed to get notifications", "err", err)
···
96
97
97
98
count, err := db.CountNotifications(
98
99
n.db,
99
99
-
db.FilterEq("recipient_did", user.Did),
100
100
-
db.FilterEq("read", 0),
100
100
+
orm.FilterEq("recipient_did", user.Did),
101
101
+
orm.FilterEq("read", 0),
101
102
)
102
103
if err != nil {
103
104
http.Error(w, "Failed to get unread count", http.StatusInternalServerError)
+11
-10
appview/notify/db/db.go
···
12
12
"tangled.org/core/appview/models"
13
13
"tangled.org/core/appview/notify"
14
14
"tangled.org/core/idresolver"
15
15
+
"tangled.org/core/orm"
15
16
)
16
17
17
18
const (
···
42
43
return
43
44
}
44
45
var err error
45
45
-
repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", string(star.RepoAt)))
46
46
+
repo, err := db.GetRepo(n.db, orm.FilterEq("at_uri", string(star.RepoAt)))
46
47
if err != nil {
47
48
log.Printf("NewStar: failed to get repos: %v", err)
48
49
return
···
80
81
// - collaborators in the repo
81
82
var recipients []syntax.DID
82
83
recipients = append(recipients, syntax.DID(issue.Repo.Did))
83
83
-
collaborators, err := db.GetCollaborators(n.db, db.FilterEq("repo_at", issue.Repo.RepoAt()))
84
84
+
collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", issue.Repo.RepoAt()))
84
85
if err != nil {
85
86
log.Printf("failed to fetch collaborators: %v", err)
86
87
return
···
119
120
}
120
121
121
122
func (n *databaseNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) {
122
122
-
issues, err := db.GetIssues(n.db, db.FilterEq("at_uri", comment.IssueAt))
123
123
+
issues, err := db.GetIssues(n.db, orm.FilterEq("at_uri", comment.IssueAt))
123
124
if err != nil {
124
125
log.Printf("NewIssueComment: failed to get issues: %v", err)
125
126
return
···
207
208
}
208
209
209
210
func (n *databaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {
210
210
-
repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", string(pull.RepoAt)))
211
211
+
repo, err := db.GetRepo(n.db, orm.FilterEq("at_uri", string(pull.RepoAt)))
211
212
if err != nil {
212
213
log.Printf("NewPull: failed to get repos: %v", err)
213
214
return
···
218
219
// - collaborators in the repo
219
220
var recipients []syntax.DID
220
221
recipients = append(recipients, syntax.DID(repo.Did))
221
221
-
collaborators, err := db.GetCollaborators(n.db, db.FilterEq("repo_at", repo.RepoAt()))
222
222
+
collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", repo.RepoAt()))
222
223
if err != nil {
223
224
log.Printf("failed to fetch collaborators: %v", err)
224
225
return
···
258
259
return
259
260
}
260
261
261
261
-
repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", comment.RepoAt))
262
262
+
repo, err := db.GetRepo(n.db, orm.FilterEq("at_uri", comment.RepoAt))
262
263
if err != nil {
263
264
log.Printf("NewPullComment: failed to get repos: %v", err)
264
265
return
···
327
328
// - all issue participants
328
329
var recipients []syntax.DID
329
330
recipients = append(recipients, syntax.DID(issue.Repo.Did))
330
330
-
collaborators, err := db.GetCollaborators(n.db, db.FilterEq("repo_at", issue.Repo.RepoAt()))
331
331
+
collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", issue.Repo.RepoAt()))
331
332
if err != nil {
332
333
log.Printf("failed to fetch collaborators: %v", err)
333
334
return
···
366
367
367
368
func (n *databaseNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) {
368
369
// Get repo details
369
369
-
repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", string(pull.RepoAt)))
370
370
+
repo, err := db.GetRepo(n.db, orm.FilterEq("at_uri", string(pull.RepoAt)))
370
371
if err != nil {
371
372
log.Printf("NewPullState: failed to get repos: %v", err)
372
373
return
···
377
378
// - all pull participants
378
379
var recipients []syntax.DID
379
380
recipients = append(recipients, syntax.DID(repo.Did))
380
380
-
collaborators, err := db.GetCollaborators(n.db, db.FilterEq("repo_at", repo.RepoAt()))
381
381
+
collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", repo.RepoAt()))
381
382
if err != nil {
382
383
log.Printf("failed to fetch collaborators: %v", err)
383
384
return
···
443
444
444
445
prefMap, err := db.GetNotificationPreferences(
445
446
n.db,
446
446
-
db.FilterIn("user_did", slices.Collect(maps.Keys(recipientSet))),
447
447
+
orm.FilterIn("user_did", slices.Collect(maps.Keys(recipientSet))),
447
448
)
448
449
if err != nil {
449
450
// failed to get prefs for users
+3
-2
appview/oauth/handler.go
···
16
16
"tangled.org/core/api/tangled"
17
17
"tangled.org/core/appview/db"
18
18
"tangled.org/core/consts"
19
19
+
"tangled.org/core/orm"
19
20
"tangled.org/core/tid"
20
21
)
21
22
···
97
98
// and create an sh.tangled.spindle.member record with that
98
99
spindleMembers, err := db.GetSpindleMembers(
99
100
o.Db,
100
100
-
db.FilterEq("instance", "spindle.tangled.sh"),
101
101
-
db.FilterEq("subject", did),
101
101
+
orm.FilterEq("instance", "spindle.tangled.sh"),
102
102
+
orm.FilterEq("subject", did),
102
103
)
103
104
if err != nil {
104
105
l.Error("failed to get spindle members", "err", err)
+12
-11
appview/pipelines/pipelines.go
···
16
16
"tangled.org/core/appview/reporesolver"
17
17
"tangled.org/core/eventconsumer"
18
18
"tangled.org/core/idresolver"
19
19
+
"tangled.org/core/orm"
19
20
"tangled.org/core/rbac"
20
21
spindlemodel "tangled.org/core/spindle/models"
21
22
···
81
82
ps, err := db.GetPipelineStatuses(
82
83
p.db,
83
84
30,
84
84
-
db.FilterEq("repo_owner", f.Did),
85
85
-
db.FilterEq("repo_name", f.Name),
86
86
-
db.FilterEq("knot", f.Knot),
85
85
+
orm.FilterEq("repo_owner", f.Did),
86
86
+
orm.FilterEq("repo_name", f.Name),
87
87
+
orm.FilterEq("knot", f.Knot),
87
88
)
88
89
if err != nil {
89
90
l.Error("failed to query db", "err", err)
···
122
123
ps, err := db.GetPipelineStatuses(
123
124
p.db,
124
125
1,
125
125
-
db.FilterEq("repo_owner", f.Did),
126
126
-
db.FilterEq("repo_name", f.Name),
127
127
-
db.FilterEq("knot", f.Knot),
128
128
-
db.FilterEq("id", pipelineId),
126
126
+
orm.FilterEq("repo_owner", f.Did),
127
127
+
orm.FilterEq("repo_name", f.Name),
128
128
+
orm.FilterEq("knot", f.Knot),
129
129
+
orm.FilterEq("id", pipelineId),
129
130
)
130
131
if err != nil {
131
132
l.Error("failed to query db", "err", err)
···
189
190
ps, err := db.GetPipelineStatuses(
190
191
p.db,
191
192
1,
192
192
-
db.FilterEq("repo_owner", f.Did),
193
193
-
db.FilterEq("repo_name", f.Name),
194
194
-
db.FilterEq("knot", f.Knot),
195
195
-
db.FilterEq("id", pipelineId),
193
193
+
orm.FilterEq("repo_owner", f.Did),
194
194
+
orm.FilterEq("repo_name", f.Name),
195
195
+
orm.FilterEq("knot", f.Knot),
196
196
+
orm.FilterEq("id", pipelineId),
196
197
)
197
198
if err != nil || len(ps) != 1 {
198
199
l.Error("pipeline query failed", "err", err, "count", len(ps))
+2
-1
appview/pulls/opengraph.go
···
13
13
"tangled.org/core/appview/db"
14
14
"tangled.org/core/appview/models"
15
15
"tangled.org/core/appview/ogcard"
16
16
+
"tangled.org/core/orm"
16
17
"tangled.org/core/patchutil"
17
18
"tangled.org/core/types"
18
19
)
···
276
277
}
277
278
278
279
// Get comment count from database
279
279
-
comments, err := db.GetPullComments(s.db, db.FilterEq("pull_id", pull.ID))
280
280
+
comments, err := db.GetPullComments(s.db, orm.FilterEq("pull_id", pull.ID))
280
281
if err != nil {
281
282
log.Printf("failed to get pull comments: %v", err)
282
283
}
+19
-18
appview/pulls/pulls.go
···
30
30
"tangled.org/core/appview/validator"
31
31
"tangled.org/core/appview/xrpcclient"
32
32
"tangled.org/core/idresolver"
33
33
+
"tangled.org/core/orm"
33
34
"tangled.org/core/patchutil"
34
35
"tangled.org/core/rbac"
35
36
"tangled.org/core/tid"
···
190
191
ps, err := db.GetPipelineStatuses(
191
192
s.db,
192
193
len(shas),
193
193
-
db.FilterEq("repo_owner", f.Did),
194
194
-
db.FilterEq("repo_name", f.Name),
195
195
-
db.FilterEq("knot", f.Knot),
196
196
-
db.FilterIn("sha", shas),
194
194
+
orm.FilterEq("repo_owner", f.Did),
195
195
+
orm.FilterEq("repo_name", f.Name),
196
196
+
orm.FilterEq("knot", f.Knot),
197
197
+
orm.FilterIn("sha", shas),
197
198
)
198
199
if err != nil {
199
200
log.Printf("failed to fetch pipeline statuses: %s", err)
···
217
218
218
219
labelDefs, err := db.GetLabelDefinitions(
219
220
s.db,
220
220
-
db.FilterIn("at_uri", f.Labels),
221
221
-
db.FilterContains("scope", tangled.RepoPullNSID),
221
221
+
orm.FilterIn("at_uri", f.Labels),
222
222
+
orm.FilterContains("scope", tangled.RepoPullNSID),
222
223
)
223
224
if err != nil {
224
225
log.Println("failed to fetch labels", err)
···
597
598
598
599
pulls, err := db.GetPulls(
599
600
s.db,
600
600
-
db.FilterIn("id", ids),
601
601
+
orm.FilterIn("id", ids),
601
602
)
602
603
if err != nil {
603
604
log.Println("failed to get pulls", err)
···
648
649
ps, err := db.GetPipelineStatuses(
649
650
s.db,
650
651
len(shas),
651
651
-
db.FilterEq("repo_owner", f.Did),
652
652
-
db.FilterEq("repo_name", f.Name),
653
653
-
db.FilterEq("knot", f.Knot),
654
654
-
db.FilterIn("sha", shas),
652
652
+
orm.FilterEq("repo_owner", f.Did),
653
653
+
orm.FilterEq("repo_name", f.Name),
654
654
+
orm.FilterEq("knot", f.Knot),
655
655
+
orm.FilterIn("sha", shas),
655
656
)
656
657
if err != nil {
657
658
log.Printf("failed to fetch pipeline statuses: %s", err)
···
664
665
665
666
labelDefs, err := db.GetLabelDefinitions(
666
667
s.db,
667
667
-
db.FilterIn("at_uri", f.Labels),
668
668
-
db.FilterContains("scope", tangled.RepoPullNSID),
668
668
+
orm.FilterIn("at_uri", f.Labels),
669
669
+
orm.FilterContains("scope", tangled.RepoPullNSID),
669
670
)
670
671
if err != nil {
671
672
log.Println("failed to fetch labels", err)
···
1498
1499
// fork repo
1499
1500
repo, err := db.GetRepo(
1500
1501
s.db,
1501
1501
-
db.FilterEq("did", forkOwnerDid),
1502
1502
-
db.FilterEq("name", forkName),
1502
1502
+
orm.FilterEq("did", forkOwnerDid),
1503
1503
+
orm.FilterEq("name", forkName),
1503
1504
)
1504
1505
if err != nil {
1505
1506
log.Println("failed to get repo", "did", forkOwnerDid, "name", forkName, "err", err)
···
2066
2067
tx,
2067
2068
p.ParentChangeId,
2068
2069
// these should be enough filters to be unique per-stack
2069
2069
-
db.FilterEq("repo_at", p.RepoAt.String()),
2070
2070
-
db.FilterEq("owner_did", p.OwnerDid),
2071
2071
-
db.FilterEq("change_id", p.ChangeId),
2070
2070
+
orm.FilterEq("repo_at", p.RepoAt.String()),
2071
2071
+
orm.FilterEq("owner_did", p.OwnerDid),
2072
2072
+
orm.FilterEq("change_id", p.ChangeId),
2072
2073
)
2073
2074
2074
2075
if err != nil {
+10
-9
appview/repo/artifact.go
···
15
15
"tangled.org/core/appview/models"
16
16
"tangled.org/core/appview/pages"
17
17
"tangled.org/core/appview/xrpcclient"
18
18
+
"tangled.org/core/orm"
18
19
"tangled.org/core/tid"
19
20
"tangled.org/core/types"
20
21
···
155
156
156
157
artifacts, err := db.GetArtifact(
157
158
rp.db,
158
158
-
db.FilterEq("repo_at", f.RepoAt()),
159
159
-
db.FilterEq("tag", tag.Tag.Hash[:]),
160
160
-
db.FilterEq("name", filename),
159
159
+
orm.FilterEq("repo_at", f.RepoAt()),
160
160
+
orm.FilterEq("tag", tag.Tag.Hash[:]),
161
161
+
orm.FilterEq("name", filename),
161
162
)
162
163
if err != nil {
163
164
log.Println("failed to get artifacts", err)
···
234
235
235
236
artifacts, err := db.GetArtifact(
236
237
rp.db,
237
237
-
db.FilterEq("repo_at", f.RepoAt()),
238
238
-
db.FilterEq("tag", tag[:]),
239
239
-
db.FilterEq("name", filename),
238
238
+
orm.FilterEq("repo_at", f.RepoAt()),
239
239
+
orm.FilterEq("tag", tag[:]),
240
240
+
orm.FilterEq("name", filename),
240
241
)
241
242
if err != nil {
242
243
log.Println("failed to get artifacts", err)
···
276
277
defer tx.Rollback()
277
278
278
279
err = db.DeleteArtifact(tx,
279
279
-
db.FilterEq("repo_at", f.RepoAt()),
280
280
-
db.FilterEq("tag", artifact.Tag[:]),
281
281
-
db.FilterEq("name", filename),
280
280
+
orm.FilterEq("repo_at", f.RepoAt()),
281
281
+
orm.FilterEq("tag", artifact.Tag[:]),
282
282
+
orm.FilterEq("name", filename),
282
283
)
283
284
if err != nil {
284
285
log.Println("failed to remove artifact record from db", err)
+3
-2
appview/repo/feed.go
···
11
11
"tangled.org/core/appview/db"
12
12
"tangled.org/core/appview/models"
13
13
"tangled.org/core/appview/pagination"
14
14
+
"tangled.org/core/orm"
14
15
15
16
"github.com/bluesky-social/indigo/atproto/identity"
16
17
"github.com/bluesky-social/indigo/atproto/syntax"
···
20
21
func (rp *Repo) getRepoFeed(ctx context.Context, repo *models.Repo, ownerSlashRepo string) (*feeds.Feed, error) {
21
22
const feedLimitPerType = 100
22
23
23
23
-
pulls, err := db.GetPullsWithLimit(rp.db, feedLimitPerType, db.FilterEq("repo_at", repo.RepoAt()))
24
24
+
pulls, err := db.GetPullsWithLimit(rp.db, feedLimitPerType, orm.FilterEq("repo_at", repo.RepoAt()))
24
25
if err != nil {
25
26
return nil, err
26
27
}
···
28
29
issues, err := db.GetIssuesPaginated(
29
30
rp.db,
30
31
pagination.Page{Limit: feedLimitPerType},
31
31
-
db.FilterEq("repo_at", repo.RepoAt()),
32
32
+
orm.FilterEq("repo_at", repo.RepoAt()),
32
33
)
33
34
if err != nil {
34
35
return nil, err
+3
-2
appview/repo/index.go
···
23
23
"tangled.org/core/appview/models"
24
24
"tangled.org/core/appview/pages"
25
25
"tangled.org/core/appview/xrpcclient"
26
26
+
"tangled.org/core/orm"
26
27
"tangled.org/core/types"
27
28
28
29
"github.com/go-chi/chi/v5"
···
171
172
// first attempt to fetch from db
172
173
langs, err := db.GetRepoLanguages(
173
174
rp.db,
174
174
-
db.FilterEq("repo_at", repo.RepoAt()),
175
175
-
db.FilterEq("ref", currentRef),
175
175
+
orm.FilterEq("repo_at", repo.RepoAt()),
176
176
+
orm.FilterEq("ref", currentRef),
176
177
)
177
178
178
179
if err != nil || langs == nil {
+3
-2
appview/repo/opengraph.go
···
16
16
"tangled.org/core/appview/db"
17
17
"tangled.org/core/appview/models"
18
18
"tangled.org/core/appview/ogcard"
19
19
+
"tangled.org/core/orm"
19
20
"tangled.org/core/types"
20
21
)
21
22
···
338
339
var languageStats []types.RepoLanguageDetails
339
340
langs, err := db.GetRepoLanguages(
340
341
rp.db,
341
341
-
db.FilterEq("repo_at", f.RepoAt()),
342
342
-
db.FilterEq("is_default_ref", 1),
342
342
+
orm.FilterEq("repo_at", f.RepoAt()),
343
343
+
orm.FilterEq("is_default_ref", 1),
343
344
)
344
345
if err != nil {
345
346
log.Printf("failed to get language stats from db: %v", err)
+17
-16
appview/repo/repo.go
···
24
24
xrpcclient "tangled.org/core/appview/xrpcclient"
25
25
"tangled.org/core/eventconsumer"
26
26
"tangled.org/core/idresolver"
27
27
+
"tangled.org/core/orm"
27
28
"tangled.org/core/rbac"
28
29
"tangled.org/core/tid"
29
30
"tangled.org/core/xrpc/serviceauth"
···
345
346
// get form values
346
347
labelId := r.FormValue("label-id")
347
348
348
348
-
label, err := db.GetLabelDefinition(rp.db, db.FilterEq("id", labelId))
349
349
+
label, err := db.GetLabelDefinition(rp.db, orm.FilterEq("id", labelId))
349
350
if err != nil {
350
351
fail("Failed to find label definition.", err)
351
352
return
···
409
410
410
411
err = db.UnsubscribeLabel(
411
412
tx,
412
412
-
db.FilterEq("repo_at", f.RepoAt()),
413
413
-
db.FilterEq("label_at", removedAt),
413
413
+
orm.FilterEq("repo_at", f.RepoAt()),
414
414
+
orm.FilterEq("label_at", removedAt),
414
415
)
415
416
if err != nil {
416
417
fail("Failed to unsubscribe label.", err)
417
418
return
418
419
}
419
420
420
420
-
err = db.DeleteLabelDefinition(tx, db.FilterEq("id", label.Id))
421
421
+
err = db.DeleteLabelDefinition(tx, orm.FilterEq("id", label.Id))
421
422
if err != nil {
422
423
fail("Failed to delete label definition.", err)
423
424
return
···
456
457
}
457
458
458
459
labelAts := r.Form["label"]
459
459
-
_, err = db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", labelAts))
460
460
+
_, err = db.GetLabelDefinitions(rp.db, orm.FilterIn("at_uri", labelAts))
460
461
if err != nil {
461
462
fail("Failed to subscribe to label.", err)
462
463
return
···
542
543
}
543
544
544
545
labelAts := r.Form["label"]
545
545
-
_, err = db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", labelAts))
546
546
+
_, err = db.GetLabelDefinitions(rp.db, orm.FilterIn("at_uri", labelAts))
546
547
if err != nil {
547
548
fail("Failed to unsubscribe to label.", err)
548
549
return
···
582
583
583
584
err = db.UnsubscribeLabel(
584
585
rp.db,
585
585
-
db.FilterEq("repo_at", f.RepoAt()),
586
586
-
db.FilterIn("label_at", labelAts),
586
586
+
orm.FilterEq("repo_at", f.RepoAt()),
587
587
+
orm.FilterIn("label_at", labelAts),
587
588
)
588
589
if err != nil {
589
590
fail("Failed to unsubscribe label.", err)
···
612
613
613
614
labelDefs, err := db.GetLabelDefinitions(
614
615
rp.db,
615
615
-
db.FilterIn("at_uri", f.Labels),
616
616
-
db.FilterContains("scope", subject.Collection().String()),
616
616
+
orm.FilterIn("at_uri", f.Labels),
617
617
+
orm.FilterContains("scope", subject.Collection().String()),
617
618
)
618
619
if err != nil {
619
620
l.Error("failed to fetch label defs", "err", err)
···
625
626
defs[l.AtUri().String()] = &l
626
627
}
627
628
628
628
-
states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject))
629
629
+
states, err := db.GetLabels(rp.db, orm.FilterEq("subject", subject))
629
630
if err != nil {
630
631
l.Error("failed to build label state", "err", err)
631
632
return
···
660
661
661
662
labelDefs, err := db.GetLabelDefinitions(
662
663
rp.db,
663
663
-
db.FilterIn("at_uri", f.Labels),
664
664
-
db.FilterContains("scope", subject.Collection().String()),
664
664
+
orm.FilterIn("at_uri", f.Labels),
665
665
+
orm.FilterContains("scope", subject.Collection().String()),
665
666
)
666
667
if err != nil {
667
668
l.Error("failed to fetch labels", "err", err)
···
673
674
defs[l.AtUri().String()] = &l
674
675
}
675
676
676
676
-
states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject))
677
677
+
states, err := db.GetLabels(rp.db, orm.FilterEq("subject", subject))
677
678
if err != nil {
678
679
l.Error("failed to build label state", "err", err)
679
680
return
···
1036
1037
// in the user's account.
1037
1038
existingRepo, err := db.GetRepo(
1038
1039
rp.db,
1039
1039
-
db.FilterEq("did", user.Did),
1040
1040
-
db.FilterEq("name", forkName),
1040
1040
+
orm.FilterEq("did", user.Did),
1041
1041
+
orm.FilterEq("name", forkName),
1041
1042
)
1042
1043
if err != nil {
1043
1044
if !errors.Is(err, sql.ErrNoRows) {
+5
-4
appview/repo/repo_util.go
···
8
8
9
9
"tangled.org/core/appview/db"
10
10
"tangled.org/core/appview/models"
11
11
+
"tangled.org/core/orm"
11
12
"tangled.org/core/types"
12
13
)
13
14
···
102
103
ps, err := db.GetPipelineStatuses(
103
104
d,
104
105
len(shas),
105
105
-
db.FilterEq("repo_owner", repo.Did),
106
106
-
db.FilterEq("repo_name", repo.Name),
107
107
-
db.FilterEq("knot", repo.Knot),
108
108
-
db.FilterIn("sha", shas),
106
106
+
orm.FilterEq("repo_owner", repo.Did),
107
107
+
orm.FilterEq("repo_name", repo.Name),
108
108
+
orm.FilterEq("knot", repo.Knot),
109
109
+
orm.FilterIn("sha", shas),
109
110
)
110
111
if err != nil {
111
112
return nil, err
+3
-2
appview/repo/settings.go
···
14
14
"tangled.org/core/appview/oauth"
15
15
"tangled.org/core/appview/pages"
16
16
xrpcclient "tangled.org/core/appview/xrpcclient"
17
17
+
"tangled.org/core/orm"
17
18
"tangled.org/core/types"
18
19
19
20
comatproto "github.com/bluesky-social/indigo/api/atproto"
···
210
211
return
211
212
}
212
213
213
213
-
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", rp.config.Label.DefaultLabelDefs))
214
214
+
defaultLabels, err := db.GetLabelDefinitions(rp.db, orm.FilterIn("at_uri", rp.config.Label.DefaultLabelDefs))
214
215
if err != nil {
215
216
l.Error("failed to fetch labels", "err", err)
216
217
rp.pages.Error503(w)
217
218
return
218
219
}
219
220
220
220
-
labels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Labels))
221
221
+
labels, err := db.GetLabelDefinitions(rp.db, orm.FilterIn("at_uri", f.Labels))
221
222
if err != nil {
222
223
l.Error("failed to fetch labels", "err", err)
223
224
rp.pages.Error503(w)
+2
-1
appview/repo/tags.go
···
10
10
"tangled.org/core/appview/models"
11
11
"tangled.org/core/appview/pages"
12
12
xrpcclient "tangled.org/core/appview/xrpcclient"
13
13
+
"tangled.org/core/orm"
13
14
"tangled.org/core/types"
14
15
15
16
indigoxrpc "github.com/bluesky-social/indigo/xrpc"
···
44
45
rp.pages.Error503(w)
45
46
return
46
47
}
47
47
-
artifacts, err := db.GetArtifact(rp.db, db.FilterEq("repo_at", f.RepoAt()))
48
48
+
artifacts, err := db.GetArtifact(rp.db, orm.FilterEq("repo_at", f.RepoAt()))
48
49
if err != nil {
49
50
l.Error("failed grab artifacts", "err", err)
50
51
return
+5
-4
appview/serververify/verify.go
···
9
9
"tangled.org/core/api/tangled"
10
10
"tangled.org/core/appview/db"
11
11
"tangled.org/core/appview/xrpcclient"
12
12
+
"tangled.org/core/orm"
12
13
"tangled.org/core/rbac"
13
14
)
14
15
···
76
77
// mark this spindle as verified in the db
77
78
rowId, err := db.VerifySpindle(
78
79
tx,
79
79
-
db.FilterEq("owner", owner),
80
80
-
db.FilterEq("instance", instance),
80
80
+
orm.FilterEq("owner", owner),
81
81
+
orm.FilterEq("instance", instance),
81
82
)
82
83
if err != nil {
83
84
return 0, fmt.Errorf("failed to write to DB: %w", err)
···
115
116
// mark as registered
116
117
err = db.MarkRegistered(
117
118
tx,
118
118
-
db.FilterEq("did", owner),
119
119
-
db.FilterEq("domain", domain),
119
119
+
orm.FilterEq("did", owner),
120
120
+
orm.FilterEq("domain", domain),
120
121
)
121
122
if err != nil {
122
123
return fmt.Errorf("failed to register domain: %w", err)
+25
-24
appview/spindles/spindles.go
···
20
20
"tangled.org/core/appview/serververify"
21
21
"tangled.org/core/appview/xrpcclient"
22
22
"tangled.org/core/idresolver"
23
23
+
"tangled.org/core/orm"
23
24
"tangled.org/core/rbac"
24
25
"tangled.org/core/tid"
25
26
···
71
72
user := s.OAuth.GetUser(r)
72
73
all, err := db.GetSpindles(
73
74
s.Db,
74
74
-
db.FilterEq("owner", user.Did),
75
75
+
orm.FilterEq("owner", user.Did),
75
76
)
76
77
if err != nil {
77
78
s.Logger.Error("failed to fetch spindles", "err", err)
···
101
102
102
103
spindles, err := db.GetSpindles(
103
104
s.Db,
104
104
-
db.FilterEq("instance", instance),
105
105
-
db.FilterEq("owner", user.Did),
106
106
-
db.FilterIsNot("verified", "null"),
105
105
+
orm.FilterEq("instance", instance),
106
106
+
orm.FilterEq("owner", user.Did),
107
107
+
orm.FilterIsNot("verified", "null"),
107
108
)
108
109
if err != nil || len(spindles) != 1 {
109
110
l.Error("failed to get spindle", "err", err, "len(spindles)", len(spindles))
···
123
124
repos, err := db.GetRepos(
124
125
s.Db,
125
126
0,
126
126
-
db.FilterEq("spindle", instance),
127
127
+
orm.FilterEq("spindle", instance),
127
128
)
128
129
if err != nil {
129
130
l.Error("failed to get spindle repos", "err", err)
···
290
291
291
292
spindles, err := db.GetSpindles(
292
293
s.Db,
293
293
-
db.FilterEq("owner", user.Did),
294
294
-
db.FilterEq("instance", instance),
294
294
+
orm.FilterEq("owner", user.Did),
295
295
+
orm.FilterEq("instance", instance),
295
296
)
296
297
if err != nil || len(spindles) != 1 {
297
298
l.Error("failed to retrieve instance", "err", err, "len(spindles)", len(spindles))
···
319
320
// remove spindle members first
320
321
err = db.RemoveSpindleMember(
321
322
tx,
322
322
-
db.FilterEq("did", user.Did),
323
323
-
db.FilterEq("instance", instance),
323
323
+
orm.FilterEq("did", user.Did),
324
324
+
orm.FilterEq("instance", instance),
324
325
)
325
326
if err != nil {
326
327
l.Error("failed to remove spindle members", "err", err)
···
330
331
331
332
err = db.DeleteSpindle(
332
333
tx,
333
333
-
db.FilterEq("owner", user.Did),
334
334
-
db.FilterEq("instance", instance),
334
334
+
orm.FilterEq("owner", user.Did),
335
335
+
orm.FilterEq("instance", instance),
335
336
)
336
337
if err != nil {
337
338
l.Error("failed to delete spindle", "err", err)
···
410
411
411
412
spindles, err := db.GetSpindles(
412
413
s.Db,
413
413
-
db.FilterEq("owner", user.Did),
414
414
-
db.FilterEq("instance", instance),
414
414
+
orm.FilterEq("owner", user.Did),
415
415
+
orm.FilterEq("instance", instance),
415
416
)
416
417
if err != nil || len(spindles) != 1 {
417
418
l.Error("failed to retrieve instance", "err", err, "len(spindles)", len(spindles))
···
453
454
454
455
verifiedSpindle, err := db.GetSpindles(
455
456
s.Db,
456
456
-
db.FilterEq("id", rowId),
457
457
+
orm.FilterEq("id", rowId),
457
458
)
458
459
if err != nil || len(verifiedSpindle) != 1 {
459
460
l.Error("failed get new spindle", "err", err)
···
486
487
487
488
spindles, err := db.GetSpindles(
488
489
s.Db,
489
489
-
db.FilterEq("owner", user.Did),
490
490
-
db.FilterEq("instance", instance),
490
490
+
orm.FilterEq("owner", user.Did),
491
491
+
orm.FilterEq("instance", instance),
491
492
)
492
493
if err != nil || len(spindles) != 1 {
493
494
l.Error("failed to retrieve instance", "err", err, "len(spindles)", len(spindles))
···
622
623
623
624
spindles, err := db.GetSpindles(
624
625
s.Db,
625
625
-
db.FilterEq("owner", user.Did),
626
626
-
db.FilterEq("instance", instance),
626
626
+
orm.FilterEq("owner", user.Did),
627
627
+
orm.FilterEq("instance", instance),
627
628
)
628
629
if err != nil || len(spindles) != 1 {
629
630
l.Error("failed to retrieve instance", "err", err, "len(spindles)", len(spindles))
···
672
673
// get the record from the DB first:
673
674
members, err := db.GetSpindleMembers(
674
675
s.Db,
675
675
-
db.FilterEq("did", user.Did),
676
676
-
db.FilterEq("instance", instance),
677
677
-
db.FilterEq("subject", memberId.DID),
676
676
+
orm.FilterEq("did", user.Did),
677
677
+
orm.FilterEq("instance", instance),
678
678
+
orm.FilterEq("subject", memberId.DID),
678
679
)
679
680
if err != nil || len(members) != 1 {
680
681
l.Error("failed to get member", "err", err)
···
685
686
// remove from db
686
687
if err = db.RemoveSpindleMember(
687
688
tx,
688
688
-
db.FilterEq("did", user.Did),
689
689
-
db.FilterEq("instance", instance),
690
690
-
db.FilterEq("subject", memberId.DID),
689
689
+
orm.FilterEq("did", user.Did),
690
690
+
orm.FilterEq("instance", instance),
691
691
+
orm.FilterEq("subject", memberId.DID),
691
692
); err != nil {
692
693
l.Error("failed to remove spindle member", "err", err)
693
694
fail()
+6
-5
appview/state/gfi.go
···
11
11
"tangled.org/core/appview/pages"
12
12
"tangled.org/core/appview/pagination"
13
13
"tangled.org/core/consts"
14
14
+
"tangled.org/core/orm"
14
15
)
15
16
16
17
func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) {
···
20
21
21
22
goodFirstIssueLabel := s.config.Label.GoodFirstIssue
22
23
23
23
-
gfiLabelDef, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", goodFirstIssueLabel))
24
24
+
gfiLabelDef, err := db.GetLabelDefinition(s.db, orm.FilterEq("at_uri", goodFirstIssueLabel))
24
25
if err != nil {
25
26
log.Println("failed to get gfi label def", err)
26
27
s.pages.Error500(w)
27
28
return
28
29
}
29
30
30
30
-
repoLabels, err := db.GetRepoLabels(s.db, db.FilterEq("label_at", goodFirstIssueLabel))
31
31
+
repoLabels, err := db.GetRepoLabels(s.db, orm.FilterEq("label_at", goodFirstIssueLabel))
31
32
if err != nil {
32
33
log.Println("failed to get repo labels", err)
33
34
s.pages.Error503(w)
···
55
56
pagination.Page{
56
57
Limit: 500,
57
58
},
58
58
-
db.FilterIn("repo_at", repoUris),
59
59
-
db.FilterEq("open", 1),
59
59
+
orm.FilterIn("repo_at", repoUris),
60
60
+
orm.FilterEq("open", 1),
60
61
)
61
62
if err != nil {
62
63
log.Println("failed to get issues", err)
···
132
133
}
133
134
134
135
if len(uriList) > 0 {
135
135
-
allLabelDefs, err = db.GetLabelDefinitions(s.db, db.FilterIn("at_uri", uriList))
136
136
+
allLabelDefs, err = db.GetLabelDefinitions(s.db, orm.FilterIn("at_uri", uriList))
136
137
if err != nil {
137
138
log.Println("failed to fetch labels", err)
138
139
}
+6
-5
appview/state/knotstream.go
···
16
16
ec "tangled.org/core/eventconsumer"
17
17
"tangled.org/core/eventconsumer/cursor"
18
18
"tangled.org/core/log"
19
19
+
"tangled.org/core/orm"
19
20
"tangled.org/core/rbac"
20
21
"tangled.org/core/workflow"
21
22
···
30
31
31
32
knots, err := db.GetRegistrations(
32
33
d,
33
33
-
db.FilterIsNot("registered", "null"),
34
34
+
orm.FilterIsNot("registered", "null"),
34
35
)
35
36
if err != nil {
36
37
return nil, err
···
143
144
repos, err := db.GetRepos(
144
145
d,
145
146
0,
146
146
-
db.FilterEq("did", record.RepoDid),
147
147
-
db.FilterEq("name", record.RepoName),
147
147
+
orm.FilterEq("did", record.RepoDid),
148
148
+
orm.FilterEq("name", record.RepoName),
148
149
)
149
150
if err != nil {
150
151
return fmt.Errorf("failed to look for repo in DB (%s/%s): %w", record.RepoDid, record.RepoName, err)
···
209
210
repos, err := db.GetRepos(
210
211
d,
211
212
0,
212
212
-
db.FilterEq("did", record.TriggerMetadata.Repo.Did),
213
213
-
db.FilterEq("name", record.TriggerMetadata.Repo.Repo),
213
213
+
orm.FilterEq("did", record.TriggerMetadata.Repo.Did),
214
214
+
orm.FilterEq("name", record.TriggerMetadata.Repo.Repo),
214
215
)
215
216
if err != nil {
216
217
return fmt.Errorf("failed to look for repo in DB: nsid %s, rkey %s, %w", msg.Nsid, msg.Rkey, err)
+13
-12
appview/state/profile.go
···
19
19
"tangled.org/core/appview/db"
20
20
"tangled.org/core/appview/models"
21
21
"tangled.org/core/appview/pages"
22
22
+
"tangled.org/core/orm"
22
23
)
23
24
24
25
func (s *State) Profile(w http.ResponseWriter, r *http.Request) {
···
56
57
return nil, fmt.Errorf("failed to get profile: %w", err)
57
58
}
58
59
59
59
-
repoCount, err := db.CountRepos(s.db, db.FilterEq("did", did))
60
60
+
repoCount, err := db.CountRepos(s.db, orm.FilterEq("did", did))
60
61
if err != nil {
61
62
return nil, fmt.Errorf("failed to get repo count: %w", err)
62
63
}
63
64
64
64
-
stringCount, err := db.CountStrings(s.db, db.FilterEq("did", did))
65
65
+
stringCount, err := db.CountStrings(s.db, orm.FilterEq("did", did))
65
66
if err != nil {
66
67
return nil, fmt.Errorf("failed to get string count: %w", err)
67
68
}
68
69
69
69
-
starredCount, err := db.CountStars(s.db, db.FilterEq("did", did))
70
70
+
starredCount, err := db.CountStars(s.db, orm.FilterEq("did", did))
70
71
if err != nil {
71
72
return nil, fmt.Errorf("failed to get starred repo count: %w", err)
72
73
}
···
86
87
startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
87
88
punchcard, err := db.MakePunchcard(
88
89
s.db,
89
89
-
db.FilterEq("did", did),
90
90
-
db.FilterGte("date", startOfYear.Format(time.DateOnly)),
91
91
-
db.FilterLte("date", now.Format(time.DateOnly)),
90
90
+
orm.FilterEq("did", did),
91
91
+
orm.FilterGte("date", startOfYear.Format(time.DateOnly)),
92
92
+
orm.FilterLte("date", now.Format(time.DateOnly)),
92
93
)
93
94
if err != nil {
94
95
return nil, fmt.Errorf("failed to get punchcard for %s: %w", did, err)
···
123
124
repos, err := db.GetRepos(
124
125
s.db,
125
126
0,
126
126
-
db.FilterEq("did", profile.UserDid),
127
127
+
orm.FilterEq("did", profile.UserDid),
127
128
)
128
129
if err != nil {
129
130
l.Error("failed to fetch repos", "err", err)
···
193
194
repos, err := db.GetRepos(
194
195
s.db,
195
196
0,
196
196
-
db.FilterEq("did", profile.UserDid),
197
197
+
orm.FilterEq("did", profile.UserDid),
197
198
)
198
199
if err != nil {
199
200
l.Error("failed to get repos", "err", err)
···
219
220
}
220
221
l = l.With("profileDid", profile.UserDid)
221
222
222
222
-
stars, err := db.GetRepoStars(s.db, 0, db.FilterEq("did", profile.UserDid))
223
223
+
stars, err := db.GetRepoStars(s.db, 0, orm.FilterEq("did", profile.UserDid))
223
224
if err != nil {
224
225
l.Error("failed to get stars", "err", err)
225
226
s.pages.Error500(w)
···
248
249
}
249
250
l = l.With("profileDid", profile.UserDid)
250
251
251
251
-
strings, err := db.GetStrings(s.db, 0, db.FilterEq("did", profile.UserDid))
252
252
+
strings, err := db.GetStrings(s.db, 0, orm.FilterEq("did", profile.UserDid))
252
253
if err != nil {
253
254
l.Error("failed to get strings", "err", err)
254
255
s.pages.Error500(w)
···
300
301
followDids = append(followDids, extractDid(follow))
301
302
}
302
303
303
303
-
profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids))
304
304
+
profiles, err := db.GetProfiles(s.db, orm.FilterIn("did", followDids))
304
305
if err != nil {
305
306
l.Error("failed to get profiles", "followDids", followDids, "err", err)
306
307
return ¶ms, err
···
703
704
log.Printf("getting profile data for %s: %s", user.Did, err)
704
705
}
705
706
706
706
-
repos, err := db.GetRepos(s.db, 0, db.FilterEq("did", user.Did))
707
707
+
repos, err := db.GetRepos(s.db, 0, orm.FilterEq("did", user.Did))
707
708
if err != nil {
708
709
log.Printf("getting repos for %s: %s", user.Did, err)
709
710
}
+2
-1
appview/state/spindlestream.go
···
17
17
ec "tangled.org/core/eventconsumer"
18
18
"tangled.org/core/eventconsumer/cursor"
19
19
"tangled.org/core/log"
20
20
+
"tangled.org/core/orm"
20
21
"tangled.org/core/rbac"
21
22
spindle "tangled.org/core/spindle/models"
22
23
)
···
27
28
28
29
spindles, err := db.GetSpindles(
29
30
d,
30
30
-
db.FilterIsNot("verified", "null"),
31
31
+
orm.FilterIsNot("verified", "null"),
31
32
)
32
33
if err != nil {
33
34
return nil, err
+9
-8
appview/state/state.go
···
30
30
"tangled.org/core/jetstream"
31
31
"tangled.org/core/log"
32
32
tlog "tangled.org/core/log"
33
33
+
"tangled.org/core/orm"
33
34
"tangled.org/core/rbac"
34
35
"tangled.org/core/tid"
35
36
···
299
300
return
300
301
}
301
302
302
302
-
gfiLabel, err := db.GetLabelDefinition(s.db, db.FilterEq("at_uri", s.config.Label.GoodFirstIssue))
303
303
+
gfiLabel, err := db.GetLabelDefinition(s.db, orm.FilterEq("at_uri", s.config.Label.GoodFirstIssue))
303
304
if err != nil {
304
305
// non-fatal
305
306
}
···
323
324
324
325
regs, err := db.GetRegistrations(
325
326
s.db,
326
326
-
db.FilterEq("did", user.Did),
327
327
-
db.FilterEq("needs_upgrade", 1),
327
327
+
orm.FilterEq("did", user.Did),
328
328
+
orm.FilterEq("needs_upgrade", 1),
328
329
)
329
330
if err != nil {
330
331
l.Error("non-fatal: failed to get registrations", "err", err)
···
332
333
333
334
spindles, err := db.GetSpindles(
334
335
s.db,
335
335
-
db.FilterEq("owner", user.Did),
336
336
-
db.FilterEq("needs_upgrade", 1),
336
336
+
orm.FilterEq("owner", user.Did),
337
337
+
orm.FilterEq("needs_upgrade", 1),
337
338
)
338
339
if err != nil {
339
340
l.Error("non-fatal: failed to get spindles", "err", err)
···
504
505
// Check for existing repos
505
506
existingRepo, err := db.GetRepo(
506
507
s.db,
507
507
-
db.FilterEq("did", user.Did),
508
508
-
db.FilterEq("name", repoName),
508
508
+
orm.FilterEq("did", user.Did),
509
509
+
orm.FilterEq("name", repoName),
509
510
)
510
511
if err == nil && existingRepo != nil {
511
512
l.Info("repo exists")
···
665
666
}
666
667
667
668
func BackfillDefaultDefs(e db.Execer, r *idresolver.Resolver, defaults []string) error {
668
668
-
defaultLabels, err := db.GetLabelDefinitions(e, db.FilterIn("at_uri", defaults))
669
669
+
defaultLabels, err := db.GetLabelDefinitions(e, orm.FilterIn("at_uri", defaults))
669
670
if err != nil {
670
671
return err
671
672
}
+7
-6
appview/strings/strings.go
···
17
17
"tangled.org/core/appview/pages"
18
18
"tangled.org/core/appview/pages/markup"
19
19
"tangled.org/core/idresolver"
20
20
+
"tangled.org/core/orm"
20
21
"tangled.org/core/tid"
21
22
22
23
"github.com/bluesky-social/indigo/api/atproto"
···
108
109
strings, err := db.GetStrings(
109
110
s.Db,
110
111
0,
111
111
-
db.FilterEq("did", id.DID),
112
112
-
db.FilterEq("rkey", rkey),
112
112
+
orm.FilterEq("did", id.DID),
113
113
+
orm.FilterEq("rkey", rkey),
113
114
)
114
115
if err != nil {
115
116
l.Error("failed to fetch string", "err", err)
···
199
200
all, err := db.GetStrings(
200
201
s.Db,
201
202
0,
202
202
-
db.FilterEq("did", id.DID),
203
203
-
db.FilterEq("rkey", rkey),
203
203
+
orm.FilterEq("did", id.DID),
204
204
+
orm.FilterEq("rkey", rkey),
204
205
)
205
206
if err != nil {
206
207
l.Error("failed to fetch string", "err", err)
···
408
409
409
410
if err := db.DeleteString(
410
411
s.Db,
411
411
-
db.FilterEq("did", user.Did),
412
412
-
db.FilterEq("rkey", rkey),
412
412
+
orm.FilterEq("did", user.Did),
413
413
+
orm.FilterEq("rkey", rkey),
413
414
); err != nil {
414
415
fail("Failed to delete string.", err)
415
416
return
+2
-1
appview/validator/issue.go
···
6
6
7
7
"tangled.org/core/appview/db"
8
8
"tangled.org/core/appview/models"
9
9
+
"tangled.org/core/orm"
9
10
)
10
11
11
12
func (v *Validator) ValidateIssueComment(comment *models.IssueComment) error {
12
13
// if comments have parents, only ingest ones that are 1 level deep
13
14
if comment.ReplyTo != nil {
14
14
-
parents, err := db.GetIssueComments(v.db, db.FilterEq("at_uri", *comment.ReplyTo))
15
15
+
parents, err := db.GetIssueComments(v.db, orm.FilterEq("at_uri", *comment.ReplyTo))
15
16
if err != nil {
16
17
return fmt.Errorf("failed to fetch parent comment: %w", err)
17
18
}
+122
orm/orm.go
···
1
1
+
package orm
2
2
+
3
3
+
import (
4
4
+
"context"
5
5
+
"database/sql"
6
6
+
"fmt"
7
7
+
"log/slog"
8
8
+
"reflect"
9
9
+
"strings"
10
10
+
)
11
11
+
12
12
+
type migrationFn = func(*sql.Tx) error
13
13
+
14
14
+
func RunMigration(c *sql.Conn, logger *slog.Logger, name string, migrationFn migrationFn) error {
15
15
+
logger = logger.With("migration", name)
16
16
+
17
17
+
tx, err := c.BeginTx(context.Background(), nil)
18
18
+
if err != nil {
19
19
+
return err
20
20
+
}
21
21
+
defer tx.Rollback()
22
22
+
23
23
+
var exists bool
24
24
+
err = tx.QueryRow("select exists (select 1 from migrations where name = ?)", name).Scan(&exists)
25
25
+
if err != nil {
26
26
+
return err
27
27
+
}
28
28
+
29
29
+
if !exists {
30
30
+
// run migration
31
31
+
err = migrationFn(tx)
32
32
+
if err != nil {
33
33
+
logger.Error("failed to run migration", "err", err)
34
34
+
return err
35
35
+
}
36
36
+
37
37
+
// mark migration as complete
38
38
+
_, err = tx.Exec("insert into migrations (name) values (?)", name)
39
39
+
if err != nil {
40
40
+
logger.Error("failed to mark migration as complete", "err", err)
41
41
+
return err
42
42
+
}
43
43
+
44
44
+
// commit the transaction
45
45
+
if err := tx.Commit(); err != nil {
46
46
+
return err
47
47
+
}
48
48
+
49
49
+
logger.Info("migration applied successfully")
50
50
+
} else {
51
51
+
logger.Warn("skipped migration, already applied")
52
52
+
}
53
53
+
54
54
+
return nil
55
55
+
}
56
56
+
57
57
+
type Filter struct {
58
58
+
Key string
59
59
+
arg any
60
60
+
Cmp string
61
61
+
}
62
62
+
63
63
+
func newFilter(key, cmp string, arg any) Filter {
64
64
+
return Filter{
65
65
+
Key: key,
66
66
+
arg: arg,
67
67
+
Cmp: cmp,
68
68
+
}
69
69
+
}
70
70
+
71
71
+
func FilterEq(key string, arg any) Filter { return newFilter(key, "=", arg) }
72
72
+
func FilterNotEq(key string, arg any) Filter { return newFilter(key, "<>", arg) }
73
73
+
func FilterGte(key string, arg any) Filter { return newFilter(key, ">=", arg) }
74
74
+
func FilterLte(key string, arg any) Filter { return newFilter(key, "<=", arg) }
75
75
+
func FilterIs(key string, arg any) Filter { return newFilter(key, "is", arg) }
76
76
+
func FilterIsNot(key string, arg any) Filter { return newFilter(key, "is not", arg) }
77
77
+
func FilterIn(key string, arg any) Filter { return newFilter(key, "in", arg) }
78
78
+
func FilterLike(key string, arg any) Filter { return newFilter(key, "like", arg) }
79
79
+
func FilterNotLike(key string, arg any) Filter { return newFilter(key, "not like", arg) }
80
80
+
func FilterContains(key string, arg any) Filter {
81
81
+
return newFilter(key, "like", fmt.Sprintf("%%%v%%", arg))
82
82
+
}
83
83
+
84
84
+
func (f Filter) Condition() string {
85
85
+
rv := reflect.ValueOf(f.arg)
86
86
+
kind := rv.Kind()
87
87
+
88
88
+
// if we have `FilterIn(k, [1, 2, 3])`, compile it down to `k in (?, ?, ?)`
89
89
+
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
90
90
+
if rv.Len() == 0 {
91
91
+
// always false
92
92
+
return "1 = 0"
93
93
+
}
94
94
+
95
95
+
placeholders := make([]string, rv.Len())
96
96
+
for i := range placeholders {
97
97
+
placeholders[i] = "?"
98
98
+
}
99
99
+
100
100
+
return fmt.Sprintf("%s %s (%s)", f.Key, f.Cmp, strings.Join(placeholders, ", "))
101
101
+
}
102
102
+
103
103
+
return fmt.Sprintf("%s %s ?", f.Key, f.Cmp)
104
104
+
}
105
105
+
106
106
+
func (f Filter) Arg() []any {
107
107
+
rv := reflect.ValueOf(f.arg)
108
108
+
kind := rv.Kind()
109
109
+
if (kind == reflect.Slice && rv.Type().Elem().Kind() != reflect.Uint8) || kind == reflect.Array {
110
110
+
if rv.Len() == 0 {
111
111
+
return nil
112
112
+
}
113
113
+
114
114
+
out := make([]any, rv.Len())
115
115
+
for i := range rv.Len() {
116
116
+
out[i] = rv.Index(i).Interface()
117
117
+
}
118
118
+
return out
119
119
+
}
120
120
+
121
121
+
return []any{f.arg}
122
122
+
}