Skip to main content

Store

Trait Store 

Source
pub trait Store: Send + Sync {
    // Required methods
    fn get<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 RecordKey,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn put<'life0, 'async_trait>(
        &'life0 self,
        record: Record,
        expected: Option<Revision>,
    ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn list<'life0, 'life1, 'async_trait>(
        &'life0 self,
        prefix: &'life1 KeyPrefix,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn delete_as<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 RecordKey,
        expected: Option<Revision>,
        author: Option<Identity>,
    ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn get_raw<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 RecordKey,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn list_raw<'life0, 'life1, 'async_trait>(
        &'life0 self,
        prefix: &'life1 KeyPrefix,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn put_raw<'life0, 'async_trait>(
        &'life0 self,
        record: Record,
        expected: Option<Revision>,
    ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn purge<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 RecordKey,
        expected: Revision,
    ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided method
    fn delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 RecordKey,
        expected: Option<Revision>,
    ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

A pluggable storage substrate over generic records.

Required Methods§

Source

fn get<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetch a record by key. Returns None for an absent key and for a tombstoned one: a delete is invisible on this surface, and only get_raw shows the tombstone. See ADR 0021.

Source

fn put<'life0, 'async_trait>( &'life0 self, record: Record, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Conditionally write record. expected is the revision the caller believes is current (None means “expect no existing record”). If the store’s current revision differs, returns PutResult::Conflict.

A tombstoned key counts as absent (ADR 0021, spec §8.5):

  • expected == None recreates the key, with one exception: a manifest tombstone (deleted_kind of GraphManifest or VectorManifest) holds a restore window, so a create over it is refused with Err(CoreError::Invalid) (ADR 0030). Restore it with gonzalo undelete, or discard it with gonzalo purge; once collect removes the tombstone the key is free again. Otherwise the store re-stamps record.revision to continue the chain past the tombstone, so the caller must read the real revision back from PutResult::Committed rather than reuse the one it built.
  • Any Some(_) — including the tombstone’s own revision, which consumers never learn — is Err(CoreError::NotFound).

A create over a manifest tombstone is therefore a second error case (Err(CoreError::Invalid), which the daemon answers 400 / InvalidArgument), alongside the following one.

A record whose kind is RecordKind::Tombstone is always rejected with an error, on every current state: deletes go through delete_as, and replication writes tombstones through put_raw.

Source

fn list<'life0, 'life1, 'async_trait>( &'life0 self, prefix: &'life1 KeyPrefix, ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List keys matching prefix, excluding tombstoned keys. See list_raw for a listing that includes them.

Source

fn delete_as<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Option<Revision>, author: Option<Identity>, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Conditionally delete the record at key. expected is the revision the caller believes is current: None deletes unconditionally; Some(rev) deletes only if the current revision matches, else DeleteResult::Conflict. Deleting an absent key is a no-op Deleted. Some(author) records who deleted (stores that write tombstones stamp it on the tombstone’s meta.author). See ADR 0018 and ADR 0021.

Source

fn get_raw<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like get, but also returns tombstones. For replication (sync, pull, collection) only: consumers must use get. A store must never implement this by calling get, which would hide the deletions replication exists to carry. See ADR 0021.

Source

fn list_raw<'life0, 'life1, 'async_trait>( &'life0 self, prefix: &'life1 KeyPrefix, ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like list, but also includes tombstoned keys. For replication only. See ADR 0021.

Source

fn put_raw<'life0, 'async_trait>( &'life0 self, record: Record, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Replication write: store record exactly as given, never re-stamping. A create (expected == None) that finds anything stored, tombstones included, is a Conflict carrying it. Sync and pull use this; consumers must use put. A store must never implement this by calling put, whose recreation rule would resurrect records mid-sync. See ADR 0021.

Source

fn purge<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Revision, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Physically remove the record at key only if its current revision is expected; otherwise DeleteResult::Conflict. Absent is an idempotent Deleted. The only physical removal in the system: used by tombstone collection, which must pass the tombstone’s revision so a record recreated in the meantime survives. See ADR 0021.

Provided Methods§

Source

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

delete_as without an author. Provided; stores implement delete_as.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§