httk.store.backend.mongo.store

MongoDB store layout initialization and collection preparation.

Exceptions

StoreClockRegressionError

A writable store clock is behind its process-local timestamp mark.

Classes

MongoStore

Object store foundation for MongoDB-backed storable records.

Module Contents

exception httk.store.backend.mongo.store.StoreClockRegressionError(mark_ns, clock_ns)

Bases: RuntimeError

A writable store clock is behind its process-local timestamp mark.

class httk.store.backend.mongo.store.MongoStore(database, *, entry_records=None, entry_families=None, entry_ids=None, store_timestamps=True, store_timestamp_resolution=1000, allow_clock_regression=False, clock_regression_grace=True, upgrade=False)

Object store foundation for MongoDB-backed storable records.

Construction stamps a new empty database or validates the existing layout declaration. Record collections are deliberately created only by the explicit ensure_collections() operation; save and fetch belong to a later phase.

Parameters:
  • database (httk.store.backend.mongo.database.MongoDatabase) – The MongoDB database wrapper.

  • entry_records (collections.abc.Mapping[type, type | tuple[type, ...]] | None) – The required entry-family declaration on first open.

  • entry_families (collections.abc.Sequence[httk.store.storage_layout.EntryFamilyDeclaration] | None) – Application-owned declarations which bypass global registration.

  • entry_ids (httk.store.store_common.EntryIdScheme | None) – Optional scheme used to mint ids for defined entry families.

  • store_timestamps (bool) – Whether saved parent documents receive timestamps.

  • store_timestamp_resolution (int) – Nanoseconds represented by one stored unit.

  • allow_clock_regression (bool) – Whether to disable the process-local clock guard.

  • clock_regression_grace (bool) – Whether to wait briefly for sub-millisecond regressions.

  • upgrade (bool) – Whether to apply a purely additive schema-fingerprint change on reopen instead of raising. Documents are schemaless, so the physical apply is a no-op and only the stored fingerprint is re-stamped; non-additive or non-schema differences still raise.

Raises:
supports_page = True

Whether this backend implements keyset result paging.

property layout: httk.store.storage_layout.StorageLayout

Return the immutable persisted entry declaration.

Returns:

The normalized storage layout.

Return type:

httk.store.storage_layout.StorageLayout

property entry_layout: tuple[httk.store.storage_layout.EntryFamilyLayout, ...]

Return configured entry-family layouts in stable order.

Returns:

The configured entry-family layouts.

Return type:

tuple[httk.store.storage_layout.EntryFamilyLayout, …]

property entry_records: collections.abc.Mapping[type, tuple[type, ...]]

Return configured family classes mapped to backing classes.

Returns:

The normalized entry declaration keyed by family class.

Return type:

collections.abc.Mapping[type, tuple[type, …]]

property store_timestamps: bool

Whether parent documents carry store-managed timestamps.

property store_timestamp_resolution: int | None

Return nanoseconds per stored timestamp unit, or None when disabled.

ensure_collections(*classes)

Synchronously create or update record collections and their indexes.

Parameters:

*classes (type) – Storable record classes whose collections should be prepared. A configured multi-record family also prepares its dispatch collection.

Returns:

None.

Raises:

ValueError – If a requested physical name is reserved.

Return type:

None

transaction()

Return a flat explicit MongoDB transaction context manager.

Returns:

A context that commits on normal exit and aborts on exception.

Raises:

TransactionsUnavailableError – If this store is in degraded mode.

Return type:

contextlib.AbstractContextManager[None]

clear_stale_lock()

Clear a stale fsck lease after verifying its owner is dead.

This is an administrative operation. Clearing a merely slow fsck can corrupt the store because the lease protocol intentionally has no fencing token.

Returns:

None.

Raises:

StoreLockedError – If the fsck lease is still fresh.

Return type:

None

fsck(*, repair=True, collect_garbage=True, repair_conflicts=False, force=False, clamp_future_timestamps=False, known_types=())

Exclusively repair dispatch integrity and collect orphan dependencies.

Main-role records and dispatch-addressed records are roots. Only dependency-role documents are eligible for collection; fsck never creates a dispatch for a dependency-role backing.

Parameters:
  • repair (bool) – Insert missing dispatches for main multi-family backings.

  • collect_garbage (bool) – Delete unmarked dependency documents.

  • repair_conflicts (bool) – Delete invalid dispatch documents after reporting them.

  • force (bool) – Administrative stale-lease override for the fsck handshake.

  • clamp_future_timestamps (bool) – Clamp timestamps beyond the allowed future slack when repairing.

  • known_types (tuple[type, ...]) – Record classes that attribute ordinary collections from earlier store sessions, allowing a safe sweep after reopen.

Returns:

An immutable FsckSummary.

Return type:

