pub trait WritableValueSet: ValueSet {
// Required methods
fn insert_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn replace_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn patch_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
partial: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn delete<'life0, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn delete_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
}Expand description
Write operations on raw storage values. Every write is retry-safe, and a write through a narrowed set only touches rows inside that set.
“The set” is everything that narrows this value set (a table’s conditions, a Vista’s narrowing). An unnarrowed set is the only way to write anywhere.
| operation | row in the set | row exists outside the set | no such row |
|---|---|---|---|
delete(id) | deleted, Ok(()) | untouched, Ok(()) | Ok(()) |
insert_value(id, r) | untouched, returns the stored row | Conflict where the backend can see it; never an overwrite | inserted; must fit the set, else Conflict |
patch_value(id, p) | applied; Conflict if the result leaves the set | NotFound | NotFound |
replace_value(id, r) | replaced; Conflict if it leaves the set | Conflict where verifiable | created; must fit the set |
delete_all() | deletes exactly the set | — | — |
A row “fits the set” when it satisfies every condition: equality
conditions are invariants (an absent or null column is filled on insert and
replace, validated on patch); operator conditions are evaluated by the
backend. A backend that can’t apply or evaluate a condition refuses the
write with Unsupported. An eventually-consistent backend can’t see an id
held outside the set before it writes; it documents what it does instead,
and never overwrites silently.
See documentation for ValueSet for implementation example.
Required Methods§
Sourcefn insert_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn insert_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Insert value with a specific ID (often generated) (HTTP POST with ID)
Idempotent: an id already in the set returns the stored row
untouched; an id held outside the set is Conflict; a new row must
fit the set.
Returns: Record as it was stored.
§Use Case
Generate unique ID and store record while avoiding duplicates.
Sourcefn replace_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn replace_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
record: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Replace the entire record at the specified ID (HTTP PUT)
Idempotent: completely overwrites existing data if present. If
possible, will remove/recreate record; therefore if record doesn’t
contain certain attributes which were present in the database, those
will be removed. If record does not exist, will create it.
Confined: a row in the set is replaced (Conflict if the new row
would leave the set); an id held outside the set is Conflict where
the backend can verify it; a created row must fit the set.
Returns: Record as it was stored.
§Use Case
Replace with a new version of a record.
Sourcefn patch_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
partial: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn patch_value<'life0, 'life1, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
partial: &'life1 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>, VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Partially update a record by merging with the provided value (HTTP PATCH)
NotFound (marked) when the row is missing or outside the set;
Conflict when the patched row would leave the set. The exact merge
behavior depends on the storage implementation - typically merges
object fields for JSON-like values.
Returns: Record as it was stored (not only the partial change).
§Use Case
Update only the modified fields of a record.
Sourcefn delete<'life0, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn delete<'life0, 'async_trait>(
&'life0 self,
id: impl Into<Self::Id> + Send + 'async_trait,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Delete a record by ID (HTTP DELETE)
Idempotent and confined: a missing row or a row outside the set is
left alone and reports Ok(()) — nothing is revealed about rows
outside the set.
Sourcefn delete_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn delete_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), VantageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Delete all records in the set (HTTP DELETE without ID)
Idempotent: deletes exactly the set. Executing several times is OK.
Execute on a subset of your entire database.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".