package db import ( "database/sql" "fmt" "os" "path/filepath" _ "modernc.org/sqlite" ) func Open(path string) (*sql.DB, error) { dir := filepath.Dir(path) if err := os.MkdirAll(dir, 0o755); err != nil { return nil, fmt.Errorf("create db directory: %w", err) } db, err := sql.Open("sqlite", path) if err != nil { return nil, fmt.Errorf("open database: %w", err) } for _, pragma := range []string{ "PRAGMA journal_mode=WAL", "PRAGMA synchronous=NORMAL", } { if _, err := db.Exec(pragma); err != nil { db.Close() return nil, fmt.Errorf("set %s: %w", pragma, err) } } if err := migrate(db); err != nil { db.Close() return nil, fmt.Errorf("migrate: %w", err) } return db, nil } func migrate(db *sql.DB) error { _, err := db.Exec(` CREATE TABLE IF NOT EXISTS history ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TEXT NOT NULL, hostname TEXT NOT NULL, working_dir TEXT NOT NULL, command TEXT NOT NULL, UNIQUE(timestamp, hostname, working_dir, command) ); CREATE INDEX IF NOT EXISTS idx_history_timestamp ON history(timestamp DESC); CREATE INDEX IF NOT EXISTS idx_history_hostname ON history(hostname); CREATE INDEX IF NOT EXISTS idx_history_working_dir ON history(working_dir); CREATE TABLE IF NOT EXISTS sync_meta ( key TEXT PRIMARY KEY, value TEXT NOT NULL ); `) return err }