Skip to main content

ResourceStore

Trait ResourceStore 

Source
pub trait ResourceStore:
    ResourceStoreReader
    + Send
    + Sync
    + 'static {
    // Required methods
    fn create_versioned<'life0, 'async_trait>(
        &'life0 self,
        resource: Resource,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             Self: 'async_trait;
    fn delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 ResourceIdent,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn replace_atomically_versioned<'life0, 'life1, 'async_trait>(
        &'life0 self,
        delete: &'life1 ResourceIdent,
        create: Resource,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn update_checked<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 ResourceIdent,
        resource: Resource,
        precondition: Precondition,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn rename<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        id: &'life1 ResourceIdent,
        new_name: &'life2 ResourceName,
        precondition: Precondition,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;
    fn add_association<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        from: &'life1 ResourceIdent,
        to: &'life2 ResourceIdent,
        label: &'life3 AssociationLabel,
        properties: Option<HashMap<String, Value>>,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait;
    fn remove_association<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        from: &'life1 ResourceIdent,
        to: &'life2 ResourceIdent,
        label: &'life3 AssociationLabel,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait;
    fn list_associations<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        resource: &'life1 ResourceIdent,
        label: &'life2 AssociationLabel,
        target_label: Option<&'life3 ResourceIdent>,
        max_results: Option<usize>,
        page_token: Option<String>,
    ) -> Pin<Box<dyn Future<Output = Result<(Vec<ResourceIdent>, Option<String>), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait;

    // Provided methods
    fn create<'life0, 'async_trait>(
        &'life0 self,
        resource: Resource,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             Self: 'async_trait { ... }
    fn replace_atomically<'life0, 'life1, 'async_trait>(
        &'life0 self,
        delete: &'life1 ResourceIdent,
        create: Resource,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait { ... }
    fn update<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 ResourceIdent,
        resource: Resource,
    ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait { ... }
    fn list_associations_with_properties<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        resource: &'life1 ResourceIdent,
        label: &'life2 AssociationLabel,
        target_label: Option<&'life3 ResourceIdent>,
        max_results: Option<usize>,
        page_token: Option<String>,
    ) -> Pin<Box<dyn Future<Output = Result<(Vec<(ResourceIdent, Option<HashMap<String, Value>>)>, Option<String>), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait { ... }
}
Expand description

Generic store that can be used to store and retrieve resources.

Any implementation must conform to the following rules:

  • Id fields are managed by the store and must be globally unique. If the id field is set on a resource, it can be ignored.

Required Methods§

Source

