Skip to main content

AzothDb

Struct AzothDb 

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

Unified Axiom database

Bundles together canonical store, projection store, and projector for easy management.

Implementations§

Source§

impl AzothDb

Source

pub fn backup_with_options<P: AsRef<Path>>( &self, dir: P, options: &BackupOptions, ) -> Result<()>

Backup with custom options (encryption and compression)

Source

pub fn restore_with_options<P: AsRef<Path>, Q: AsRef<Path>>( backup_dir: P, target_path: Q, options: &BackupOptions, ) -> Result<Self>

Restore from backup with custom options

Source§

impl AzothDb

Source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>

Open an Axiom database at the given path

Creates subdirectories:

  • {path}/canonical/ - LMDB canonical store
  • {path}/projection.db - SQLite projection store
Source

pub fn open_with_config( base_path: PathBuf, canonical_config: CanonicalConfig, projection_config: ProjectionConfig, ) -> Result<Self>

Open with custom configurations

Source

pub fn open_with_projector_config( base_path: PathBuf, canonical_config: CanonicalConfig, projection_config: ProjectionConfig, projector_config: ProjectorConfig, ) -> Result<Self>

Open with custom projector config

Source

pub fn canonical(&self) -> &Arc<LmdbCanonicalStore>

Get reference to canonical store

Source

pub fn projection(&self) -> &Arc<SqliteProjectionStore>

Get reference to projection store

Source

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

Get the projection write connection.

Use this for migrations, DDL, and projector event application. For read-only queries, prefer query() / query_async() which automatically use the read pool for concurrent access.

§Example
let conn = db.projection_write_conn();
let guard = conn.lock();
guard.execute("INSERT INTO ...", params![])?;
Source

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

👎Deprecated since 0.3.0: Use query()/query_async() for reads, projection_write_conn() for writes

Get the underlying SQLite connection for the projection store.

Deprecated: prefer projection_write_conn() for writes and query() / query_async() for reads. This method returns the write connection, which contends with the projector.

Source

pub fn projector(&self) -> &Projector<LmdbCanonicalStore, SqliteProjectionStore>

Get reference to projector

Source

pub fn event_notify(&self) -> Arc<Notify>

Get the shared event notification handle.

This Notify fires after every successful event append. Consumers (event processors, custom projectors) can call notify.notified().await to wake immediately when new events are available, eliminating polling.

Source

pub fn base_path(&self) -> &Path

Get the base path

Source

pub fn migrate(&self, manager: &MigrationManager) -> Result<()>

Run migrations on the projection store

Source

pub fn backup_to<P: AsRef<Path>>(&self, dir: P) -> Result<()>

Backup the entire database to a directory

Follows the safe backup workflow:

  1. Pause ingestion
  2. Seal canonical
  3. Run projector to catch up
  4. Backup both stores
  5. Resume ingestion
Source

pub fn restore_from<P: AsRef<Path>>( backup_dir: P, target_path: P, ) -> Result<Self>

Restore from a backup directory

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 an async SQL query on the projection store

This is a convenience wrapper around projection().query_async().

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

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

Execute a synchronous SQL query on the projection store

§Example
let balance: i64 = db.query(|conn| {
    conn.query_row("SELECT balance FROM accounts WHERE id = ?1", [1], |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 asynchronously

§Example
db.execute_async(|conn| {
    conn.execute("CREATE TABLE balances (id INTEGER PRIMARY KEY, amount INTEGER)", [])?;
    Ok(())
}).await?;
Source

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

Execute arbitrary SQL statements synchronously

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

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

Execute a SQL transaction

§Example
db.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 SQL transaction asynchronously

Source

pub async fn submit_write<F, R>(&self, f: F) -> Result<R>
where F: for<'a> FnOnce(&mut LmdbWriteTxn<'a>) -> Result<R> + Send + 'static, R: Send + 'static,

Execute a write operation on the canonical store asynchronously.

Opens a write transaction, passes it to the closure, and commits atomically – all inside spawn_blocking. This replaces ad-hoc spawn_blocking wrappers at each call site.

§Example
use azoth_core::traits::CanonicalTxn;

db.submit_write(|txn| {
    txn.put_state(b"balance", b"100")?;
    txn.append_event(b"{\"type\":\"deposit\",\"amount\":100}")?;
    Ok(())
}).await?;
Source

pub fn write_batch(&self) -> WriteBatch<'_>

Create a new write batch for atomic multi-operation commits.

§Example
let mut batch = db.write_batch();
batch.put(b"key1", b"value1");
batch.put(b"key2", b"value2");
batch.append_event(b"batch_update:{\"keys\":2}");
let info = batch.commit()?;
Source

pub fn scan_prefix(&self, prefix: &[u8]) -> Result<Box<dyn StateIter>>

Scan state keys with a prefix

Returns an iterator over (key, value) pairs with keys starting with the prefix.

§Example
use azoth_core::traits::StateIter;

let mut iter = db.scan_prefix(b"user:")?;
while let Some((key, value)) = iter.next()? {
    println!("Key: {:?}, Value: {:?}", key, value);
}
Source

pub fn range( &self, start: &[u8], end: Option<&[u8]>, ) -> Result<Box<dyn StateIter>>

Iterate state keys in a range

§Example
use azoth_core::traits::StateIter;

let mut iter = db.range(b"user:a", Some(b"user:z"))?;
while let Some((key, value)) = iter.next()? {
    println!("Key: {:?}, Value: {:?}", key, value);
}
Source

pub fn prepare_shutdown(&self) -> Result<()>

Prepare database for shutdown

This method should be called before closing the database to ensure all pending operations complete. It:

  1. Pauses ingestion
  2. Seals the canonical store
  3. Runs projector to catch up

After calling this, you can create a final checkpoint using CheckpointManager::shutdown_checkpoint(), then call close().

§Example
// Prepare for shutdown
db.prepare_shutdown()?;

// Create final checkpoint (async)
checkpoint_manager.shutdown_checkpoint().await?;

// Close database
db.close()?;
Source

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

Close the database (ensures clean shutdown)

For graceful shutdown with checkpoint, call shutdown() first.

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more