Go · 29385 bytes Raw Blame History
1 // Code generated by sqlc. DO NOT EDIT.
2 // versions:
3 // sqlc v1.31.1
4 // source: issues.sql
5
6 package issuesdb
7
8 import (
9 "context"
10
11 "github.com/jackc/pgx/v5/pgtype"
12 )
13
14 const addIssueLabel = `-- name: AddIssueLabel :exec
15
16 INSERT INTO issue_labels (issue_id, label_id, applied_by_user_id)
17 VALUES ($1, $2, $3::bigint)
18 ON CONFLICT (issue_id, label_id) DO NOTHING
19 `
20
21 type AddIssueLabelParams struct {
22 IssueID int64
23 LabelID int64
24 AppliedByUserID pgtype.Int8
25 }
26
27 // ─── issue ↔ label ───────────────────────────────────────────────────
28 func (q *Queries) AddIssueLabel(ctx context.Context, db DBTX, arg AddIssueLabelParams) error {
29 _, err := db.Exec(ctx, addIssueLabel, arg.IssueID, arg.LabelID, arg.AppliedByUserID)
30 return err
31 }
32
33 const allocateIssueNumber = `-- name: AllocateIssueNumber :one
34 UPDATE repo_issue_counter
35 SET next_number = next_number + 1
36 WHERE repo_id = $1
37 RETURNING (next_number - 1)::bigint AS allocated
38 `
39
40 // UPDATE … RETURNING is concurrency-safe: each row update is
41 // serialized by the row lock; concurrent transactions see different
42 // values. The caller wraps this in the same tx as the issue insert.
43 func (q *Queries) AllocateIssueNumber(ctx context.Context, db DBTX, repoID int64) (int64, error) {
44 row := db.QueryRow(ctx, allocateIssueNumber, repoID)
45 var allocated int64
46 err := row.Scan(&allocated)
47 return allocated, err
48 }
49
50 const assignUserToIssue = `-- name: AssignUserToIssue :exec
51
52 INSERT INTO issue_assignees (issue_id, user_id, assigned_by_user_id)
53 VALUES ($1, $2, $3::bigint)
54 ON CONFLICT (issue_id, user_id) DO NOTHING
55 `
56
57 type AssignUserToIssueParams struct {
58 IssueID int64
59 UserID int64
60 AssignedByUserID pgtype.Int8
61 }
62
63 // ─── assignees ───────────────────────────────────────────────────────
64 func (q *Queries) AssignUserToIssue(ctx context.Context, db DBTX, arg AssignUserToIssueParams) error {
65 _, err := db.Exec(ctx, assignUserToIssue, arg.IssueID, arg.UserID, arg.AssignedByUserID)
66 return err
67 }
68
69 const countIssueEvents = `-- name: CountIssueEvents :one
70 SELECT COUNT(*) FROM issue_events WHERE issue_id = $1
71 `
72
73 func (q *Queries) CountIssueEvents(ctx context.Context, db DBTX, issueID int64) (int64, error) {
74 row := db.QueryRow(ctx, countIssueEvents, issueID)
75 var count int64
76 err := row.Scan(&count)
77 return count, err
78 }
79
80 const countIssues = `-- name: CountIssues :one
81 SELECT count(*)::bigint FROM issues
82 WHERE repo_id = $1
83 AND ($2::text IS NULL OR state::text = $2::text)
84 AND kind = COALESCE($3::issue_kind, 'issue')
85 `
86
87 type CountIssuesParams struct {
88 RepoID int64
89 StateFilter pgtype.Text
90 Kind NullIssueKind
91 }
92
93 func (q *Queries) CountIssues(ctx context.Context, db DBTX, arg CountIssuesParams) (int64, error) {
94 row := db.QueryRow(ctx, countIssues, arg.RepoID, arg.StateFilter, arg.Kind)
95 var column_1 int64
96 err := row.Scan(&column_1)
97 return column_1, err
98 }
99
100 const createIssue = `-- name: CreateIssue :one
101
102 INSERT INTO issues (
103 repo_id, number, kind, title, body, author_user_id
104 ) VALUES (
105 $1, $2, $3, $4, $5, $6::bigint
106 )
107 RETURNING id, repo_id, number, kind, title, body, body_html_cached, md_pipeline_version, author_user_id, state, state_reason, locked, lock_reason, milestone_id, created_at, updated_at, edited_at, closed_at, closed_by_user_id
108 `
109
110 type CreateIssueParams struct {
111 RepoID int64
112 Number int64
113 Kind IssueKind
114 Title string
115 Body string
116 AuthorUserID pgtype.Int8
117 }
118
119 // ─── issues ──────────────────────────────────────────────────────────
120 func (q *Queries) CreateIssue(ctx context.Context, db DBTX, arg CreateIssueParams) (Issue, error) {
121 row := db.QueryRow(ctx, createIssue,
122 arg.RepoID,
123 arg.Number,
124 arg.Kind,
125 arg.Title,
126 arg.Body,
127 arg.AuthorUserID,
128 )
129 var i Issue
130 err := row.Scan(
131 &i.ID,
132 &i.RepoID,
133 &i.Number,
134 &i.Kind,
135 &i.Title,
136 &i.Body,
137 &i.BodyHtmlCached,
138 &i.MdPipelineVersion,
139 &i.AuthorUserID,
140 &i.State,
141 &i.StateReason,
142 &i.Locked,
143 &i.LockReason,
144 &i.MilestoneID,
145 &i.CreatedAt,
146 &i.UpdatedAt,
147 &i.EditedAt,
148 &i.ClosedAt,
149 &i.ClosedByUserID,
150 )
151 return i, err
152 }
153
154 const createIssueComment = `-- name: CreateIssueComment :one
155
156 INSERT INTO issue_comments (issue_id, author_user_id, body, body_html_cached)
157 VALUES ($1, $4::bigint, $2, $3)
158 RETURNING id, issue_id, author_user_id, body, body_html_cached, md_pipeline_version, created_at, updated_at, edited_at
159 `
160
161 type CreateIssueCommentParams struct {
162 IssueID int64
163 Body string
164 BodyHtmlCached pgtype.Text
165 AuthorUserID pgtype.Int8
166 }
167
168 // ─── comments ────────────────────────────────────────────────────────
169 func (q *Queries) CreateIssueComment(ctx context.Context, db DBTX, arg CreateIssueCommentParams) (IssueComment, error) {
170 row := db.QueryRow(ctx, createIssueComment,
171 arg.IssueID,
172 arg.Body,
173 arg.BodyHtmlCached,
174 arg.AuthorUserID,
175 )
176 var i IssueComment
177 err := row.Scan(
178 &i.ID,
179 &i.IssueID,
180 &i.AuthorUserID,
181 &i.Body,
182 &i.BodyHtmlCached,
183 &i.MdPipelineVersion,
184 &i.CreatedAt,
185 &i.UpdatedAt,
186 &i.EditedAt,
187 )
188 return i, err
189 }
190
191 const createLabel = `-- name: CreateLabel :one
192
193 INSERT INTO labels (repo_id, name, color, description)
194 VALUES ($1, $2, $3, $4)
195 RETURNING id, repo_id, name, color, description, created_at
196 `
197
198 type CreateLabelParams struct {
199 RepoID int64
200 Name string
201 Color string
202 Description string
203 }
204
205 // ─── labels ──────────────────────────────────────────────────────────
206 func (q *Queries) CreateLabel(ctx context.Context, db DBTX, arg CreateLabelParams) (Label, error) {
207 row := db.QueryRow(ctx, createLabel,
208 arg.RepoID,
209 arg.Name,
210 arg.Color,
211 arg.Description,
212 )
213 var i Label
214 err := row.Scan(
215 &i.ID,
216 &i.RepoID,
217 &i.Name,
218 &i.Color,
219 &i.Description,
220 &i.CreatedAt,
221 )
222 return i, err
223 }
224
225 const createMilestone = `-- name: CreateMilestone :one
226
227 INSERT INTO milestones (repo_id, title, description, due_on)
228 VALUES ($1, $2, $3, $4::timestamptz)
229 RETURNING id, repo_id, title, description, state, due_on, created_at, closed_at
230 `
231
232 type CreateMilestoneParams struct {
233 RepoID int64
234 Title string
235 Description string
236 DueOn pgtype.Timestamptz
237 }
238
239 // ─── milestones ──────────────────────────────────────────────────────
240 func (q *Queries) CreateMilestone(ctx context.Context, db DBTX, arg CreateMilestoneParams) (Milestone, error) {
241 row := db.QueryRow(ctx, createMilestone,
242 arg.RepoID,
243 arg.Title,
244 arg.Description,
245 arg.DueOn,
246 )
247 var i Milestone
248 err := row.Scan(
249 &i.ID,
250 &i.RepoID,
251 &i.Title,
252 &i.Description,
253 &i.State,
254 &i.DueOn,
255 &i.CreatedAt,
256 &i.ClosedAt,
257 )
258 return i, err
259 }
260
261 const deleteIssueComment = `-- name: DeleteIssueComment :exec
262 DELETE FROM issue_comments WHERE id = $1
263 `
264
265 func (q *Queries) DeleteIssueComment(ctx context.Context, db DBTX, id int64) error {
266 _, err := db.Exec(ctx, deleteIssueComment, id)
267 return err
268 }
269
270 const deleteLabel = `-- name: DeleteLabel :exec
271 DELETE FROM labels WHERE id = $1
272 `
273
274 func (q *Queries) DeleteLabel(ctx context.Context, db DBTX, id int64) error {
275 _, err := db.Exec(ctx, deleteLabel, id)
276 return err
277 }
278
279 const deleteMilestone = `-- name: DeleteMilestone :exec
280 DELETE FROM milestones WHERE id = $1
281 `
282
283 func (q *Queries) DeleteMilestone(ctx context.Context, db DBTX, id int64) error {
284 _, err := db.Exec(ctx, deleteMilestone, id)
285 return err
286 }
287
288 const ensureRepoIssueCounter = `-- name: EnsureRepoIssueCounter :exec
289
290
291 INSERT INTO repo_issue_counter (repo_id, next_number)
292 VALUES ($1, 1)
293 ON CONFLICT (repo_id) DO NOTHING
294 `
295
296 // SPDX-License-Identifier: AGPL-3.0-or-later
297 // ─── per-repo numbering ───────────────────────────────────────────────
298 // Lazy-initialize the counter row. Idempotent — invoked from repo
299 // create AND from the first issue insert (defensive in case someone
300 // migrates an old repo that predates S21).
301 func (q *Queries) EnsureRepoIssueCounter(ctx context.Context, db DBTX, repoID int64) error {
302 _, err := db.Exec(ctx, ensureRepoIssueCounter, repoID)
303 return err
304 }
305
306 const getIssueByID = `-- name: GetIssueByID :one
307 SELECT id, repo_id, number, kind, title, body, body_html_cached, md_pipeline_version, author_user_id, state, state_reason, locked, lock_reason, milestone_id, created_at, updated_at, edited_at, closed_at, closed_by_user_id FROM issues WHERE id = $1
308 `
309
310 func (q *Queries) GetIssueByID(ctx context.Context, db DBTX, id int64) (Issue, error) {
311 row := db.QueryRow(ctx, getIssueByID, id)
312 var i Issue
313 err := row.Scan(
314 &i.ID,
315 &i.RepoID,
316 &i.Number,
317 &i.Kind,
318 &i.Title,
319 &i.Body,
320 &i.BodyHtmlCached,
321 &i.MdPipelineVersion,
322 &i.AuthorUserID,
323 &i.State,
324 &i.StateReason,
325 &i.Locked,
326 &i.LockReason,
327 &i.MilestoneID,
328 &i.CreatedAt,
329 &i.UpdatedAt,
330 &i.EditedAt,
331 &i.ClosedAt,
332 &i.ClosedByUserID,
333 )
334 return i, err
335 }
336
337 const getIssueByNumber = `-- name: GetIssueByNumber :one
338 SELECT id, repo_id, number, kind, title, body, body_html_cached, md_pipeline_version, author_user_id, state, state_reason, locked, lock_reason, milestone_id, created_at, updated_at, edited_at, closed_at, closed_by_user_id FROM issues
339 WHERE repo_id = $1 AND number = $2
340 `
341
342 type GetIssueByNumberParams struct {
343 RepoID int64
344 Number int64
345 }
346
347 func (q *Queries) GetIssueByNumber(ctx context.Context, db DBTX, arg GetIssueByNumberParams) (Issue, error) {
348 row := db.QueryRow(ctx, getIssueByNumber, arg.RepoID, arg.Number)
349 var i Issue
350 err := row.Scan(
351 &i.ID,
352 &i.RepoID,
353 &i.Number,
354 &i.Kind,
355 &i.Title,
356 &i.Body,
357 &i.BodyHtmlCached,
358 &i.MdPipelineVersion,
359 &i.AuthorUserID,
360 &i.State,
361 &i.StateReason,
362 &i.Locked,
363 &i.LockReason,
364 &i.MilestoneID,
365 &i.CreatedAt,
366 &i.UpdatedAt,
367 &i.EditedAt,
368 &i.ClosedAt,
369 &i.ClosedByUserID,
370 )
371 return i, err
372 }
373
374 const getIssueComment = `-- name: GetIssueComment :one
375 SELECT id, issue_id, author_user_id, body, body_html_cached, md_pipeline_version, created_at, updated_at, edited_at FROM issue_comments WHERE id = $1
376 `
377
378 func (q *Queries) GetIssueComment(ctx context.Context, db DBTX, id int64) (IssueComment, error) {
379 row := db.QueryRow(ctx, getIssueComment, id)
380 var i IssueComment
381 err := row.Scan(
382 &i.ID,
383 &i.IssueID,
384 &i.AuthorUserID,
385 &i.Body,
386 &i.BodyHtmlCached,
387 &i.MdPipelineVersion,
388 &i.CreatedAt,
389 &i.UpdatedAt,
390 &i.EditedAt,
391 )
392 return i, err
393 }
394
395 const getLabelByName = `-- name: GetLabelByName :one
396 SELECT id, repo_id, name, color, description, created_at FROM labels WHERE repo_id = $1 AND name = $2
397 `
398
399 type GetLabelByNameParams struct {
400 RepoID int64
401 Name string
402 }
403
404 func (q *Queries) GetLabelByName(ctx context.Context, db DBTX, arg GetLabelByNameParams) (Label, error) {
405 row := db.QueryRow(ctx, getLabelByName, arg.RepoID, arg.Name)
406 var i Label
407 err := row.Scan(
408 &i.ID,
409 &i.RepoID,
410 &i.Name,
411 &i.Color,
412 &i.Description,
413 &i.CreatedAt,
414 )
415 return i, err
416 }
417
418 const getMilestone = `-- name: GetMilestone :one
419 SELECT id, repo_id, title, description, state, due_on, created_at, closed_at FROM milestones WHERE id = $1
420 `
421
422 func (q *Queries) GetMilestone(ctx context.Context, db DBTX, id int64) (Milestone, error) {
423 row := db.QueryRow(ctx, getMilestone, id)
424 var i Milestone
425 err := row.Scan(
426 &i.ID,
427 &i.RepoID,
428 &i.Title,
429 &i.Description,
430 &i.State,
431 &i.DueOn,
432 &i.CreatedAt,
433 &i.ClosedAt,
434 )
435 return i, err
436 }
437
438 const insertIssueEvent = `-- name: InsertIssueEvent :one
439
440 INSERT INTO issue_events (issue_id, actor_user_id, kind, meta, ref_target_id)
441 VALUES ($1, $4::bigint, $2, $3, $5::bigint)
442 RETURNING id, issue_id, actor_user_id, kind, meta, ref_target_id, created_at
443 `
444
445 type InsertIssueEventParams struct {
446 IssueID int64
447 Kind string
448 Meta []byte
449 ActorUserID pgtype.Int8
450 RefTargetID pgtype.Int8
451 }
452
453 // ─── events + references ─────────────────────────────────────────────
454 func (q *Queries) InsertIssueEvent(ctx context.Context, db DBTX, arg InsertIssueEventParams) (IssueEvent, error) {
455 row := db.QueryRow(ctx, insertIssueEvent,
456 arg.IssueID,
457 arg.Kind,
458 arg.Meta,
459 arg.ActorUserID,
460 arg.RefTargetID,
461 )
462 var i IssueEvent
463 err := row.Scan(
464 &i.ID,
465 &i.IssueID,
466 &i.ActorUserID,
467 &i.Kind,
468 &i.Meta,
469 &i.RefTargetID,
470 &i.CreatedAt,
471 )
472 return i, err
473 }
474
475 const insertIssueReference = `-- name: InsertIssueReference :exec
476 INSERT INTO issue_references (
477 source_issue_id, target_issue_id, source_kind, source_object_id
478 ) VALUES (
479 $3::bigint, $1, $2, $4::bigint
480 )
481 `
482
483 type InsertIssueReferenceParams struct {
484 TargetIssueID int64
485 SourceKind IssueRefSource
486 SourceIssueID pgtype.Int8
487 SourceObjectID pgtype.Int8
488 }
489
490 func (q *Queries) InsertIssueReference(ctx context.Context, db DBTX, arg InsertIssueReferenceParams) error {
491 _, err := db.Exec(ctx, insertIssueReference,
492 arg.TargetIssueID,
493 arg.SourceKind,
494 arg.SourceIssueID,
495 arg.SourceObjectID,
496 )
497 return err
498 }
499
500 const listIssueAssignees = `-- name: ListIssueAssignees :many
501 SELECT a.issue_id, a.user_id, a.assigned_at, u.username, u.display_name
502 FROM issue_assignees a
503 JOIN users u ON u.id = a.user_id
504 WHERE a.issue_id = $1
505 ORDER BY a.assigned_at
506 `
507
508 type ListIssueAssigneesRow struct {
509 IssueID int64
510 UserID int64
511 AssignedAt pgtype.Timestamptz
512 Username string
513 DisplayName string
514 }
515
516 func (q *Queries) ListIssueAssignees(ctx context.Context, db DBTX, issueID int64) ([]ListIssueAssigneesRow, error) {
517 rows, err := db.Query(ctx, listIssueAssignees, issueID)
518 if err != nil {
519 return nil, err
520 }
521 defer rows.Close()
522 items := []ListIssueAssigneesRow{}
523 for rows.Next() {
524 var i ListIssueAssigneesRow
525 if err := rows.Scan(
526 &i.IssueID,
527 &i.UserID,
528 &i.AssignedAt,
529 &i.Username,
530 &i.DisplayName,
531 ); err != nil {
532 return nil, err
533 }
534 items = append(items, i)
535 }
536 if err := rows.Err(); err != nil {
537 return nil, err
538 }
539 return items, nil
540 }
541
542 const listIssueComments = `-- name: ListIssueComments :many
543 SELECT id, issue_id, author_user_id, body, body_html_cached, md_pipeline_version, created_at, updated_at, edited_at FROM issue_comments
544 WHERE issue_id = $1
545 ORDER BY created_at ASC
546 `
547
548 func (q *Queries) ListIssueComments(ctx context.Context, db DBTX, issueID int64) ([]IssueComment, error) {
549 rows, err := db.Query(ctx, listIssueComments, issueID)
550 if err != nil {
551 return nil, err
552 }
553 defer rows.Close()
554 items := []IssueComment{}
555 for rows.Next() {
556 var i IssueComment
557 if err := rows.Scan(
558 &i.ID,
559 &i.IssueID,
560 &i.AuthorUserID,
561 &i.Body,
562 &i.BodyHtmlCached,
563 &i.MdPipelineVersion,
564 &i.CreatedAt,
565 &i.UpdatedAt,
566 &i.EditedAt,
567 ); err != nil {
568 return nil, err
569 }
570 items = append(items, i)
571 }
572 if err := rows.Err(); err != nil {
573 return nil, err
574 }
575 return items, nil
576 }
577
578 const listIssueEvents = `-- name: ListIssueEvents :many
579 SELECT id, issue_id, actor_user_id, kind, meta, ref_target_id, created_at FROM issue_events
580 WHERE issue_id = $1
581 ORDER BY created_at ASC
582 `
583
584 func (q *Queries) ListIssueEvents(ctx context.Context, db DBTX, issueID int64) ([]IssueEvent, error) {
585 rows, err := db.Query(ctx, listIssueEvents, issueID)
586 if err != nil {
587 return nil, err
588 }
589 defer rows.Close()
590 items := []IssueEvent{}
591 for rows.Next() {
592 var i IssueEvent
593 if err := rows.Scan(
594 &i.ID,
595 &i.IssueID,
596 &i.ActorUserID,
597 &i.Kind,
598 &i.Meta,
599 &i.RefTargetID,
600 &i.CreatedAt,
601 ); err != nil {
602 return nil, err
603 }
604 items = append(items, i)
605 }
606 if err := rows.Err(); err != nil {
607 return nil, err
608 }
609 return items, nil
610 }
611
612 const listIssueEventsWithActor = `-- name: ListIssueEventsWithActor :many
613 SELECT e.id, e.issue_id, e.actor_user_id, e.kind, e.meta, e.ref_target_id,
614 e.created_at, u.username AS actor_username
615 FROM issue_events e
616 LEFT JOIN users u ON u.id = e.actor_user_id
617 WHERE e.issue_id = $1
618 ORDER BY e.created_at ASC, e.id ASC
619 LIMIT $2 OFFSET $3
620 `
621
622 type ListIssueEventsWithActorParams struct {
623 IssueID int64
624 Limit int32
625 Offset int32
626 }
627
628 type ListIssueEventsWithActorRow struct {
629 ID int64
630 IssueID int64
631 ActorUserID pgtype.Int8
632 Kind string
633 Meta []byte
634 RefTargetID pgtype.Int8
635 CreatedAt pgtype.Timestamptz
636 ActorUsername pgtype.Text
637 }
638
639 // Paginated timeline shape for the REST `/issues/{n}/events` endpoint:
640 // the same event rows ListIssueEvents returns, but LEFT-joined to users
641 // so the response can carry `actor_username` without a second round-trip.
642 // Suspended/deleted actor rows still appear (the timeline is historical
643 // truth), with NULL username when the user row is unrecoverable.
644 func (q *Queries) ListIssueEventsWithActor(ctx context.Context, db DBTX, arg ListIssueEventsWithActorParams) ([]ListIssueEventsWithActorRow, error) {
645 rows, err := db.Query(ctx, listIssueEventsWithActor, arg.IssueID, arg.Limit, arg.Offset)
646 if err != nil {
647 return nil, err
648 }
649 defer rows.Close()
650 items := []ListIssueEventsWithActorRow{}
651 for rows.Next() {
652 var i ListIssueEventsWithActorRow
653 if err := rows.Scan(
654 &i.ID,
655 &i.IssueID,
656 &i.ActorUserID,
657 &i.Kind,
658 &i.Meta,
659 &i.RefTargetID,
660 &i.CreatedAt,
661 &i.ActorUsername,
662 ); err != nil {
663 return nil, err
664 }
665 items = append(items, i)
666 }
667 if err := rows.Err(); err != nil {
668 return nil, err
669 }
670 return items, nil
671 }
672
673 const listIssues = `-- name: ListIssues :many
674 SELECT id, repo_id, number, kind, title, body, body_html_cached, md_pipeline_version, author_user_id, state, state_reason, locked, lock_reason, milestone_id, created_at, updated_at, edited_at, closed_at, closed_by_user_id FROM issues
675 WHERE repo_id = $1
676 AND ($4::text IS NULL OR state::text = $4::text)
677 AND kind = COALESCE($5::issue_kind, 'issue')
678 ORDER BY updated_at DESC
679 LIMIT $2 OFFSET $3
680 `
681
682 type ListIssuesParams struct {
683 RepoID int64
684 Limit int32
685 Offset int32
686 StateFilter pgtype.Text
687 Kind NullIssueKind
688 }
689
690 // Filterable list. Caller passes a state filter (open/closed/all
691 // where 'all' is encoded as NULL); label/assignee/author/milestone
692 // filtering happens after this query in Go for v1 — see the
693 // internal/issues/list.go composer. Per-page hardcoded at 25 in the
694 // handler; offset is the (page-1)*25.
695 func (q *Queries) ListIssues(ctx context.Context, db DBTX, arg ListIssuesParams) ([]Issue, error) {
696 rows, err := db.Query(ctx, listIssues,
697 arg.RepoID,
698 arg.Limit,
699 arg.Offset,
700 arg.StateFilter,
701 arg.Kind,
702 )
703 if err != nil {
704 return nil, err
705 }
706 defer rows.Close()
707 items := []Issue{}
708 for rows.Next() {
709 var i Issue
710 if err := rows.Scan(
711 &i.ID,
712 &i.RepoID,
713 &i.Number,
714 &i.Kind,
715 &i.Title,
716 &i.Body,
717 &i.BodyHtmlCached,
718 &i.MdPipelineVersion,
719 &i.AuthorUserID,
720 &i.State,
721 &i.StateReason,
722 &i.Locked,
723 &i.LockReason,
724 &i.MilestoneID,
725 &i.CreatedAt,
726 &i.UpdatedAt,
727 &i.EditedAt,
728 &i.ClosedAt,
729 &i.ClosedByUserID,
730 ); err != nil {
731 return nil, err
732 }
733 items = append(items, i)
734 }
735 if err := rows.Err(); err != nil {
736 return nil, err
737 }
738 return items, nil
739 }
740
741 const listLabels = `-- name: ListLabels :many
742 SELECT id, repo_id, name, color, description, created_at FROM labels WHERE repo_id = $1 ORDER BY name
743 `
744
745 func (q *Queries) ListLabels(ctx context.Context, db DBTX, repoID int64) ([]Label, error) {
746 rows, err := db.Query(ctx, listLabels, repoID)
747 if err != nil {
748 return nil, err
749 }
750 defer rows.Close()
751 items := []Label{}
752 for rows.Next() {
753 var i Label
754 if err := rows.Scan(
755 &i.ID,
756 &i.RepoID,
757 &i.Name,
758 &i.Color,
759 &i.Description,
760 &i.CreatedAt,
761 ); err != nil {
762 return nil, err
763 }
764 items = append(items, i)
765 }
766 if err := rows.Err(); err != nil {
767 return nil, err
768 }
769 return items, nil
770 }
771
772 const listLabelsOnIssue = `-- name: ListLabelsOnIssue :many
773 SELECT l.id, l.repo_id, l.name, l.color, l.description, l.created_at
774 FROM issue_labels il
775 JOIN labels l ON l.id = il.label_id
776 WHERE il.issue_id = $1
777 ORDER BY l.name
778 `
779
780 func (q *Queries) ListLabelsOnIssue(ctx context.Context, db DBTX, issueID int64) ([]Label, error) {
781 rows, err := db.Query(ctx, listLabelsOnIssue, issueID)
782 if err != nil {
783 return nil, err
784 }
785 defer rows.Close()
786 items := []Label{}
787 for rows.Next() {
788 var i Label
789 if err := rows.Scan(
790 &i.ID,
791 &i.RepoID,
792 &i.Name,
793 &i.Color,
794 &i.Description,
795 &i.CreatedAt,
796 ); err != nil {
797 return nil, err
798 }
799 items = append(items, i)
800 }
801 if err := rows.Err(); err != nil {
802 return nil, err
803 }
804 return items, nil
805 }
806
807 const listMilestones = `-- name: ListMilestones :many
808 SELECT id, repo_id, title, description, state, due_on, created_at, closed_at FROM milestones WHERE repo_id = $1 ORDER BY state, due_on NULLS LAST, title
809 `
810
811 func (q *Queries) ListMilestones(ctx context.Context, db DBTX, repoID int64) ([]Milestone, error) {
812 rows, err := db.Query(ctx, listMilestones, repoID)
813 if err != nil {
814 return nil, err
815 }
816 defer rows.Close()
817 items := []Milestone{}
818 for rows.Next() {
819 var i Milestone
820 if err := rows.Scan(
821 &i.ID,
822 &i.RepoID,
823 &i.Title,
824 &i.Description,
825 &i.State,
826 &i.DueOn,
827 &i.CreatedAt,
828 &i.ClosedAt,
829 ); err != nil {
830 return nil, err
831 }
832 items = append(items, i)
833 }
834 if err := rows.Err(); err != nil {
835 return nil, err
836 }
837 return items, nil
838 }
839
840 const listProfileAuthoredIssuesForUser = `-- name: ListProfileAuthoredIssuesForUser :many
841 SELECT
842 i.id, i.repo_id, i.number, i.kind, i.title, i.state, i.created_at, i.closed_at,
843 pr.merged_at,
844 r.name AS repo_name, r.visibility, r.owner_user_id, r.owner_org_id,
845 COALESCE(u.username, o.slug)::text AS owner_slug
846 FROM issues i
847 JOIN repos r ON r.id = i.repo_id
848 LEFT JOIN pull_requests pr ON pr.issue_id = i.id
849 LEFT JOIN users u ON u.id = r.owner_user_id
850 LEFT JOIN orgs o ON o.id = r.owner_org_id
851 WHERE i.author_user_id = $1
852 AND i.created_at >= $2
853 AND i.created_at < $3
854 AND r.deleted_at IS NULL
855 ORDER BY i.created_at DESC, i.id DESC
856 LIMIT $4
857 `
858
859 type ListProfileAuthoredIssuesForUserParams struct {
860 AuthorUserID pgtype.Int8
861 CreatedAt pgtype.Timestamptz
862 CreatedAt_2 pgtype.Timestamptz
863 Limit int32
864 }
865
866 type ListProfileAuthoredIssuesForUserRow struct {
867 ID int64
868 RepoID int64
869 Number int64
870 Kind IssueKind
871 Title string
872 State IssueState
873 CreatedAt pgtype.Timestamptz
874 ClosedAt pgtype.Timestamptz
875 MergedAt pgtype.Timestamptz
876 RepoName string
877 Visibility RepoVisibility
878 OwnerUserID pgtype.Int8
879 OwnerOrgID pgtype.Int8
880 OwnerSlug string
881 }
882
883 // Cross-repository profile contribution activity. The handler performs the
884 // final repo visibility gate with policy.IsVisibleTo so private issues and
885 // PRs never leak through the public profile timeline.
886 func (q *Queries) ListProfileAuthoredIssuesForUser(ctx context.Context, db DBTX, arg ListProfileAuthoredIssuesForUserParams) ([]ListProfileAuthoredIssuesForUserRow, error) {
887 rows, err := db.Query(ctx, listProfileAuthoredIssuesForUser,
888 arg.AuthorUserID,
889 arg.CreatedAt,
890 arg.CreatedAt_2,
891 arg.Limit,
892 )
893 if err != nil {
894 return nil, err
895 }
896 defer rows.Close()
897 items := []ListProfileAuthoredIssuesForUserRow{}
898 for rows.Next() {
899 var i ListProfileAuthoredIssuesForUserRow
900 if err := rows.Scan(
901 &i.ID,
902 &i.RepoID,
903 &i.Number,
904 &i.Kind,
905 &i.Title,
906 &i.State,
907 &i.CreatedAt,
908 &i.ClosedAt,
909 &i.MergedAt,
910 &i.RepoName,
911 &i.Visibility,
912 &i.OwnerUserID,
913 &i.OwnerOrgID,
914 &i.OwnerSlug,
915 ); err != nil {
916 return nil, err
917 }
918 items = append(items, i)
919 }
920 if err := rows.Err(); err != nil {
921 return nil, err
922 }
923 return items, nil
924 }
925
926 const milestoneIssueCounts = `-- name: MilestoneIssueCounts :one
927 SELECT
928 count(*) FILTER (WHERE state = 'open')::int AS open_count,
929 count(*) FILTER (WHERE state = 'closed')::int AS closed_count
930 FROM issues
931 WHERE milestone_id = $1
932 `
933
934 type MilestoneIssueCountsRow struct {
935 OpenCount int32
936 ClosedCount int32
937 }
938
939 // Open + closed counts for the milestone progress bar.
940 func (q *Queries) MilestoneIssueCounts(ctx context.Context, db DBTX, milestoneID pgtype.Int8) (MilestoneIssueCountsRow, error) {
941 row := db.QueryRow(ctx, milestoneIssueCounts, milestoneID)
942 var i MilestoneIssueCountsRow
943 err := row.Scan(&i.OpenCount, &i.ClosedCount)
944 return i, err
945 }
946
947 const removeIssueLabel = `-- name: RemoveIssueLabel :exec
948 DELETE FROM issue_labels WHERE issue_id = $1 AND label_id = $2
949 `
950
951 type RemoveIssueLabelParams struct {
952 IssueID int64
953 LabelID int64
954 }
955
956 func (q *Queries) RemoveIssueLabel(ctx context.Context, db DBTX, arg RemoveIssueLabelParams) error {
957 _, err := db.Exec(ctx, removeIssueLabel, arg.IssueID, arg.LabelID)
958 return err
959 }
960
961 const setIssueLock = `-- name: SetIssueLock :exec
962 UPDATE issues
963 SET locked = $2, lock_reason = $3::text, updated_at = now()
964 WHERE id = $1
965 `
966
967 type SetIssueLockParams struct {
968 ID int64
969 Locked bool
970 LockReason pgtype.Text
971 }
972
973 func (q *Queries) SetIssueLock(ctx context.Context, db DBTX, arg SetIssueLockParams) error {
974 _, err := db.Exec(ctx, setIssueLock, arg.ID, arg.Locked, arg.LockReason)
975 return err
976 }
977
978 const setIssueMilestone = `-- name: SetIssueMilestone :exec
979 UPDATE issues
980 SET milestone_id = $2::bigint, updated_at = now()
981 WHERE id = $1
982 `
983
984 type SetIssueMilestoneParams struct {
985 ID int64
986 MilestoneID pgtype.Int8
987 }
988
989 func (q *Queries) SetIssueMilestone(ctx context.Context, db DBTX, arg SetIssueMilestoneParams) error {
990 _, err := db.Exec(ctx, setIssueMilestone, arg.ID, arg.MilestoneID)
991 return err
992 }
993
994 const setIssueState = `-- name: SetIssueState :exec
995 UPDATE issues
996 SET state = $2,
997 state_reason = $3::issue_state_reason,
998 closed_at = CASE WHEN $2::issue_state = 'closed' THEN now() ELSE NULL END,
999 closed_by_user_id = $4::bigint,
1000 updated_at = now()
1001 WHERE id = $1
1002 `
1003
1004 type SetIssueStateParams struct {
1005 ID int64
1006 State IssueState
1007 StateReason NullIssueStateReason
1008 ClosedByUserID pgtype.Int8
1009 }
1010
1011 func (q *Queries) SetIssueState(ctx context.Context, db DBTX, arg SetIssueStateParams) error {
1012 _, err := db.Exec(ctx, setIssueState,
1013 arg.ID,
1014 arg.State,
1015 arg.StateReason,
1016 arg.ClosedByUserID,
1017 )
1018 return err
1019 }
1020
1021 const setMilestoneState = `-- name: SetMilestoneState :exec
1022 UPDATE milestones SET state = $2, closed_at = CASE WHEN $2::milestone_state = 'closed' THEN now() ELSE NULL END WHERE id = $1
1023 `
1024
1025 type SetMilestoneStateParams struct {
1026 ID int64
1027 State MilestoneState
1028 }
1029
1030 func (q *Queries) SetMilestoneState(ctx context.Context, db DBTX, arg SetMilestoneStateParams) error {
1031 _, err := db.Exec(ctx, setMilestoneState, arg.ID, arg.State)
1032 return err
1033 }
1034
1035 const unassignUserFromIssue = `-- name: UnassignUserFromIssue :exec
1036 DELETE FROM issue_assignees WHERE issue_id = $1 AND user_id = $2
1037 `
1038
1039 type UnassignUserFromIssueParams struct {
1040 IssueID int64
1041 UserID int64
1042 }
1043
1044 func (q *Queries) UnassignUserFromIssue(ctx context.Context, db DBTX, arg UnassignUserFromIssueParams) error {
1045 _, err := db.Exec(ctx, unassignUserFromIssue, arg.IssueID, arg.UserID)
1046 return err
1047 }
1048
1049 const updateIssueCommentBody = `-- name: UpdateIssueCommentBody :exec
1050 UPDATE issue_comments
1051 SET body = $2, body_html_cached = $3, edited_at = now(), updated_at = now()
1052 WHERE id = $1
1053 `
1054
1055 type UpdateIssueCommentBodyParams struct {
1056 ID int64
1057 Body string
1058 BodyHtmlCached pgtype.Text
1059 }
1060
1061 func (q *Queries) UpdateIssueCommentBody(ctx context.Context, db DBTX, arg UpdateIssueCommentBodyParams) error {
1062 _, err := db.Exec(ctx, updateIssueCommentBody, arg.ID, arg.Body, arg.BodyHtmlCached)
1063 return err
1064 }
1065
1066 const updateIssueTitleBody = `-- name: UpdateIssueTitleBody :exec
1067 UPDATE issues
1068 SET title = $2, body = $3, body_html_cached = $4, edited_at = now(), updated_at = now()
1069 WHERE id = $1
1070 `
1071
1072 type UpdateIssueTitleBodyParams struct {
1073 ID int64
1074 Title string
1075 Body string
1076 BodyHtmlCached pgtype.Text
1077 }
1078
1079 func (q *Queries) UpdateIssueTitleBody(ctx context.Context, db DBTX, arg UpdateIssueTitleBodyParams) error {
1080 _, err := db.Exec(ctx, updateIssueTitleBody,
1081 arg.ID,
1082 arg.Title,
1083 arg.Body,
1084 arg.BodyHtmlCached,
1085 )
1086 return err
1087 }
1088
1089 const updateLabel = `-- name: UpdateLabel :exec
1090 UPDATE labels
1091 SET name = $2, color = $3, description = $4
1092 WHERE id = $1
1093 `
1094
1095 type UpdateLabelParams struct {
1096 ID int64
1097 Name string
1098 Color string
1099 Description string
1100 }
1101
1102 func (q *Queries) UpdateLabel(ctx context.Context, db DBTX, arg UpdateLabelParams) error {
1103 _, err := db.Exec(ctx, updateLabel,
1104 arg.ID,
1105 arg.Name,
1106 arg.Color,
1107 arg.Description,
1108 )
1109 return err
1110 }
1111
1112 const updateMilestone = `-- name: UpdateMilestone :exec
1113 UPDATE milestones SET title = $2, description = $3, due_on = $4::timestamptz WHERE id = $1
1114 `
1115
1116 type UpdateMilestoneParams struct {
1117 ID int64
1118 Title string
1119 Description string
1120 DueOn pgtype.Timestamptz
1121 }
1122
1123 func (q *Queries) UpdateMilestone(ctx context.Context, db DBTX, arg UpdateMilestoneParams) error {
1124 _, err := db.Exec(ctx, updateMilestone,
1125 arg.ID,
1126 arg.Title,
1127 arg.Description,
1128 arg.DueOn,
1129 )
1130 return err
1131 }
1132