forked from tangled.org/core
this repo has no description

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