forked from tangled.org/core
Monorepo for Tangled

appview: db: replace `Issue.IssueAt` to `Issue.Rkey`

Replace `Issue.IssueAt` to `Issue.Rkey`. `issue_at` column still exist,
but not used and will be removed in future.

Remove `db.SetIssueAt()` in flavor of `Rkey`.
Create rkey *before* adding to DB, and save same rkey to PDS.
This is safe as `tx` is will be dropped when `ctx` is canceled with
error.

Signed-off-by: Seongmin Lee <boltlessengineer@proton.me>

authored by boltless.me and committed by Tangled cde279f0 bbb4d612

Changed files
+39 -30
appview
db
issues
pages
templates
repo
issues
+11
appview/db/db.go
··· 663 663 return err 664 664 }) 665 665 666 + runMigration(conn, "add-rkey-to-issues", func(tx *sql.Tx) error { 667 + _, err := tx.Exec(` 668 + alter table issues add column rkey text not null default ''; 669 + 670 + -- get last url section from issue_at and save to rkey column 671 + update issues 672 + set rkey = replace(issue_at, rtrim(issue_at, replace(issue_at, '/', '')), ''); 673 + `) 674 + return err 675 + }) 676 + 666 677 return &DB{db}, nil 667 678 } 668 679
+19 -14
appview/db/issues.go
··· 2 2 3 3 import ( 4 4 "database/sql" 5 + "fmt" 5 6 "time" 6 7 7 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 + "tangled.sh/tangled.sh/core/api/tangled" 8 10 "tangled.sh/tangled.sh/core/appview/pagination" 9 11 ) 10 12 ··· 13 15 RepoAt syntax.ATURI 14 16 OwnerDid string 15 17 IssueId int 16 - IssueAt string 18 + Rkey string 17 19 Created time.Time 18 20 Title string 19 21 Body string ··· 42 44 Edited *time.Time 43 45 } 44 46 47 + func (i *Issue) AtUri() syntax.ATURI { 48 + return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.OwnerDid, tangled.RepoIssueNSID, i.Rkey)) 49 + } 50 + 45 51 func NewIssue(tx *sql.Tx, issue *Issue) error { 46 52 defer tx.Rollback() 47 53 ··· 67 73 issue.IssueId = nextId 68 74 69 75 res, err := tx.Exec(` 70 - insert into issues (repo_at, owner_did, issue_id, title, body) 71 - values (?, ?, ?, ?, ?) 72 - `, issue.RepoAt, issue.OwnerDid, issue.IssueId, issue.Title, issue.Body) 76 + insert into issues (repo_at, owner_did, rkey, issue_at, issue_id, title, body) 77 + values (?, ?, ?, ?, ?, ?, ?) 78 + `, issue.RepoAt, issue.OwnerDid, issue.Rkey, issue.AtUri(), issue.IssueId, issue.Title, issue.Body) 73 79 if err != nil { 74 80 return err 75 81 } ··· 87 93 return nil 88 94 } 89 95 90 - func SetIssueAt(e Execer, repoAt syntax.ATURI, issueId int, issueAt string) error { 91 - _, err := e.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId) 92 - return err 93 - } 94 - 95 96 func GetIssueAt(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { 96 97 var issueAt string 97 98 err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) ··· 117 118 select 118 119 i.id, 119 120 i.owner_did, 121 + i.rkey, 120 122 i.issue_id, 121 123 i.created, 122 124 i.title, ··· 136 138 select 137 139 id, 138 140 owner_did, 141 + rkey, 139 142 issue_id, 140 143 created, 141 144 title, ··· 156 159 var issue Issue 157 160 var createdAt string 158 161 var metadata IssueMetadata 159 - err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) 162 + err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) 160 163 if err != nil { 161 164 return nil, err 162 165 } ··· 187 190 `select 188 191 i.id, 189 192 i.owner_did, 193 + i.rkey, 190 194 i.repo_at, 191 195 i.issue_id, 192 196 i.created, ··· 219 223 err := rows.Scan( 220 224 &issue.ID, 221 225 &issue.OwnerDid, 226 + &issue.Rkey, 222 227 &issue.RepoAt, 223 228 &issue.IssueId, 224 229 &issueCreatedAt, ··· 262 267 } 263 268 264 269 func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { 265 - query := `select id, owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 270 + query := `select id, owner_did, rkey, created, title, body, open from issues where repo_at = ? and issue_id = ?` 266 271 row := e.QueryRow(query, repoAt, issueId) 267 272 268 273 var issue Issue 269 274 var createdAt string 270 - err := row.Scan(&issue.ID, &issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) 275 + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &createdAt, &issue.Title, &issue.Body, &issue.Open) 271 276 if err != nil { 272 277 return nil, err 273 278 } ··· 282 287 } 283 288 284 289 func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) { 285 - query := `select id, owner_did, issue_id, created, title, body, open, issue_at from issues where repo_at = ? and issue_id = ?` 290 + query := `select id, owner_did, rkey, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 286 291 row := e.QueryRow(query, repoAt, issueId) 287 292 288 293 var issue Issue 289 294 var createdAt string 290 - err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &issue.IssueAt) 295 + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) 291 296 if err != nil { 292 297 return nil, nil, err 293 298 }
+7 -14
appview/issues/issues.go
··· 11 11 12 12 comatproto "github.com/bluesky-social/indigo/api/atproto" 13 13 "github.com/bluesky-social/indigo/atproto/data" 14 - "github.com/bluesky-social/indigo/atproto/syntax" 15 14 lexutil "github.com/bluesky-social/indigo/lex/util" 16 15 "github.com/go-chi/chi/v5" 17 16 ··· 80 79 return 81 80 } 82 81 83 - reactionCountMap, err := db.GetReactionCountMap(rp.db, syntax.ATURI(issue.IssueAt)) 82 + reactionCountMap, err := db.GetReactionCountMap(rp.db, issue.AtUri()) 84 83 if err != nil { 85 84 log.Println("failed to get issue reactions") 86 85 rp.pages.Notice(w, "issues", "Failed to load issue. Try again later.") ··· 88 87 89 88 userReactions := map[db.ReactionKind]bool{} 90 89 if user != nil { 91 - userReactions = db.GetReactionStatusMap(rp.db, user.Did, syntax.ATURI(issue.IssueAt)) 90 + userReactions = db.GetReactionStatusMap(rp.db, user.Did, issue.AtUri()) 92 91 } 93 92 94 93 issueOwnerIdent, err := rp.idResolver.ResolveIdent(r.Context(), issue.OwnerDid) ··· 99 98 rp.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{ 100 99 LoggedInUser: user, 101 100 RepoInfo: f.RepoInfo(user), 102 - Issue: *issue, 101 + Issue: issue, 103 102 Comments: comments, 104 103 105 104 IssueOwnerHandle: issueOwnerIdent.Handle.String(), ··· 159 158 Rkey: tid.TID(), 160 159 Record: &lexutil.LexiconTypeDecoder{ 161 160 Val: &tangled.RepoIssueState{ 162 - Issue: issue.IssueAt, 161 + Issue: issue.AtUri().String(), 163 162 State: closed, 164 163 }, 165 164 }, ··· 651 650 652 651 issue := &db.Issue{ 653 652 RepoAt: f.RepoAt, 653 + Rkey: tid.TID(), 654 654 Title: title, 655 655 Body: body, 656 656 OwnerDid: user.Did, ··· 669 669 return 670 670 } 671 671 atUri := f.RepoAt.String() 672 - resp, err := client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ 672 + _, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ 673 673 Collection: tangled.RepoIssueNSID, 674 674 Repo: user.Did, 675 - Rkey: tid.TID(), 675 + Rkey: issue.Rkey, 676 676 Record: &lexutil.LexiconTypeDecoder{ 677 677 Val: &tangled.RepoIssue{ 678 678 Repo: atUri, ··· 685 685 }) 686 686 if err != nil { 687 687 log.Println("failed to create issue", err) 688 - rp.pages.Notice(w, "issues", "Failed to create issue.") 689 - return 690 - } 691 - 692 - err = db.SetIssueAt(rp.db, f.RepoAt, issue.IssueId, resp.Uri) 693 - if err != nil { 694 - log.Println("failed to set issue at", err) 695 688 rp.pages.Notice(w, "issues", "Failed to create issue.") 696 689 return 697 690 }
+1 -1
appview/pages/pages.go
··· 793 793 LoggedInUser *oauth.User 794 794 RepoInfo repoinfo.RepoInfo 795 795 Active string 796 - Issue db.Issue 796 + Issue *db.Issue 797 797 Comments []db.Comment 798 798 IssueOwnerHandle string 799 799
+1 -1
appview/pages/templates/repo/issues/issue.html
··· 54 54 "Kind" $kind 55 55 "Count" (index $.Reactions $kind) 56 56 "IsReacted" (index $.UserReacted $kind) 57 - "ThreadAt" $.Issue.IssueAt) 57 + "ThreadAt" $.Issue.AtUri) 58 58 }} 59 59 {{ end }} 60 60 </div>