package db import ( "database/sql" _ "embed" "fmt" "os" "path/filepath" _ "github.com/ncruces/go-sqlite3/driver" _ "github.com/ncruces/go-sqlite3/embed" ) //go:embed schema.sql var schema string func Open(dbPath string) (*sql.DB, error) { dir := filepath.Dir(dbPath) if err := os.MkdirAll(dir, 0750); err != nil { return nil, fmt.Errorf("create db dir: %w", err) } db, err := sql.Open("sqlite3", dbPath+"?_journal_mode=WAL&_busy_timeout=5000") if err != nil { return nil, fmt.Errorf("open db: %w", err) } db.SetMaxOpenConns(1) // SQLite single-writer if _, err := db.Exec(schema); err != nil { db.Close() return nil, fmt.Errorf("init schema: %w", err) } // Migrations for existing databases db.Exec("ALTER TABLE files ADD COLUMN batch_id TEXT") db.Exec("CREATE INDEX IF NOT EXISTS idx_files_batch_id ON files(batch_id) WHERE batch_id IS NOT NULL") return db, nil }