Skip to main content

connect_sqlite

Function connect_sqlite 

Source
pub async fn connect_sqlite(url: &str) -> Result<SqlitePool, Error>
Expand description

Open a SQLite-backed pool from a URL.

Applies the standard production PRAGMAs to every connection in the pool: WAL journal, NORMAL synchronous, a 5-second busy-timeout, and foreign-key enforcement on. Without these, a fresh SqlitePool ends up in journal_mode = DELETE + synchronous = FULL — the safe SQLite defaults that cost ~1-4 seconds per concurrent INSERT once any other connection touches the file (the rollback-journal lock serialises writers).

PRAGMAValueWhy
journal_modeWALReaders don’t block writers; a single writer at a time but no full-file lock. Order-of-magnitude faster for any concurrent workload — typically the session/auth/audit tables fanning out.
synchronousNORMALSkips the per-commit fsync of the rollback journal; safe with WAL since the WAL log is fsynced on checkpoint. The official SQLite docs call this the right pairing with WAL for “most applications”.
busy_timeout5000msWait up to 5 s for a contended writer to release the lock before raising SQLITE_BUSY. Without this, two concurrent writers immediately race to error.
foreign_keysONsqlite turns FK enforcement off by default. The ORM emits REFERENCES clauses assuming they’re respected — turning it on per connection makes the FK contract real.

In-memory URLs are backed by a process-unique temp file. A bare sqlite::memory: gives every connection in the pool its OWN private, empty database, so a table created on one connection is invisible to a query that lands on another — and a shared in-memory database doesn’t survive the connection (or the tokio runtime) that created it being dropped. Both surface as a flaky “no such table” whenever a pool is reused across queries or test cases. Routing in-memory URLs through a small temp file (which every connection sees and which persists for the process) sidesteps both — the same approach umbral-testing::TempPool already documents. File-backed (sqlite://app.db) and Postgres URLs are untouched.