internal/store/labels.go
49 lines · 1486 bytes
1package store
2
3// Label is one of a repository's issue labels with its colour, "" when
4// none was set (the web then derives one from the name), and how many
5// issues carry it.
6type Label struct {
7 Name string `json:"name"`
8 Color string `json:"color,omitempty"`
9 Issues int64 `json:"issues"`
10}
11
12// ListLabels lists a repository's labels by name.
13func (s *Store) ListLabels(repoID int64) ([]Label, error) {
14 rows, err := s.DB.Query(`SELECT l.name, l.color, COUNT(il.issue_id)
15 FROM labels l LEFT JOIN issue_labels il ON il.label_id = l.id
16 WHERE l.repo_id = ? GROUP BY l.id ORDER BY l.name`, repoID)
17 if err != nil {
18 return nil, err
19 }
20 defer rows.Close()
21 var out []Label
22 for rows.Next() {
23 var l Label
24 if err := rows.Scan(&l.Name, &l.Color, &l.Issues); err != nil {
25 return nil, err
26 }
27 out = append(out, l)
28 }
29 return out, rows.Err()
30}
31
32// SetLabel creates the label or sets its colour.
33func (s *Store) SetLabel(repoID int64, name, color string) error {
34 _, err := s.DB.Exec(`INSERT INTO labels (repo_id, name, color) VALUES (?, ?, ?)
35 ON CONFLICT (repo_id, name) DO UPDATE SET color = excluded.color`, repoID, name, color)
36 return err
37}
38
39// DeleteLabel removes a label and takes it off every issue.
40func (s *Store) DeleteLabel(repoID int64, name string) error {
41 res, err := s.DB.Exec("DELETE FROM labels WHERE repo_id = ? AND name = ?", repoID, name)
42 if err != nil {
43 return err
44 }
45 if n, _ := res.RowsAffected(); n == 0 {
46 return ErrNotFound
47 }
48 return nil
49}