1 package services
2
3 import (
4 "context"
5 "database/sql"
6 "errors"
7
8 "github.com/google/uuid"
9
10 sqlerr "edge-infra.dev/pkg/edge/api/apierror/sql"
11 "edge-infra.dev/pkg/edge/api/graph/model"
12 sqlquery "edge-infra.dev/pkg/edge/api/sql"
13 "edge-infra.dev/pkg/edge/api/utils"
14 )
15
16
17 type ArtifactRegistryService interface {
18
19 GetArtifactRegistry(ctx context.Context, registryEdgeID string) (*model.ArtifactRegistry, error)
20
21 GetArtifactRegistriesForBanner(ctx context.Context, bannerEdgeID string) ([]*model.ArtifactRegistry, error)
22
23 GetArtifactRegistriesForCluster(ctx context.Context, clusterEdgeID string) ([]*model.ArtifactRegistry, error)
24
25 CreateArtifactRegistryEntry(ctx context.Context, createArtifactRegistry *model.ArtifactRegistryCreateInput) (*model.ArtifactRegistry, error)
26
27 UpdateArtifactRegistryEntry(ctx context.Context, registryEdgeID string, updateArtifactRegistry *model.ArtifactRegistryUpdateInput) (*model.ArtifactRegistry, error)
28
29 DeleteArtifactRegistryEntry(ctx context.Context, registryEdgeID string) (bool, error)
30
31
32 GetClusterArtifactRegistry(ctx context.Context, clusterRegistryEdgeID string) (*model.ClusterArtifactRegistry, error)
33
34 GetClusterArtifactRegistries(ctx context.Context, clusterEdgeID string) ([]*model.ClusterArtifactRegistry, error)
35
36 CreateClusterArtifactRegistryEntry(ctx context.Context, createClusterArtifactRegistry *model.ClusterArtifactRegistryCreateInput) (*model.ClusterArtifactRegistry, error)
37
38 DeleteClusterArtifactRegistryEntry(ctx context.Context, clusterRegistryEdgeID string) (bool, error)
39 }
40
41 func NewArtifactRegistryService(sqlDB *sql.DB) ArtifactRegistryService {
42 return &artifactRegistryService{
43 SQLDB: sqlDB,
44 }
45 }
46
47 type artifactRegistryService struct {
48 SQLDB *sql.DB
49 }
50
51 func (s *artifactRegistryService) GetArtifactRegistry(ctx context.Context, registryEdgeID string) (*model.ArtifactRegistry, error) {
52 row := s.SQLDB.QueryRowContext(ctx, sqlquery.GetArtifactRegistryByIDQuery, registryEdgeID)
53 return s.scanArtifactRegistryRow(row)
54 }
55
56 func (s *artifactRegistryService) scanArtifactRegistryRow(row *sql.Row) (*model.ArtifactRegistry, error) {
57 artifactRegistry := &model.ArtifactRegistry{}
58 if err := row.Scan(&artifactRegistry.RegistryEdgeID, &artifactRegistry.BannerEdgeID, &artifactRegistry.Description, &artifactRegistry.URL); err != nil {
59 return nil, err
60 }
61 return artifactRegistry, nil
62 }
63
64 func (s *artifactRegistryService) GetArtifactRegistriesForBanner(ctx context.Context, bannerEdgeID string) ([]*model.ArtifactRegistry, error) {
65 rows, err := s.SQLDB.QueryContext(ctx, sqlquery.GetArtifactRegistriesForBannerQuery, bannerEdgeID)
66 if err != nil {
67 return nil, err
68 }
69 return s.scanArtifactRegistryRows(rows)
70 }
71
72 func (s *artifactRegistryService) GetArtifactRegistriesForCluster(ctx context.Context, clusterEdgeID string) ([]*model.ArtifactRegistry, error) {
73 rows, err := s.SQLDB.QueryContext(ctx, sqlquery.GetArtifactRegistriesForClusterQuery, clusterEdgeID)
74 if err != nil {
75 return nil, err
76 }
77 return s.scanArtifactRegistryRows(rows)
78 }
79
80 func (s *artifactRegistryService) scanArtifactRegistryRows(rows *sql.Rows) ([]*model.ArtifactRegistry, error) {
81 artifactRegistries := []*model.ArtifactRegistry{}
82
83 for rows.Next() {
84 artifactRegistry := &model.ArtifactRegistry{}
85 if err := rows.Scan(&artifactRegistry.RegistryEdgeID, &artifactRegistry.BannerEdgeID, &artifactRegistry.Description, &artifactRegistry.URL); err != nil {
86 return nil, err
87 }
88 artifactRegistries = append(artifactRegistries, artifactRegistry)
89 }
90
91 if err := rows.Err(); err != nil {
92 return nil, sqlerr.Wrap(err)
93 }
94
95 return artifactRegistries, nil
96 }
97
98 func (s *artifactRegistryService) CreateArtifactRegistryEntry(ctx context.Context, createArtifactRegistry *model.ArtifactRegistryCreateInput) (artifactRegistry *model.ArtifactRegistry, err error) {
99 if err := utils.ValidateArtifactRegistryCreateInput(createArtifactRegistry); err != nil {
100 return nil, err
101 }
102
103 transaction, err := s.SQLDB.BeginTx(ctx, nil)
104 if err != nil {
105 return nil, err
106 }
107
108 defer func() {
109 err = rollbackOnError(transaction, err)
110 }()
111
112 artifactRegistry = utils.CreateArtifactRegistryModel(
113 uuid.NewString(),
114 createArtifactRegistry.BannerEdgeID,
115 createArtifactRegistry.URL,
116 createArtifactRegistry.Description,
117 )
118
119 args := []any{
120 artifactRegistry.RegistryEdgeID,
121 artifactRegistry.BannerEdgeID,
122 artifactRegistry.Description,
123 artifactRegistry.URL,
124 }
125
126 if _, err = transaction.ExecContext(ctx, sqlquery.ArtifactRegistryCreateQuery, args...); err != nil {
127 return
128 }
129
130 if err = transaction.Commit(); err != nil {
131 return
132 }
133
134 return artifactRegistry, nil
135 }
136
137 func (s *artifactRegistryService) UpdateArtifactRegistryEntry(ctx context.Context, registryEdgeID string, updateArtifactRegistry *model.ArtifactRegistryUpdateInput) (artifactRegistry *model.ArtifactRegistry, err error) {
138 if err := utils.ValidateArtifactRegistryUpdateInput(updateArtifactRegistry); err != nil {
139 return nil, err
140 }
141
142 currentArtifactRegistry, err := s.GetArtifactRegistry(ctx, registryEdgeID)
143 if err != nil {
144 return nil, err
145 }
146
147
148 if !utils.ArtifactRegistryNeedsUpdating(currentArtifactRegistry, updateArtifactRegistry) {
149 return currentArtifactRegistry, nil
150 }
151
152 transaction, err := s.SQLDB.BeginTx(ctx, nil)
153 if err != nil {
154 return nil, err
155 }
156
157 defer func() {
158 err = rollbackOnError(transaction, err)
159 }()
160
161 artifactRegistry = utils.UpdateArtifactRegistry(currentArtifactRegistry, updateArtifactRegistry)
162
163 args := []any{
164 artifactRegistry.Description,
165 artifactRegistry.URL,
166 registryEdgeID,
167 }
168
169 if _, err = transaction.ExecContext(ctx, sqlquery.ArtifactRegistryUpdateQuery, args...); err != nil {
170 return
171 }
172
173 if err = transaction.Commit(); err != nil {
174 return
175 }
176
177 return artifactRegistry, nil
178 }
179
180 func (s *artifactRegistryService) DeleteArtifactRegistryEntry(ctx context.Context, registryEdgeID string) (bool, error) {
181
182 if exists, err := s.artifactRegistryEntryExists(ctx, registryEdgeID); err != nil {
183 return false, err
184 } else if !exists {
185 return false, nil
186 }
187
188 if _, err := s.SQLDB.ExecContext(ctx, sqlquery.ArtifactRegistryDeleteQuery, registryEdgeID); err != nil {
189 return false, err
190 }
191
192 return true, nil
193 }
194
195 func (s *artifactRegistryService) artifactRegistryEntryExists(ctx context.Context, registryEdgeID string) (bool, error) {
196 exists := false
197
198 row := s.SQLDB.QueryRowContext(ctx, sqlquery.ArtifactRegistryExistsQuery, registryEdgeID)
199 if err := row.Scan(&exists); err != nil {
200 return false, err
201 }
202
203 return exists, nil
204 }
205
206 func (s *artifactRegistryService) GetClusterArtifactRegistry(ctx context.Context, clusterRegistryEdgeID string) (*model.ClusterArtifactRegistry, error) {
207 row := s.SQLDB.QueryRowContext(ctx, sqlquery.GetClusterArtifactRegistryByIDQuery, clusterRegistryEdgeID)
208 return s.scanClusterArtifactRegistryRow(row)
209 }
210
211 func (s *artifactRegistryService) scanClusterArtifactRegistryRow(row *sql.Row) (*model.ClusterArtifactRegistry, error) {
212 clusterArtifactRegistry := &model.ClusterArtifactRegistry{}
213 if err := row.Scan(&clusterArtifactRegistry.ClusterRegistryEdgeID, &clusterArtifactRegistry.ClusterEdgeID, &clusterArtifactRegistry.RegistryEdgeID); err != nil {
214 return nil, err
215 }
216 return clusterArtifactRegistry, nil
217 }
218
219 func (s *artifactRegistryService) GetClusterArtifactRegistries(ctx context.Context, clusterEdgeID string) ([]*model.ClusterArtifactRegistry, error) {
220 rows, err := s.SQLDB.QueryContext(ctx, sqlquery.GetClusterArtifactRegistriesForClusterQuery, clusterEdgeID)
221 if err != nil {
222 return nil, err
223 }
224 return s.scanClusterArtifactRegistryRows(rows)
225 }
226
227 func (s *artifactRegistryService) scanClusterArtifactRegistryRows(rows *sql.Rows) ([]*model.ClusterArtifactRegistry, error) {
228 clusterArtifactRegistries := []*model.ClusterArtifactRegistry{}
229
230 for rows.Next() {
231 clusterArtifactRegistry := &model.ClusterArtifactRegistry{}
232 if err := rows.Scan(&clusterArtifactRegistry.ClusterRegistryEdgeID, &clusterArtifactRegistry.ClusterEdgeID, &clusterArtifactRegistry.RegistryEdgeID); err != nil {
233 return nil, err
234 }
235 clusterArtifactRegistries = append(clusterArtifactRegistries, clusterArtifactRegistry)
236 }
237
238 if err := rows.Err(); err != nil {
239 return nil, sqlerr.Wrap(err)
240 }
241
242 return clusterArtifactRegistries, nil
243 }
244
245 func (s *artifactRegistryService) CreateClusterArtifactRegistryEntry(ctx context.Context, createClusterArtifactRegistry *model.ClusterArtifactRegistryCreateInput) (clusterArtifactRegistry *model.ClusterArtifactRegistry, err error) {
246 transaction, err := s.SQLDB.BeginTx(ctx, nil)
247 if err != nil {
248 return nil, err
249 }
250
251 defer func() {
252 err = rollbackOnError(transaction, err)
253 }()
254
255 clusterArtifactRegistry = utils.CreateClusterArtifactRegistryModel(
256 uuid.NewString(),
257 createClusterArtifactRegistry.ClusterEdgeID,
258 createClusterArtifactRegistry.RegistryEdgeID,
259 )
260
261 args := []any{
262 clusterArtifactRegistry.ClusterRegistryEdgeID,
263 clusterArtifactRegistry.ClusterEdgeID,
264 clusterArtifactRegistry.RegistryEdgeID,
265 }
266
267 if _, err = transaction.ExecContext(ctx, sqlquery.ClusterArtifactRegistryCreateQuery, args...); err != nil {
268 return
269 }
270
271 if err = transaction.Commit(); err != nil {
272 return
273 }
274
275 return clusterArtifactRegistry, nil
276 }
277
278 func (s *artifactRegistryService) DeleteClusterArtifactRegistryEntry(ctx context.Context, clusterRegistryEdgeID string) (bool, error) {
279
280 if exists, err := s.clusterArtifactRegistryEntryExists(ctx, clusterRegistryEdgeID); err != nil {
281 return false, err
282 } else if !exists {
283 return false, nil
284 }
285
286 if _, err := s.SQLDB.ExecContext(ctx, sqlquery.ClusterArtifactRegistryDeleteQuery, clusterRegistryEdgeID); err != nil {
287 return false, err
288 }
289
290 return true, nil
291 }
292
293 func (s *artifactRegistryService) clusterArtifactRegistryEntryExists(ctx context.Context, clusterRegistryEdgeID string) (bool, error) {
294 exists := false
295
296 row := s.SQLDB.QueryRowContext(ctx, sqlquery.ClusterArtifactRegistryExistsQuery, clusterRegistryEdgeID)
297 if err := row.Scan(&exists); err != nil {
298 return false, err
299 }
300
301 return exists, nil
302 }
303
304 func rollbackOnError(transaction *sql.Tx, err error) error {
305 if err != nil {
306 return errors.Join(err, transaction.Rollback())
307 }
308 return nil
309 }
310
View as plain text