summaryrefslogtreecommitdiff
path: root/internal/database/db.go
diff options
context:
space:
mode:
authorT <t@tjp.lol>2025-08-02 17:25:59 -0600
committerT <t@tjp.lol>2025-08-04 09:34:14 -0600
commit8be5f93f5b2d4b6f438ca84094937a0f7101c59b (patch)
tree3cedb6379818a28179e269477c12ae06dd57ca36 /internal/database/db.go
Initial commit of punchcard.
Contains working time tracking commands, and the stub of a command to generate reports.
Diffstat (limited to 'internal/database/db.go')
-rw-r--r--internal/database/db.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/internal/database/db.go b/internal/database/db.go
new file mode 100644
index 0000000..f699d14
--- /dev/null
+++ b/internal/database/db.go
@@ -0,0 +1,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
+}