forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

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>

Changed files
+39 -30
appview
db
issues
pages
templates
repo
issues
+11
appview/db/db.go
···
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
}
+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,
···
})
if err != nil {
log.Println("failed to create issue", err)
-
rp.pages.Notice(w, "issues", "Failed to create issue.")
-
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
}
+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>