pub struct Database {
pool: SqlitePool,
db_path: PathBuf,
db_dir: Option<PathBuf>,
}Expand description
Database handle providing synchronous API over async SQLx operations.
Uses a bridge pattern with RUNTIME.block_on() to maintain synchronous interface
for compatibility with existing single-threaded event loop.
Fields§
§pool: SqlitePool§db_path: PathBufThe path to the database file.
db_dir: Option<PathBuf>The directory containing the database file.
Will be empty if the database path is in-memory or has no parent directory.
Implementations§
Source§impl Database
impl Database
Sourcepub fn new<P: AsRef<Path> + Debug>(path: P) -> Result<Self, Error>
pub fn new<P: AsRef<Path> + Debug>(path: P) -> Result<Self, Error>
Create a new database connection pool.
Does not run any migrations — call Database::init after construction.
§Arguments
path- Path to the SQLite database file (will be created if it doesn’t exist)
§Returns
Ok(Database)- Successfully connected databaseErr(Error)- Connection failure
Sourcepub fn close(&self)
pub fn close(&self)
Close all connections in the pool, checkpointing WAL and releasing file handles.
After calling this, no further database operations should be performed. This must be called before unmounting the filesystem that contains the database file, to ensure SQLite releases all file descriptors and flushes any pending WAL data.
Sourcepub fn migration_runner(&self) -> MigrationRunner
pub fn migration_runner(&self) -> MigrationRunner
Returns a MigrationRunner bound to this database’s pool.
Use this to execute all registered runtime migrations after the database is initialized.
Sourcepub fn init(&mut self, backup_retention: usize) -> Result<(), Error>
pub fn init(&mut self, backup_retention: usize) -> Result<(), Error>
Initialises the database for use by the application.
Performs, in order:
- Integrity check (
PRAGMA quick_check). - Version gate — detects upgrades, downgrades, and fresh installs.
- Restore from backup if corruption or downgrade is detected.
- Schema and runtime migrations.
- Version stamp update.
- Post-migration backup (when the version changes).
Must be called once after Database::new before the database is used.
Intended for use in the synchronous startup path.
Sourceasync fn restore_if_needed(
&mut self,
app_version: &GitVersion,
) -> Result<(), Error>
async fn restore_if_needed( &mut self, app_version: &GitVersion, ) -> Result<(), Error>
Checks integrity and the version gate, restoring a backup when either fails.
Corruption and downgrade are treated identically: close the pool, restore
the best available backup for app_version, and reopen the pool so the
caller can continue with migrations against a known-good database.
Returns an error if a restore is needed but no backup directory or compatible backup exists.
§Invariant
db_path is always a real file path at the point where the pool is
reopened. This is guaranteed because db_dir is None only for
:memory: databases, which return early before reaching that point.
Sourceasync fn create_version_backup(
&self,
app_version: &GitVersion,
retention: usize,
) -> Result<(), Error>
async fn create_version_backup( &self, app_version: &GitVersion, retention: usize, ) -> Result<(), Error>
Creates a versioned backup after migrations on every startup.
Skipped in test builds, when the database is in-memory (no db_dir),
or when retention is zero.
Sourceasync fn migrate(&mut self) -> Result<(), Error>
async fn migrate(&mut self) -> Result<(), Error>
Runs schema migrations (sqlx) followed by runtime migrations.
Sourceasync fn check_integrity(&self) -> Result<(), Error>
async fn check_integrity(&self) -> Result<(), Error>
Runs a lightweight SQLite integrity check.
Checkpoints the WAL first so that any WAL corruption is caught and all
WAL pages are flushed into the main file before PRAGMA quick_check
runs. Without this, a corrupt WAL would be invisible to quick_check.
PRAGMA wal_checkpoint returns nullable integer columns (busy, log,
checkpointed) that sqlx typed macros cannot map, so an untyped
[sqlx::query()] with .execute() is used — only the success or failure
of the checkpoint matters here.
Returns Ok(()) if both the checkpoint and PRAGMA quick_check succeed.
On failure, logs the error and returns it so the caller can decide
whether to restore.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Database
impl !RefUnwindSafe for Database
impl Send for Database
impl Sync for Database
impl Unpin for Database
impl UnsafeUnpin for Database
impl !UnwindSafe for Database
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more