forked from tangled.org/core
this repo has no description
at master 8.5 kB view raw
1package db 2 3import ( 4 "database/sql" 5 "time" 6 7 "github.com/bluesky-social/indigo/atproto/syntax" 8) 9 10type Repo struct { 11 Did string 12 Name string 13 Knot string 14 Rkey string 15 Created time.Time 16 AtUri string 17 Description string 18 19 // optionally, populate this when querying for reverse mappings 20 RepoStats *RepoStats 21 22 // optional 23 Source string 24} 25 26func GetAllRepos(e Execer, limit int) ([]Repo, error) { 27 var repos []Repo 28 29 rows, err := e.Query( 30 `select did, name, knot, rkey, description, created, source 31 from repos 32 order by created desc 33 limit ? 34 `, 35 limit, 36 ) 37 if err != nil { 38 return nil, err 39 } 40 defer rows.Close() 41 42 for rows.Next() { 43 var repo Repo 44 err := scanRepo( 45 rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created, &repo.Source, 46 ) 47 if err != nil { 48 return nil, err 49 } 50 repos = append(repos, repo) 51 } 52 53 if err := rows.Err(); err != nil { 54 return nil, err 55 } 56 57 return repos, nil 58} 59 60func GetAllReposByDid(e Execer, did string) ([]Repo, error) { 61 var repos []Repo 62 63 rows, err := e.Query( 64 `select 65 r.did, 66 r.name, 67 r.knot, 68 r.rkey, 69 r.description, 70 r.created, 71 count(s.id) as star_count, 72 r.source 73 from 74 repos r 75 left join 76 stars s on r.at_uri = s.repo_at 77 where 78 r.did = ? 79 group by 80 r.at_uri 81 order by r.created desc`, 82 did) 83 if err != nil { 84 return nil, err 85 } 86 defer rows.Close() 87 88 for rows.Next() { 89 var repo Repo 90 var repoStats RepoStats 91 var createdAt string 92 var nullableDescription sql.NullString 93 var nullableSource sql.NullString 94 95 err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount, &nullableSource) 96 if err != nil { 97 return nil, err 98 } 99 100 if nullableDescription.Valid { 101 repo.Description = nullableDescription.String 102 } 103 104 if nullableSource.Valid { 105 repo.Source = nullableSource.String 106 } 107 108 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 109 if err != nil { 110 repo.Created = time.Now() 111 } else { 112 repo.Created = createdAtTime 113 } 114 115 repo.RepoStats = &repoStats 116 117 repos = append(repos, repo) 118 } 119 120 if err := rows.Err(); err != nil { 121 return nil, err 122 } 123 124 return repos, nil 125} 126 127func GetRepo(e Execer, did, name string) (*Repo, error) { 128 var repo Repo 129 var nullableDescription sql.NullString 130 131 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where did = ? and name = ?`, did, name) 132 133 var createdAt string 134 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil { 135 return nil, err 136 } 137 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) 138 repo.Created = createdAtTime 139 140 if nullableDescription.Valid { 141 repo.Description = nullableDescription.String 142 } else { 143 repo.Description = "" 144 } 145 146 return &repo, nil 147} 148 149func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) { 150 var repo Repo 151 var nullableDescription sql.NullString 152 153 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where at_uri = ?`, atUri) 154 155 var createdAt string 156 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil { 157 return nil, err 158 } 159 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) 160 repo.Created = createdAtTime 161 162 if nullableDescription.Valid { 163 repo.Description = nullableDescription.String 164 } else { 165 repo.Description = "" 166 } 167 168 return &repo, nil 169} 170 171func AddRepo(e Execer, repo *Repo) error { 172 _, err := e.Exec( 173 `insert into repos 174 (did, name, knot, rkey, at_uri, description, source) 175 values (?, ?, ?, ?, ?, ?, ?)`, 176 repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri, repo.Description, repo.Source, 177 ) 178 return err 179} 180 181func RemoveRepo(e Execer, did, name string) error { 182 _, err := e.Exec(`delete from repos where did = ? and name = ?`, did, name) 183 return err 184} 185 186func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) { 187 var nullableSource sql.NullString 188 err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&nullableSource) 189 if err != nil { 190 return "", err 191 } 192 return nullableSource.String, nil 193} 194 195func GetForksByDid(e Execer, did string) ([]Repo, error) { 196 var repos []Repo 197 198 rows, err := e.Query( 199 `select did, name, knot, rkey, description, created, at_uri, source 200 from repos 201 where did = ? and source is not null and source != '' 202 order by created desc`, 203 did, 204 ) 205 if err != nil { 206 return nil, err 207 } 208 defer rows.Close() 209 210 for rows.Next() { 211 var repo Repo 212 var createdAt string 213 var nullableDescription sql.NullString 214 var nullableSource sql.NullString 215 216 err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repo.AtUri, &nullableSource) 217 if err != nil { 218 return nil, err 219 } 220 221 if nullableDescription.Valid { 222 repo.Description = nullableDescription.String 223 } 224 225 if nullableSource.Valid { 226 repo.Source = nullableSource.String 227 } 228 229 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 230 if err != nil { 231 repo.Created = time.Now() 232 } else { 233 repo.Created = createdAtTime 234 } 235 236 repos = append(repos, repo) 237 } 238 239 if err := rows.Err(); err != nil { 240 return nil, err 241 } 242 243 return repos, nil 244} 245 246func GetForkByDid(e Execer, did string, name string) (*Repo, error) { 247 var repo Repo 248 var createdAt string 249 var nullableDescription sql.NullString 250 var nullableSource sql.NullString 251 252 row := e.QueryRow( 253 `select did, name, knot, rkey, description, created, at_uri, source 254 from repos 255 where did = ? and name = ? and source is not null and source != ''`, 256 did, name, 257 ) 258 259 err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repo.AtUri, &nullableSource) 260 if err != nil { 261 return nil, err 262 } 263 264 if nullableDescription.Valid { 265 repo.Description = nullableDescription.String 266 } 267 268 if nullableSource.Valid { 269 repo.Source = nullableSource.String 270 } 271 272 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 273 if err != nil { 274 repo.Created = time.Now() 275 } else { 276 repo.Created = createdAtTime 277 } 278 279 return &repo, nil 280} 281 282func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error { 283 _, err := e.Exec( 284 `insert into collaborators (did, repo) 285 values (?, (select id from repos where did = ? and name = ? and knot = ?));`, 286 collaborator, repoOwnerDid, repoName, repoKnot) 287 return err 288} 289 290func UpdateDescription(e Execer, repoAt, newDescription string) error { 291 _, err := e.Exec( 292 `update repos set description = ? where at_uri = ?`, newDescription, repoAt) 293 return err 294} 295 296func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) { 297 var repos []Repo 298 299 rows, err := e.Query( 300 `select 301 r.did, r.name, r.knot, r.rkey, r.description, r.created, count(s.id) as star_count 302 from 303 repos r 304 join 305 collaborators c on r.id = c.repo 306 left join 307 stars s on r.at_uri = s.repo_at 308 where 309 c.did = ? 310 group by 311 r.id;`, collaborator) 312 if err != nil { 313 return nil, err 314 } 315 defer rows.Close() 316 317 for rows.Next() { 318 var repo Repo 319 var repoStats RepoStats 320 var createdAt string 321 var nullableDescription sql.NullString 322 323 err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount) 324 if err != nil { 325 return nil, err 326 } 327 328 if nullableDescription.Valid { 329 repo.Description = nullableDescription.String 330 } else { 331 repo.Description = "" 332 } 333 334 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 335 if err != nil { 336 repo.Created = time.Now() 337 } else { 338 repo.Created = createdAtTime 339 } 340 341 repo.RepoStats = &repoStats 342 343 repos = append(repos, repo) 344 } 345 346 if err := rows.Err(); err != nil { 347 return nil, err 348 } 349 350 return repos, nil 351} 352 353type RepoStats struct { 354 StarCount int 355 IssueCount IssueCount 356 PullCount PullCount 357} 358 359func scanRepo(rows *sql.Rows, did, name, knot, rkey, description *string, created *time.Time, source *string) error { 360 var createdAt string 361 var nullableDescription sql.NullString 362 var nullableSource sql.NullString 363 if err := rows.Scan(did, name, knot, rkey, &nullableDescription, &createdAt, &nullableSource); err != nil { 364 return err 365 } 366 367 if nullableDescription.Valid { 368 *description = nullableDescription.String 369 } else { 370 *description = "" 371 } 372 373 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 374 if err != nil { 375 *created = time.Now() 376 } else { 377 *created = createdAtTime 378 } 379 380 if nullableSource.Valid { 381 *source = nullableSource.String 382 } else { 383 *source = "" 384 } 385 386 return nil 387}