Expand description
A PostgreSQL store for Datumesh: function descriptors, receipts,
blobs, versions of cells over transaction time, lineage, namespaces and function names.
PgStore implements Store, and through it datumesh_core’s Resolver, so
datumesh_core::verify can recompute receipts of stored cells from it.
The API is synchronous (the postgres driver, a small connection pool). Async callers run
it on a blocking thread, e.g. tokio::task::spawn_blocking.
PgStore::connect / PgStore::connect_with take a URL and PoolOptions; TLS
(rustls) is used as the URL’s sslmode says and always verifies the server’s
certificate and host name, against the Mozilla roots plus those added with
PoolOptions::tls_root_certificates_pem. No type of the driver or of a TLS crate is
part of the API, except in pg_unstable (any connection function, the driver
itself), which is outside semver until 1.0.
What is stored, and how:
- Descriptors are checked by the core (
Descriptor::from_json) and stored in canonical form (JCS) under their hash. Receipts are verified (datumesh_core::verify, SPEC 10.1 steps 1-6) against the key document stored for their signer host, so nothing unverified enters the store, and are stored canonical under their hash. Storing the same thing twice stores it once. A second, different valid signature over the same payload (possible only with a randomised signer: the payload names the key, so a rotated key gives a new hash) is refused (Error::Conflict) and the stored receipt kept. - Blobs are stored in the database, under the SHA-256 of their content.
- Versions: from transaction time
txon, cellcell_idhas the value of a receipt. Append-only and in tx order per cell, enforced by the database (triggers) as well as byStore::put_version, which also checks that the receipt is stored and is of that cell at that tx. - Computed versions: from transaction time
txon, cellcell_idhas the value a receipt computed, as of the receipt’s asof. Derived rather than facts, so they are added in any order, keyed on (cell, tx, asof), insert-only (Store::put_computed,Store::computed_asof). - Answering as of A: a receipt answers as of A only when its
txand itsasofare both at or before A (Store::stored_asof;Store::version_asoflooks attxonly). - Lineage:
put_receiptrecords an edge to each of the receipt’sinputs, held or not;Store::cell_dependentslifts it to cells. - Namespaces: a host’s key document (checked as SPEC 9.2 requires), with when it was validated. Store it before the host’s receipts. Replacing it later (a key revoked or dropped) does not touch receipts already stored: they verified when they were stored, and putting one of them again is still idempotent.
- Names: which function hash a fully qualified function name meant from a transaction time on. Append-only, like versions.
Instants are compared as text (fixed width, COLLATE "C"), which is exact; each is also
stored as timestamptz, which round-trips every instant of the specification exactly.
Every Store method returns a Result: a malformed argument is Error::Invalid with
the core’s code, a database failure Error::Database. The Resolver methods keep the
core’s Option signatures; there a failure is logged with tracing (target
datumesh_store) and answered None, which verify reports as unavailable.
The schema comes from migrate::apply (the datumesh-store migrate command), through
a store on the (possibly empty) database.
Modules§
- migrate
- Schema migrations: plain SQL files (
migrations/*.sql, embedded), applied in order with a tracking table, and a schema check that compares the live database’s catalog with the catalog the migrations produce in a scratch database. - pg_
unstable - Outside semver until 1.0: this module exposes the
postgresdriver’s types, and any release may change it, including a patch release.
Structs§
- Database
Error - A database failure,
Error::Database: what the server said (its message and SQLSTATE), or the driver’s description of a failure that is not the server’s. - Namespace
- A namespace’s host and its key document.
- PgStore
- The store on PostgreSQL, with a connection pool.
Send + Sync: share one per process (behind anArc); each call checks a connection out for its duration. - Pool
Options - How the pool behaves, and the roots TLS connections are verified against.
- Version
- A version of a cell: from transaction time
txon, the cell’s value is that of the receiptreceipt_hash, which states it as ofasof.
Enums§
Traits§
- Resolver
- What step 7 of SPEC 10.1 obtains: the descriptor, the input receipts and the evaluated
value. This crate evaluates no functions and fetches nothing; the caller supplies a
resolver, and
verifyasks it only for what step 7 reaches for the receipt at hand: - Store
- A Datumesh store: a
Resolverthat can also be written to.