From 5a6a440a0a9b975061b529d9cd68b7ace4445688 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Thu, 24 Jul 2025 00:03:31 +0900 Subject: [PATCH] appview: db: replace `Issue.IssueAt` to `Issue.Rkey` Change-Id: pltwsolxxvntlrmqqkrnswpqytozvmro 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 --- appview/db/db.go | 11 +++++++ appview/db/issues.go | 33 +++++++++++-------- appview/issues/issues.go | 21 ++++-------- appview/pages/pages.go | 2 +- .../pages/templates/repo/issues/issue.html | 2 +- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/appview/db/db.go b/appview/db/db.go index ba5895f..afb4fe9 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -663,6 +663,17 @@ func Make(dbPath string) (*DB, error) { return err }) + runMigration(conn, "add-rkey-to-issues", func(tx *sql.Tx) error { + _, err := tx.Exec(` + alter table issues add column rkey text not null default ''; + + -- get last url section from issue_at and save to rkey column + update issues + set rkey = replace(issue_at, rtrim(issue_at, replace(issue_at, '/', '')), ''); + `) + return err + }) + return &DB{db}, nil } diff --git a/appview/db/issues.go b/appview/db/issues.go index 5d28656..bea2c81 100644 --- a/appview/db/issues.go +++ b/appview/db/issues.go @@ -2,9 +2,11 @@ package db import ( "database/sql" + "fmt" "time" "github.com/bluesky-social/indigo/atproto/syntax" + "tangled.sh/tangled.sh/core/api/tangled" "tangled.sh/tangled.sh/core/appview/pagination" ) @@ -13,7 +15,7 @@ type Issue struct { RepoAt syntax.ATURI OwnerDid string IssueId int - IssueAt string + Rkey string Created time.Time Title string Body string @@ -42,6 +44,10 @@ type Comment struct { Edited *time.Time } +func (i *Issue) AtUri() syntax.ATURI { + return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.OwnerDid, tangled.RepoIssueNSID, i.Rkey)) +} + func NewIssue(tx *sql.Tx, issue *Issue) error { defer tx.Rollback() @@ -67,9 +73,9 @@ func NewIssue(tx *sql.Tx, issue *Issue) error { issue.IssueId = nextId res, err := tx.Exec(` - insert into issues (repo_at, owner_did, issue_id, title, body) - values (?, ?, ?, ?, ?) - `, issue.RepoAt, issue.OwnerDid, issue.IssueId, issue.Title, issue.Body) + insert into issues (repo_at, owner_did, rkey, issue_at, issue_id, title, body) + values (?, ?, ?, ?, ?, ?, ?) + `, issue.RepoAt, issue.OwnerDid, issue.Rkey, issue.AtUri(), issue.IssueId, issue.Title, issue.Body) if err != nil { return err } @@ -87,11 +93,6 @@ func NewIssue(tx *sql.Tx, issue *Issue) error { return nil } -func SetIssueAt(e Execer, repoAt syntax.ATURI, issueId int, issueAt string) error { - _, err := e.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId) - return err -} - func GetIssueAt(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { var issueAt string err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) @@ -117,6 +118,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) select i.id, i.owner_did, + i.rkey, i.issue_id, i.created, i.title, @@ -136,6 +138,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) select id, owner_did, + rkey, issue_id, created, title, @@ -156,7 +159,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) var issue Issue var createdAt string var metadata IssueMetadata - err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) + err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) if err != nil { return nil, err } @@ -187,6 +190,7 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, `select i.id, i.owner_did, + i.rkey, i.repo_at, i.issue_id, i.created, @@ -219,6 +223,7 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, err := rows.Scan( &issue.ID, &issue.OwnerDid, + &issue.Rkey, &issue.RepoAt, &issue.IssueId, &issueCreatedAt, @@ -262,12 +267,12 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, } func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { - query := `select id, owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` + query := `select id, owner_did, rkey, created, title, body, open from issues where repo_at = ? and issue_id = ?` row := e.QueryRow(query, repoAt, issueId) var issue Issue var createdAt string - err := row.Scan(&issue.ID, &issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &createdAt, &issue.Title, &issue.Body, &issue.Open) if err != nil { return nil, err } @@ -282,12 +287,12 @@ func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { } func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) { - query := `select id, owner_did, issue_id, created, title, body, open, issue_at from issues where repo_at = ? and issue_id = ?` + query := `select id, owner_did, rkey, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` row := e.QueryRow(query, repoAt, issueId) var issue Issue var createdAt string - err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &issue.IssueAt) + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.Rkey, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) if err != nil { return nil, nil, err } diff --git a/appview/issues/issues.go b/appview/issues/issues.go index 7693078..da21ef0 100644 --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -11,7 +11,6 @@ import ( comatproto "github.com/bluesky-social/indigo/api/atproto" "github.com/bluesky-social/indigo/atproto/data" - "github.com/bluesky-social/indigo/atproto/syntax" lexutil "github.com/bluesky-social/indigo/lex/util" "github.com/go-chi/chi/v5" @@ -80,7 +79,7 @@ func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { return } - reactionCountMap, err := db.GetReactionCountMap(rp.db, syntax.ATURI(issue.IssueAt)) + reactionCountMap, err := db.GetReactionCountMap(rp.db, issue.AtUri()) if err != nil { log.Println("failed to get issue reactions") rp.pages.Notice(w, "issues", "Failed to load issue. Try again later.") @@ -88,7 +87,7 @@ func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { userReactions := map[db.ReactionKind]bool{} if user != nil { - userReactions = db.GetReactionStatusMap(rp.db, user.Did, syntax.ATURI(issue.IssueAt)) + userReactions = db.GetReactionStatusMap(rp.db, user.Did, issue.AtUri()) } issueOwnerIdent, err := rp.idResolver.ResolveIdent(r.Context(), issue.OwnerDid) @@ -99,7 +98,7 @@ func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { rp.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{ LoggedInUser: user, RepoInfo: f.RepoInfo(user), - Issue: *issue, + Issue: issue, Comments: comments, IssueOwnerHandle: issueOwnerIdent.Handle.String(), @@ -159,7 +158,7 @@ func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) { Rkey: tid.TID(), Record: &lexutil.LexiconTypeDecoder{ Val: &tangled.RepoIssueState{ - Issue: issue.IssueAt, + Issue: issue.AtUri().String(), State: closed, }, }, @@ -651,6 +650,7 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { issue := &db.Issue{ RepoAt: f.RepoAt, + Rkey: tid.TID(), Title: title, Body: body, OwnerDid: user.Did, @@ -669,10 +669,10 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { return } atUri := f.RepoAt.String() - resp, err := client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ + _, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ Collection: tangled.RepoIssueNSID, Repo: user.Did, - Rkey: tid.TID(), + Rkey: issue.Rkey, Record: &lexutil.LexiconTypeDecoder{ Val: &tangled.RepoIssue{ Repo: atUri, @@ -689,13 +689,6 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { return } - err = db.SetIssueAt(rp.db, f.RepoAt, issue.IssueId, resp.Uri) - if err != nil { - log.Println("failed to set issue at", err) - rp.pages.Notice(w, "issues", "Failed to create issue.") - return - } - rp.notifier.NewIssue(r.Context(), issue) rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) diff --git a/appview/pages/pages.go b/appview/pages/pages.go index 6697ffa..24c4668 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -793,7 +793,7 @@ type RepoSingleIssueParams struct { LoggedInUser *oauth.User RepoInfo repoinfo.RepoInfo Active string - Issue db.Issue + Issue *db.Issue Comments []db.Comment IssueOwnerHandle string diff --git a/appview/pages/templates/repo/issues/issue.html b/appview/pages/templates/repo/issues/issue.html index 9dc9a65..e8e426c 100644 --- a/appview/pages/templates/repo/issues/issue.html +++ b/appview/pages/templates/repo/issues/issue.html @@ -54,7 +54,7 @@ "Kind" $kind "Count" (index $.Reactions $kind) "IsReacted" (index $.UserReacted $kind) - "ThreadAt" $.Issue.IssueAt) + "ThreadAt" $.Issue.AtUri) }} {{ end }} -- 2.43.0