httk.store.backend.mongo.fsck.FsckSummary

save(obj, *, as_record=None, id_series=None, alternative_of=None, alternative_kind=None, links=None)

Store an object graph and return its integer sid.

Passing alternative_of (a stored main entry’s id) with alternative_kind saves obj as a named ALTERNATIVE representation of that main: it copies the main’s public id, joins the main’s alternative group, and hashes with the group identity folded in so its content never dedups onto the main. The main must live in obj’s own backing collection and must itself be a main (not another alternative).

Parameters:
  • obj (Any) – The object or projected domain object to store.

  • as_record (type | None) – An explicit alternate storage-record class.

  • id_series (str | None) – Override the configured entry-id series when an id must be minted.

  • alternative_of (str | None) – The stored main entry’s id this record is an alternative of, if any.

  • alternative_kind (str | None) – The alternative kind name (grammar [a-z][a-z0-9_]*); required with alternative_of.

  • links (collections.abc.Mapping[str, object] | None) – Weak links to add after saving, mapping each declared link name to a target or iterable of targets; the save and every link are applied in one atomic transaction.

Returns:

The stored sid.

Raises:
  • TypeError – If obj is a cursor proxy.

  • ValueError – If exactly one of alternative_of/alternative_kind is given, the kind is malformed, or the named main is missing, in another backing collection, or itself an alternative.

  • StorageProjectionCycleError – If the projected graph cycles.

  • EntryMetadataConflictError – If identity-excluded metadata conflicts.

Return type:

int

fetch[T](cls, sid, *, eager=False)

Fetch and hydrate cls at sid.

The eager flag is accepted for backend transparency with SqlStore; the Mongo document is fully in memory at read, so the returned record is always materialized and its values and semantics are identical either way.

Parameters:
  • cls (type[T]) – The storable record class.

  • sid (int) – The integer sid.

  • eager (bool) – Accepted for interface parity; a materialized record is always returned.

Returns:

The hydrated record.

Raises:

KeyError – If the record does not exist.

Return type:

T

fetch_many[T](cls, sids, *, eager=False)

Fetch and hydrate cls at each sid in sids.

The eager flag is accepted for backend transparency; Mongo always returns materialized records (see fetch()).

Parameters:
  • cls (type[T]) – The storable record class.

  • sids (collections.abc.Sequence[int]) – The integer sids to fetch.

  • eager (bool) – Accepted for interface parity; materialized records are always returned.

Returns:

The hydrated records in sids order.

Raises:

KeyError – If any record does not exist.

Return type:

list[T]

fetch_by_content_id[T](cls, key, *, eager=False)

Fetch a content-addressed record, or return None.

The eager flag is accepted for backend transparency; Mongo always returns a materialized record (see fetch()).

Parameters:
  • cls (type[T]) – The storable record class.

  • key (str) – The content identity.

  • eager (bool) – Accepted for interface parity; a materialized record is always returned.

Returns:

The hydrated record or None.

Raises:

SchemaError – If cls is not content-id deduplicated.

Return type:

T | None

fetch_entry(family_cls, content_id, *, eager=False)

Fetch the concrete backing record for an entry-family identity.

The eager flag is accepted for backend transparency; Mongo always returns a materialized record (see fetch()).

Parameters:
  • family_cls (type) – The configured entry-family class.

  • content_id (str) – The entry content identity.

  • eager (bool) – Accepted for interface parity; a materialized record is always returned.

Returns:

The backing record or None.

Raises:
Return type:

object | None

sid_of(obj, *, as_record=None)

Return the sid known for obj, using content lookup when allowed.

Parameters:
  • obj (Any) – The object whose sid is requested.

  • as_record (type | None) – An explicit alternate record class.

Returns:

The sid, or None.

Return type:

int | None

replace(predecessor, obj, *, id_series=None, links=None)

Store obj as a logical replacement of predecessor and return its sid.

The saved document copies predecessor’s logical_id (its lineage identity) instead of starting a fresh one, so both documents share the lineage history() walks. Nothing is updated or deleted: plain fetch() and searcher() queries keep returning both documents, and the lineage’s latest document is simply the one with the highest sid. predecessor need not itself be the latest document of its lineage — replacing an already-replaced document is allowed and extends the same lineage. obj is saved through the ordinary save() path, so its dedup policy, timestamp capture, identity caching and entry-family dispatch all behave exactly as they do there.

If obj’s content deduplicates onto an existing document (under the "content_id" or "by_value" policies), that document’s lineage is compared with predecessor’s: an equal lineage (including obj equalling predecessor itself) is an idempotent no-op returning the existing sid, while a different lineage raises EntryReplacementError.

links optionally adds weak links to the replacement’s lineage, as in save(); the replace and every link are applied in one atomic transaction.

