appview: db: replace Issue.IssueAt to Issue.Rkey #498

merged
opened by boltless.me targeting master from boltless.me/core: push-pltwsolxxvnt

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

Changed files
+39 -30
appview
db
issues
pages
templates
repo
issues
+11
appview/db/db.go
···
return err
})
+
runMigration(db, "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
}
+19 -14
appview/db/issues.go
···
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"
)
···
RepoAt syntax.ATURI
OwnerDid string
IssueId int
-
IssueAt string
+
Rkey string
Created time.Time
Title string
Body string
···
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()
···
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
}
···
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)
···
select
i.id,
i.owner_did,
+
i.rkey,
i.issue_id,
i.created,
i.title,
···
select
id,
owner_did,
+
rkey,
issue_id,
created,
title,
···
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
}
···
`select
i.id,
i.owner_did,
+
i.rkey,
i.repo_at,
i.issue_id,
i.created,
···
err := rows.Scan(
&issue.ID,
&issue.OwnerDid,
+
&issue.Rkey,
&issue.RepoAt,
&issue.IssueId,
&issueCreatedAt,
···
}
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
}
···
}
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
}
+7 -14
appview/issues/issues.go
···
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"
···
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.")
···
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)
···
rp.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{
LoggedInUser: user,
RepoInfo: f.RepoInfo(user),
-
Issue: *issue,
+
Issue: issue,
Comments: comments,
IssueOwnerHandle: issueOwnerIdent.Handle.String(),
···
Rkey: tid.TID(),
Record: &lexutil.LexiconTypeDecoder{
Val: &tangled.RepoIssueState{
-
Issue: issue.IssueAt,
+
Issue: issue.AtUri().String(),
State: closed,
},
},
···
issue := &db.Issue{
RepoAt: f.RepoAt,
+
Rkey: tid.TID(),
Title: title,
Body: body,
OwnerDid: user.Did,
···
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,
···
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))
+1 -1
appview/pages/pages.go
···
LoggedInUser *oauth.User
RepoInfo repoinfo.RepoInfo
Active string
-
Issue db.Issue
+
Issue *db.Issue
Comments []db.Comment
IssueOwnerHandle string
+1 -1
appview/pages/templates/repo/issues/issue.html
···
"Kind" $kind
"Count" (index $.Reactions $kind)
"IsReacted" (index $.UserReacted $kind)
-
"ThreadAt" $.Issue.IssueAt)
+
"ThreadAt" $.Issue.AtUri)
}}
{{ end }}
</div>