pub struct WriteTxn<'db> { /* private fields */ }Expand description
Public write transaction.
Acquired by crate::Db::transaction. Holds the in-process
write-serialization mutex + cross-process WRITER_LOCK for its
entire lifetime. commit / rollback consume self; dropping
without explicitly committing rolls back automatically.
Implementations§
Source§impl<'db> WriteTxn<'db>
impl<'db> WriteTxn<'db>
Sourcepub fn collection<T: Document>(&mut self) -> Result<Collection<'_, T>>
pub fn collection<T: Document>(&mut self) -> Result<Collection<'_, T>>
Open a typed handle to the collection T lives in.
Lazily creates the catalog row + an empty primary B-tree on
first call for a given T inside the current process. The
catalog mutation is staged in the same WAL transaction as
the user’s subsequent writes — a rolled-back txn leaves no
half-created collection.
§Errors
Error::Busyif the pager / catalog mutex is poisoned.- Any error the pager / B-tree / postcard codec returns.
Sourcepub fn commit(self) -> Result<()>
pub fn commit(self) -> Result<()>
Commit the transaction.
#90: flushes every cached CollectionDescriptor back to the
catalog (one Catalog::update per touched collection) BEFORE
the WAL commit, so the coalesced next_id / primary_root /
index-root advances land durably in the same transaction as the
document + index writes. A flush failure aborts the commit (the
? propagates and self drops, rolling the WAL back) rather
than committing a half-flushed catalog.
#93: AFTER the WAL commit succeeds, fold this txn’s staged
reconciled-collection names into the shared per-process
reconciled set, so the expensive T::indexes()
reconciliation is skipped for those collections on later txns.
Promotion is deliberately POST-commit: a rolled-back txn never
reaches here, so it cannot poison the shared cache into skipping
reconciliation against a catalog whose index rows it just rolled
back. A poisoned reconciled mutex maps to Error::Busy (Rule
7) but does NOT un-commit the durable WAL state.
§Errors
As obj_core::WriteTxn::commit, plus any catalog / pager /
postcard error surfaced by the descriptor flush, plus
Error::Busy if the shared reconciled mutex is poisoned at
promotion time (after the commit has already landed durably).
Sourcepub fn insert_raw_indexed(
&mut self,
collection: &str,
payload: &[u8],
type_version: u32,
entries: &[(String, Vec<u8>)],
) -> Result<Id>
pub fn insert_raw_indexed( &mut self, collection: &str, payload: &[u8], type_version: u32, entries: &[(String, Vec<u8>)], ) -> Result<Id>
Engine API: insert a raw-bytes document into collection
AND maintain the named secondary indexes from caller-supplied
field-encoded keys. Returns the freshly-allocated Id.
Unlike Self::insert_raw_bytes (primary-only), this is the
schema-bearing raw write: the C ABI cannot reflect index keys
out of an opaque payload, so the CALLER supplies one
(index_name, field_key) entry per index value, where
field_key is the order-preserving encoding of the indexed
field (produced by obj_core::index::encode_field —
libobj::obj_index_key_encode wraps it). obj does the
kind-specific STORAGE-key composition (append the Id suffix
for Standard / Each / Composite; use the field key as-is
with the Id as value + enforce uniqueness for Unique),
matching the typed path byte-for-byte.
Atomicity: the primary insert + every index maintenance lands
inside the same WAL transaction. An unknown index name
(Error::IndexNotFound) or a uniqueness violation
(Error::UniqueConstraintViolation) surfaces via ? and the
surrounding WriteTxn rolls back the staged primary write
atomically — no half-written index.
§Errors
Error::IndexNotFoundif an entry names an index that does not exist or is notActiveoncollection.Error::UniqueConstraintViolationif aUniqueentry’s key already maps to a different document.- As
Self::insert_with_version(namespaced / too-large / pager / catalog).
Sourcepub fn update_raw_indexed(
&mut self,
collection: &str,
id: Id,
payload: &[u8],
type_version: u32,
remove: &[(String, Vec<u8>)],
add: &[(String, Vec<u8>)],
) -> Result<()>
pub fn update_raw_indexed( &mut self, collection: &str, id: Id, payload: &[u8], type_version: u32, remove: &[(String, Vec<u8>)], add: &[(String, Vec<u8>)], ) -> Result<()>
Engine API: update the document at id in collection to
payload AND move its secondary-index entries from the OLD
caller-supplied field keys to the NEW ones.
obj cannot re-derive the OLD index keys from the stored opaque
bytes, so the caller MUST supply BOTH the remove set (the
field keys the document indexed under before this update) and
the add set (the field keys it indexes under after). Each is
one (index_name, field_key) entry per index value. The
kind-specific composition + uniqueness enforcement matches
Self::insert_raw_indexed.
Atomicity: the primary update + every index removal/insertion lands in the same WAL transaction; any error rolls the whole thing back.
§Errors
Error::CollectionNotFoundifiddoes not exist.Error::IndexNotFound/Error::UniqueConstraintViolationasSelf::insert_raw_indexed.- As
Self::update_with_version.
Sourcepub fn delete_raw_indexed(
&mut self,
collection: &str,
id: Id,
remove: &[(String, Vec<u8>)],
) -> Result<bool>
pub fn delete_raw_indexed( &mut self, collection: &str, id: Id, remove: &[(String, Vec<u8>)], ) -> Result<bool>
Engine API: delete the document at id in collection
AND remove its secondary-index entries given the caller-
supplied OLD field keys. Returns Ok(true) if the primary
record existed, Ok(false) if not.
As with Self::update_raw_indexed, obj cannot re-derive the
index keys from stored bytes, so the caller supplies the
remove set (one (index_name, field_key) per indexed value).
The index removals always run (even on Ok(false)) so a caller
can repair a known-stale index entry; this mirrors the typed
Collection::delete which also diffs against the supplied OLD
key set regardless of primary presence.
§Errors
Error::IndexNotFoundif aremoveentry names an unknown / non-Activeindex.- As
Self::delete_raw_bytes.
Sourcepub fn reconcile_indexes_raw(
&mut self,
collection: &str,
version: u32,
specs: &[IndexSpec],
) -> Result<()>
pub fn reconcile_indexes_raw( &mut self, collection: &str, version: u32, specs: &[IndexSpec], ) -> Result<()>
Engine API: declare / reconcile a runtime obj_core::IndexSpec set
into the catalog for collection, making each Active BEFORE
any index-maintaining raw write (Self::insert_raw_indexed &c.
require the index already Active).
This is the NON-generic equivalent of the #[derive(Document)]
reconcile path (WriteTxn::collection::<T>(), which reflects
T::indexes()): a caller that has no Rust Document type — the
obj-py / FFI index-declaration path (#108) — supplies the specs
directly. Both share ONE body
(reconcile_specs_once) so the cache /
staging / validation / catalog-walk semantics never diverge.
Lazy-creates the collection’s catalog row + empty primary B-tree
on first call (as the typed path does), then runs the same
shared ∪ staged skip-cache: a SECOND call with the same
(collection, version) is a no-op (the underlying
Catalog::reconcile_indexes is itself idempotent for matching
(name, kind, key_paths)). The catalog mutation is staged in the
live WAL transaction — a rolled-back txn leaves no half-declared
index, and the per-process reconciled cache is only promoted on a
successful Self::commit.
§version (#130)
The skip-cache is keyed by (collection, version), not by
collection alone, so a LATER schema version of the same
collection that ADDS an index reconciles on its first call rather
than being skipped. The caller passes the schema version the
specs belong to (e.g. the typed Document::VERSION or the
obj-py @document version). One narrow caveat applies when two
live versions of one collection declare DIFFERENT (conflicting)
index sets and their writes interleave in a single process — see
the reconcile_specs_once internal docs. Index ADDITION (the
common monotonic case) is fully correct.
§Errors
Error::InvalidArgumentif any spec is malformed (validated before any catalog mutation).Error::IndexKindMismatch/Error::IndexKeyPathsMismatchif a spec re-declares an existingActiveindex with a different(kind, key_paths).Error::Busyon a poisoned pager / catalog mutex.- Pager / B-tree / postcard errors propagated.