pub trait DocumentStore: Send + Sync {
Show 41 methods
// Required methods
fn put_stored(
&mut self,
doc_id: DocId,
document: StoredDocument,
) -> StorageBackendResult<()>;
fn get_stored(
&self,
doc_id: DocId,
) -> StorageBackendResult<Option<StoredDocument>>;
fn delete(&mut self, doc_id: DocId) -> StorageBackendResult<()>;
fn clear(&mut self) -> StorageBackendResult<()>;
fn doc_ids(&self) -> StorageBackendResult<Vec<DocId>>;
fn len(&self) -> StorageBackendResult<usize>;
fn snapshot(&self) -> StorageBackendResult<Arc<dyn DocumentStore>>;
// Provided methods
fn put_stored_unused(
&mut self,
doc_id: DocId,
document: StoredDocument,
namespace: DocumentIdNamespace,
) -> StorageBackendResult<()> { ... }
fn get_stored_many_controlled(
&self,
doc_ids: &[DocId],
control: &StorageReadControl,
) -> StorageBackendResult<RetainedDocumentPage> { ... }
fn field_presence_controlled(
&self,
doc_ids: &[DocId],
fields: &[&str],
control: &StorageReadControl,
) -> StorageBackendResult<BudgetedVec<bool>> { ... }
fn with_field_ref_controlled(
&self,
doc_id: DocId,
field: &str,
control: &StorageReadControl,
visitor: &mut dyn FnMut(Option<&Value>) -> StorageBackendResult<()>,
) -> StorageBackendResult<()> { ... }
fn put(
&mut self,
doc_id: DocId,
document: Document,
) -> StorageBackendResult<()> { ... }
fn get(&self, doc_id: DocId) -> StorageBackendResult<Option<Document>> { ... }
fn get_stored_many(
&self,
doc_ids: &[DocId],
) -> StorageBackendResult<BTreeMap<DocId, StoredDocument>> { ... }
fn get_metadata(
&self,
doc_id: DocId,
) -> StorageBackendResult<Option<DocumentMetadata>> { ... }
fn contains_doc_id(&self, doc_id: DocId) -> StorageBackendResult<bool> { ... }
fn get_field(
&self,
doc_id: DocId,
field: &str,
) -> StorageBackendResult<Option<Value>> { ... }
fn find_doc_id_by_field(
&self,
field: &str,
value: &Value,
) -> StorageBackendResult<Option<DocId>> { ... }
fn patch_fields(
&mut self,
doc_id: DocId,
updates: &BTreeMap<String, Value>,
) -> StorageBackendResult<bool> { ... }
fn get_many(
&self,
doc_ids: &[DocId],
) -> StorageBackendResult<BTreeMap<DocId, Document>> { ... }
fn get_fields_multi(
&self,
doc_ids: &[DocId],
fields: &[&str],
) -> StorageBackendResult<BTreeMap<DocId, Vec<Value>>> { ... }
fn for_each_fields_multi(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, Vec<Value>) -> bool,
) -> StorageBackendResult<()> { ... }
fn for_each_fields_multi_ref(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<()> { ... }
fn for_each_fields_multi_ref_with_presence(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
) -> StorageBackendResult<()> { ... }
fn get_shared_fields(
&self,
_doc_ids: &[DocId],
_fields: &[&str],
) -> StorageBackendResult<Option<Vec<Option<SharedDocumentRow>>>> { ... }
fn get_fields_bulk(
&self,
doc_ids: &[DocId],
field: &str,
) -> StorageBackendResult<BTreeMap<DocId, Value>> { ... }
fn has_value(
&self,
field: &str,
value: &Value,
) -> StorageBackendResult<bool> { ... }
fn find_doc_id_by_fields(
&self,
fields: &[String],
values: &[Value],
) -> StorageBackendResult<Option<DocId>> { ... }
fn eval_path(
&self,
doc_id: DocId,
path: &[PathSegment],
) -> StorageBackendResult<Option<Value>> { ... }
fn next_doc_id(
&self,
after: Option<DocId>,
) -> StorageBackendResult<Option<DocId>> { ... }
fn next_doc_ids(
&self,
after: Option<DocId>,
limit: usize,
) -> StorageBackendResult<Vec<DocId>> { ... }
fn next_doc_ids_controlled(
&self,
_after: Option<DocId>,
limit: usize,
control: &StorageReadControl,
) -> StorageBackendResult<BudgetedVec<DocId>> { ... }
fn next_shared_fields(
&self,
_after: Option<DocId>,
_limit: usize,
_fields: &[&str],
) -> StorageBackendResult<Option<Vec<(DocId, SharedDocumentRow)>>> { ... }
fn for_each_next_fields(
&self,
_after: Option<DocId>,
_limit: usize,
_fields: &[&str],
_visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>> { ... }
fn for_each_next_fields_borrowed(
&self,
after: Option<DocId>,
limit: usize,
fields: &[&str],
visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>> { ... }
fn for_each_fields_multi_borrowed(
&self,
_ids: &[DocId],
_fields: &[&str],
_visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>> { ... }
fn max_doc_id(&self) -> StorageBackendResult<DocId> { ... }
fn is_empty(&self) -> StorageBackendResult<bool> { ... }
fn iter_all(
&self,
) -> StorageBackendResult<Box<dyn Iterator<Item = (DocId, Document)> + '_>> { ... }
fn retained_snapshot(
&self,
) -> StorageBackendResult<Option<Arc<dyn DocumentStore>>> { ... }
fn writable_snapshot(&self) -> StorageBackendResult<Box<dyn DocumentStore>> { ... }
}Expand description
Mutating methods are fallible: persistent backends surface their write failures so callers (engine DML, upserts, referential rewrites) can abort the enclosing transaction instead of silently committing a partially-applied statement. A rewrite that deletes a row and then fails to re-insert it must never look like success.
Required Methods§
Sourcefn put_stored(
&mut self,
doc_id: DocId,
document: StoredDocument,
) -> StorageBackendResult<()>
fn put_stored( &mut self, doc_id: DocId, document: StoredDocument, ) -> StorageBackendResult<()>
Persist one typed storage record. Every backend owns the physical representation of tuple metadata and must keep it outside the public field map.
Sourcefn get_stored(
&self,
doc_id: DocId,
) -> StorageBackendResult<Option<StoredDocument>>
fn get_stored( &self, doc_id: DocId, ) -> StorageBackendResult<Option<StoredDocument>>
Read one typed storage record without projecting metadata into user fields.
fn delete(&mut self, doc_id: DocId) -> StorageBackendResult<()>
fn clear(&mut self) -> StorageBackendResult<()>
fn doc_ids(&self) -> StorageBackendResult<Vec<DocId>>
fn len(&self) -> StorageBackendResult<usize>
Sourcefn snapshot(&self) -> StorageBackendResult<Arc<dyn DocumentStore>>
fn snapshot(&self) -> StorageBackendResult<Arc<dyn DocumentStore>>
Read-only handle suitable for an ExecutionContext. Persistent
backends share their connection; memory backends deep-clone so the
snapshot is isolated from later mutations.
Provided Methods§
Sourcefn put_stored_unused(
&mut self,
doc_id: DocId,
document: StoredDocument,
namespace: DocumentIdNamespace,
) -> StorageBackendResult<()>
fn put_stored_unused( &mut self, doc_id: DocId, document: StoredDocument, namespace: DocumentIdNamespace, ) -> StorageBackendResult<()>
Persist a document whose identity no document of the table ever had, as the caller has established from the identity watermark of namespace. A provider that keys its records by that namespace may write them without reading what they would replace, and only while it stores the table under that namespace; a record that exists after all fails the commit. The default replaces as put_stored does.
Sourcefn get_stored_many_controlled(
&self,
doc_ids: &[DocId],
control: &StorageReadControl,
) -> StorageBackendResult<RetainedDocumentPage>
fn get_stored_many_controlled( &self, doc_ids: &[DocId], control: &StorageReadControl, ) -> StorageBackendResult<RetainedDocumentPage>
Read one fixed view into a charged page in exactly the requested order, preserving duplicates and missing rows. The page and every decoded field payload retain the invoking allowance. Unsupported providers must not fall back to unbounded owned materialization.
Sourcefn field_presence_controlled(
&self,
doc_ids: &[DocId],
fields: &[&str],
control: &StorageReadControl,
) -> StorageBackendResult<BudgetedVec<bool>>
fn field_presence_controlled( &self, doc_ids: &[DocId], fields: &[&str], control: &StorageReadControl, ) -> StorageBackendResult<BudgetedVec<bool>>
Read field existence on one selected view, in document-major and then field order. A stored NULL is present; an absent field or document is not. The returned boolean buffer retains the invoking allowance. The default uses controlled rows without invoking legacy owned materializers; stores can inspect their existing field layout without copying values.
Sourcefn with_field_ref_controlled(
&self,
doc_id: DocId,
field: &str,
control: &StorageReadControl,
visitor: &mut dyn FnMut(Option<&Value>) -> StorageBackendResult<()>,
) -> StorageBackendResult<()>
fn with_field_ref_controlled( &self, doc_id: DocId, field: &str, control: &StorageReadControl, visitor: &mut dyn FnMut(Option<&Value>) -> StorageBackendResult<()>, ) -> StorageBackendResult<()>
Borrow one selected field, preserving absence versus stored NULL. The visitor runs exactly once while the provider keeps the value and its decoding allowance alive. Immutable stores can lend an existing scalar without allocating a projection or presence page.
Sourcefn put(&mut self, doc_id: DocId, document: Document) -> StorageBackendResult<()>
fn put(&mut self, doc_id: DocId, document: Document) -> StorageBackendResult<()>
Replace public fields while preserving metadata already owned by the stored tuple. Engine code that creates a new tuple version must call DocumentStore::put_stored with the new metadata explicitly.
fn get(&self, doc_id: DocId) -> StorageBackendResult<Option<Document>>
Sourcefn get_stored_many(
&self,
doc_ids: &[DocId],
) -> StorageBackendResult<BTreeMap<DocId, StoredDocument>>
fn get_stored_many( &self, doc_ids: &[DocId], ) -> StorageBackendResult<BTreeMap<DocId, StoredDocument>>
Bulk variant of DocumentStore::get_stored.
Sourcefn get_metadata(
&self,
doc_id: DocId,
) -> StorageBackendResult<Option<DocumentMetadata>>
fn get_metadata( &self, doc_id: DocId, ) -> StorageBackendResult<Option<DocumentMetadata>>
Read one tuple’s storage metadata without exposing it as a field.
fn contains_doc_id(&self, doc_id: DocId) -> StorageBackendResult<bool>
Sourcefn get_field(
&self,
doc_id: DocId,
field: &str,
) -> StorageBackendResult<Option<Value>>
fn get_field( &self, doc_id: DocId, field: &str, ) -> StorageBackendResult<Option<Value>>
Read a single field. Returns an owned Value so persistent
backends (SQLite, …) can decode on demand without reaching
for a reference into a transient row.
Sourcefn find_doc_id_by_field(
&self,
field: &str,
value: &Value,
) -> StorageBackendResult<Option<DocId>>
fn find_doc_id_by_field( &self, field: &str, value: &Value, ) -> StorageBackendResult<Option<DocId>>
Find the first document whose top-level field equals value.
Persistent stores can override this with an indexed or JSON-path
lookup so point updates do not have to materialise every row.
Sourcefn patch_fields(
&mut self,
doc_id: DocId,
updates: &BTreeMap<String, Value>,
) -> StorageBackendResult<bool>
fn patch_fields( &mut self, doc_id: DocId, updates: &BTreeMap<String, Value>, ) -> StorageBackendResult<bool>
Apply top-level field updates without requiring callers to
materialise the whole document. Value::Null matches put by
removing the stored field. Ok(false) means the document does
not exist; write failures surface as Err.
Sourcefn get_many(
&self,
doc_ids: &[DocId],
) -> StorageBackendResult<BTreeMap<DocId, Document>>
fn get_many( &self, doc_ids: &[DocId], ) -> StorageBackendResult<BTreeMap<DocId, Document>>
Bulk variant of DocumentStore::get. Ids without a stored
document are absent from the result. The default implementation
walks each id one at a time; persistent backends should
override to batch the reads into few queries.
Sourcefn get_fields_multi(
&self,
doc_ids: &[DocId],
fields: &[&str],
) -> StorageBackendResult<BTreeMap<DocId, Vec<Value>>>
fn get_fields_multi( &self, doc_ids: &[DocId], fields: &[&str], ) -> StorageBackendResult<BTreeMap<DocId, Vec<Value>>>
Fetch several top-level fields for many documents. The result
vector is aligned with fields; missing fields come back as
Value::Null, ids without a document are absent. Persistent
backends override this to extract all fields in one scan
instead of materialising whole documents.
Sourcefn for_each_fields_multi(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, Vec<Value>) -> bool,
) -> StorageBackendResult<()>
fn for_each_fields_multi( &self, doc_ids: &[DocId], fields: &[&str], visitor: &mut dyn FnMut(DocId, Vec<Value>) -> bool, ) -> StorageBackendResult<()>
Visit a column projection in the caller’s document-id order.
The callback receives one owned row at a time, allowing scan and
aggregate pipelines to avoid materialising a second doc-id map.
Returning false stops the visit early. Missing documents yield
a row of NULLs, matching row-evaluator semantics.
Sourcefn for_each_fields_multi_ref(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<()>
fn for_each_fields_multi_ref( &self, doc_ids: &[DocId], fields: &[&str], visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool, ) -> StorageBackendResult<()>
Visit a column projection by reference when the backend can keep decoded values alive for the duration of the callback. The default adapter preserves the backend’s owned/batched projection path; in-memory stores override it to avoid cloning every projected value.
Sourcefn for_each_fields_multi_ref_with_presence(
&self,
doc_ids: &[DocId],
fields: &[&str],
visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
) -> StorageBackendResult<()>
fn for_each_fields_multi_ref_with_presence( &self, doc_ids: &[DocId], fields: &[&str], visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool, ) -> StorageBackendResult<()>
Visit a projection together with whether each requested document
actually exists. This avoids a separate contains_doc_id probe when a
caller must distinguish a missing document from an existing document
whose requested fields are all NULL.
Return rows aligned with doc_ids as shared positional projections
when the backend owns stable decoded value vectors. None means the
backend does not support zero-copy projection; entries inside the
returned vector are None only for missing document ids.
Sourcefn get_fields_bulk(
&self,
doc_ids: &[DocId],
field: &str,
) -> StorageBackendResult<BTreeMap<DocId, Value>>
fn get_fields_bulk( &self, doc_ids: &[DocId], field: &str, ) -> StorageBackendResult<BTreeMap<DocId, Value>>
Bulk variant of DocumentStore::get_field. The default
implementation walks each id one at a time; persistent backends
should override to run a single batched query.
Sourcefn has_value(&self, field: &str, value: &Value) -> StorageBackendResult<bool>
fn has_value(&self, field: &str, value: &Value) -> StorageBackendResult<bool>
Return true if any document has field == value.
Sourcefn find_doc_id_by_fields(
&self,
fields: &[String],
values: &[Value],
) -> StorageBackendResult<Option<DocId>>
fn find_doc_id_by_fields( &self, fields: &[String], values: &[Value], ) -> StorageBackendResult<Option<DocId>>
Find the first document whose top-level fields match every requested value.
Sourcefn eval_path(
&self,
doc_id: DocId,
path: &[PathSegment],
) -> StorageBackendResult<Option<Value>>
fn eval_path( &self, doc_id: DocId, path: &[PathSegment], ) -> StorageBackendResult<Option<Value>>
Evaluate a hierarchical path expression against a document.
Sourcefn next_doc_id(
&self,
after: Option<DocId>,
) -> StorageBackendResult<Option<DocId>>
fn next_doc_id( &self, after: Option<DocId>, ) -> StorageBackendResult<Option<DocId>>
Return the first stored document id strictly greater than after, or
the first id when after is None. Scan operators use this cursor API
so a full table scan does not need a cardinality-sized id vector before
it can yield its first row.
Sourcefn next_doc_ids(
&self,
after: Option<DocId>,
limit: usize,
) -> StorageBackendResult<Vec<DocId>>
fn next_doc_ids( &self, after: Option<DocId>, limit: usize, ) -> StorageBackendResult<Vec<DocId>>
Return up to limit document ids strictly greater than after, in
ascending order. Scan operators use this bounded cursor instead of
reacquiring their store lock and issuing one backend lookup per row.
Sourcefn next_doc_ids_controlled(
&self,
_after: Option<DocId>,
limit: usize,
control: &StorageReadControl,
) -> StorageBackendResult<BudgetedVec<DocId>>
fn next_doc_ids_controlled( &self, _after: Option<DocId>, limit: usize, control: &StorageReadControl, ) -> StorageBackendResult<BudgetedVec<DocId>>
Read at most limit identities in strictly ascending order after after, retaining the supplied allowance with the output. Implementations reserve producer scratch and output before allocation, preserve this store’s selected view, and never read document payloads. The default rejects unsupported providers without calling an unbounded owned cursor; empty requests still honor cancellation. Controlled consumers use read_document_ids to validate the returned page and its allowance.
Return the next bounded id range and its shared positional projections
in one storage traversal when stable decoded rows are available.
None lets persistent backends use the ordinary id + projection path.
Sourcefn for_each_next_fields(
&self,
_after: Option<DocId>,
_limit: usize,
_fields: &[&str],
_visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>>
fn for_each_next_fields( &self, _after: Option<DocId>, _limit: usize, _fields: &[&str], _visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool, ) -> StorageBackendResult<Option<usize>>
Visit the next bounded id range through a reusable borrowed projection of each backend-owned row. Missing fields are exposed as SQL NULL. Some(count) means the backend supports this borrowed cursor and reports how many rows it visited; None selects the ordinary cursor path without invoking visitor.
Sourcefn for_each_next_fields_borrowed(
&self,
after: Option<DocId>,
limit: usize,
fields: &[&str],
visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>>
fn for_each_next_fields_borrowed( &self, after: Option<DocId>, limit: usize, fields: &[&str], visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool, ) -> StorageBackendResult<Option<usize>>
Visit a bounded ascending projection while permitting the provider to retain a physical read borrow. The caller must not reenter storage, invoke host callbacks, or execute nested SQL from visitor. Missing fields are SQL NULL; stopping the visitor must not decode later rows. None must leave the visitor uncalled. Providers without a physical borrow reuse their ordinary projected cursor.
Sourcefn for_each_fields_multi_borrowed(
&self,
_ids: &[DocId],
_fields: &[&str],
_visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
) -> StorageBackendResult<Option<usize>>
fn for_each_fields_multi_borrowed( &self, _ids: &[DocId], _fields: &[&str], _visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool, ) -> StorageBackendResult<Option<usize>>
Visit requested point projections, including missing rows and duplicate IDs, in caller order while allowing a physical read borrow. Neither the visitor nor its callees may reenter storage, invoke host callbacks, or execute nested SQL. A stopped visitor must not read later IDs. Some(count) counts callbacks; None must leave the visitor uncalled and selects the ordinary projection path.
fn max_doc_id(&self) -> StorageBackendResult<DocId>
fn is_empty(&self) -> StorageBackendResult<bool>
Sourcefn iter_all(
&self,
) -> StorageBackendResult<Box<dyn Iterator<Item = (DocId, Document)> + '_>>
fn iter_all( &self, ) -> StorageBackendResult<Box<dyn Iterator<Item = (DocId, Document)> + '_>>
Iterate over (doc_id, document) pairs in id order. The default
implementation fetches each document individually; SQLite-backed
stores override with a single query.
Sourcefn retained_snapshot(
&self,
) -> StorageBackendResult<Option<Arc<dyn DocumentStore>>>
fn retained_snapshot( &self, ) -> StorageBackendResult<Option<Arc<dyn DocumentStore>>>
Share an already immutable retained view, preserving its selected rows, allocation owners and cancellation boundary. This capability must not capture a new live view or copy row payloads. The default reports that controlled copying is required without invoking the legacy snapshot method, whose persistent implementations may share a mutable connection.
Sourcefn writable_snapshot(&self) -> StorageBackendResult<Box<dyn DocumentStore>>
fn writable_snapshot(&self) -> StorageBackendResult<Box<dyn DocumentStore>>
Independent writable copy used by the in-memory engine transaction rollback path. Persistent engines restore through their backend transaction and need not implement this operation.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".