pub struct Database {
conn: Arc<Mutex<Connection>>,
service: RusqliteService,
path: PathBuf,
}Expand description
The database: opened once at startup and owned for the life of the app.
All access goes through Database::service, which hands out clones of one
RusqliteService — a writer thread plus a pool of read-only connections
(see db_service). Nothing else opens the database file.
Fields§
§conn: Arc<Mutex<Connection>>The read-write connection. Owned by the service’s writer thread; kept here only for migrations (which run before that thread starts taking work) and for tests.
service: RusqliteService§path: PathBufImplementations§
Source§impl Database
impl Database
Sourcepub fn open(path: &PathBuf) -> SqliteResult<Self>
pub fn open(path: &PathBuf) -> SqliteResult<Self>
Open or create the database at a specific path
Sourcefn open_reader(path: &PathBuf) -> SqliteResult<Connection>
fn open_reader(path: &PathBuf) -> SqliteResult<Connection>
A connection that can only read. query_only makes an accidental write
routed to the pool fail loudly instead of racing the writer.
Sourcefn migrate_connection(
conn: &Mutex<Connection>,
migrations: &[(&str, &str)],
) -> SqliteResult<()>
fn migrate_connection( conn: &Mutex<Connection>, migrations: &[(&str, &str)], ) -> SqliteResult<()>
Apply migrations in order, skipping ones _migrations already records.
Each migration is one transaction, and the _migrations row is written
inside it. SQLite autocommits every statement otherwise, so a migration
that failed partway — low disk, an OOM kill, the process dying mid-boot —
used to leave its earlier statements applied while recording nothing.
execute_batch aborts on the first error, so the retry on the next launch
then failed at statement 1 (“duplicate column name”) and kept failing
forever; Database::open turns that into a panic, so the app never
started again and the only fix was clearing app data. Committing the
schema change and the bookkeeping together makes a migration all-or-nothing
and a retry always safe.
Every migration is pure DDL/DML, which SQLite runs transactionally — a
PRAGMA or VACUUM added to one would not roll back and must not be.
Runs on the bare connection, before the writer thread takes it, so
tests can also inject a failing migration through migrate_with.
TRACES: UR-002 | DR-012 | UT-014
Sourcepub fn service(&self) -> RusqliteService
pub fn service(&self) -> RusqliteService
A handle to the database service. Cheap: every call returns a clone of the same writer thread and reader pool.