labels.go
⎇
Raw
1package db
2
3import (
4 "context"
5 "database/sql"
6 "errors"
7 "strings"
8)
9
10type Label struct {
11 ID int64
12 RepoID int64
13 Name string
14 Color string
15 CreatedAt string
16}
17
18// placeholders returns "?, ?, ?" for an IN clause of n values.
19func placeholders(n int) string {
20 return strings.TrimSuffix(strings.Repeat("?, ", n), ", ")
21}
22
23func int64Args(ids []int64) []any {
24 args := make([]any, len(ids))
25 for i, id := range ids {
26 args[i] = id
27 }
28 return args
29}
30
31func (d *DB) ListLabels(ctx context.Context, repoID int64) ([]Label, error) {
32 rows, err := d.QueryContext(ctx,
33 `SELECT id, repo_id, name, color, created_at FROM labels WHERE repo_id = ? ORDER BY name ASC`,
34 repoID)
35 if err != nil {
36 return nil, err
37 }
38 defer rows.Close()
39 return scanLabels(rows)
40}
41
42func scanLabels(rows *sql.Rows) ([]Label, error) {
43 var out []Label
44 for rows.Next() {
45 var l Label
46 if err := rows.Scan(&l.ID, &l.RepoID, &l.Name, &l.Color, &l.CreatedAt); err != nil {
47 return nil, err
48 }
49 out = append(out, l)
50 }
51 return out, rows.Err()
52}
53
54// LabelInRepo returns the label only when it belongs to the given repo.
55func (d *DB) LabelInRepo(ctx context.Context, id, repoID int64) (*Label, error) {
56 var l Label
57 err := d.QueryRowContext(ctx,
58 `SELECT id, repo_id, name, color, created_at FROM labels WHERE id = ? AND repo_id = ?`,
59 id, repoID).Scan(&l.ID, &l.RepoID, &l.Name, &l.Color, &l.CreatedAt)
60 if errors.Is(err, sql.ErrNoRows) {
61 return nil, nil
62 }
63 if err != nil {
64 return nil, err
65 }
66 return &l, nil
67}
68
69func (d *DB) CreateLabel(ctx context.Context, repoID int64, name, color, createdAt string) error {
70 _, err := d.ExecContext(ctx,
71 `INSERT INTO labels (repo_id, name, color, created_at) VALUES (?, ?, ?, ?)`,
72 repoID, name, color, createdAt)
73 return err
74}
75
76func (d *DB) DeleteLabel(ctx context.Context, id int64) error {
77 _, err := d.ExecContext(ctx, `DELETE FROM labels WHERE id = ?`, id)
78 return err
79}
80