forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1package db 2 3import ( 4 "database/sql" 5 "time" 6) 7 8type Issue struct { 9 RepoAt string 10 OwnerDid string 11 IssueId int 12 IssueAt string 13 Created *time.Time 14 Title string 15 Body string 16 Open bool 17} 18 19type Comment struct { 20 OwnerDid string 21 RepoAt string 22 CommentAt string 23 Issue int 24 CommentId int 25 Body string 26 Created *time.Time 27} 28 29func (d *DB) NewIssue(issue *Issue) error { 30 tx, err := d.db.Begin() 31 if err != nil { 32 return err 33 } 34 defer tx.Rollback() 35 36 _, err = tx.Exec(` 37 insert or ignore into repo_issue_seqs (repo_at, next_issue_id) 38 values (?, 1) 39 `, issue.RepoAt) 40 if err != nil { 41 return err 42 } 43 44 var nextId int 45 err = tx.QueryRow(` 46 update repo_issue_seqs 47 set next_issue_id = next_issue_id + 1 48 where repo_at = ? 49 returning next_issue_id - 1 50 `, issue.RepoAt).Scan(&nextId) 51 if err != nil { 52 return err 53 } 54 55 issue.IssueId = nextId 56 57 _, err = tx.Exec(` 58 insert into issues (repo_at, owner_did, issue_id, title, body) 59 values (?, ?, ?, ?, ?) 60 `, issue.RepoAt, issue.OwnerDid, issue.IssueId, issue.Title, issue.Body) 61 if err != nil { 62 return err 63 } 64 65 if err := tx.Commit(); err != nil { 66 return err 67 } 68 69 return nil 70} 71 72func (d *DB) SetIssueAt(repoAt string, issueId int, issueAt string) error { 73 _, err := d.db.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId) 74 return err 75} 76 77func (d *DB) GetIssueAt(repoAt string, issueId int) (string, error) { 78 var issueAt string 79 err := d.db.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) 80 return issueAt, err 81} 82 83func (d *DB) GetIssueId(repoAt string) (int, error) { 84 var issueId int 85 err := d.db.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId) 86 return issueId - 1, err 87} 88 89func (d *DB) GetIssueOwnerDid(repoAt string, issueId int) (string, error) { 90 var ownerDid string 91 err := d.db.QueryRow(`select owner_did from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&ownerDid) 92 return ownerDid, err 93} 94 95func (d *DB) GetIssues(repoAt string) ([]Issue, error) { 96 var issues []Issue 97 98 rows, err := d.db.Query(`select owner_did, issue_id, created, title, body, open from issues where repo_at = ? order by created desc`, repoAt) 99 if err != nil { 100 return nil, err 101 } 102 defer rows.Close() 103 104 for rows.Next() { 105 var issue Issue 106 var createdAt string 107 err := rows.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) 108 if err != nil { 109 return nil, err 110 } 111 112 createdTime, err := time.Parse(time.RFC3339, createdAt) 113 if err != nil { 114 return nil, err 115 } 116 issue.Created = &createdTime 117 118 issues = append(issues, issue) 119 } 120 121 if err := rows.Err(); err != nil { 122 return nil, err 123 } 124 125 return issues, nil 126} 127 128func (d *DB) GetIssue(repoAt string, issueId int) (*Issue, error) { 129 query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 130 row := d.db.QueryRow(query, repoAt, issueId) 131 132 var issue Issue 133 var createdAt string 134 err := row.Scan(&issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) 135 if err != nil { 136 return nil, err 137 } 138 139 createdTime, err := time.Parse(time.RFC3339, createdAt) 140 if err != nil { 141 return nil, err 142 } 143 issue.Created = &createdTime 144 145 return &issue, nil 146} 147 148func (d *DB) GetIssueWithComments(repoAt string, issueId int) (*Issue, []Comment, error) { 149 query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 150 row := d.db.QueryRow(query, repoAt, issueId) 151 152 var issue Issue 153 var createdAt string 154 err := row.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) 155 if err != nil { 156 return nil, nil, err 157 } 158 159 createdTime, err := time.Parse(time.RFC3339, createdAt) 160 if err != nil { 161 return nil, nil, err 162 } 163 issue.Created = &createdTime 164 165 comments, err := d.GetComments(repoAt, issueId) 166 if err != nil { 167 return nil, nil, err 168 } 169 170 return &issue, comments, nil 171} 172 173func (d *DB) NewComment(comment *Comment) error { 174 query := `insert into comments (owner_did, repo_at, comment_at, issue_id, comment_id, body) values (?, ?, ?, ?, ?, ?)` 175 _, err := d.db.Exec( 176 query, 177 comment.OwnerDid, 178 comment.RepoAt, 179 comment.CommentAt, 180 comment.Issue, 181 comment.CommentId, 182 comment.Body, 183 ) 184 return err 185} 186 187func (d *DB) GetComments(repoAt string, issueId int) ([]Comment, error) { 188 var comments []Comment 189 190 rows, err := d.db.Query(`select owner_did, issue_id, comment_id, comment_at, body, created from comments where repo_at = ? and issue_id = ? order by created asc`, repoAt, issueId) 191 if err == sql.ErrNoRows { 192 return []Comment{}, nil 193 } 194 if err != nil { 195 return nil, err 196 } 197 defer rows.Close() 198 199 for rows.Next() { 200 var comment Comment 201 var createdAt string 202 err := rows.Scan(&comment.OwnerDid, &comment.Issue, &comment.CommentId, &comment.CommentAt, &comment.Body, &createdAt) 203 if err != nil { 204 return nil, err 205 } 206 207 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 208 if err != nil { 209 return nil, err 210 } 211 comment.Created = &createdAtTime 212 213 comments = append(comments, comment) 214 } 215 216 if err := rows.Err(); err != nil { 217 return nil, err 218 } 219 220 return comments, nil 221} 222 223func (d *DB) CloseIssue(repoAt string, issueId int) error { 224 _, err := d.db.Exec(`update issues set open = 0 where repo_at = ? and issue_id = ?`, repoAt, issueId) 225 return err 226} 227 228func (d *DB) ReopenIssue(repoAt string, issueId int) error { 229 _, err := d.db.Exec(`update issues set open = 1 where repo_at = ? and issue_id = ?`, repoAt, issueId) 230 return err 231}