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