internal/store/statuses.go
62 lines · 2056 bytes
1package store
2
3type CommitStatus struct {
4 Context string
5 State string // pending | success | failure | error
6 Description string
7 TargetURL string
8 Creator string
9 UpdatedAt string
10}
11
12// SetCommitStatus upserts the latest state for one context on one commit.
13func (s *Store) SetCommitStatus(repoID int64, sha, context, state, description, targetURL string, creatorID int64) error {
14 _, err := s.DB.Exec(`
15 INSERT INTO commit_statuses (repo_id, commit_sha, context, state, description, target_url, creator_id)
16 VALUES (?, ?, ?, ?, ?, ?, ?)
17 ON CONFLICT (repo_id, commit_sha, context) DO UPDATE SET
18 state = excluded.state, description = excluded.description,
19 target_url = excluded.target_url, creator_id = excluded.creator_id,
20 updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now')`,
21 repoID, sha, context, state, description, targetURL, creatorID)
22 return err
23}
24
25// ListCommitStatuses returns the latest status per context for a commit.
26func (s *Store) ListCommitStatuses(repoID int64, sha string) ([]CommitStatus, error) {
27 rows, err := s.DB.Query(`
28 SELECT cs.context, cs.state, cs.description, cs.target_url, COALESCE(u.username, ''), cs.updated_at
29 FROM commit_statuses cs LEFT JOIN users u ON u.id = cs.creator_id
30 WHERE cs.repo_id = ? AND cs.commit_sha = ? ORDER BY cs.context`, repoID, sha)
31 if err != nil {
32 return nil, err
33 }
34 defer rows.Close()
35 var out []CommitStatus
36 for rows.Next() {
37 var c CommitStatus
38 if err := rows.Scan(&c.Context, &c.State, &c.Description, &c.TargetURL, &c.Creator, &c.UpdatedAt); err != nil {
39 return nil, err
40 }
41 out = append(out, c)
42 }
43 return out, rows.Err()
44}
45
46// CombinedStatus reduces per-context states to one: error/failure dominate,
47// then pending, then success; "" when no statuses exist.
48func CombinedStatus(statuses []CommitStatus) string {
49 if len(statuses) == 0 {
50 return ""
51 }
52 combined := "success"
53 for _, s := range statuses {
54 switch s.State {
55 case "error", "failure":
56 return "failure"
57 case "pending":
58 combined = "pending"
59 }
60 }
61 return combined
62}