43 lines
996 B
Go
43 lines
996 B
Go
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
|
|
}
|