Monorepo for Tangled tangled.org

orm: extract orm package from appview #875

merged opened by oppi.li targeting master from op/zxpquyouulmx

includes query and migration helpers

Signed-off-by: oppiliappan me@oppi.li

Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:qfpnj4og54vl56wngdriaxug/sh.tangled.repo.pull/3m7mtqstsqz22
+519 -464
Diff #0
+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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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)
+2 -1
appview/repo/tags.go
··· 10 "tangled.org/core/appview/models" 11 "tangled.org/core/appview/pages" 12 xrpcclient "tangled.org/core/appview/xrpcclient" 13 "tangled.org/core/types" 14 15 indigoxrpc "github.com/bluesky-social/indigo/xrpc" ··· 44 rp.pages.Error503(w) 45 return 46 } 47 - artifacts, err := db.GetArtifact(rp.db, db.FilterEq("repo_at", f.RepoAt())) 48 if err != nil { 49 l.Error("failed grab artifacts", "err", err) 50 return
··· 10 "tangled.org/core/appview/models" 11 "tangled.org/core/appview/pages" 12 xrpcclient "tangled.org/core/appview/xrpcclient" 13 + "tangled.org/core/orm" 14 "tangled.org/core/types" 15 16 indigoxrpc "github.com/bluesky-social/indigo/xrpc" ··· 45 rp.pages.Error503(w) 46 return 47 } 48 + artifacts, err := db.GetArtifact(rp.db, orm.FilterEq("repo_at", f.RepoAt())) 49 if err != nil { 50 l.Error("failed grab artifacts", "err", err) 51 return
+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
··· 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
··· 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
··· 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
··· 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 &params, 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 &params, 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
··· 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
··· 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
··· 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
··· 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
···
··· 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 + }

History

1 round 3 comments
sign up or login to add to the discussion
oppi.li submitted #0
1 commit
expand
orm: extract orm package from appview
expand 3 comments

This PR is only about code organization right? Seems good to me.

About migration logic, how do you think about using up/down style migrations by maybe using external tools? We can still use our own ORM but migration helpers like goose/v3 or migrate/v4 seems useful.

not entirely convinced yet that something like migrate/v4 adds a lot of value. the onus is still on the developer to write idempotent migrations (i.e., if an up migration adds a column, the down migration should remove it, and the library does not really assist in ensuring this property).

This PR is only about code organization right? Seems good to me.

but yes, this is only for organization, i want to be able to write migrations for knotserver and spindle + be able to use the query builder as well.

pull request successfully merged