+46
-21
appview/db/issues.go
+46
-21
appview/db/issues.go
···
171
171
}
172
172
173
173
func NewIssue(tx *sql.Tx, issue *Issue) error {
174
-
defer tx.Rollback()
175
-
174
+
// ensure sequence exists
176
175
_, err := tx.Exec(`
177
176
insert or ignore into repo_issue_seqs (repo_at, next_issue_id)
178
177
values (?, 1)
179
-
`, issue.RepoAt)
178
+
`, issue.RepoAt)
180
179
if err != nil {
181
180
return err
182
181
}
183
182
184
-
var nextId int
183
+
// check if issue already exists
184
+
var existingRowId, existingIssueId sql.NullInt64
185
185
err = tx.QueryRow(`
186
-
update repo_issue_seqs
187
-
set next_issue_id = next_issue_id + 1
188
-
where repo_at = ?
189
-
returning next_issue_id - 1
190
-
`, issue.RepoAt).Scan(&nextId)
191
-
if err != nil {
192
-
return err
193
-
}
186
+
select rowid, issue_id from issues
187
+
where did = ? and rkey = ?
188
+
`, issue.Did, issue.Rkey).Scan(&existingRowId, &existingIssueId)
194
189
195
-
issue.IssueId = nextId
190
+
switch {
191
+
case err == sql.ErrNoRows:
192
+
return createNewIssue(tx, issue)
196
193
197
-
res, err := tx.Exec(`
198
-
insert into issues (repo_at, owner_did, rkey, issue_at, issue_id, title, body)
199
-
values (?, ?, ?, ?, ?, ?, ?)
200
-
`, issue.RepoAt, issue.OwnerDid, issue.Rkey, issue.AtUri(), issue.IssueId, issue.Title, issue.Body)
201
-
if err != nil {
194
+
case err != nil:
202
195
return err
196
+
197
+
default:
198
+
// Case 3: Issue exists - update it
199
+
return updateIssue(tx, issue, existingRowId.Int64, int(existingIssueId.Int64))
203
200
}
201
+
}
204
202
205
-
lastID, err := res.LastInsertId()
203
+
func createNewIssue(tx *sql.Tx, issue *Issue) error {
204
+
// get next issue_id
205
+
var newIssueId int
206
+
err := tx.QueryRow(`
207
+
update repo_issue_seqs
208
+
set next_issue_id = next_issue_id + 1
209
+
where repo_at = ?
210
+
returning next_issue_id - 1
211
+
`, issue.RepoAt).Scan(&newIssueId)
206
212
if err != nil {
207
213
return err
208
214
}
209
-
issue.ID = lastID
215
+
216
+
// insert new issue
217
+
row := tx.QueryRow(`
218
+
insert into issues (repo_at, did, rkey, issue_id, title, body)
219
+
values (?, ?, ?, ?, ?, ?)
220
+
returning rowid, issue_id
221
+
`, issue.RepoAt, issue.Did, issue.Rkey, newIssueId, issue.Title, issue.Body)
210
222
211
-
if err := tx.Commit(); err != nil {
223
+
return row.Scan(&issue.Id, &issue.IssueId)
224
+
}
225
+
226
+
func updateIssue(tx *sql.Tx, issue *Issue, existingRowId int64, existingIssueId int) error {
227
+
// update existing issue
228
+
_, err := tx.Exec(`
229
+
update issues
230
+
set title = ?, body = ?
231
+
where did = ? and rkey = ?
232
+
`, issue.Title, issue.Body, issue.Did, issue.Rkey)
233
+
if err != nil {
212
234
return err
213
235
}
214
236
237
+
// set the values from existing record
238
+
issue.Id = existingRowId
239
+
issue.IssueId = existingIssueId
215
240
return nil
216
241
}
217
242