fn create_versioned<'life0, 'async_trait>( &'life0 self, resource: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Create a resource, returning its initial store version alongside it.

The u64 is the store’s monotonic per-object version at creation — the same counter get_versioned reads and update_checked asserts. Callers that turn the version into an etag (e.g. the Delta createTable path) use this instead of assuming a fresh object’s version, so the etag stays correct even if the store’s initial version is ever nonzero.

Source

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Delete a resource and all connected associations by its identifier.

The implementing store should delete all associations of the resource before deleting the resource itself.

§Arguments
  • id: The identifier of the resource to delete.
Source

fn replace_atomically_versioned<'life0, 'life1, 'async_trait>( &'life0 self, delete: &'life1 ResourceIdent, create: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

replace_atomically, returning the created object’s store version alongside it (see create_versioned).

This is a required method with no default: every backend store is transactional (olai_store::store::Transactional), so a non-atomic delete-then-create fallback would be a silent correctness footgun.

Source

fn update_checked<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, resource: Resource, precondition: Precondition, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Update a resource under an optimistic-concurrency precondition.

With Precondition::Version this is a compare-and-swap: the write succeeds only if the stored version still equals the expected one, else it fails with Conflict. With Precondition::Any it is an unconditional overwrite. Returns the resource and its new version.

Source

fn rename<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, new_name: &'life2 ResourceName, precondition: Precondition, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Rename a resource to a new (possibly namespaced) name.

Preserves the resource’s id, label, associations, and sealed secrets — only the name changes. With Precondition::Version the rename is a compare-and-swap against the stored version. Returns the renamed resource and its new version.

Source

fn add_association<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, from: &'life1 ResourceIdent, to: &'life2 ResourceIdent, label: &'life3 AssociationLabel, properties: Option<HashMap<String, Value>>, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

Add an association between two resources.

Associations are directed edges between resources with a label and optional properties. Between two resources must be at most one association with a given label. Associations are bi-directional, meaning that if an association is added from A to B, there is also an association from B to A with the inverse label. Some labels are symmetric, meaning that the inverse label is the same as the label.

§Arguments
  • from: The source resource of the association.
  • to: The target resource of the association.
  • label: The label of the association.
  • properties: Optional properties of the association.
§Errors
Source

fn remove_association<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, from: &'life1 ResourceIdent, to: &'life2 ResourceIdent, label: &'life3 AssociationLabel, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

Remove an association between two resources.

Implementations must remove the inverse association as well.

§Arguments
  • from: The source resource of the association.
  • to: The target resource of the association.
  • label: The label of the association.
§Errors
  • NotFound If the association does not exist.
Source

fn list_associations<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, resource: &'life1 ResourceIdent, label: &'life2 AssociationLabel, target_label: Option<&'life3 ResourceIdent>, max_results: Option<usize>, page_token: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<(Vec<ResourceIdent>, Option<String>), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

List associations of a resource.

List associations of a resource with the given label.

§Arguments
  • resource: The resource to list associations of.
  • label: The label of the associations to list.
  • target_label: The label of the target resource of the associations to list.
  • max_results: The maximum number of results to return.
  • page_token: The token to use to get the next page of results.
§Returns

The list of associations of the resource with the given label. The token to use to get the next page of results.

Provided Methods§

Source

fn create<'life0, 'async_trait>( &'life0 self, resource: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Create a new resource.

§Arguments
  • resource: The resource to create.
§Returns

The created resource.

Convenience for create_versioned, discarding the created object’s initial version.

Source

fn replace_atomically<'life0, 'life1, 'async_trait>( &'life0 self, delete: &'life1 ResourceIdent, create: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Atomically delete one resource and create another in one transaction.

Used by the managed-table commit flow, where a StagingTable reservation must be replaced by a Table at the same uuid (the id is fixed at staging time and the Delta API protocol depends on it). This is a genuine relabelStagingTable and Table are distinct, immutable object labels — so it cannot be a rename (which changes the name, not the label). Because the object store keys objects by a single uuid, the delete and the create cannot both exist at that id: they must land in one atomic unit of work so a crash between them cannot leave the reservation gone without the table, and concurrent readers see either the old row or the new one, never neither.

§Arguments
  • delete: The identifier of the resource to remove.
  • create: The resource to create (carrying the adopted id).
§Returns

The created resource and its reference.

Convenience for replace_atomically_versioned, discarding the created object’s version.

Source

fn update<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, resource: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Update a resource unconditionally.

Convenience for update_checked with Precondition::Any, discarding the returned version.

§Arguments
  • id: The identifier of the resource to update.
  • resource: The updated resource.
§Returns

The updated resource.

Source

fn list_associations_with_properties<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, resource: &'life1 ResourceIdent, label: &'life2 AssociationLabel, target_label: Option<&'life3 ResourceIdent>, max_results: Option<usize>, page_token: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<(Vec<(ResourceIdent, Option<HashMap<String, Value>>)>, Option<String>), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

List associations of a resource together with each association’s properties.

Like list_associations, but also returns the PropertyMap stored on each association edge (e.g. a tag assignment’s value).

The default implementation delegates to list_associations and returns None for every property map; stores that persist association properties should override this to surface them.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementations on Foreign Types§

Source§

impl<T> ResourceStore for Arc<T>
where T: ResourceStore,

Source§

fn create_versioned<'life0, 'async_trait>( &'life0 self, resource: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Arc<T>: 'async_trait,

Source§

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Arc<T>: 'async_trait,

Source§

fn replace_atomically_versioned<'life0, 'life1, 'async_trait>( &'life0 self, delete: &'life1 ResourceIdent, create: Resource, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Arc<T>: 'async_trait,

Source§

fn update_checked<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, resource: Resource, precondition: Precondition, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Arc<T>: 'async_trait,

Source§

fn rename<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 ResourceIdent, new_name: &'life2 ResourceName, precondition: Precondition, ) -> Pin<Box<dyn Future<Output = Result<(Resource, ResourceRef, u64), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Arc<T>: 'async_trait,

Source§

fn add_association<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, from: &'life1 ResourceIdent, to: &'life2 ResourceIdent, label: &'life3 AssociationLabel, properties: Option<HashMap<String, Value>>, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Arc<T>: 'async_trait,

Source§

fn remove_association<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, from: &'life1 ResourceIdent, to: &'life2 ResourceIdent, label: &'life3 AssociationLabel, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Arc<T>: 'async_trait,

Source§

fn list_associations<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, resource: &'life1 ResourceIdent, label: &'life2 AssociationLabel, target_label: Option<&'life3 ResourceIdent>, max_results: Option<usize>, page_token: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<(Vec<ResourceIdent>, Option<String>), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Arc<T>: 'async_trait,

Source§

fn list_associations_with_properties<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, resource: &'life1 ResourceIdent, label: &'life2 AssociationLabel, target_label: Option<&'life3 ResourceIdent>, max_results: Option<usize>, page_token: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<(Vec<(ResourceIdent, Option<HashMap<String, Value>>)>, Option<String>), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Arc<T>: 'async_trait,

Implementors§