231 lines
5.6 kB
1
package db
2
3
import (
4
"database/sql"
5
"time"
6
)
7
8
type 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
19
type 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
29
func (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
72
func (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
77
func (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
83
func (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
89
func (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
95
func (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
128
func (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
148
func (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
173
func (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
187
func (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
223
func (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
228
func (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
}
232