Skip to main content

Database

Struct Database 

Source
pub struct Database { /* private fields */ }
Expand description

A handle onto one SQL database.

Send + Sync, cheap to share behind an Arc — see the module doc’s Threading model section for what that concurrency contract does and doesn’t buy a caller. Every operation is a blocking synchronous call; see the module doc’s UI-thread discipline section before calling one from the platform UI thread.

Implementations§

Source§

impl Database

Source

pub fn open(name: &str) -> Result<Self, DatabaseError>

Open (creating if absent) the named database at this crate’s standard location, <data_dir>/databases/<name>.db (frust_paths::data_dir), using the compiled default engine.

name is sanitized: it must be non-empty and contain no path separator (/ or \) — see Self::open_with for choosing a different engine, and Self::open_at for an explicit path.

The databases/ directory is deliberately shared by every frust app on the machine (no per-binary app_stem component), which is also why this crate does its own file-level read-through on macOS: if <data_dir>/databases/<name>.db doesn’t exist but the same shape under frust_paths::legacy_data_dir does, the legacy file is opened where it already lives — nothing is migrated, copied, or deleted. data_dir()’s own built-in macOS fallback probes <base>/<app_stem> and so can never see this crate’s paths.

Platform locations:

  • Android: <Context.getFilesDir()>/databases/<name>.db. This directory is installed by the platform shell at nativeInitPlatform time; Database::open must run after this initialization completes (typically from app code, not from a static initializer).
  • iOS, macOS, Linux, Windows: <data_dir>/databases/<name>.db, where data_dir is resolved from environment variables (HOME, XDG_DATA_HOME, APPDATA, etc.).
§Errors

DatabaseError::Storage if name is invalid, no data directory can be resolved (an unset HOME/APPDATA — this crate never guesses a fallback that could silently write into the process’s current directory, matching frust-shared-preferences’s own FileStore::standard precedent), the databases directory can’t be created, or (only once both engine features are compiled out) no engine is available at all — that last case reports Storage naming the missing feature, not DatabaseError::EngineUnavailable, which no path here can construct: each Engine variant is gated on the feature compiling its own backend, so an engine an OpenOptions::engine caller can name is by construction compiled in (see that variant’s own doc).

Source

pub fn open_in_memory() -> Result<Self, DatabaseError>

Open a private, non-shared in-memory database using the compiled default engine — gone once this handle is dropped.

§Errors

See Self::open.

Source

pub fn open_at(path: &Path) -> Result<Self, DatabaseError>

Open (creating if absent) the database at an explicit path, using the compiled default engine — bypasses Self::open’s standard location and name sanitization entirely.

§Errors

See Self::open.

Source

pub fn open_with( name: &str, options: OpenOptions, ) -> Result<Self, DatabaseError>

Open (creating if absent) the named database at this crate’s standard location, with an explicit OpenOptions (currently: engine selection).

§Errors

See Self::open.

Source

pub fn execute( &self, sql: &str, params: impl IntoParams, ) -> Result<u64, DatabaseError>

Run a non-row-returning statement (INSERT/UPDATE/DELETE/DDL), returning the number of rows affected.

§Errors

DatabaseError::Sql if the engine rejects the statement; DatabaseError::Reentrant if the calling thread is already inside a Self::transaction closure on this same handle (use the Transaction’s own execute there).

Source

pub fn query( &self, sql: &str, params: impl IntoParams, ) -> Result<Vec<Row>, DatabaseError>

Run a row-returning statement (SELECT), returning every resulting row.

§Errors

DatabaseError::Sql if the engine rejects the statement; DatabaseError::Reentrant if the calling thread is already inside a Self::transaction closure on this same handle (use the Transaction’s own query there).

Source

pub fn transaction<T>( &self, f: impl FnOnce(&Transaction<'_>) -> Result<T, DatabaseError>, ) -> Result<T, DatabaseError>

Run f inside a BEGIN/COMMIT/ROLLBACK transaction — the same plain SQL on both engines, run through the engine seam. Commits on Ok, rolls back on Err, and returns whatever f returned (or its error).

The transaction is rolled back on every path out that isn’t a successful COMMIT — including the COMMIT statement itself failing (SQLite’s deferred-constraint check runs there and leaves the transaction open) and f panicking — so a call always leaves the handle’s connection ready for the next one, never stranded mid-transaction.

f must not call execute/query/transaction on the same Database handle: the connection is already locked for the transaction’s whole span, and re-entering it from the same thread is refused with DatabaseError::Reentrant rather than deadlocking. Use the Transaction handle f is given instead. Other threads calling this handle meanwhile are unaffected — they queue, per the module doc’s Threading model section.

§Errors

f’s own error, if it returns Err (after rolling back). A BEGIN/COMMIT/ROLLBACK statement itself failing also surfaces as DatabaseError::Sql (again after rolling back). DatabaseError::Reentrant if the calling thread already holds this handle’s connection.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.