app.storage.postgres.records

Record and revision queries of the PostgreSQL store.

Upserts use INSERT ... ON CONFLICT against the partial unique indexes uq_record_published_location and uq_record_candidate_identity_ref. The search vector is maintained by a database trigger, so it is never written here.

Public API: put_revision(), get_revision(), upsert_record(), create_candidate(), get_record(), list_change_tokens(), delete_published(), list_identity_siblings(), list_relationship_summaries(), list_relationship_candidates(), list_facets().

app.storage.postgres.records.put_revision(session, digest, content)

Store a snapshot unless it exists.

Parameters:
  • session (Session) – Unit-of-work session.

  • digest (str) – Digest string.

  • content (str) – Canonical text.

Return type:

bool

Returns:

True if newly stored.

app.storage.postgres.records.get_revision(session, digest)

Fetch a snapshot.

Parameters:
  • session (Session) – Unit-of-work session.

  • digest (str) – Digest string.

Return type:

Revision | None

Returns:

The snapshot, or None.

app.storage.postgres.records.upsert_record(session, record, kind)

Insert or replace a published or candidate row.

Parameters:
  • session (Session) – Unit-of-work session.

  • record (RecordWrite) – Row content.

  • kind (RecordState) – Published or candidate.

Return type:

UpsertResult

Returns:

The outcome.

app.storage.postgres.records.create_candidate(session, record)

Insert a candidate row only if its key is free.

Parameters:
  • session (Session) – Unit-of-work session.

  • record (RecordWrite) – Row content.

Return type:

UpsertResult

Returns:

The outcome.

Raises:

CandidateExistsError – If the candidate exists.

app.storage.postgres.records.get_record(session, record_id)

Fetch one record row.

Parameters:
  • session (Session) – Unit-of-work session.

  • record_id (UUID) – Record id.

Return type:

StoredRecord | None

Returns:

The row, or None.

app.storage.postgres.records.list_change_tokens(session, source_id, project)

List the stored change state of published files.

Parameters:
  • session (Session) – Unit-of-work session.

  • source_id (str) – Registration id.

  • project (str | None) – Restrict to one project, or None.

Return type:

list[ChangeTokenEntry]

Returns:

Entries ordered by project and path.

app.storage.postgres.records.delete_published(session, record_ids)

Delete published rows by id; candidates are never deleted here.

Parameters:
  • session (Session) – Unit-of-work session.

  • record_ids (Collection[UUID]) – Ids to delete.

Return type:

int

Returns:

Number of deleted rows.

app.storage.postgres.records.list_identity_siblings(session, identity)

List every row of an identity.

Parameters:
  • session (Session) – Unit-of-work session.

  • identity (Identity) – Logical identity.

Return type:

list[StoredRecord]

Returns:

Published rows first, then by ref and path.

app.storage.postgres.records.list_relationship_summaries(session, kind)

List relationship summaries keyed by str(record id).

Parameters:
  • session (Session) – Unit-of-work session.

  • kind (RecordState | None) – Restrict to one state, or None for all rows.

Return type:

list[RecordSummary]

Returns:

One summary per row, ordered by identity and path.

app.storage.postgres.records.list_relationship_candidates(session, self_uuid, link_targets)

List the published rows that can affect one record’s relationships.

A bounded alternative to list_relationship_summaries(PUBLISHED) for one detail request: instead of every published row, this returns only rows that RelationshipIndex could possibly use to resolve self_uuid’s relationships –

  • other rows sharing self_uuid (duplicate-identity detection);

  • rows whose adr_uuid is one of link_targets (candidates for resolving self_uuid’s own outbound links, with every row sharing a target so ambiguity still resolves correctly);

  • rows that link to self_uuid via updates, obsoletes or corrects (inbound links and errata).

The Postgres planner still scans every published row (links has no index), but only the rows that match are sent to the client and turned into RecordSummary objects, which is where the cost of list_relationship_summaries() actually goes at catalog scale (see docs/developer/performance.rst). The result, combined with list_identity_siblings(), is exactly the summary set list_relationship_summaries() would have narrowed RelationshipIndex to for this one record’s view().

Parameters:
  • session (Session) – Unit-of-work session.

  • self_uuid (UUID) – The viewed record’s own UUID.

  • link_targets (Collection[UUID]) – UUIDs the viewed record’s own updates, obsoletes and corrects links target.

Return type:

list[RecordSummary]

Returns:

The matching published rows, ordered by identity and path.

app.storage.postgres.records.list_facets(session)

Count decision rows per (source_id, project), for filter UIs.

Errata are not counted, matching the default search.

Parameters:

session (Session) – Unit-of-work session.

Return type:

list[FacetEntry]

Returns:

One entry per pair, ordered by source id then project.