forked from tangled.org/core
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 PullState int 11 12const ( 13 PullClosed PullState = iota 14 PullOpen 15 PullMerged 16) 17 18func (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 31func (p PullState) IsOpen() bool { 32 return p == PullOpen 33} 34func (p PullState) IsMerged() bool { 35 return p == PullMerged 36} 37func (p PullState) IsClosed() bool { 38 return p == PullClosed 39} 40 41type Pull struct { 42 ID int 43 OwnerDid string 44 RepoAt syntax.ATURI 45 PullAt syntax.ATURI 46 TargetBranch string 47 Patch string 48 PullId int 49 Title string 50 Body string 51 State PullState 52 Created time.Time 53 Rkey string 54} 55 56type PullComment struct { 57 ID int 58 OwnerDid string 59 PullId int 60 RepoAt string 61 CommentId int 62 CommentAt string 63 Body string 64 Created time.Time 65} 66 67func NewPull(tx *sql.Tx, pull *Pull) error { 68 defer tx.Rollback() 69 70 _, err := tx.Exec(` 71 insert or ignore into repo_pull_seqs (repo_at, next_pull_id) 72 values (?, 1) 73 `, pull.RepoAt) 74 if err != nil { 75 return err 76 } 77 78 var nextId int 79 err = tx.QueryRow(` 80 update repo_pull_seqs 81 set next_pull_id = next_pull_id + 1 82 where repo_at = ? 83 returning next_pull_id - 1 84 `, pull.RepoAt).Scan(&nextId) 85 if err != nil { 86 return err 87 } 88 89 pull.PullId = nextId 90 pull.State = PullOpen 91 92 _, err = tx.Exec(` 93 insert into pulls (repo_at, owner_did, pull_id, title, target_branch, body, patch, rkey, state) 94 values (?, ?, ?, ?, ?, ?, ?, ?, ?) 95 `, pull.RepoAt, pull.OwnerDid, pull.PullId, pull.Title, pull.TargetBranch, pull.Body, pull.Patch, pull.Rkey, pull.State) 96 if err != nil { 97 return err 98 } 99 100 if err := tx.Commit(); err != nil { 101 return err 102 } 103 104 return nil 105} 106 107func SetPullAt(e Execer, repoAt syntax.ATURI, pullId int, pullAt string) error { 108 _, err := e.Exec(`update pulls set pull_at = ? where repo_at = ? and pull_id = ?`, pullAt, repoAt, pullId) 109 return err 110} 111 112func GetPullAt(e Execer, repoAt syntax.ATURI, pullId int) (string, error) { 113 var pullAt string 114 err := e.QueryRow(`select pull_at from pulls where repo_at = ? and pull_id = ?`, repoAt, pullId).Scan(&pullAt) 115 return pullAt, err 116} 117 118func NextPullId(e Execer, repoAt syntax.ATURI) (int, error) { 119 var pullId int 120 err := e.QueryRow(`select next_pull_id from repo_pull_seqs where repo_at = ?`, repoAt).Scan(&pullId) 121 return pullId - 1, err 122} 123 124func GetPulls(e Execer, repoAt syntax.ATURI, state PullState) ([]Pull, error) { 125 var pulls []Pull 126 127 rows, err := e.Query(` 128 select 129 owner_did, 130 pull_id, 131 created, 132 title, 133 state, 134 target_branch, 135 pull_at, 136 body, 137 patch, 138 rkey 139 from 140 pulls 141 where 142 repo_at = ? and state = ? 143 order by 144 created desc`, repoAt, state) 145 if err != nil { 146 return nil, err 147 } 148 defer rows.Close() 149 150 for rows.Next() { 151 var pull Pull 152 var createdAt string 153 err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 154 if err != nil { 155 return nil, err 156 } 157 158 createdTime, err := time.Parse(time.RFC3339, createdAt) 159 if err != nil { 160 return nil, err 161 } 162 pull.Created = createdTime 163 164 pulls = append(pulls, pull) 165 } 166 167 if err := rows.Err(); err != nil { 168 return nil, err 169 } 170 171 return pulls, nil 172} 173 174func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, error) { 175 query := `select owner_did, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 176 row := e.QueryRow(query, repoAt, pullId) 177 178 var pull Pull 179 var createdAt string 180 err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 181 if err != nil { 182 return nil, err 183 } 184 185 createdTime, err := time.Parse(time.RFC3339, createdAt) 186 if err != nil { 187 return nil, err 188 } 189 pull.Created = createdTime 190 191 return &pull, nil 192} 193 194func GetPullWithComments(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, []PullComment, error) { 195 query := `select owner_did, pull_id, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 196 row := e.QueryRow(query, repoAt, pullId) 197 198 var pull Pull 199 var createdAt string 200 err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 201 if err != nil { 202 return nil, nil, err 203 } 204 205 createdTime, err := time.Parse(time.RFC3339, createdAt) 206 if err != nil { 207 return nil, nil, err 208 } 209 pull.Created = createdTime 210 211 comments, err := GetPullComments(e, repoAt, pullId) 212 if err != nil { 213 return nil, nil, err 214 } 215 216 return &pull, comments, nil 217} 218 219func NewPullComment(e Execer, comment *PullComment) error { 220 query := `insert into pull_comments (owner_did, repo_at, comment_at, pull_id, comment_id, body) values (?, ?, ?, ?, ?, ?)` 221 _, err := e.Exec( 222 query, 223 comment.OwnerDid, 224 comment.RepoAt, 225 comment.CommentAt, 226 comment.PullId, 227 comment.CommentId, 228 comment.Body, 229 ) 230 return err 231} 232 233func GetPullComments(e Execer, repoAt syntax.ATURI, pullId int) ([]PullComment, error) { 234 var comments []PullComment 235 236 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) 237 if err == sql.ErrNoRows { 238 return []PullComment{}, nil 239 } 240 if err != nil { 241 return nil, err 242 } 243 defer rows.Close() 244 245 for rows.Next() { 246 var comment PullComment 247 var createdAt string 248 err := rows.Scan(&comment.OwnerDid, &comment.PullId, &comment.CommentId, &comment.CommentAt, &comment.Body, &createdAt) 249 if err != nil { 250 return nil, err 251 } 252 253 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 254 if err != nil { 255 return nil, err 256 } 257 comment.Created = createdAtTime 258 259 comments = append(comments, comment) 260 } 261 262 if err := rows.Err(); err != nil { 263 return nil, err 264 } 265 266 return comments, nil 267} 268 269func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState PullState) error { 270 _, err := e.Exec(`update pulls set state = ? where repo_at = ? and pull_id = ?`, pullState, repoAt, pullId) 271 return err 272} 273 274func ClosePull(e Execer, repoAt syntax.ATURI, pullId int) error { 275 err := SetPullState(e, repoAt, pullId, PullClosed) 276 return err 277} 278 279func ReopenPull(e Execer, repoAt syntax.ATURI, pullId int) error { 280 err := SetPullState(e, repoAt, pullId, PullOpen) 281 return err 282} 283 284func MergePull(e Execer, repoAt syntax.ATURI, pullId int) error { 285 err := SetPullState(e, repoAt, pullId, PullMerged) 286 return err 287} 288 289type PullCount struct { 290 Open int 291 Merged int 292 Closed int 293} 294 295func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) { 296 row := e.QueryRow(` 297 select 298 count(case when state = ? then 1 end) as open_count, 299 count(case when state = ? then 1 end) as merged_count, 300 count(case when state = ? then 1 end) as closed_count 301 from pulls 302 where repo_at = ?`, 303 PullOpen, 304 PullMerged, 305 PullClosed, 306 repoAt, 307 ) 308 309 var count PullCount 310 if err := row.Scan(&count.Open, &count.Merged, &count.Closed); err != nil { 311 return PullCount{0, 0, 0}, err 312 } 313 314 return count, nil 315} 316 317func EditPatch(e Execer, repoAt syntax.ATURI, pullId int, patch string) error { 318 _, err := e.Exec(`update pulls set patch = ? where repo_at = ? and pull_id = ?`, patch, repoAt, pullId) 319 return err 320}