// Package cachedb opens cache.db, the SQLite file in the state directory that // holds RouteWatch's caches of answers from outside services. It is separate // from the routes database so that a cache write never queues behind a write // to that database. package cachedb import ( "context" "database/sql" _ "embed" // for schema.sql "fmt" "path/filepath" _ "github.com/mattn/go-sqlite3" // CGO SQLite driver ) const ( // fileName is the database's file in the state directory. fileName = "cache.db" // busyTimeoutMs is how long a write waits for another write to finish. busyTimeoutMs = 5000 ) //go:embed schema.sql var schema string // Open opens cache.db in stateDir, creating the file and its tables when they // do not exist. The caller closes the database. func Open(ctx context.Context, stateDir string) (*sql.DB, error) { dsn := fmt.Sprintf( "file:%s?_journal_mode=WAL&_synchronous=NORMAL&_busy_timeout=%d"+ "&_txlock=immediate", filepath.Join(stateDir, fileName), busyTimeoutMs, ) db, err := sql.Open("sqlite3", dsn) if err != nil { return nil, fmt.Errorf("opening the cache database: %w", err) } _, err = db.ExecContext(ctx, schema) if err != nil { _ = db.Close() return nil, fmt.Errorf("creating the cache database's tables: %w", err) } return db, nil }