pub trait DocumentStore: Send + Sync {
Show 33 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(
&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_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 max_doc_id(&self) -> StorageBackendResult<DocId> { ... }
fn is_empty(&self) -> StorageBackendResult<bool> { ... }
fn iter_all(
&self,
) -> StorageBackendResult<Box<dyn Iterator<Item = (DocId, Document)> + '_>> { ... }
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(&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.
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.
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 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".