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.
This commit is contained in:
parent
436cf101d6
commit
dfb89fab66
1 changed files with 9 additions and 33 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use sqlx::migrate::Migrator;
|
use sqlx::migrate::Migrator;
|
||||||
|
use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode, SqliteSynchronous};
|
||||||
|
|
||||||
pub type DatabasePool = sqlx::SqlitePool;
|
pub type DatabasePool = sqlx::SqlitePool;
|
||||||
type PoolOptions = sqlx::sqlite::SqlitePoolOptions;
|
type PoolOptions = sqlx::sqlite::SqlitePoolOptions;
|
||||||
|
|
@ -14,50 +15,25 @@ pub struct Database {
|
||||||
impl Database {
|
impl Database {
|
||||||
pub async fn connect(database_url: &str) -> anyhow::Result<Self> {
|
pub async fn connect(database_url: &str) -> anyhow::Result<Self> {
|
||||||
let pool = {
|
let pool = {
|
||||||
use sqlx::sqlite::SqliteConnectOptions;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
let options = SqliteConnectOptions::from_str(database_url)
|
let options = SqliteConnectOptions::from_str(database_url)
|
||||||
.with_context(|| format!("invalid database url: {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()
|
PoolOptions::new()
|
||||||
.max_connections(5)
|
.max_connections(1)
|
||||||
.connect_with(options)
|
.connect_with(options)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed to connect to database: {database_url}"))?
|
.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 };
|
let db = Self { pool };
|
||||||
db.migrate().await?;
|
db.migrate().await?;
|
||||||
Ok(db)
|
Ok(db)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue