internal/store/stack.go

96df83f2d3eb9f241bcaa53fcc243d090c53ab2b
gitbay/internal/store/stack.go history · blame · raw

59 lines · 1838 bytes

 1package store
 2
 3import (
 4	"database/sql"
 5	"errors"
 6)
 7
 8// Stacked merge requests: B is stacked on A when B's target branch is A's
 9// source branch, both open, in the same repository. Nothing is stored;
10// these two reads derive it.
11
12// OpenMRsByTarget lists the open merge requests in repoID targeting
13// targetRef, oldest first.
14func (s *Store) OpenMRsByTarget(repoID int64, targetRef string) ([]MR, error) {
15	rows, err := s.DB.Query(
16		mrSelect+" WHERE m.repo_id = ? AND m.target_ref = ? AND m.state = 'open' ORDER BY m.number",
17		repoID, targetRef)
18	if err != nil {
19		return nil, err
20	}
21	defer rows.Close()
22	var out []MR
23	for rows.Next() {
24		m, err := scanMR(rows)
25		if err != nil {
26			return nil, err
27		}
28		out = append(out, m)
29	}
30	return out, rows.Err()
31}
32
33// OpenMRBySource finds the open merge request in repoID whose source is
34// the repository's own branch sourceRef. ok is false when there is none.
35func (s *Store) OpenMRBySource(repoID int64, sourceRef string) (MR, bool, error) {
36	m, err := scanMR(s.DB.QueryRow(
37		mrSelect+" WHERE m.repo_id = ? AND m.source_repo_id = ? AND m.source_ref = ? AND m.state = 'open' ORDER BY m.number LIMIT 1",
38		repoID, repoID, sourceRef))
39	if errors.Is(err, sql.ErrNoRows) {
40		return MR{}, false, nil
41	}
42	return m, err == nil, err
43}
44
45// RetargetKeepingReviews moves a merge request onto a new target without
46// staling its reviews: used when the branch it was stacked on has merged,
47// so the diff against the new target is the diff the reviews were of.
48func (s *Store) RetargetKeepingReviews(mrID int64, targetRef string) error {
49	res, err := s.DB.Exec(
50		"UPDATE merge_requests SET target_ref = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE id = ?",
51		targetRef, mrID)
52	if err != nil {
53		return err
54	}
55	if n, _ := res.RowsAffected(); n == 0 {
56		return ErrNotFound
57	}
58	return nil
59}