package db import ( "database/sql" "fmt" "os" "path/filepath" _ "modernc.org/sqlite" ) // DB wraps a SQLite database connection. type DB struct { *sql.DB } // Open opens (or creates) a SQLite database at the given path with the // standard Metacircular pragmas: WAL mode, foreign keys, busy timeout. func Open(path string) (*DB, error) { dir := filepath.Dir(path) if err := os.MkdirAll(dir, 0700); err != nil { return nil, fmt.Errorf("db: create directory %s: %w", dir, err) } sqlDB, err := sql.Open("sqlite", path) if err != nil { return nil, fmt.Errorf("db: open %s: %w", path, err) } pragmas := []string{ "PRAGMA journal_mode = WAL", "PRAGMA foreign_keys = ON", "PRAGMA busy_timeout = 5000", } for _, p := range pragmas { if _, err := sqlDB.Exec(p); err != nil { _ = sqlDB.Close() return nil, fmt.Errorf("db: %s: %w", p, err) } } // Set file permissions to 0600 (owner read/write only). if err := os.Chmod(path, 0600); err != nil { _ = sqlDB.Close() return nil, fmt.Errorf("db: chmod %s: %w", path, err) } return &DB{sqlDB}, nil }