Commit 8a7642b427

8a7642b42755b0a3ac36d283ded97f7c8f638796

parent: d722ba57f3

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-11 15:08 UTC

store: SetLabel and DeleteLabel check the org inside their transaction

Ref #203
internal/store/labels.go +19 −6
@@ -82,29 +82,42 @@ func orgHoldsLabel(q interface {
8282// SetLabel creates the repository's label or sets its colour. A name the
8383// org holds is refused with ErrOrgScoped.
8484func (s *Store) SetLabel(repo Repo, name, color string) error {
85 if held, err := orgHoldsLabel(s.DB, repo, name); err != nil || held {
85 tx, err := s.DB.Begin()
86 if err != nil {
87 return err
88 }
89 defer tx.Rollback()
90 if held, err := orgHoldsLabel(tx, repo, name); err != nil || held {
8691 if err != nil {
8792 return err
8893 }
8994 return ErrOrgScoped
9095 }
91 _, err := s.DB.Exec(`INSERT INTO labels (repo_id, name, color) VALUES (?, ?, ?)
96 _, err = tx.Exec(`INSERT INTO labels (repo_id, name, color) VALUES (?, ?, ?)
9297 ON CONFLICT (repo_id, name) WHERE repo_id IS NOT NULL DO UPDATE SET color = excluded.color`,
9398 repo.ID, name, color)
94 return err
99 if err != nil {
100 return err
101 }
102 return tx.Commit()
95103}
96104
97105// DeleteLabel removes the repository's label and takes it off every issue.
98106// An org's label is ErrOrgScoped; no label at all is ErrNotFound.
99107func (s *Store) DeleteLabel(repo Repo, name string) error {
100 res, err := s.DB.Exec("DELETE FROM labels WHERE repo_id = ? AND name = ?", repo.ID, name)
108 tx, err := s.DB.Begin()
109 if err != nil {
110 return err
111 }
112 defer tx.Rollback()
113 res, err := tx.Exec("DELETE FROM labels WHERE repo_id = ? AND name = ?", repo.ID, name)
101114 if err != nil {
102115 return err
103116 }
104117 if n, _ := res.RowsAffected(); n > 0 {
105 return nil
118 return tx.Commit()
106119 }
107 if held, err := orgHoldsLabel(s.DB, repo, name); err != nil || held {
120 if held, err := orgHoldsLabel(tx, repo, name); err != nil || held {
108121 if err != nil {
109122 return err
110123 }