1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: Apache-2.0
4
5package db
6
7import (
8 "database/sql"
9 "fmt"
10 "sync"
11)
12
13// DeleteProject deletes a project from the database.
14func DeleteProject(db *sql.DB, mu *sync.Mutex, id string) error {
15 mu.Lock()
16 defer mu.Unlock()
17
18 _, err := db.Exec("DELETE FROM projects WHERE id = ?", id)
19 if err != nil {
20 return fmt.Errorf("failed to execute SQL: %w", err)
21 }
22
23 _, err = db.Exec("DELETE FROM releases WHERE project_id = ?", id)
24 if err != nil {
25 return fmt.Errorf("failed to execute SQL: %w", err)
26 }
27
28 return nil
29}
30
31// GetProject returns a project from the database.
32func GetProject(db *sql.DB, id string) (map[string]string, error) {
33 var name, forge, url, version string
34
35 err := db.QueryRow(
36 "SELECT name, forge, url, version FROM projects WHERE id = ?",
37 id,
38 ).Scan(&name, &forge, &url, &version)
39 if err != nil {
40 return nil, fmt.Errorf("failed to scan row: %w", err)
41 }
42
43 project := map[string]string{
44 "id": id,
45 "name": name,
46 "url": url,
47 "forge": forge,
48 "version": version,
49 }
50
51 return project, nil
52}
53
54// UpsertProject adds or updates a project in the database.
55func UpsertProject(db *sql.DB, mu *sync.Mutex, id, url, name, forge, running string) error {
56 mu.Lock()
57 defer mu.Unlock()
58
59 _, err := db.Exec(`INSERT INTO projects (id, url, name, forge, version)
60 VALUES (?, ?, ?, ?, ?)
61 ON CONFLICT(id) DO
62 UPDATE SET
63 name = excluded.name,
64 forge = excluded.forge,
65 version = excluded.version;`, id, url, name, forge, running)
66 if err != nil {
67 return fmt.Errorf("failed to execute SQL: %w", err)
68 }
69
70 return nil
71}
72
73// GetProjects returns a list of all projects in the database.
74func GetProjects(db *sql.DB) ([]map[string]string, error) {
75 rows, err := db.Query("SELECT id, name, url, forge, version FROM projects")
76 if err != nil {
77 return nil, fmt.Errorf("failed to query database: %w", err)
78 }
79 defer rows.Close()
80
81 var projects []map[string]string
82 for rows.Next() {
83 var id, name, url, forge, version string
84
85 err = rows.Scan(&id, &name, &url, &forge, &version)
86 if err != nil {
87 return nil, fmt.Errorf("failed to scan row: %w", err)
88 }
89
90 project := map[string]string{
91 "id": id,
92 "name": name,
93 "url": url,
94 "forge": forge,
95 "version": version,
96 }
97 projects = append(projects, project)
98 }
99
100 if err = rows.Err(); err != nil {
101 return nil, fmt.Errorf("failed to iterate over rows: %w", err)
102 }
103
104 return projects, nil
105}