this repo has no description
1package db
2
3import (
4 "database/sql"
5 "time"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8)
9
10type Pull struct {
11 ID int
12 OwnerDid string
13 RepoAt syntax.ATURI
14 PullAt syntax.ATURI
15 TargetBranch string
16 Patch string
17 PullId int
18 Title string
19 Body string
20 Open int
21 Created time.Time
22 Rkey string
23}
24
25type PullComment struct {
26 ID int
27 OwnerDid string
28 PullId int
29 RepoAt string
30 CommentId int
31 CommentAt string
32 Body string
33 Created time.Time
34}
35
36func NewPull(tx *sql.Tx, pull *Pull) error {
37 defer tx.Rollback()
38
39 _, err := tx.Exec(`
40 insert or ignore into repo_pull_seqs (repo_at, next_pull_id)
41 values (?, 1)
42 `, pull.RepoAt)
43 if err != nil {
44 return err
45 }
46
47 var nextId int
48 err = tx.QueryRow(`
49 update repo_pull_seqs
50 set next_pull_id = next_pull_id + 1
51 where repo_at = ?
52 returning next_pull_id - 1
53 `, pull.RepoAt).Scan(&nextId)
54 if err != nil {
55 return err
56 }
57
58 pull.PullId = nextId
59
60 _, err = tx.Exec(`
61 insert into pulls (repo_at, owner_did, pull_id, title, target_branch, body, patch, rkey)
62 values (?, ?, ?, ?, ?, ?, ?, ?)
63 `, pull.RepoAt, pull.OwnerDid, pull.PullId, pull.Title, pull.TargetBranch, pull.Body, pull.Patch, pull.Rkey)
64 if err != nil {
65 return err
66 }
67
68 if err := tx.Commit(); err != nil {
69 return err
70 }
71
72 return nil
73}
74
75func SetPullAt(e Execer, repoAt syntax.ATURI, pullId int, pullAt string) error {
76 _, err := e.Exec(`update pulls set pull_at = ? where repo_at = ? and pull_id = ?`, pullAt, repoAt, pullId)
77 return err
78}
79
80func GetPullAt(e Execer, repoAt syntax.ATURI, pullId int) (string, error) {
81 var pullAt string
82 err := e.QueryRow(`select pull_at from pulls where repo_at = ? and pull_id = ?`, repoAt, pullId).Scan(&pullAt)
83 return pullAt, err
84}
85
86func GetPullId(e Execer, repoAt syntax.ATURI) (int, error) {
87 var pullId int
88 err := e.QueryRow(`select next_pull_id from repo_pull_seqs where repo_at = ?`, repoAt).Scan(&pullId)
89 return pullId - 1, err
90}
91
92func GetPullOwnerDid(e Execer, repoAt syntax.ATURI, pullId int) (string, error) {
93 var ownerDid string
94 err := e.QueryRow(`select owner_did from pulls where repo_at = ? and pull_id = ?`, repoAt, pullId).Scan(&ownerDid)
95 return ownerDid, err
96}
97
98func GetPulls(e Execer, repoAt syntax.ATURI) ([]Pull, error) {
99 var pulls []Pull
100
101 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)
102 if err != nil {
103 return nil, err
104 }
105 defer rows.Close()
106
107 for rows.Next() {
108 var pull Pull
109 var createdAt string
110 err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
111 if err != nil {
112 return nil, err
113 }
114
115 createdTime, err := time.Parse(time.RFC3339, createdAt)
116 if err != nil {
117 return nil, err
118 }
119 pull.Created = createdTime
120
121 pulls = append(pulls, pull)
122 }
123
124 if err := rows.Err(); err != nil {
125 return nil, err
126 }
127
128 return pulls, nil
129}
130
131func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, error) {
132 query := `select owner_did, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
133 row := e.QueryRow(query, repoAt, pullId)
134
135 var pull Pull
136 var createdAt string
137 err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
138 if err != nil {
139 return nil, err
140 }
141
142 createdTime, err := time.Parse(time.RFC3339, createdAt)
143 if err != nil {
144 return nil, err
145 }
146 pull.Created = createdTime
147
148 return &pull, nil
149}
150
151func GetPullWithComments(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, []PullComment, error) {
152 query := `select owner_did, pull_id, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?`
153 row := e.QueryRow(query, repoAt, pullId)
154
155 var pull Pull
156 var createdAt string
157 err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey)
158 if err != nil {
159 return nil, nil, err
160 }
161
162 createdTime, err := time.Parse(time.RFC3339, createdAt)
163 if err != nil {
164 return nil, nil, err
165 }
166 pull.Created = createdTime
167
168 comments, err := GetPullComments(e, repoAt, pullId)
169 if err != nil {
170 return nil, nil, err
171 }
172
173 return &pull, comments, nil
174}
175
176func NewPullComment(e Execer, comment *PullComment) error {
177 query := `insert into pull_comments (owner_did, repo_at, comment_at, pull_id, comment_id, body) values (?, ?, ?, ?, ?, ?)`
178 _, err := e.Exec(
179 query,
180 comment.OwnerDid,
181 comment.RepoAt,
182 comment.CommentAt,
183 comment.PullId,
184 comment.CommentId,
185 comment.Body,
186 )
187 return err
188}
189
190func GetPullComments(e Execer, repoAt syntax.ATURI, pullId int) ([]PullComment, error) {
191 var comments []PullComment
192
193 rows, err := e.Query(`select owner_did, pull_id, comment_id, comment_at, body, created from pull_comments where repo_at = ? and pull_id = ? order by created asc`, repoAt, pullId)
194 if err == sql.ErrNoRows {
195 return []PullComment{}, nil
196 }
197 if err != nil {
198 return nil, err
199 }
200 defer rows.Close()
201
202 for rows.Next() {
203 var comment PullComment
204 var createdAt string
205 err := rows.Scan(&comment.OwnerDid, &comment.PullId, &comment.CommentId, &comment.CommentAt, &comment.Body, &createdAt)
206 if err != nil {
207 return nil, err
208 }
209
210 createdAtTime, err := time.Parse(time.RFC3339, createdAt)
211 if err != nil {
212 return nil, err
213 }
214 comment.Created = createdAtTime
215
216 comments = append(comments, comment)
217 }
218
219 if err := rows.Err(); err != nil {
220 return nil, err
221 }
222
223 return comments, nil
224}
225
226func ClosePull(e Execer, repoAt syntax.ATURI, pullId int) error {
227 _, err := e.Exec(`update pulls set open = 0 where repo_at = ? and pull_id = ?`, repoAt, pullId)
228 return err
229}
230
231func ReopenPull(e Execer, repoAt syntax.ATURI, pullId int) error {
232 _, err := e.Exec(`update pulls set open = 1 where repo_at = ? and pull_id = ?`, repoAt, pullId)
233 return err
234}
235
236type PullCount struct {
237 Open int
238 Closed int
239}
240
241func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) {
242 row := e.QueryRow(`
243 select
244 count(case when open = 1 then 1 end) as open_count,
245 count(case when open = 0 then 1 end) as closed_count
246 from pulls
247 where repo_at = ?`,
248 repoAt,
249 )
250
251 var count PullCount
252 if err := row.Scan(&count.Open, &count.Closed); err != nil {
253 return PullCount{0, 0}, err
254 }
255
256 return count, nil
257}