From dfb89fab66883d37cc4ef3cc83444b029a99b194 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Mon, 9 Feb 2026 20:36:40 +0000 Subject: [PATCH] fix(db): set pragmas per-connection and use single pool connection PRAGMAs executed on the pool only applied to one random connection out of five. Move all settings to SqliteConnectOptions so every connection gets them. Reduce max_connections to 1 to eliminate cross-connection WAL snapshot staleness that caused 404s on newly created entities. --- src/infrastructure/database.rs | 42 ++++++++-------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/src/infrastructure/database.rs b/src/infrastructure/database.rs index 7db90d8..1e5d9fa 100644 --- a/src/infrastructure/database.rs +++ b/src/infrastructure/database.rs @@ -1,5 +1,6 @@ use anyhow::Context; use sqlx::migrate::Migrator; +use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode, SqliteSynchronous}; pub type DatabasePool = sqlx::SqlitePool; type PoolOptions = sqlx::sqlite::SqlitePoolOptions; @@ -14,50 +15,25 @@ pub struct Database { impl Database { pub async fn connect(database_url: &str) -> anyhow::Result { let pool = { - use sqlx::sqlite::SqliteConnectOptions; use std::str::FromStr; let options = SqliteConnectOptions::from_str(database_url) .with_context(|| format!("invalid database url: {database_url}"))? - .create_if_missing(true); + .create_if_missing(true) + .journal_mode(SqliteJournalMode::Wal) + .synchronous(SqliteSynchronous::Normal) + .foreign_keys(true) + .pragma("cache_size", "-8000") + .pragma("temp_store", "MEMORY") + .busy_timeout(std::time::Duration::from_secs(5)); PoolOptions::new() - .max_connections(5) + .max_connections(1) .connect_with(options) .await .with_context(|| format!("failed to connect to database: {database_url}"))? }; - sqlx::query("PRAGMA foreign_keys = ON;") - .execute(&pool) - .await - .context("failed to enable foreign keys for sqlite")?; - - sqlx::query("PRAGMA journal_mode = WAL;") - .execute(&pool) - .await - .context("failed to enable WAL journal mode for sqlite")?; - - sqlx::query("PRAGMA synchronous = NORMAL;") - .execute(&pool) - .await - .context("failed to set synchronous mode for sqlite")?; - - sqlx::query("PRAGMA cache_size = -8000;") - .execute(&pool) - .await - .context("failed to set cache size for sqlite")?; - - sqlx::query("PRAGMA temp_store = MEMORY;") - .execute(&pool) - .await - .context("failed to set temp_store for sqlite")?; - - sqlx::query("PRAGMA busy_timeout = 5000;") - .execute(&pool) - .await - .context("failed to set busy_timeout for sqlite")?; - let db = Self { pool }; db.migrate().await?; Ok(db)