package database import ( "context" "database/sql" "fmt" _ "modernc.org/sqlite" ) // DB wraps sql.DB so the rest of the codebase has a single type to depend on. type DB struct { *sql.DB } // Connect opens (or creates) the SQLite file at path and runs pragmas for // safe, performant operation. Pass ":memory:" for tests. func Connect(_ context.Context, path string) (*DB, error) { db, err := sql.Open("sqlite", path) if err != nil { return nil, fmt.Errorf("open sqlite: %w", err) } // WAL mode gives much better read concurrency without blocking reads // during writes. foreign_keys must be enabled per-connection in SQLite. 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 { return nil, fmt.Errorf("pragma %q: %w", p, err) } } if err := db.Ping(); err != nil { return nil, fmt.Errorf("ping sqlite: %w", err) } return &DB{db}, nil }