From d34881530adda7fb75be84737798da46d17bfa8c Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Mon, 2 Mar 2026 22:04:49 -0500 Subject: [PATCH] feat(03-01): extract shared applyPRAGMAs and add production PRAGMAs to NewDB - Extract inline foreign_keys PRAGMA into shared applyPRAGMAs function - Add synchronous=NORMAL, cache_size=-8000, mmap_size=67108864 PRAGMAs - NewDB now calls applyPRAGMAs instead of inline PRAGMA exec - applyPRAGMAs will be reused by NewTestDB for production-mirroring tests --- backend/database/database.go | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/backend/database/database.go b/backend/database/database.go index c916830..088e1a2 100644 --- a/backend/database/database.go +++ b/backend/database/database.go @@ -53,15 +53,8 @@ func NewDB(logger *slog.Logger) (*DB, error) { db.SetMaxOpenConns(1) // SQLite only supports one writer at a time - // Enable foreign key enforcement — SQLite disables it by - // default, which means ON DELETE CASCADE will not work without - // this pragma. - if _, err := db.ExecContext( - dbCtx, "PRAGMA foreign_keys = ON", - ); err != nil { - return nil, fmt.Errorf( - "could not enable foreign keys: %w", err, - ) + if err := applyPRAGMAs(dbCtx, db); err != nil { + return nil, fmt.Errorf("could not apply PRAGMAs: %w", err) } // Execute SQL files from the embedded schemas directory @@ -150,6 +143,27 @@ func (d *DB) QueryContext(query string, args ...any) (*sql.Rows, error) { return d.db.QueryContext(d.Ctx, query, args...) } +// applyPRAGMAs configures SQLite connection settings. Called by both +// NewDB and NewTestDB to ensure identical behavior. +func applyPRAGMAs(ctx context.Context, db *sql.DB) error { + pragmas := []string{ + "PRAGMA foreign_keys = ON", + "PRAGMA synchronous = NORMAL", + "PRAGMA cache_size = -8000", + "PRAGMA mmap_size = 67108864", + } + + for _, pragma := range pragmas { + if _, err := db.ExecContext(ctx, pragma); err != nil { + return fmt.Errorf( + "could not apply PRAGMA %q: %w", pragma, err, + ) + } + } + + return nil +} + // runMigrations applies incremental schema changes using SQLite's // PRAGMA user_version as the version tracker. Each migration runs // once and bumps the version so it is never re-applied.