Parameters:
  • predecessor (Any) – The stored instance being replaced; it must have been stored or fetched through this store.

  • obj (Any) – The replacement object to store.

  • id_series (str | None) – Override the configured entry-id series when an id must be minted.

  • links (collections.abc.Mapping[str, object] | None) – Weak links to add, mapping each declared link name to a target or iterable of targets.

Returns:

The stored replacement document’s sid.

Raises:
  • ValueError – If predecessor is not known to this store, or obj’s record collection differs from predecessor’s.

  • EntryReplacementError – If obj deduplicates onto a document from a different lineage.

Return type:

int

Assert a weak link named name from source’s lineage to target’s lineage.

Weak links live in a dedicated append-only link collection and bind lineages: both endpoints always resolve to their latest revision. The operation is idempotent per the pair (source lineage, target lineage) — a live pair is a no-op, a retracted pair is revived, an absent pair founds a fresh link lineage — and duplicate pair lineages (from concurrent writers, which Mongo transactions do not exclude) are tolerated: the pair is live if any lineage is live.

Parameters:
  • source (Any) – The stored source instance declaring the link.

  • name (str) – The declared weak-link name.

  • target (Any) – The stored target instance whose type matches the link declaration.

Returns:

None.

Raises:
Return type:

None

Retract the weak link named name from source’s lineage to target’s lineage.

Retracts every live lineage of the pair (duplicate-tolerant); an absent or already-retracted pair is a no-op. Retraction appends a revision — no document is deleted, and history/as_of still see the earlier live rows.

Parameters:
  • source (Any) – The stored source instance declaring the link.

  • name (str) – The declared weak-link name.

  • target (Any) – The stored target instance whose type matches the link declaration.

Returns:

None.

Raises:
Return type:

None

linked(source, name, *, eager=False)

Return the latest revisions of the targets currently linked from source under name.

Targets are deduplicated by lineage and ordered by first-link order (the link lineage’s root logical_id, ascending; stable across retract+relink). Each returned object is the latest revision of its target lineage. eager is accepted for interface parity with the SQL store; a Mongo fetch is always fully materialized.

Parameters:
  • source (Any) – The stored source instance declaring the link.

  • name (str) – The declared weak-link name.

  • eager (bool) – Accepted for interface parity; a materialized record is always returned.

Returns:

The linked targets’ latest revisions, deduplicated and ordered by first-link order.

Raises:
Return type:

tuple[Any, …]

history(obj)

Return every record in obj’s replacement lineage, oldest first.

The lineage is the set of documents sharing obj’s logical_id — the fresh record that started it and every replace() of it — ordered by sid ascending (the fresh record first, the latest replacement last). Records are reconstructed through the same machinery as fetch().

Parameters:

obj (Any) – A stored instance whose lineage to walk; it must have been stored or fetched through this store.

Returns:

The lineage’s records ordered by ascending sid.

Raises:

ValueError – If obj is not known to this store.

Return type:

tuple[Any, …]

searcher(*, as_of=None, only_latest=False, only_main_alt=True)

Return a Mongo searcher bound to this store’s read path.

Queries use the active transaction session when one is open, so they see that transaction’s uncommitted writes, and object outputs hydrate through fetch(), preserving the identity-cache contract.

Parameters:
  • as_of (object) – Optional historic cutoff in canonical timestamp form.

  • only_latest (bool) – Whether root variables are restricted to the latest document of each logical_id lineage by sid (bounded by as_of when given). Reference/child scopes stay unfiltered so pinned references may still resolve replaced documents.

  • only_main_alt (bool) – Whether root variables are restricted to mains (alt_kind absent), hiding named alternatives. Defaults to True; pass False to reveal alternatives.

Returns:

A new MongoDB searcher bound to this store.

Return type:

Any

stored_property_plan(family)

Return the wire-form Mongo stored-property plan for one configured entry family.

This method is a serving edge: like the entry providers, it serves the family’s definition in OPTIMADE wire form (served_form()), so a prefixed family whose __httk_stored_properties__ keys are served names plans correctly. served_form() is idempotent for standard (unprefixed) families, so their plans are byte-identical.

Parameters:

family (type) – The logical entry-family class to plan.

Returns:

The validated Mongo stored-property plan.

Return type:

Any

referring(cls, *, field, to, eager=False)

Return records whose reference field points at to, ordered by sid.

The eager flag is accepted for backend transparency; Mongo always returns materialized records (see fetch()).

Parameters:
  • cls (type) – The referring record class.

  • field (str) – The reference field.

  • to (Any) – The stored target instance.

  • eager (bool) – Accepted for interface parity; materialized records are always returned.

Returns:

Matching records ordered by sid.

Raises:
  • SchemaError – If the field or target class is incompatible.

  • ValueError – If to is not stored or fetched here.

Return type:

list[Any]