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