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 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`, did) 81 if err != nil { 82 return nil, err 83 } 84 defer rows.Close() 85 86 for rows.Next() { 87 var repo Repo 88 var repoStats RepoStats 89 var createdAt string 90 var nullableDescription sql.NullString 91 92 err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount) 93 if err != nil { 94 return nil, err 95 } 96 97 if nullableDescription.Valid { 98 repo.Description = nullableDescription.String 99 } else { 100 repo.Description = "" 101 } 102 103 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 104 if err != nil { 105 repo.Created = time.Now() 106 } else { 107 repo.Created = createdAtTime 108 } 109 110 repo.RepoStats = &repoStats 111 112 repos = append(repos, repo) 113 } 114 115 if err := rows.Err(); err != nil { 116 return nil, err 117 } 118 119 return repos, nil 120} 121 122func GetRepo(e Execer, did, name string) (*Repo, error) { 123 var repo Repo 124 var nullableDescription sql.NullString 125 126 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where did = ? and name = ?`, did, name) 127 128 var createdAt string 129 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil { 130 return nil, err 131 } 132 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) 133 repo.Created = createdAtTime 134 135 if nullableDescription.Valid { 136 repo.Description = nullableDescription.String 137 } else { 138 repo.Description = "" 139 } 140 141 return &repo, nil 142} 143 144func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) { 145 var repo Repo 146 var nullableDescription sql.NullString 147 148 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where at_uri = ?`, atUri) 149 150 var createdAt string 151 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil { 152 return nil, err 153 } 154 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) 155 repo.Created = createdAtTime 156 157 if nullableDescription.Valid { 158 repo.Description = nullableDescription.String 159 } else { 160 repo.Description = "" 161 } 162 163 return &repo, nil 164} 165 166func AddRepo(e Execer, repo *Repo) error { 167 _, err := e.Exec( 168 `insert into repos 169 (did, name, knot, rkey, at_uri, description, source) 170 values (?, ?, ?, ?, ?, ?, ?)`, 171 repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri, repo.Description, repo.Source, 172 ) 173 return err 174} 175 176func RemoveRepo(e Execer, did, name, rkey string) error { 177 _, err := e.Exec(`delete from repos where did = ? and name = ? and rkey = ?`, did, name, rkey) 178 return err 179} 180 181func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) { 182 var source string 183 err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&source) 184 if err != nil { 185 return "", err 186 } 187 return source, nil 188} 189 190func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error { 191 _, err := e.Exec( 192 `insert into collaborators (did, repo) 193 values (?, (select id from repos where did = ? and name = ? and knot = ?));`, 194 collaborator, repoOwnerDid, repoName, repoKnot) 195 return err 196} 197 198func UpdateDescription(e Execer, repoAt, newDescription string) error { 199 _, err := e.Exec( 200 `update repos set description = ? where at_uri = ?`, newDescription, repoAt) 201 return err 202} 203 204func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) { 205 var repos []Repo 206 207 rows, err := e.Query( 208 `select 209 r.did, r.name, r.knot, r.rkey, r.description, r.created, count(s.id) as star_count 210 from 211 repos r 212 join 213 collaborators c on r.id = c.repo 214 left join 215 stars s on r.at_uri = s.repo_at 216 where 217 c.did = ? 218 group by 219 r.id;`, collaborator) 220 if err != nil { 221 return nil, err 222 } 223 defer rows.Close() 224 225 for rows.Next() { 226 var repo Repo 227 var repoStats RepoStats 228 var createdAt string 229 var nullableDescription sql.NullString 230 231 err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount) 232 if err != nil { 233 return nil, err 234 } 235 236 if nullableDescription.Valid { 237 repo.Description = nullableDescription.String 238 } else { 239 repo.Description = "" 240 } 241 242 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 243 if err != nil { 244 repo.Created = time.Now() 245 } else { 246 repo.Created = createdAtTime 247 } 248 249 repo.RepoStats = &repoStats 250 251 repos = append(repos, repo) 252 } 253 254 if err := rows.Err(); err != nil { 255 return nil, err 256 } 257 258 return repos, nil 259} 260 261type RepoStats struct { 262 StarCount int 263 IssueCount IssueCount 264 PullCount PullCount 265} 266 267func scanRepo(rows *sql.Rows, did, name, knot, rkey, description *string, created *time.Time, source *string) error { 268 var createdAt string 269 var nullableDescription sql.NullString 270 var nullableSource sql.NullString 271 if err := rows.Scan(did, name, knot, rkey, &nullableDescription, &createdAt, &nullableSource); err != nil { 272 return err 273 } 274 275 if nullableDescription.Valid { 276 *description = nullableDescription.String 277 } else { 278 *description = "" 279 } 280 281 createdAtTime, err := time.Parse(time.RFC3339, createdAt) 282 if err != nil { 283 *created = time.Now() 284 } else { 285 *created = createdAtTime 286 } 287 288 if nullableSource.Valid { 289 *source = nullableSource.String 290 } else { 291 *source = "" 292 } 293 294 return nil 295}