Skip to main content

SqliteProjectionStore

Struct SqliteProjectionStore 

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

SQLite-backed projection store

Uses separate connections for reads and writes. SQLite WAL mode allows readers and writers to operate concurrently at the database level. While each connection still needs mutex protection (rusqlite::Connection is not Sync), using separate connections means reads don’t block writes and vice versa.

Optionally supports a read connection pool for higher concurrency.

Implementations§

Source§

impl SqliteProjectionStore

Source

pub fn conn(&self) -> &Arc<Mutex<Connection>>

Get the underlying write connection (for migrations and custom queries)

Returns an Arc to the Mutex-protected SQLite connection. Users should lock the mutex to access the connection.

Source

pub async fn query_async<F, R>(&self, f: F) -> Result<R>
where F: FnOnce(&Connection) -> Result<R> + Send + 'static, R: Send + 'static,

Execute a read-only SQL query asynchronously

This method runs the query on a separate thread to avoid blocking, making it safe to call from async contexts. Uses a read-only connection that doesn’t block writes.

§Example
let balance: i64 = store.query_async(|conn| {
    conn.query_row("SELECT balance FROM accounts WHERE id = ?1", [account_id], |row| row.get(0))
}).await?;
Source

pub fn query<F, R>(&self, f: F) -> Result<R>
where F: FnOnce(&Connection) -> Result<R>,

Execute a read-only SQL query synchronously

This is a convenience method for non-async contexts. For async contexts, prefer query_async. Uses a read-only connection that doesn’t block writes.

§Example
let balance: i64 = store.query(|conn| {
    conn.query_row("SELECT balance FROM accounts WHERE id = ?1", [account_id], |row| row.get(0))
})?;
Source

pub async fn execute_async<F>(&self, f: F) -> Result<()>
where F: FnOnce(&Connection) -> Result<()> + Send + 'static,

Execute arbitrary SQL statements (DDL/DML) asynchronously

Useful for creating tables, indexes, or performing bulk updates. Uses the write connection.

§Example
store.execute_async(|conn| {
    conn.execute("CREATE TABLE IF NOT EXISTS balances (id INTEGER PRIMARY KEY, amount INTEGER)", [])?;
    conn.execute("CREATE INDEX IF NOT EXISTS idx_amount ON balances(amount)", [])?;
    Ok(())
}).await?;
Source

pub fn execute<F>(&self, f: F) -> Result<()>
where F: FnOnce(&Connection) -> Result<()>,

Execute arbitrary SQL statements (DDL/DML) synchronously

Uses the write connection.

§Example
store.execute(|conn| {
    conn.execute("CREATE TABLE IF NOT EXISTS balances (id INTEGER PRIMARY KEY, amount INTEGER)", [])?;
    Ok(())
})?;
Source

pub fn transaction<F>(&self, f: F) -> Result<()>
where F: FnOnce(&Transaction<'_>) -> Result<()>,

Execute a transaction with multiple SQL statements

The closure receives a transaction object and can execute multiple statements atomically. If the closure returns an error, the transaction is rolled back. Uses the write connection.

§Example
store.transaction(|tx| {
    tx.execute("INSERT INTO accounts (id, balance) VALUES (?1, ?2)", params![1, 100])?;
    tx.execute("INSERT INTO accounts (id, balance) VALUES (?1, ?2)", params![2, 200])?;
    Ok(())
})?;
Source

pub async fn transaction_async<F>(&self, f: F) -> Result<()>
where F: FnOnce(&Transaction<'_>) -> Result<()> + Send + 'static,

Execute a transaction asynchronously

Uses the write connection.

Source

pub fn read_pool(&self) -> Option<&Arc<SqliteReadPool>>

Get reference to the read pool (if enabled)

Returns None if read pooling was not enabled in config.

Source

pub fn has_read_pool(&self) -> bool

Check if read pooling is enabled

Source

pub fn db_path(&self) -> &Path

Get the database path

Trait Implementations§

Source§

impl ProjectionStore for SqliteProjectionStore

Source§

type Txn<'a> = SimpleProjectionTxn<'a>

Source§

fn open(cfg: ProjectionConfig) -> Result<Self>

Open a projection store
Source§

fn close(&self) -> Result<()>

Close the store
Source§

fn begin_txn(&self) -> Result<Self::Txn<'_>>

Begin a transaction
Source§

fn get_cursor(&self) -> Result<EventId>

Get the current cursor (last applied event ID)
Source§

fn migrate(&self, target_version: u32) -> Result<()>

Run migrations to target schema version
Source§

fn backup_to(&self, path: &Path) -> Result<()>

Create a backup
Source§

fn restore_from(path: &Path, cfg: ProjectionConfig) -> Result<Self>

Restore from a backup
Source§

fn schema_version(&self) -> Result<u32>

Get the schema version

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.