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
Self::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.