diff --git a/appview/db/artifact.go b/appview/db/artifact.go --- a/appview/db/artifact.go +++ b/appview/db/artifact.go @@ -16,7 +16,7 @@ _, err := e.Exec( `insert or ignore into artifacts ( did, rkey, - repo_at, + repo_did, tag, created, blob_cid, @@ -27,7 +27,7 @@ ) values (?, ?, ?, ?, ?, ?, ?, ?, ?)`, artifact.Did, artifact.Rkey, - artifact.RepoAt, + artifact.RepoDid, artifact.Tag[:], artifact.CreatedAt.Format(time.RFC3339), artifact.BlobCid.String(), @@ -56,7 +56,7 @@ query := fmt.Sprintf(`select did, rkey, - repo_at, + repo_did, tag, created, blob_cid, @@ -82,7 +82,7 @@ if err := rows.Scan( &artifact.Did, &artifact.Rkey, - &artifact.RepoAt, + &artifact.RepoDid, &tag, &createdAt, &blobCid, diff --git a/appview/db/collaborators.go b/appview/db/collaborators.go --- a/appview/db/collaborators.go +++ b/appview/db/collaborators.go @@ -11,8 +11,8 @@ ) func AddCollaborator(e Execer, c models.Collaborator) error { _, err := e.Exec( - `insert into collaborators (did, rkey, subject_did, repo_at) values (?, ?, ?, ?);`, - c.Did, c.Rkey, c.SubjectDid, c.RepoAt, + `insert into collaborators (did, rkey, subject_did, repo_did) values (?, ?, ?, ?);`, + c.Did, c.Rkey, c.SubjectDid, string(c.RepoDid), ) return err } @@ -37,29 +37,29 @@ return err } func CollaboratingIn(e Execer, collaborator string) ([]models.Repo, error) { - rows, err := e.Query(`select repo_at from collaborators where subject_did = ?`, collaborator) + rows, err := e.Query(`select repo_did from collaborators where subject_did = ?`, collaborator) if err != nil { return nil, err } defer rows.Close() - var repoAts []string + var repoDids []string for rows.Next() { - var aturi string - err := rows.Scan(&aturi) + var repoDid string + err := rows.Scan(&repoDid) if err != nil { return nil, err } - repoAts = append(repoAts, aturi) + repoDids = append(repoDids, repoDid) } if err := rows.Err(); err != nil { return nil, err } - if repoAts == nil { + if repoDids == nil { return nil, nil } - return GetRepos(e, orm.FilterIn("at_uri", repoAts)) + return GetRepos(e, orm.FilterIn("repo_did", repoDids)) } func GetCollaborators(e Execer, filters ...orm.Filter) ([]models.Collaborator, error) { @@ -79,7 +79,7 @@ id, did, rkey, subject_did, - repo_at, + repo_did, created from collaborators %s`, whereClause, @@ -97,7 +97,7 @@ &collaborator.Id, &collaborator.Did, &collaborator.Rkey, &collaborator.SubjectDid, - &collaborator.RepoAt, + &collaborator.RepoDid, &createdAt, ); err != nil { return nil, err diff --git a/appview/db/issues.go b/appview/db/issues.go --- a/appview/db/issues.go +++ b/appview/db/issues.go @@ -19,9 +19,9 @@ func PutIssue(tx *sql.Tx, issue *models.Issue) error { // ensure sequence exists _, err := tx.Exec(` - insert or ignore into repo_issue_seqs (repo_at, next_issue_id) + insert or ignore into repo_issue_seqs (repo_did, next_issue_id) values (?, 1) - `, issue.RepoAt) + `, issue.RepoDid) if err != nil { return err } @@ -57,19 +57,19 @@ var newIssueId int err := tx.QueryRow(` update repo_issue_seqs set next_issue_id = next_issue_id + 1 - where repo_at = ? + where repo_did = ? returning next_issue_id - 1 - `, issue.RepoAt).Scan(&newIssueId) + `, issue.RepoDid).Scan(&newIssueId) if err != nil { return err } // insert new issue row := tx.QueryRow(` - insert into issues (repo_at, did, rkey, issue_id, title, body) + insert into issues (repo_did, did, rkey, issue_id, title, body) values (?, ?, ?, ?, ?, ?) returning rowid, issue_id - `, issue.RepoAt, issue.Did, issue.Rkey, newIssueId, issue.Title, issue.Body) + `, issue.RepoDid, issue.Did, issue.Rkey, newIssueId, issue.Title, issue.Body) err = row.Scan(&issue.Id, &issue.IssueId) if err != nil { @@ -132,7 +132,7 @@ select id, did, rkey, - repo_at, + repo_did, issue_id, title, body, @@ -166,7 +166,7 @@ err := rows.Scan( &issue.Id, &issue.Did, &issue.Rkey, - &issue.RepoAt, + &issue.RepoDid, &issue.IssueId, &issue.Title, &issue.Body, @@ -201,23 +201,23 @@ issueMap[atUri] = &issue } // collect reverse repos - repoAts := make([]string, 0, len(issueMap)) // or just []string{} + repoDids := make([]string, 0, len(issueMap)) for _, issue := range issueMap { - repoAts = append(repoAts, string(issue.RepoAt)) + repoDids = append(repoDids, string(issue.RepoDid)) } - repos, err := GetRepos(e, orm.FilterIn("at_uri", repoAts)) + repos, err := GetRepos(e, orm.FilterIn("repo_did", repoDids)) if err != nil { return nil, fmt.Errorf("failed to build repo mappings: %w", err) } repoMap := make(map[string]*models.Repo) for i := range repos { - repoMap[string(repos[i].RepoAt())] = &repos[i] + repoMap[repos[i].RepoDid] = &repos[i] } for issueAt, i := range issueMap { - if r, ok := repoMap[string(i.RepoAt)]; ok { + if r, ok := repoMap[string(i.RepoDid)]; ok { i.Repo = r } else { // do not show up the issue if the repo is deleted @@ -274,11 +274,11 @@ return issues, nil } -func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*models.Issue, error) { +func GetIssue(e Execer, repoDid string, issueId int) (*models.Issue, error) { issues, err := GetIssuesPaginated( e, pagination.Page{}, - orm.FilterEq("repo_at", repoAt), + orm.FilterEq("repo_did", repoDid), orm.FilterEq("issue_id", issueId), ) if err != nil { @@ -530,14 +530,14 @@ _, err := e.Exec(query, args...) return err } -func GetIssueCount(e Execer, repoAt syntax.ATURI) (models.IssueCount, error) { +func GetIssueCount(e Execer, repoDid string) (models.IssueCount, error) { row := e.QueryRow(` select count(case when open = 1 then 1 end) as open_count, count(case when open = 0 then 1 end) as closed_count from issues - where repo_at = ?`, - repoAt, + where repo_did = ?`, + repoDid, ) var count models.IssueCount diff --git a/appview/db/language.go b/appview/db/language.go --- a/appview/db/language.go +++ b/appview/db/language.go @@ -24,7 +24,7 @@ whereClause = " where " + strings.Join(conditions, " and ") } query := fmt.Sprintf( - `select id, repo_at, ref, is_default_ref, language, bytes from repo_languages %s`, + `select id, repo_did, ref, is_default_ref, language, bytes from repo_languages %s`, whereClause, ) rows, err := e.Query(query, args...) @@ -40,7 +40,7 @@ var isDefaultRef int err := rows.Scan( &rl.Id, - &rl.RepoAt, + &rl.RepoDid, &rl.Ref, &isDefaultRef, &rl.Language, @@ -65,7 +65,7 @@ } func InsertRepoLanguages(e Execer, langs []models.RepoLanguage) error { stmt, err := e.Prepare( - "insert or replace into repo_languages (repo_at, ref, is_default_ref, language, bytes) values (?, ?, ?, ?, ?)", + "insert or replace into repo_languages (repo_did, ref, is_default_ref, language, bytes) values (?, ?, ?, ?, ?)", ) if err != nil { return err @@ -77,7 +77,7 @@ if l.IsDefaultRef { isDefaultRef = 1 } - _, err := stmt.Exec(l.RepoAt, l.Ref, isDefaultRef, l.Language, l.Bytes) + _, err := stmt.Exec(l.RepoDid, l.Ref, isDefaultRef, l.Language, l.Bytes) if err != nil { return err } @@ -105,10 +105,10 @@ _, err := e.Exec(query, args...) return err } -func UpdateRepoLanguages(tx *sql.Tx, repoAt syntax.ATURI, ref string, langs []models.RepoLanguage) error { +func UpdateRepoLanguages(tx *sql.Tx, repoDid syntax.DID, ref string, langs []models.RepoLanguage) error { err := DeleteRepoLanguages( tx, - orm.FilterEq("repo_at", repoAt), + orm.FilterEq("repo_did", repoDid), orm.FilterEq("ref", ref), ) if err != nil { diff --git a/appview/db/profile.go b/appview/db/profile.go --- a/appview/db/profile.go +++ b/appview/db/profile.go @@ -489,7 +489,7 @@ case models.VanityStatRepositoryCount: query = `select count(id) from repos where did = ?` args = append(args, did) case models.VanityStatStarCount: - query = `select count(id) from stars where subject_at like 'at://' || ? || '%'` + query = `select count(s.id) from stars s join repos r on s.subject = r.repo_did where s.subject_type = 'repo' and r.did = ?` args = append(args, did) case models.VanityStatNone: return 0, nil diff --git a/appview/db/pulls.go b/appview/db/pulls.go --- a/appview/db/pulls.go +++ b/appview/db/pulls.go @@ -30,13 +30,13 @@ } if existing.Branch != new.Branch { return false } - if existing.RepoAt == nil && new.RepoAt == nil { + if existing.RepoDid == nil && new.RepoDid == nil { return true } - if existing.RepoAt == nil || new.RepoAt == nil { + if existing.RepoDid == nil || new.RepoDid == nil { return false } - return *existing.RepoAt == *new.RepoAt + return *existing.RepoDid == *new.RepoDid } func compareSubmissions(existing, new []*models.PullSubmission) bool { @@ -60,9 +60,9 @@ func PutPull(tx *sql.Tx, pull *models.Pull) error { // ensure sequence exists _, err := tx.Exec(` - insert or ignore into repo_pull_seqs (repo_at, next_pull_id) + insert or ignore into repo_pull_seqs (repo_did, next_pull_id) values (?, 1) - `, pull.RepoAt) + `, pull.RepoDid) if err != nil { return err } @@ -94,7 +94,7 @@ if existingPull.Title == pull.Title && existingPull.Body == pull.Body && existingPull.TargetBranch == pull.TargetBranch && - existingPull.RepoAt == pull.RepoAt && + existingPull.RepoDid == pull.RepoDid && dependentOnEqual && pullSourceEqual && submissionsEqual { @@ -119,9 +119,9 @@ } func createNewPull(tx *sql.Tx, pull *models.Pull) error { _, err := tx.Exec(` - insert or ignore into repo_pull_seqs (repo_at, next_pull_id) + insert or ignore into repo_pull_seqs (repo_did, next_pull_id) values (?, 1) - `, pull.RepoAt) + `, pull.RepoDid) if err != nil { return err } @@ -130,9 +130,9 @@ var nextId int err = tx.QueryRow(` update repo_pull_seqs set next_pull_id = next_pull_id + 1 - where repo_at = ? + where repo_did = ? returning next_pull_id - 1 - `, pull.RepoAt).Scan(&nextId) + `, pull.RepoDid).Scan(&nextId) if err != nil { return err } @@ -140,19 +140,19 @@ pull.PullId = nextId pull.State = models.PullOpen - var sourceBranch, sourceRepoAt *string + var sourceBranch, sourceRepoDid *string if pull.PullSource != nil { sourceBranch = &pull.PullSource.Branch - if pull.PullSource.RepoAt != nil { - x := pull.PullSource.RepoAt.String() - sourceRepoAt = &x + if pull.PullSource.RepoDid != nil { + x := string(*pull.PullSource.RepoDid) + sourceRepoDid = &x } } result, err := tx.Exec( ` insert into pulls ( - repo_at, + repo_did, owner_did, pull_id, title, @@ -162,10 +162,10 @@ rkey, state, dependent_on, source_branch, - source_repo_at + source_repo_did ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - pull.RepoAt, + pull.RepoDid, pull.OwnerDid, pull.PullId, pull.Title, @@ -175,7 +175,7 @@ pull.Rkey, pull.State, pull.DependentOn, sourceBranch, - sourceRepoAt, + sourceRepoDid, ) if err != nil { return err @@ -224,12 +224,12 @@ return nil } func updatePull(tx *sql.Tx, pull *models.Pull, existingPull *models.Pull) error { - var sourceBranch, sourceRepoAt *string + var sourceBranch, sourceRepoDid *string if pull.PullSource != nil { sourceBranch = &pull.PullSource.Branch - if pull.PullSource.RepoAt != nil { - x := pull.PullSource.RepoAt.String() - sourceRepoAt = &x + if pull.PullSource.RepoDid != nil { + x := string(*pull.PullSource.RepoDid) + sourceRepoDid = &x } } @@ -240,9 +240,9 @@ body = ?, target_branch = ?, dependent_on = ?, source_branch = ?, - source_repo_at = ? + source_repo_did = ? where owner_did = ? and rkey = ? - `, pull.Title, pull.Body, pull.TargetBranch, pull.DependentOn, sourceBranch, sourceRepoAt, pull.OwnerDid, pull.Rkey) + `, pull.Title, pull.Body, pull.TargetBranch, pull.DependentOn, sourceBranch, sourceRepoDid, pull.OwnerDid, pull.Rkey) if err != nil { return err } @@ -283,9 +283,9 @@ } return nil } -func NextPullId(e Execer, repoAt syntax.ATURI) (int, error) { +func NextPullId(e Execer, repoDid string) (int, error) { var pullId int - err := e.QueryRow(`select next_pull_id from repo_pull_seqs where repo_at = ?`, repoAt).Scan(&pullId) + err := e.QueryRow(`select next_pull_id from repo_pull_seqs where repo_did = ?`, repoDid).Scan(&pullId) return pullId - 1, err } @@ -316,7 +316,7 @@ query := fmt.Sprintf(` select id, owner_did, - repo_at, + repo_did, pull_id, created, title, @@ -325,7 +325,7 @@ target_branch, body, rkey, source_branch, - source_repo_at, + source_repo_did, dependent_on from pulls @@ -344,11 +344,11 @@ for rows.Next() { var pull models.Pull var createdAt string - var sourceBranch, sourceRepoAt, dependentOn sql.NullString + var sourceBranch, sourceRepoDid, dependentOn sql.NullString err := rows.Scan( &pull.ID, &pull.OwnerDid, - &pull.RepoAt, + &pull.RepoDid, &pull.PullId, &createdAt, &pull.Title, @@ -357,7 +357,7 @@ &pull.TargetBranch, &pull.Body, &pull.Rkey, &sourceBranch, - &sourceRepoAt, + &sourceRepoDid, &dependentOn, ) if err != nil { @@ -374,12 +374,12 @@ if sourceBranch.Valid { pull.PullSource = &models.PullSource{ Branch: sourceBranch.String, } - if sourceRepoAt.Valid { - sourceRepoAtParsed, err := syntax.ParseATURI(sourceRepoAt.String) + if sourceRepoDid.Valid { + sourceRepoDidParsed, err := syntax.ParseDID(sourceRepoDid.String) if err != nil { return nil, err } - pull.PullSource.RepoAt = &sourceRepoAtParsed + pull.PullSource.RepoDid = &sourceRepoDidParsed } } @@ -417,32 +417,31 @@ p.Labels = labels } } - // build up reverse mappings: p.Repo and p.PullSource - var repoAts []syntax.ATURI + // build up reverse mappings: p.Repo and p.PullSource.Repo + var repoDids []syntax.DID for _, p := range pulls { - repoAts = append(repoAts, p.RepoAt) - if p.PullSource != nil && p.PullSource.RepoAt != nil { - repoAts = append(repoAts, *p.PullSource.RepoAt) + repoDids = append(repoDids, p.RepoDid) + if p.PullSource != nil && p.PullSource.RepoDid != nil { + repoDids = append(repoDids, *p.PullSource.RepoDid) } } - repos, err := GetRepos(e, orm.FilterIn("at_uri", repoAts)) + repos, err := GetRepos(e, orm.FilterIn("repo_did", repoDids)) if err != nil && !errors.Is(err, sql.ErrNoRows) { - return nil, fmt.Errorf("failed to get source repos: %w", err) + return nil, fmt.Errorf("failed to get repos: %w", err) } - repoMap := make(map[syntax.ATURI]*models.Repo) + repoMap := make(map[syntax.DID]*models.Repo) for _, r := range repos { - repoMap[r.RepoAt()] = &r + repoMap[syntax.DID(r.RepoDid)] = &r } for _, p := range pulls { - if repo, ok := repoMap[p.RepoAt]; ok { + if repo, ok := repoMap[p.RepoDid]; ok { p.Repo = repo } - - if p.PullSource != nil && p.PullSource.RepoAt != nil { - if sourceRepo, ok := repoMap[*p.PullSource.RepoAt]; ok { + if p.PullSource != nil && p.PullSource.RepoDid != nil { + if sourceRepo, ok := repoMap[*p.PullSource.RepoDid]; ok { p.PullSource.Repo = sourceRepo } } @@ -625,7 +624,7 @@ select id, pull_id, submission_id, - repo_at, + repo_did, owner_did, comment_at, body, @@ -651,7 +650,7 @@ err := rows.Scan( &comment.ID, &comment.PullId, &comment.SubmissionId, - &comment.RepoAt, + &comment.RepoDid, &comment.OwnerDid, &comment.CommentAt, &comment.Body, @@ -705,7 +704,7 @@ rows, err := e.Query(` select p.owner_did, - p.repo_at, + p.repo_did, p.pull_id, p.created, p.title, @@ -718,7 +717,7 @@ r.created from pulls p join - repos r on p.repo_at = r.at_uri + repos r on p.repo_did = r.repo_did where p.owner_did = ? and p.created >= date ('now', ?) order by @@ -734,7 +733,7 @@ var repo models.Repo var pullCreatedAt, repoCreatedAt string err := rows.Scan( &pull.OwnerDid, - &pull.RepoAt, + &pull.RepoDid, &pull.PullId, &pullCreatedAt, &pull.Title, @@ -774,11 +773,11 @@ return pulls, nil } func NewPullComment(tx *sql.Tx, comment *models.PullComment) (int64, error) { - query := `insert into pull_comments (owner_did, repo_at, submission_id, comment_at, pull_id, body) values (?, ?, ?, ?, ?, ?)` + query := `insert into pull_comments (owner_did, repo_did, submission_id, comment_at, pull_id, body) values (?, ?, ?, ?, ?, ?)` res, err := tx.Exec( query, comment.OwnerDid, - comment.RepoAt, + comment.RepoDid, comment.SubmissionId, comment.CommentAt, comment.PullId, @@ -888,7 +887,7 @@ return err } -func GetPullCount(e Execer, repoAt syntax.ATURI) (models.PullCount, error) { +func GetPullCount(e Execer, repoDid string) (models.PullCount, error) { row := e.QueryRow(` select count(case when state = ? then 1 end) as open_count, @@ -896,12 +895,12 @@ count(case when state = ? then 1 end) as merged_count, count(case when state = ? then 1 end) as closed_count, count(case when state = ? then 1 end) as deleted_count from pulls - where repo_at = ?`, + where repo_did = ?`, models.PullOpen, models.PullMerged, models.PullClosed, models.PullAbandoned, - repoAt, + repoDid, ) var count models.PullCount diff --git a/appview/db/reference.go b/appview/db/reference.go --- a/appview/db/reference.go +++ b/appview/db/reference.go @@ -60,7 +60,7 @@ join repos r on r.did = inp.owner_did and r.name = inp.name join issues i - on i.repo_at = r.at_uri + on i.repo_did = r.repo_did and i.issue_id = inp.issue_id left join issue_comments c on inp.comment_id is not null @@ -131,11 +131,11 @@ join repos r on r.did = inp.owner_did and r.name = inp.name join pulls p - on p.repo_at = r.at_uri + on p.repo_did = r.repo_did and p.pull_id = inp.pull_id left join pull_comments c on inp.comment_id is not null - and c.repo_at = r.at_uri and c.pull_id = p.pull_id + and c.repo_did = p.repo_did and c.pull_id = p.pull_id and c.id = inp.comment_id `, strings.Join(vals, ","), @@ -319,7 +319,7 @@ fmt.Sprintf( `select r.did, r.name, i.issue_id, i.title, i.open from issues i join repos r - on r.at_uri = i.repo_at + on r.repo_did = i.repo_did where (i.did, i.rkey) in (%s)`, strings.Join(vals, ","), ), @@ -357,7 +357,7 @@ from issue_comments c join issues i on i.at_uri = c.issue_at join repos r - on r.at_uri = i.repo_at + on r.repo_did = i.repo_did where %s and %s`, filter.Condition(), exclude.Condition(), @@ -401,7 +401,7 @@ fmt.Sprintf( `select r.did, r.name, p.pull_id, p.title, p.state from pulls p join repos r - on r.at_uri = p.repo_at + on r.repo_did = p.repo_did where (p.owner_did, p.rkey) in (%s)`, strings.Join(vals, ","), ), @@ -437,9 +437,9 @@ fmt.Sprintf( `select r.did, r.name, p.pull_id, c.id, p.title, p.state from repos r join pulls p - on r.at_uri = p.repo_at + on r.repo_did = p.repo_did join pull_comments c - on r.at_uri = c.repo_at and p.pull_id = c.pull_id + on p.repo_did = c.repo_did and p.pull_id = c.pull_id where %s and %s`, filter.Condition(), exclude.Condition(), diff --git a/appview/db/repos.go b/appview/db/repos.go --- a/appview/db/repos.go +++ b/appview/db/repos.go @@ -66,7 +66,7 @@ return nil, err } defer rows.Close() - repoMap := make(map[syntax.ATURI]*models.Repo) + repoMap := make(map[string]*models.Repo) for rows.Next() { var repo models.Repo var createdAt string @@ -116,7 +116,7 @@ repo.RepoDid = repoDid.String } repo.RepoStats = &models.RepoStats{} - repoMap[repo.RepoAt()] = &repo + repoMap[repo.RepoDid] = &repo } if err = rows.Err(); err != nil { @@ -133,13 +133,13 @@ inClause := strings.TrimSuffix(strings.Repeat("?, ", len(repoMap)), ", ") args = make([]any, len(repoMap)) i := 0 for _, r := range repoMap { - args[i] = r.RepoAt() + args[i] = r.RepoDid i++ } // get labels for all repos labelsQuery := fmt.Sprintf( - `select repo_at, label_at from repo_labels where repo_at in (%s)`, + `select repo_did, label_at from repo_labels where repo_did in (%s)`, inClause, ) @@ -150,27 +150,27 @@ } defer rows.Close() for rows.Next() { - var repoat, labelat string - if err := rows.Scan(&repoat, &labelat); err != nil { + var repoDid, labelat string + if err := rows.Scan(&repoDid, &labelat); err != nil { continue } - if r, ok := repoMap[syntax.ATURI(repoat)]; ok { + if r, ok := repoMap[repoDid]; ok { r.Labels = append(r.Labels, labelat) } } // get primary language for all repos languageQuery := fmt.Sprintf(` - select repo_at, language + select repo_did, language from ( select - repo_at, language, + repo_did, language, row_number() over ( - partition by repo_at + partition by repo_did order by bytes desc ) as rn from repo_languages - where repo_at in (%s) + where repo_did in (%s) and is_default_ref = 1 and language <> '' ) @@ -184,12 +184,12 @@ } defer rows.Close() for rows.Next() { - var repoat, lang string - if err := rows.Scan(&repoat, &lang); err != nil { + var repoDid, lang string + if err := rows.Scan(&repoDid, &lang); err != nil { log.Println("err", "err", err) continue } - if r, ok := repoMap[syntax.ATURI(repoat)]; ok { + if r, ok := repoMap[repoDid]; ok { r.RepoStats.Language = lang } } @@ -199,7 +199,7 @@ } // get star counts starCountQuery := fmt.Sprintf( - `select subject_at, count(1) from stars where subject_at in (%s) group by subject_at`, + `select subject, count(1) from stars where subject_type = 'repo' and subject in (%s) group by subject`, inClause, ) @@ -210,13 +210,13 @@ } defer rows.Close() for rows.Next() { - var repoat string + var repoDid string var count int - if err := rows.Scan(&repoat, &count); err != nil { + if err := rows.Scan(&repoDid, &count); err != nil { log.Println("err", "err", err) continue } - if r, ok := repoMap[syntax.ATURI(repoat)]; ok { + if r, ok := repoMap[repoDid]; ok { r.RepoStats.StarCount = count } } @@ -227,12 +227,12 @@ // get issue counts issueCountQuery := fmt.Sprintf(` select - repo_at, + repo_did, count(case when open = 1 then 1 end) as open_count, count(case when open = 0 then 1 end) as closed_count from issues - where repo_at in (%s) - group by repo_at + where repo_did in (%s) + group by repo_did `, inClause) rows, err = e.Query(issueCountQuery, args...) @@ -242,13 +242,13 @@ } defer rows.Close() for rows.Next() { - var repoat string + var repoDid string var open, closed int - if err := rows.Scan(&repoat, &open, &closed); err != nil { + if err := rows.Scan(&repoDid, &open, &closed); err != nil { log.Println("err", "err", err) continue } - if r, ok := repoMap[syntax.ATURI(repoat)]; ok { + if r, ok := repoMap[repoDid]; ok { r.RepoStats.IssueCount.Open = open r.RepoStats.IssueCount.Closed = closed } @@ -260,14 +260,14 @@ // get pull counts pullCountQuery := fmt.Sprintf(` select - repo_at, + repo_did, count(case when state = ? then 1 end) as open_count, count(case when state = ? then 1 end) as merged_count, count(case when state = ? then 1 end) as closed_count, count(case when state = ? then 1 end) as deleted_count from pulls - where repo_at in (%s) - group by repo_at + where repo_did in (%s) + group by repo_did `, inClause) pullArgs := append([]any{ @@ -284,13 +284,13 @@ } defer rows.Close() for rows.Next() { - var repoat string + var repoDid string var open, merged, closed, deleted int - if err := rows.Scan(&repoat, &open, &merged, &closed, &deleted); err != nil { + if err := rows.Scan(&repoDid, &open, &merged, &closed, &deleted); err != nil { log.Println("err", "err", err) continue } - if r, ok := repoMap[syntax.ATURI(repoat)]; ok { + if r, ok := repoMap[repoDid]; ok { r.RepoStats.PullCount.Open = open r.RepoStats.PullCount.Merged = merged r.RepoStats.PullCount.Closed = closed @@ -406,10 +406,10 @@ repoDid = &repo.RepoDid } _, err := tx.Exec( `update repos - set knot = ?, description = ?, website = ?, topics = ?, repo_did = coalesce(?, repo_did) + set name = ?, knot = ?, description = ?, website = ?, topics = ?, repo_did = coalesce(?, repo_did) where did = ? and rkey = ? `, - repo.Knot, repo.Description, repo.Website, repo.TopicStr(), repoDid, repo.Did, repo.Rkey, + repo.Name, repo.Knot, repo.Description, repo.Website, repo.TopicStr(), repoDid, repo.Did, repo.Rkey, ) return err } @@ -437,7 +437,7 @@ repo.Id = id for _, dl := range repo.Labels { if err := SubscribeLabel(tx, &models.RepoLabel{ - RepoAt: repo.RepoAt(), + RepoDid: syntax.DID(repo.RepoDid), LabelAt: syntax.ATURI(dl), }); err != nil { return fmt.Errorf("failed to subscribe to label: %w", err) @@ -447,22 +447,22 @@ return nil } -func RemoveRepo(e Execer, did, name string) error { - _, err := e.Exec(`delete from repos where did = ? and name = ?`, did, name) +func RemoveRepo(e Execer, did, rkey string) error { + _, err := e.Exec(`delete from repos where did = ? and rkey = ?`, did, rkey) return err } -func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) { +func GetRepoSource(e Execer, repoDid string) (string, error) { var nullableSource sql.NullString - err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&nullableSource) + err := e.QueryRow(`select source from repos where repo_did = ?`, repoDid).Scan(&nullableSource) if err != nil { return "", err } return nullableSource.String, nil } -func GetRepoSourceRepo(e Execer, repoAt syntax.ATURI) (*models.Repo, error) { - source, err := GetRepoSource(e, repoAt) +func GetRepoSourceRepo(e Execer, repoDid string) (*models.Repo, error) { + source, err := GetRepoSource(e, repoDid) if source == "" || errors.Is(err, sql.ErrNoRows) { return nil, nil } @@ -481,7 +481,7 @@ rows, err := e.Query( `select distinct r.id, r.did, r.name, r.knot, r.rkey, r.description, r.website, r.created, r.source, r.repo_did from repos r - left join collaborators c on r.at_uri = c.repo_at + left join collaborators c on r.repo_did = c.repo_did where (r.did = ? or c.subject_did = ?) and r.source is not null and r.source != '' @@ -537,7 +537,7 @@ return repos, nil } -func GetForkByDid(e Execer, did string, name string) (*models.Repo, error) { +func GetForkByDid(e Execer, did string, rkey string) (*models.Repo, error) { var repo models.Repo var createdAt string var nullableDescription sql.NullString @@ -549,8 +549,8 @@ row := e.QueryRow( `select id, did, name, knot, rkey, description, website, topics, created, source, repo_did from repos - where did = ? and name = ? and source is not null and source != ''`, - did, name, + where did = ? and rkey = ? and source is not null and source != ''`, + did, rkey, ) err := row.Scan(&repo.Id, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &nullableWebsite, &nullableTopicStr, &createdAt, &nullableSource, &nullableRepoDid) @@ -599,20 +599,21 @@ userDidCol string table string nsid syntax.NSID fkCol string + fkVal string } sources := []record{ - {"did", "repos", tangled.RepoNSID, "at_uri"}, - {"did", "issues", tangled.RepoIssueNSID, "repo_at"}, - {"owner_did", "pulls", tangled.RepoPullNSID, "repo_at"}, - {"did", "collaborators", tangled.RepoCollaboratorNSID, "repo_at"}, - {"did", "artifacts", tangled.RepoArchiveNSID, "repo_at"}, - {"did", "stars", tangled.FeedStarNSID, "subject_at"}, + {"did", "repos", tangled.RepoNSID, "at_uri", repoAtUri}, + {"did", "issues", tangled.RepoIssueNSID, "repo_did", repoDid}, + {"owner_did", "pulls", tangled.RepoPullNSID, "repo_did", repoDid}, + {"did", "collaborators", tangled.RepoCollaboratorNSID, "repo_did", repoDid}, + {"did", "artifacts", tangled.RepoArchiveNSID, "repo_did", repoDid}, + {"did", "stars", tangled.FeedStarNSID, "subject", repoDid}, } for _, src := range sources { rows, err := tx.Query( fmt.Sprintf(`SELECT %s, rkey FROM %s WHERE %s = ?`, src.userDidCol, src.table, src.fkCol), - repoAtUri, + src.fkVal, ) if err != nil { return fmt.Errorf("query %s for pds rewrites: %w", src.table, err) @@ -689,22 +690,22 @@ return nil } -func UpdateDescription(e Execer, repoAt, newDescription string) error { +func UpdateDescription(e Execer, repoDid, newDescription string) error { _, err := e.Exec( - `update repos set description = ? where at_uri = ?`, newDescription, repoAt) + `update repos set description = ? where repo_did = ?`, newDescription, repoDid) return err } -func UpdateSpindle(e Execer, repoAt string, spindle *string) error { +func UpdateSpindle(e Execer, repoDid string, spindle *string) error { _, err := e.Exec( - `update repos set spindle = ? where at_uri = ?`, spindle, repoAt) + `update repos set spindle = ? where repo_did = ?`, spindle, repoDid) return err } func SubscribeLabel(e Execer, rl *models.RepoLabel) error { - query := `insert or ignore into repo_labels (repo_at, label_at) values (?, ?)` + query := `insert or ignore into repo_labels (repo_did, label_at) values (?, ?)` - _, err := e.Exec(query, rl.RepoAt.String(), rl.LabelAt.String()) + _, err := e.Exec(query, string(rl.RepoDid), rl.LabelAt.String()) return err } @@ -739,7 +740,7 @@ if conditions != nil { whereClause = " where " + strings.Join(conditions, " and ") } - query := fmt.Sprintf(`select id, repo_at, label_at from repo_labels %s`, whereClause) + query := fmt.Sprintf(`select id, repo_did, label_at from repo_labels %s`, whereClause) rows, err := e.Query(query, args...) if err != nil { @@ -751,7 +752,7 @@ var labels []models.RepoLabel for rows.Next() { var label models.RepoLabel - err := rows.Scan(&label.Id, &label.RepoAt, &label.LabelAt) + err := rows.Scan(&label.Id, &label.RepoDid, &label.LabelAt) if err != nil { return nil, err } diff --git a/appview/db/site_deploys.go b/appview/db/site_deploys.go --- a/appview/db/site_deploys.go +++ b/appview/db/site_deploys.go @@ -11,7 +11,7 @@ // AddSiteDeploy records a site deploy attempt. func AddSiteDeploy(e Execer, deploy *models.SiteDeploy) error { result, err := e.Exec(` insert into site_deploys ( - repo_at, + repo_did, branch, dir, commit_sha, @@ -20,7 +20,7 @@ trigger, error ) values (?, ?, ?, ?, ?, ?, ?) `, - deploy.RepoAt, + deploy.RepoDid, deploy.Branch, deploy.Dir, deploy.CommitSHA, @@ -42,7 +42,7 @@ return nil } // GetSiteDeploys returns recent deploy records for a repository, newest first. -func GetSiteDeploys(e Execer, repoAt string, limit int) ([]models.SiteDeploy, error) { +func GetSiteDeploys(e Execer, repoDid string, limit int) ([]models.SiteDeploy, error) { if limit <= 0 { limit = 20 } @@ -50,7 +50,7 @@ rows, err := e.Query(` select id, - repo_at, + repo_did, branch, dir, commit_sha, @@ -59,10 +59,10 @@ trigger, error, created_at from site_deploys - where repo_at = ? + where repo_did = ? order by created_at desc limit ? - `, repoAt, limit) + `, repoDid, limit) if err != nil { return nil, fmt.Errorf("failed to query site deploys: %w", err) } @@ -75,7 +75,7 @@ var createdAt string if err := rows.Scan( &d.Id, - &d.RepoAt, + &d.RepoDid, &d.Branch, &d.Dir, &d.CommitSHA, diff --git a/appview/db/sites.go b/appview/db/sites.go --- a/appview/db/sites.go +++ b/appview/db/sites.go @@ -138,18 +138,18 @@ return nil } // GetRepoSiteConfig returns the site configuration for a repo, or nil if not configured. -func GetRepoSiteConfig(e Execer, repoAt string) (*models.RepoSite, error) { +func GetRepoSiteConfig(e Execer, repoDid string) (*models.RepoSite, error) { row := e.QueryRow(` - select id, repo_at, branch, dir, is_index, created, updated + select id, repo_did, branch, dir, is_index, created, updated from repo_sites - where repo_at = ? - `, repoAt) + where repo_did = ? + `, repoDid) var s models.RepoSite var isIndex int var createdStr, updatedStr string - err := row.Scan(&s.ID, &s.RepoAt, &s.Branch, &s.Dir, &isIndex, &createdStr, &updatedStr) + err := row.Scan(&s.ID, &s.RepoDid, &s.Branch, &s.Dir, &isIndex, &createdStr, &updatedStr) if errors.Is(err, sql.ErrNoRows) { return nil, nil } @@ -173,37 +173,37 @@ return &s, nil } // SetRepoSiteConfig inserts or replaces the site configuration for a repo. -func SetRepoSiteConfig(e Execer, repoAt, branch, dir string, isIndex bool) error { +func SetRepoSiteConfig(e Execer, repoDid, branch, dir string, isIndex bool) error { isIndexInt := 0 if isIndex { isIndexInt = 1 } _, err := e.Exec(` - insert into repo_sites (repo_at, branch, dir, is_index, updated) + insert into repo_sites (repo_did, branch, dir, is_index, updated) values (?, ?, ?, ?, strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) - on conflict(repo_at) do update set + on conflict(repo_did) do update set branch = excluded.branch, dir = excluded.dir, is_index = excluded.is_index, updated = excluded.updated - `, repoAt, branch, dir, isIndexInt) + `, repoDid, branch, dir, isIndexInt) return err } // DeleteRepoSiteConfig removes the site configuration for a repo. -func DeleteRepoSiteConfig(e Execer, repoAt string) error { - _, err := e.Exec(`delete from repo_sites where repo_at = ?`, repoAt) +func DeleteRepoSiteConfig(e Execer, repoDid string) error { + _, err := e.Exec(`delete from repo_sites where repo_did = ?`, repoDid) return err } // GetRepoSiteConfigsForDid returns all site configurations for repos owned by a DID. -// RepoName is populated on each returned RepoSite. +// RepoRkey is populated on each returned RepoSite. func GetRepoSiteConfigsForDid(e Execer, did string) ([]*models.RepoSite, error) { rows, err := e.Query(` - select rs.id, rs.repo_at, r.name, rs.branch, rs.dir, rs.is_index, rs.created, rs.updated + select rs.id, rs.repo_did, r.rkey, rs.branch, rs.dir, rs.is_index, rs.created, rs.updated from repo_sites rs - join repos r on r.at_uri = rs.repo_at + join repos r on r.repo_did = rs.repo_did where r.did = ? `, did) if err != nil { @@ -216,7 +216,7 @@ for rows.Next() { var s models.RepoSite var isIndex int var createdStr, updatedStr string - if err := rows.Scan(&s.ID, &s.RepoAt, &s.RepoName, &s.Branch, &s.Dir, &isIndex, &createdStr, &updatedStr); err != nil { + if err := rows.Scan(&s.ID, &s.RepoDid, &s.RepoRkey, &s.Branch, &s.Dir, &isIndex, &createdStr, &updatedStr); err != nil { return nil, err } s.IsIndex = isIndex != 0 @@ -237,34 +237,34 @@ // DeleteRepoSiteConfigsForDid removes all site configurations for repos owned by a DID. func DeleteRepoSiteConfigsForDid(e Execer, did string) error { _, err := e.Exec(` delete from repo_sites - where repo_at in ( - select at_uri from repos where did = ? + where repo_did in ( + select repo_did from repos where did = ? ) `, did) return err } -// GetIndexRepoAtForDid returns the repo_at of the repo that currently holds -// is_index=1 for the given DID, excluding excludeRepoAt (the current repo). +// GetIndexRepoDidForDid returns the repo_did of the repo that currently holds +// is_index=1 for the given DID, excluding excludeRepoDid (the current repo). // Returns "", nil if no other repo is the index site. -func GetIndexRepoAtForDid(e Execer, did, excludeRepoAt string) (string, error) { +func GetIndexRepoDidForDid(e Execer, did, excludeRepoDid string) (string, error) { row := e.QueryRow(` - select rs.repo_at + select rs.repo_did from repo_sites rs - join repos r on r.at_uri = rs.repo_at + join repos r on r.repo_did = rs.repo_did where r.did = ? and rs.is_index = 1 - and rs.repo_at != ? + and rs.repo_did != ? limit 1 - `, did, excludeRepoAt) + `, did, excludeRepoDid) - var repoAt string - err := row.Scan(&repoAt) + var repoDid string + err := row.Scan(&repoDid) if errors.Is(err, sql.ErrNoRows) { return "", nil } if err != nil { return "", err } - return repoAt, nil + return repoDid, nil } diff --git a/appview/db/star.go b/appview/db/star.go --- a/appview/db/star.go +++ b/appview/db/star.go @@ -1,42 +1,40 @@ package db import ( - "database/sql" - "errors" "fmt" "log" "slices" "strings" "time" - "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/appview/models" "tangled.org/core/appview/pagination" "tangled.org/core/orm" ) func AddStar(e Execer, star *models.Star) error { - query := `insert or ignore into stars (did, subject_at, rkey) values (?, ?, ?)` + query := `insert or ignore into stars (did, subject_type, subject, rkey) values (?, ?, ?, ?)` _, err := e.Exec( query, star.Did, - star.RepoAt.String(), + string(star.SubjectType), + star.Subject, star.Rkey, ) return err } // Get a star record -func GetStar(e Execer, did string, subjectAt syntax.ATURI) (*models.Star, error) { +func GetStar(e Execer, did string, subject string) (*models.Star, error) { query := ` - select did, subject_at, created, rkey + select did, subject_type, subject, created, rkey from stars - where did = ? and subject_at = ?` - row := e.QueryRow(query, did, subjectAt) + where did = ? and subject = ?` + row := e.QueryRow(query, did, subject) var star models.Star var created string - err := row.Scan(&star.Did, &star.RepoAt, &created, &star.Rkey) + err := row.Scan(&star.Did, &star.SubjectType, &star.Subject, &created, &star.Rkey) if err != nil { return nil, err } @@ -52,15 +50,15 @@ return &star, nil } -func GetStars(e Execer, subjectAt syntax.ATURI, page pagination.Page) ([]models.Star, error) { +func GetStars(e Execer, subject string, page pagination.Page) ([]models.Star, error) { query := ` - select did, subject_at, created, rkey + select did, subject_type, subject, created, rkey from stars - where subject_at = ? + where subject = ? order by created desc limit ? offset ? ` - rows, err := e.Query(query, subjectAt, page.Limit, page.Offset) + rows, err := e.Query(query, subject, page.Limit, page.Offset) if err != nil { return nil, err } @@ -70,7 +68,7 @@ var stars []models.Star for rows.Next() { var star models.Star var created string - if err := rows.Scan(&star.Did, &star.RepoAt, &created, &star.Rkey); err != nil { + if err := rows.Scan(&star.Did, &star.SubjectType, &star.Subject, &created, &star.Rkey); err != nil { return nil, err } @@ -85,8 +83,8 @@ return stars, rows.Err() } // Remove a star -func DeleteStar(e Execer, did string, subjectAt syntax.ATURI) error { - _, err := e.Exec(`delete from stars where did = ? and subject_at = ?`, did, subjectAt) +func DeleteStar(e Execer, did string, subject string) error { + _, err := e.Exec(`delete from stars where did = ? and subject = ?`, did, subject) return err } @@ -96,36 +94,38 @@ _, err := e.Exec(`delete from stars where did = ? and rkey = ?`, did, rkey) return err } -func GetStarCount(e Execer, subjectAt syntax.ATURI) (int, error) { +func GetStarCount(e Execer, subjectType models.StarSubjectType, subject string) (int, error) { stars := 0 err := e.QueryRow( - `select count(did) from stars where subject_at = ?`, subjectAt).Scan(&stars) + `select count(did) from stars where subject_type = ? and subject = ?`, + string(subjectType), subject, + ).Scan(&stars) if err != nil { return 0, err } return stars, nil } -// getStarStatuses returns a map of repo URIs to star status for a given user +// getStarStatuses returns a map of subjects to star status for a given user // This is an internal helper function to avoid N+1 queries -func getStarStatuses(e Execer, userDid string, repoAts []syntax.ATURI) (map[string]bool, error) { - if len(repoAts) == 0 || userDid == "" { +func getStarStatuses(e Execer, userDid string, subjects []string) (map[string]bool, error) { + if len(subjects) == 0 || userDid == "" { return make(map[string]bool), nil } - placeholders := make([]string, len(repoAts)) - args := make([]any, len(repoAts)+1) + placeholders := make([]string, len(subjects)) + args := make([]any, len(subjects)+1) args[0] = userDid - for i, repoAt := range repoAts { + for i, subj := range subjects { placeholders[i] = "?" - args[i+1] = repoAt.String() + args[i+1] = subj } query := fmt.Sprintf(` - SELECT subject_at + SELECT subject FROM stars - WHERE did = ? AND subject_at IN (%s) + WHERE did = ? AND subject IN (%s) `, strings.Join(placeholders, ",")) rows, err := e.Query(query, args...) @@ -135,34 +135,34 @@ } defer rows.Close() result := make(map[string]bool) - // Initialize all repos as not starred - for _, repoAt := range repoAts { - result[repoAt.String()] = false + // Initialize all subjects as not starred + for _, subj := range subjects { + result[subj] = false } - // Mark starred repos as true + // Mark starred subjects as true for rows.Next() { - var repoAt string - if err := rows.Scan(&repoAt); err != nil { + var subj string + if err := rows.Scan(&subj); err != nil { return nil, err } - result[repoAt] = true + result[subj] = true } return result, nil } -func GetStarStatus(e Execer, userDid string, subjectAt syntax.ATURI) bool { - statuses, err := getStarStatuses(e, userDid, []syntax.ATURI{subjectAt}) +func GetStarStatus(e Execer, userDid string, subject string) bool { + statuses, err := getStarStatuses(e, userDid, []string{subject}) if err != nil { return false } - return statuses[subjectAt.String()] + return statuses[subject] } -// GetStarStatuses returns a map of repo URIs to star status for a given user -func GetStarStatuses(e Execer, userDid string, subjectAts []syntax.ATURI) (map[string]bool, error) { - return getStarStatuses(e, userDid, subjectAts) +// GetStarStatuses returns a map of subjects to star status for a given user +func GetStarStatuses(e Execer, userDid string, subjects []string) (map[string]bool, error) { + return getStarStatuses(e, userDid, subjects) } // GetRepoStars return a list of stars each holding target repository. @@ -175,10 +175,9 @@ conditions = append(conditions, filter.Condition()) args = append(args, filter.Arg()...) } - whereClause := "" - if conditions != nil { - whereClause = " where " + strings.Join(conditions, " and ") - } + conditions = append(conditions, "subject_type = 'repo'") + + whereClause := " where " + strings.Join(conditions, " and ") pageClause := "" if page.Limit != 0 { @@ -186,7 +185,7 @@ pageClause = fmt.Sprintf(" limit %d offset %d", page.Limit, page.Offset) } repoQuery := fmt.Sprintf( - `select did, subject_at, created, rkey + `select did, subject_type, subject, created, rkey from stars %s order by created desc @@ -204,7 +203,7 @@ starMap := make(map[string][]models.Star) for rows.Next() { var star models.Star var created string - err := rows.Scan(&star.Did, &star.RepoAt, &created, &star.Rkey) + err := rows.Scan(&star.Did, &star.SubjectType, &star.Subject, &created, &star.Rkey) if err != nil { return nil, err } @@ -214,8 +213,7 @@ if t, err := time.Parse(time.RFC3339, created); err == nil { star.Created = t } - repoAt := string(star.RepoAt) - starMap[repoAt] = append(starMap[repoAt], star) + starMap[star.Subject] = append(starMap[star.Subject], star) } // populate *Repo in each star @@ -230,14 +228,14 @@ if len(args) == 0 { return nil, nil } - repos, err := GetRepos(e, orm.FilterIn("at_uri", args)) + repos, err := GetRepos(e, orm.FilterIn("repo_did", args)) if err != nil { return nil, err } var repoStars []models.RepoStar for _, r := range repos { - if stars, ok := starMap[string(r.RepoAt())]; ok { + if stars, ok := starMap[r.RepoDid]; ok { for _, star := range stars { repoStars = append(repoStars, models.RepoStar{ Star: star, @@ -275,9 +273,7 @@ } repoQuery := fmt.Sprintf(`select count(1) from stars %s`, whereClause) var count int64 - err := e.QueryRow(repoQuery, args...).Scan(&count) - - if !errors.Is(err, sql.ErrNoRows) && err != nil { + if err := e.QueryRow(repoQuery, args...).Scan(&count); err != nil { return 0, err } @@ -286,23 +282,25 @@ } // GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week func GetTopStarredReposLastWeek(e Execer) ([]models.Repo, error) { - // first, get the top repo URIs by star count from the last week + // first, get the top repo DIDs by star count from the last week query := ` with recent_starred_repos as ( - select distinct subject_at + select distinct subject from stars where created >= datetime('now', '-7 days') + and subject_type = 'repo' ), repo_star_counts as ( select - s.subject_at, + s.subject, count(*) as stars_gained_last_week from stars s - join recent_starred_repos rsr on s.subject_at = rsr.subject_at + join recent_starred_repos rsr on s.subject = rsr.subject where s.created >= datetime('now', '-7 days') - group by s.subject_at + and s.subject_type = 'repo' + group by s.subject ) - select rsc.subject_at + select rsc.subject from repo_star_counts rsc order by rsc.stars_gained_last_week desc limit 5 @@ -314,26 +312,26 @@ return nil, err } defer rows.Close() - var repoUris []string + var repoDids []string for rows.Next() { - var repoUri string - err := rows.Scan(&repoUri) + var repoDid string + err := rows.Scan(&repoDid) if err != nil { return nil, err } - repoUris = append(repoUris, repoUri) + repoDids = append(repoDids, repoDid) } if err := rows.Err(); err != nil { return nil, err } - if len(repoUris) == 0 { + if len(repoDids) == 0 { return []models.Repo{}, nil } // get full repo data - repos, err := GetRepos(e, orm.FilterIn("at_uri", repoUris)) + repos, err := GetRepos(e, orm.FilterIn("repo_did", repoDids)) if err != nil { return nil, err } @@ -341,12 +339,12 @@ // sort repos by the original trending order repoMap := make(map[string]models.Repo) for _, repo := range repos { - repoMap[repo.RepoAt().String()] = repo + repoMap[repo.RepoDid] = repo } - orderedRepos := make([]models.Repo, 0, len(repoUris)) - for _, uri := range repoUris { - if repo, exists := repoMap[uri]; exists { + orderedRepos := make([]models.Repo, 0, len(repoDids)) + for _, did := range repoDids { + if repo, exists := repoMap[did]; exists { orderedRepos = append(orderedRepos, repo) } } diff --git a/appview/db/timeline.go b/appview/db/timeline.go --- a/appview/db/timeline.go +++ b/appview/db/timeline.go @@ -3,7 +3,6 @@ import ( "sort" - "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/appview/models" "tangled.org/core/appview/pagination" "tangled.org/core/orm" @@ -101,18 +100,18 @@ if loggedInUserDid == "" { return nil, nil } - var repoAts []syntax.ATURI + var repoDids []string for _, r := range repos { - repoAts = append(repoAts, r.RepoAt()) + repoDids = append(repoDids, r.RepoDid) } - return GetStarStatuses(e, loggedInUserDid, repoAts) + return GetStarStatuses(e, loggedInUserDid, repoDids) } func getRepoStarInfo(repo *models.Repo, starStatuses map[string]bool) (bool, int64) { var isStarred bool if starStatuses != nil { - isStarred = starStatuses[repo.RepoAt().String()] + isStarred = starStatuses[repo.RepoDid] } var starCount int64 diff --git a/appview/db/webhooks.go b/appview/db/webhooks.go --- a/appview/db/webhooks.go +++ b/appview/db/webhooks.go @@ -6,7 +6,6 @@ "fmt" "strings" "time" - "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/appview/models" "tangled.org/core/orm" ) @@ -28,7 +27,7 @@ query := fmt.Sprintf(` select id, - repo_at, + repo_did, url, secret, active, @@ -55,7 +54,7 @@ var active int err := rows.Scan( &wh.Id, - &wh.RepoAt, + &wh.RepoDid, &wh.Url, &secret, &active, @@ -119,9 +118,9 @@ active = 1 } result, err := e.Exec(` - insert into webhooks (repo_at, url, secret, active, events) + insert into webhooks (repo_did, url, secret, active, events) values (?, ?, ?, ?, ?) - `, webhook.RepoAt.String(), webhook.Url, webhook.Secret, active, eventsStr) + `, string(webhook.RepoDid), webhook.Url, webhook.Secret, active, eventsStr) if err != nil { return fmt.Errorf("failed to insert webhook: %w", err) @@ -285,14 +284,14 @@ return deliveries, nil } // GetWebhooksForRepo is a convenience function to get all webhooks for a repository -func GetWebhooksForRepo(e Execer, repoAt syntax.ATURI) ([]models.Webhook, error) { - return GetWebhooks(e, orm.FilterEq("repo_at", repoAt.String())) +func GetWebhooksForRepo(e Execer, repoDid string) ([]models.Webhook, error) { + return GetWebhooks(e, orm.FilterEq("repo_did", repoDid)) } // GetActiveWebhooksForRepo returns only active webhooks for a repository -func GetActiveWebhooksForRepo(e Execer, repoAt syntax.ATURI) ([]models.Webhook, error) { +func GetActiveWebhooksForRepo(e Execer, repoDid string) ([]models.Webhook, error) { return GetWebhooks(e, - orm.FilterEq("repo_at", repoAt.String()), + orm.FilterEq("repo_did", repoDid), orm.FilterEq("active", 1), ) } diff --git a/appview/state/gfi.go b/appview/state/gfi.go --- a/appview/state/gfi.go +++ b/appview/state/gfi.go @@ -4,7 +4,6 @@ import ( "net/http" "sort" - "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/appview/db" "tangled.org/core/appview/models" "tangled.org/core/appview/pages" @@ -48,7 +47,7 @@ } repoUris := make([]string, 0, len(repoLabels)) for _, rl := range repoLabels { - repoUris = append(repoUris, rl.RepoAt.String()) + repoUris = append(repoUris, string(rl.RepoDid)) } allIssues, err := db.GetIssuesPaginated( @@ -56,7 +55,7 @@ s.db, pagination.Page{ Limit: 500, }, - orm.FilterIn("repo_at", repoUris), + orm.FilterIn("repo_did", repoUris), orm.FilterEq("open", 1), ) if err != nil { @@ -72,12 +71,12 @@ goodFirstIssues = append(goodFirstIssues, issue) } } - repoGroups := make(map[syntax.ATURI]*models.RepoGroup) + repoGroups := make(map[string]*models.RepoGroup) for _, issue := range goodFirstIssues { - if group, exists := repoGroups[issue.Repo.RepoAt()]; exists { + if group, exists := repoGroups[issue.Repo.RepoDid]; exists { group.Issues = append(group.Issues, issue) } else { - repoGroups[issue.Repo.RepoAt()] = &models.RepoGroup{ + repoGroups[issue.Repo.RepoDid] = &models.RepoGroup{ Repo: issue.Repo, Issues: []models.Issue{issue}, } diff --git a/appview/state/star.go b/appview/state/star.go --- a/appview/state/star.go +++ b/appview/state/star.go @@ -1,6 +1,8 @@ package state import ( + "fmt" + "log" "net/http" "time" @@ -11,9 +13,37 @@ "tangled.org/core/api/tangled" "tangled.org/core/appview/db" "tangled.org/core/appview/models" "tangled.org/core/appview/pages" - "tangled.org/core/orm" "tangled.org/core/tid" ) + +func resolveStarSubject(d db.Execer, subjectUri syntax.ATURI) (models.StarSubjectType, string, *tangled.FeedStar_Subject, error) { + collection := subjectUri.Collection() + + switch collection.String() { + case tangled.RepoNSID: + repo, err := db.GetRepoByAtUri(d, subjectUri.String()) + if err != nil { + return "", "", nil, err + } + if repo.RepoDid == "" { + return "", "", nil, fmt.Errorf("repo has no DID: %s", subjectUri) + } + subject := &tangled.FeedStar_Subject{ + FeedStar_Repo: &tangled.FeedStar_Repo{Did: repo.RepoDid}, + } + return models.StarSubjectRepo, repo.RepoDid, subject, nil + + case tangled.StringNSID: + uri := subjectUri.String() + subject := &tangled.FeedStar_Subject{ + FeedStar_String: &tangled.FeedStar_String{Uri: uri}, + } + return models.StarSubjectString, uri, subject, nil + + default: + return "", "", nil, fmt.Errorf("unsupported star subject collection: %s", collection) + } +} func (s *State) Star(w http.ResponseWriter, r *http.Request) { l := s.logger.With("handler", "Star") @@ -31,6 +61,12 @@ l.Warn("invalid form", "subject", subject, "err", err) return } + subjectType, subjectKey, starSubject, err := resolveStarSubject(s.db, subjectUri) + if err != nil { + log.Println("failed to resolve star subject", err) + return + } + client, err := s.oauth.AuthorizedClient(r) if err != nil { l.Error("failed to authorize client", "err", err) @@ -44,14 +80,9 @@ case http.MethodPost: createdAt := time.Now().Format(time.RFC3339) rkey := tid.TID() - subjectStr := subjectUri.String() starRecord := &tangled.FeedStar{ CreatedAt: createdAt, - Subject: &subjectStr, - } - repo, err := db.GetRepo(s.db, orm.FilterEq("at_uri", subjectUri.String())) - if err == nil && repo.RepoDid != "" { - starRecord.SubjectDid = &repo.RepoDid + Subject: starSubject, } resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ @@ -67,9 +98,10 @@ } l.Info("created atproto record", "uri", resp.Uri) star := &models.Star{ - Did: currentUser.Did, - RepoAt: subjectUri, - Rkey: rkey, + Did: currentUser.Did, + SubjectType: subjectType, + Subject: subjectKey, + Rkey: rkey, } err = db.AddStar(s.db, star) @@ -78,9 +110,9 @@ l.Error("failed to star", "err", err) return } - starCount, err := db.GetStarCount(s.db, subjectUri) + starCount, err := db.GetStarCount(s.db, subjectType, subjectKey) if err != nil { - l.Error("failed to get star count", "subjectUri", subjectUri, "err", err) + l.Error("failed to get star count", "subject", subjectKey, "err", err) } s.notifier.NewStar(r.Context(), star) @@ -95,7 +127,7 @@ return case http.MethodDelete: // find the record in the db - star, err := db.GetStar(s.db, currentUser.Did, subjectUri) + star, err := db.GetStar(s.db, currentUser.Did, subjectKey) if err != nil { l.Error("failed to get star relationship", "err", err) return @@ -118,9 +150,9 @@ l.Warn("failed to delete star from DB", "err", err) // this is not an issue, the firehose event might have already done this } - starCount, err := db.GetStarCount(s.db, subjectUri) + starCount, err := db.GetStarCount(s.db, subjectType, subjectKey) if err != nil { - l.Error("failed to get star count", "subjectUri", subjectUri, "err", err) + l.Error("failed to get star count", "subject", subjectKey, "err", err) return } @@ -135,5 +167,4 @@ }) return } - }