1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: Apache-2.0
4
5package db
6
7import (
8 "database/sql"
9 _ "embed"
10 "errors"
11 "fmt"
12 "sync"
13
14 _ "modernc.org/sqlite"
15)
16
17//go:embed sql/schema.sql
18var schema string
19
20var mutex = &sync.Mutex{}
21
22// Open opens a connection to the SQLite database.
23func Open(dbPath string) (*sql.DB, error) {
24 db, err := sql.Open("sqlite", "file:"+dbPath+"?_pragma=journal_mode%3DWAL")
25 if err != nil {
26 return nil, fmt.Errorf("failed to open database: %w", err)
27 }
28
29 return db, nil
30}
31
32// VerifySchema checks whether the schema has been initialised and initialises it
33// if not.
34func InitialiseDatabase(dbConn *sql.DB) error {
35 var name string
36
37 err := dbConn.QueryRow("SELECT name FROM sqlite_master WHERE type='table' AND name='users'").Scan(&name)
38 if err != nil && errors.Is(err, sql.ErrNoRows) {
39 mutex.Lock()
40 defer mutex.Unlock()
41
42 if _, err := dbConn.Exec(schema); err != nil {
43 return fmt.Errorf("failed to execute SQL: %w", err)
44 }
45
46 return nil
47 }
48
49 if err != nil {
50 return fmt.Errorf("failed to scan row: %w", err)
51 }
52
53 return nil
54}