package db import ( "context" "database/sql" "path/filepath" "testing" ) // assertPoolSettings checks journal mode and busy_timeout on several // simultaneously held connections. Holding them at once forces database/sql to // open distinct connections: busy_timeout is per-connection, so a regression to // a one-shot "PRAGMA busy_timeout" on the pool shows up on conn 1 onward. func assertPoolSettings(t *testing.T, label string, db *sql.DB, wantJournal string, wantBusy int) { t.Helper() ctx := context.Background() const n = 4 conns := make([]*sql.Conn, 0, n) defer func() { for _, c := range conns { _ = c.Close() } }() for i := range n { c, err := db.Conn(ctx) if err != nil { t.Fatalf("%s: open conn %d: %v", label, i, err) } conns = append(conns, c) } for i, c := range conns { var journal string if err := c.QueryRowContext(ctx, "PRAGMA journal_mode").Scan(&journal); err != nil { t.Fatalf("%s conn %d: read journal_mode: %v", label, i, err) } if journal != wantJournal { t.Errorf("%s conn %d: journal_mode = %q, want %q", label, i, journal, wantJournal) } var busy int if err := c.QueryRowContext(ctx, "PRAGMA busy_timeout").Scan(&busy); err != nil { t.Fatalf("%s conn %d: read busy_timeout: %v", label, i, err) } if busy != wantBusy { t.Errorf("%s conn %d: busy_timeout = %d, want %d", label, i, busy, wantBusy) } } } func TestOpenLocalDBSettingsOnEveryConnection(t *testing.T) { path := filepath.Join(t.TempDir(), "db.sqlite3") db, err := OpenLocalDB(path) if err != nil { t.Fatalf("OpenLocalDB: %v", err) } defer db.Close() assertPoolSettings(t, "OpenLocalDB", db, "wal", DefaultBusyTimeoutMs) } func TestOpenHoldDBSettingsOnEveryConnection(t *testing.T) { path := filepath.Join(t.TempDir(), "db.sqlite3") h, err := OpenHoldDB(path, LibsqlConfig{}) if err != nil { t.Fatalf("OpenHoldDB: %v", err) } defer h.Close() assertPoolSettings(t, "OpenHoldDB", h.DB, "wal", DefaultBusyTimeoutMs) } func TestCarstoreSettingsOnEveryConnection(t *testing.T) { sqs, err := NewSqliteStore(t.TempDir()) if err != nil { t.Fatalf("NewSqliteStore: %v", err) } defer sqs.Close() assertPoolSettings(t, "carstore", sqs.DB(), "wal", DefaultBusyTimeoutMs) } // TestOpenLocalDBMemory documents that ":memory:" is left unwrapped: libsql // gives each connection its own private database, so there is no shared lock to // wait on and WAL does not apply. func TestOpenLocalDBMemory(t *testing.T) { db, err := OpenLocalDB(":memory:") if err != nil { t.Fatalf("OpenLocalDB(:memory:): %v", err) } defer db.Close() if err := db.Ping(); err != nil { t.Fatalf("ping in-memory db: %v", err) } }