summaryrefslogtreecommitdiff
path: root/internal/database/db.go
blob: f699d14fc7aadb7bc0a87eef0d930f55b8e88c05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package database

import (
	"database/sql"
	_ "embed"
	"fmt"
	"os"
	"path/filepath"

	"punchcard/internal/queries"

	_ "modernc.org/sqlite"
)

//go:embed schema.sql
var schema string

func GetDB() (*queries.Queries, error) {
	dataDir := os.Getenv("XDG_DATA_HOME")
	if dataDir == "" {
		homeDir, err := os.UserHomeDir()
		if err != nil {
			return nil, fmt.Errorf("failed to get user home directory: %w", err)
		}
		dataDir = filepath.Join(homeDir, ".local", "share")
	}

	punchcardDir := filepath.Join(dataDir, "punchcard")
	if err := os.MkdirAll(punchcardDir, 0o755); err != nil {
		return nil, fmt.Errorf("failed to create punchcard directory at %s: %w", punchcardDir, err)
	}

	dbPath := filepath.Join(punchcardDir, "punchcard.db")
	db, err := sql.Open("sqlite", dbPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open database at %s: %w", dbPath, err)
	}

	if err := InitializeDB(db); err != nil {
		return nil, err
	}

	return queries.New(db), nil
}

func InitializeDB(db *sql.DB) error {
	if _, err := db.Exec(schema); err != nil {
		return fmt.Errorf("failed to execute schema: %w", err)
	}

	pragmas := []string{
		"PRAGMA foreign_keys = ON;",
		"PRAGMA journal_mode = WAL;",
		"PRAGMA synchronous = NORMAL;",
		"PRAGMA cache_size = -64000;",
		"PRAGMA temp_store = MEMORY;",
		"PRAGMA mmap_size = 67108864;",
		"PRAGMA optimize;",
	}

	for _, pragma := range pragmas {
		if _, err := db.Exec(pragma); err != nil {
			return fmt.Errorf("failed to execute pragma %s: %w", pragma, err)
		}
	}

	return nil
}