Expand description
Correct-by-default sqlx SQLite pool, with the footgun fixes built in.
HardenedSqlite builds a SqlitePool with sane defaults — WAL, foreign
keys ON, a 5-second busy-timeout, synchronous = NORMAL, and
create_if_missing — plus two helpers: begin_immediate for safe
read-then-write transactions, and correct, uniquely-named in-memory pools
for tests. Every default is overridable via the builder.
§Quick start
use sqlite_hardened::{HardenedSqlite, SqlitePoolExt};
// WAL + foreign_keys + busy_timeout + synchronous=NORMAL, all applied.
let pool = HardenedSqlite::new("sqlite://app.db").connect().await?;
// BEGIN IMMEDIATE — a read-then-write transaction that can't hit a
// busy-snapshot error under WAL's single-writer rule.
let mut tx = pool.begin_immediate().await?;
sqlx::query("UPDATE counters SET n = n + 1")
.execute(&mut *tx)
.await?;
tx.commit().await?;§Overriding a default
use sqlite_hardened::HardenedSqlite;
use std::time::Duration;
let pool = HardenedSqlite::new("sqlite://app.db")
.foreign_keys(false)
.busy_timeout(Duration::from_secs(2))
.max_connections(16)
.connect()
.await?;§In-memory pools for tests
":memory:" yields a uniquely-named cache=shared database with one pinned
connection, so parallel test pools don’t collide and the schema isn’t
destroyed when the pool idles to zero connections.
use sqlite_hardened::HardenedSqlite;
let pool = HardenedSqlite::new(":memory:").connect().await?;§URL params vs. the builder
The connection URL is parsed first, so pass-through params (filename,
mode, vfs, cache, …) are honored. The hardened settings are then
always enforced from the builder — a URL query param cannot weaken them.
Structs§
- Hardened
Sqlite - Builder for a hardened
SqlitePool.
Enums§
Traits§
- Sqlite
Pool Ext pool.begin_immediate()sugar.
Functions§
- begin_
immediate - Begin a WRITE transaction with
BEGIN IMMEDIATE. - is_
memory_ url - True for the recognized in-memory URL spellings.