pub struct Database {
conn: Arc<Mutex<Connection>>,
path: PathBuf,
}Expand description
Database connection wrapper with thread-safe access
Fields§
§conn: Arc<Mutex<Connection>>§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 migrate_with(&self, migrations: &[(&str, &str)]) -> SqliteResult<()>
fn migrate_with(&self, 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.
Split out from Self::migrate so tests can inject a failing migration.
TRACES: UR-002 | DR-012 | UT-014
Sourcepub fn service(&self) -> RusqliteService
pub fn service(&self) -> RusqliteService
Get a database service for async-safe operations
This wraps all blocking database operations in spawn_blocking to prevent freezing the async runtime.