1package db
2
3import (
4 "database/sql"
5 "time"
6)
7
8type Repo struct {
9 Did string
10 Name string
11 Knot string
12 Rkey string
13 Created time.Time
14 AtUri string
15 Description string
16}
17
18func GetAllRepos(e Execer, limit int) ([]Repo, error) {
19 var repos []Repo
20
21 rows, err := e.Query(
22 `select did, name, knot, rkey, description, created
23 from repos
24 order by created desc
25 limit ?
26 `,
27 limit,
28 )
29 if err != nil {
30 return nil, err
31 }
32 defer rows.Close()
33
34 for rows.Next() {
35 var repo Repo
36 err := scanRepo(
37 rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created,
38 )
39 if err != nil {
40 return nil, err
41 }
42 repos = append(repos, repo)
43 }
44
45 if err := rows.Err(); err != nil {
46 return nil, err
47 }
48
49 return repos, nil
50}
51
52func GetAllReposByDid(e Execer, did string) ([]Repo, error) {
53 var repos []Repo
54
55 rows, err := e.Query(`select did, name, knot, rkey, description, created from repos where did = ?`, did)
56 if err != nil {
57 return nil, err
58 }
59 defer rows.Close()
60
61 for rows.Next() {
62 var repo Repo
63 err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
64 if err != nil {
65 return nil, err
66 }
67 repos = append(repos, repo)
68 }
69
70 if err := rows.Err(); err != nil {
71 return nil, err
72 }
73
74 return repos, nil
75}
76
77func GetRepo(e Execer, did, name string) (*Repo, error) {
78 var repo Repo
79 var nullableDescription sql.NullString
80
81 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where did = ? and name = ?`, did, name)
82
83 var createdAt string
84 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil {
85 return nil, err
86 }
87 createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
88 repo.Created = createdAtTime
89
90 if nullableDescription.Valid {
91 repo.Description = nullableDescription.String
92 } else {
93 repo.Description = ""
94 }
95
96 return &repo, nil
97}
98
99func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) {
100 var repo Repo
101 var nullableDescription sql.NullString
102
103 row := e.QueryRow(`select did, name, knot, created, at_uri, description from repos where at_uri = ?`, atUri)
104
105 var createdAt string
106 if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri, &nullableDescription); err != nil {
107 return nil, err
108 }
109 createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
110 repo.Created = createdAtTime
111
112 if nullableDescription.Valid {
113 repo.Description = nullableDescription.String
114 } else {
115 repo.Description = ""
116 }
117
118 return &repo, nil
119}
120
121func AddRepo(e Execer, repo *Repo) error {
122 _, err := e.Exec(
123 `insert into repos
124 (did, name, knot, rkey, at_uri, description)
125 values (?, ?, ?, ?, ?, ?)`,
126 repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri, repo.Description,
127 )
128 return err
129}
130
131func RemoveRepo(e Execer, did, name, rkey string) error {
132 _, err := e.Exec(`delete from repos where did = ? and name = ? and rkey = ?`, did, name, rkey)
133 return err
134}
135
136func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error {
137 _, err := e.Exec(
138 `insert into collaborators (did, repo)
139 values (?, (select id from repos where did = ? and name = ? and knot = ?));`,
140 collaborator, repoOwnerDid, repoName, repoKnot)
141 return err
142}
143
144func UpdateDescription(e Execer, repoAt, newDescription string) error {
145 _, err := e.Exec(
146 `update repos set description = ? where at_uri = ?`, newDescription, repoAt)
147 return err
148}
149
150func CollaboratingIn(e Execer, collaborator string) ([]Repo, error) {
151 var repos []Repo
152
153 rows, err := e.Query(`select r.did, r.name, r.knot, r.rkey, r.description, r.created from repos r join collaborators c on r.id = c.repo where c.did = ?;`, collaborator)
154 if err != nil {
155 return nil, err
156 }
157 defer rows.Close()
158
159 for rows.Next() {
160 var repo Repo
161 err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Description, &repo.Created)
162 if err != nil {
163 return nil, err
164 }
165 repos = append(repos, repo)
166 }
167
168 if err := rows.Err(); err != nil {
169 return nil, err
170 }
171
172 return repos, nil
173}
174
175type RepoStats struct {
176 StarCount int
177 IssueCount IssueCount
178}
179
180func scanRepo(rows *sql.Rows, did, name, knot, rkey, description *string, created *time.Time) error {
181 var createdAt string
182 var nullableDescription sql.NullString
183 if err := rows.Scan(did, name, knot, rkey, &nullableDescription, &createdAt); err != nil {
184 return err
185 }
186
187 if nullableDescription.Valid {
188 *description = nullableDescription.String
189 } else {
190 *description = ""
191 }
192
193 createdAtTime, err := time.Parse(time.RFC3339, createdAt)
194 if err != nil {
195 *created = time.Now()
196 } else {
197 *created = createdAtTime
198 }
199
200 return nil
201}