// Package db provides SQLite database access and migrations. package db import ( "database/sql" "fmt" "os" _ "modernc.org/sqlite" ) // Open opens or creates a SQLite database at the given path with secure // file permissions (0600) and WAL mode enabled. func Open(path string) (*sql.DB, error) { // Ensure the file has restrictive permissions if it doesn't exist yet. if _, err := os.Stat(path); os.IsNotExist(err) { f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0600) //nolint:gosec if err != nil { return nil, fmt.Errorf("db: create file: %w", err) } _ = f.Close() } db, err := sql.Open("sqlite", path) if err != nil { return nil, fmt.Errorf("db: open: %w", err) } // Enable WAL mode and foreign keys. pragmas := []string{ "PRAGMA journal_mode=WAL", "PRAGMA foreign_keys=ON", "PRAGMA busy_timeout=5000", } for _, p := range pragmas { if _, err := db.Exec(p); err != nil { _ = db.Close() return nil, fmt.Errorf("db: pragma %q: %w", p, err) } } return db, nil }