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("SELECT name, forge, url, version FROM projects WHERE id = ?", id).Scan(&name, &forge, &url, &version)
36 if err != nil {
37 return nil, fmt.Errorf("failed to scan row: %w", err)
38 }
39
40 project := map[string]string{
41 "id": id,
42 "name": name,
43 "url": url,
44 "forge": forge,
45 "version": version,
46 }
47
48 return project, nil
49}
50
51// UpsertProject adds or updates a project in the database.
52func UpsertProject(db *sql.DB, mu *sync.Mutex, id, url, name, forge, running string) error {
53 mu.Lock()
54 defer mu.Unlock()
55
56 _, err := db.Exec(`INSERT INTO projects (id, url, name, forge, version)
57 VALUES (?, ?, ?, ?, ?)
58 ON CONFLICT(id) DO
59 UPDATE SET
60 name = excluded.name,
61 forge = excluded.forge,
62 version = excluded.version;`, id, url, name, forge, running)
63 if err != nil {
64 return fmt.Errorf("failed to execute SQL: %w", err)
65 }
66
67 return nil
68}
69
70// GetProjects returns a list of all projects in the database.
71func GetProjects(db *sql.DB) ([]map[string]string, error) {
72 rows, err := db.Query("SELECT id, name, url, forge, version FROM projects")
73 if err != nil {
74 return nil, fmt.Errorf("failed to query database: %w", err)
75 }
76 defer rows.Close()
77
78 var projects []map[string]string
79 for rows.Next() {
80 var id, name, url, forge, version string
81
82 err = rows.Scan(&id, &name, &url, &forge, &version)
83 if err != nil {
84 return nil, fmt.Errorf("failed to scan row: %w", err)
85 }
86
87 project := map[string]string{
88 "id": id,
89 "name": name,
90 "url": url,
91 "forge": forge,
92 "version": version,
93 }
94 projects = append(projects, project)
95 }
96
97 if err = rows.Err(); err != nil {
98 return nil, fmt.Errorf("failed to iterate over rows: %w", err)
99 }
100
101 return projects, nil
102}