internal/store/statuses.go

075af6c002f84e2edcbd793668a23239fbe18636
gitbay/internal/store/statuses.go history · blame · raw

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}