···114 pull_at text,
115 rkey text not null,
116 target_branch text not null,
117- open integer not null default 1,
118 created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
119 unique(repo_at, pull_id),
120 foreign key (repo_at) references repos(at_uri) on delete cascade
···114 pull_at text,
115 rkey text not null,
116 target_branch text not null,
117+ state integer not null default 0 check (state in (0, 1, 2)), -- open, merged, closed
118 created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
119 unique(repo_at, pull_id),
120 foreign key (repo_at) references repos(at_uri) on delete cascade
+70-15
appview/db/pulls.go
···7 "github.com/bluesky-social/indigo/atproto/syntax"
8)
9000000000000000000000000000000010type Pull struct {
11 ID int
12 OwnerDid string
···17 PullId int
18 Title string
19 Body string
20- Open int
21 Created time.Time
22 Rkey string
23}
···89 return pullId - 1, err
90}
9192-func GetPulls(e Execer, repoAt syntax.ATURI) ([]Pull, error) {
93 var pulls []Pull
9495- rows, err := e.Query(`select owner_did, pull_id, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? order by created desc`, repoAt)
0000000000000000096 if err != nil {
97 return nil, err
98 }
···101 for rows.Next() {
102 var pull Pull
103 var createdAt string
104- err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
105 if err != nil {
106 return nil, err
107 }
···123}
124125func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, error) {
126- query := `select owner_did, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
127 row := e.QueryRow(query, repoAt, pullId)
128129 var pull Pull
130 var createdAt string
131- err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
132 if err != nil {
133 return nil, err
134 }
···143}
144145func GetPullWithComments(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, []PullComment, error) {
146- query := `select owner_did, pull_id, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
147 row := e.QueryRow(query, repoAt, pullId)
148149 var pull Pull
150 var createdAt string
151- err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
152 if err != nil {
153 return nil, nil, err
154 }
···217 return comments, nil
218}
21900000220func ClosePull(e Execer, repoAt syntax.ATURI, pullId int) error {
221- _, err := e.Exec(`update pulls set open = 0 where repo_at = ? and pull_id = ?`, repoAt, pullId)
222 return err
223}
224225func ReopenPull(e Execer, repoAt syntax.ATURI, pullId int) error {
226- _, err := e.Exec(`update pulls set open = 1 where repo_at = ? and pull_id = ?`, repoAt, pullId)
227 return err
228}
229230func MergePull(e Execer, repoAt syntax.ATURI, pullId int) error {
231- _, err := e.Exec(`update pulls set open = 2 where repo_at = ? and pull_id = ?`, repoAt, pullId)
232 return err
233}
234235type PullCount struct {
236 Open int
0237 Closed int
238}
239240func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) {
241 row := e.QueryRow(`
242 select
243- count(case when open = 1 then 1 end) as open_count,
244- count(case when open = 0 then 1 end) as closed_count
0245 from pulls
246 where repo_at = ?`,
247 repoAt,
248 )
249250 var count PullCount
251- if err := row.Scan(&count.Open, &count.Closed); err != nil {
252- return PullCount{0, 0}, err
253 }
254255 return count, nil
···7 "github.com/bluesky-social/indigo/atproto/syntax"
8)
910+type PullState int
11+12+const (
13+ PullOpen PullState = iota
14+ PullMerged
15+ PullClosed
16+)
17+18+func (p PullState) String() string {
19+ switch p {
20+ case PullOpen:
21+ return "open"
22+ case PullMerged:
23+ return "merged"
24+ case PullClosed:
25+ return "closed"
26+ default:
27+ return "closed"
28+ }
29+}
30+31+func (p PullState) IsOpen() bool {
32+ return p == PullOpen
33+}
34+func (p PullState) IsMerged() bool {
35+ return p == PullMerged
36+}
37+func (p PullState) IsClosed() bool {
38+ return p == PullClosed
39+}
40+41type Pull struct {
42 ID int
43 OwnerDid string
···48 PullId int
49 Title string
50 Body string
51+ State PullState
52 Created time.Time
53 Rkey string
54}
···120 return pullId - 1, err
121}
122123+func GetPulls(e Execer, repoAt syntax.ATURI, state PullState) ([]Pull, error) {
124 var pulls []Pull
125126+ rows, err := e.Query(`
127+ select
128+ owner_did,
129+ pull_id,
130+ created,
131+ title,
132+ state,
133+ target_branch,
134+ pull_at,
135+ body,
136+ patch,
137+ rkey
138+ from
139+ pulls
140+ where
141+ repo_at = ? and state = ?
142+ order by
143+ created desc`, repoAt, state)
144 if err != nil {
145 return nil, err
146 }
···149 for rows.Next() {
150 var pull Pull
151 var createdAt string
152+ err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
153 if err != nil {
154 return nil, err
155 }
···171}
172173func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, error) {
174+ query := `select owner_did, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
175 row := e.QueryRow(query, repoAt, pullId)
176177 var pull Pull
178 var createdAt string
179+ err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
180 if err != nil {
181 return nil, err
182 }
···191}
192193func GetPullWithComments(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, []PullComment, error) {
194+ query := `select owner_did, pull_id, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
195 row := e.QueryRow(query, repoAt, pullId)
196197 var pull Pull
198 var createdAt string
199+ err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
200 if err != nil {
201 return nil, nil, err
202 }
···265 return comments, nil
266}
267268+func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState PullState) error {
269+ _, err := e.Exec(`update pulls set state = ? where repo_at = ? and pull_id = ?`, pullState, repoAt, pullId)
270+ return err
271+}
272+273func ClosePull(e Execer, repoAt syntax.ATURI, pullId int) error {
274+ err := SetPullState(e, repoAt, pullId, PullClosed)
275 return err
276}
277278func ReopenPull(e Execer, repoAt syntax.ATURI, pullId int) error {
279+ err := SetPullState(e, repoAt, pullId, PullOpen)
280 return err
281}
282283func MergePull(e Execer, repoAt syntax.ATURI, pullId int) error {
284+ err := SetPullState(e, repoAt, pullId, PullMerged)
285 return err
286}
287288type PullCount struct {
289 Open int
290+ Merged int
291 Closed int
292}
293294func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) {
295 row := e.QueryRow(`
296 select
297+ count(case when state = 0 then 1 end) as open_count,
298+ count(case when state = 1 then 1 end) as merged_count,
299+ count(case when state = 2 then 1 end) as closed_count
300 from pulls
301 where repo_at = ?`,
302 repoAt,
303 )
304305 var count PullCount
306+ if err := row.Scan(&count.Open, &count.Merged, &count.Closed); err != nil {
307+ return PullCount{0, 0, 0}, err
308 }
309310 return count, nil
···15 <p class="text-gray-500">
16 The branch you want to make your change against.
17 </p>
18- <select class="p-1 border border-gray-200 bg-white">
19 <option disabled selected>Select a branch</option>
20 {{ range .Branches }}
21 <option
···15 <p class="text-gray-500">
16 The branch you want to make your change against.
17 </p>
18+ <select name="targetBranch" class="p-1 border border-gray-200 bg-white">
19 <option disabled selected>Select a branch</option>
20 {{ range .Branches }}
21 <option