Skip to main content

SqliteStore

Struct SqliteStore 

Source
pub struct SqliteStore { /* private fields */ }
Expand description

The store in one SQLite file (bundled SQLite, no server), with the same behaviour as PgStore: every method, error and rule of Store and Resolver. Send + Sync: share one per process (behind an Arc); each call takes a connection for its duration. Since 0.4.0.

The file is in WAL mode (readers never wait for the writer), with a busy timeout (SqliteOptions::busy_timeout). Every put_* is one transaction begun with BEGIN IMMEDIATE: it takes the database’s write lock first, so its checks (a version later than the latest, a key not yet taken) and its inserts are one atomic step against every other writer, threads of this process or other processes on the same machine. The append-only rules are also triggers in the file, so they hold for any connection. (A SQLite file on a network file system is not supported: its locks are not reliable.)

Every put_* is one transaction. Store methods return errors: a malformed argument is Error::Invalid (no query is made), a database failure Error::Database. The Resolver methods answer both with None; a database failure is logged with tracing (target datumesh_store, level error).

Implementations§

Source§

impl SqliteStore

Source

pub fn open(path: impl AsRef<Path>) -> Result<SqliteStore>

Opens the SQLite file at path with the default SqliteOptions; a missing file is created (empty: apply migrate::sqlite::apply next), as a missing directory is not. open_existing creates nothing.

Source

pub fn open_with( path: impl AsRef<Path>, options: SqliteOptions, ) -> Result<SqliteStore>

Opens the SQLite file at path, creating it when it is missing (its directory must exist). One connection is opened at once (and the file put in WAL mode), so a path that cannot be opened fails here (SQLITE_CANTOPEN); the schema is not looked at, so a new or empty file is fine (create the schema with migrate::sqlite::apply).

Source

pub fn open_existing(path: impl AsRef<Path>) -> Result<SqliteStore>

Opens an existing SQLite file without changing anything: a path with no file is Error::Database (no such database file: <path>, code SQLITE_CANTOPEN) and nothing is created; the file’s journal mode is left as it is. For checking a database (migrate::sqlite::check, the command’s migrate --check), which has no side effects. Writes through such a store work as through any other. Since 0.4.0.

Source

pub fn connect(url: &str) -> Result<SqliteStore>

Opens a store named by a URL: sqlite:<path> or sqlite://<path> (so sqlite:///var/lib/datumesh/store.db is an absolute path), or a plain file path. Query parameters are not taken: the path is everything after the scheme.

Source

pub fn path(&self) -> &Path

The database file’s path.

Source

pub fn check_statements(&self) -> Result<usize>

Prepares every SQL statement the store uses against the live schema, on a new connection, and returns how many there are. Fails with the first statement the schema cannot serve.

Trait Implementations§

Source§

impl Debug for SqliteStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Resolver for SqliteStore

Source§

fn manifest(&self, entry: &str) -> Option<Cow<'_, [u8]>>

The stored manifest of slice entry entry (Store::put_manifest), its canonical form; None when there is none, or entry is not an entry.

Source§

fn evaluate(&self, cell: &Cell, asof: &str) -> Option<Scalar>

Some only for a stored function, as PgStore’s: the value of the receipt of stored_asof’s version.

Source§

fn descriptor(&self, fn_hash: &str) -> Option<Cow<'_, [u8]>>

The descriptor JSON text offered for fn_hash, or None if unavailable (E_FN_UNAVAILABLE). Only None is unavailability: the text is parsed strictly (unparseable text reports its parse code), and any other JSON value, null included, is a descriptor offered that fails the hash check (E_FN_HASH_MISMATCH, SPEC 10.1 step 7.1).
Source§

fn receipt(&self, hash: &str) -> Option<Cow<'_, [u8]>>

The receipt JSON text offered for receipt hash hash, or None if unavailable (E_INPUT_UNAVAILABLE).
Source§

fn evaluation(&self, cell: &Cell, asof: &str) -> Option<Evaluation>

Evaluates cell as of asof, with the evaluation’s lineage when the resolver has it: the inputs entries the evaluation read (10.1 step 7.6). verify calls this once, in place of evaluate. When the value differs from the receipt’s, a lineage that replaces one of the receipt’s inputs by a later version of the same cell (whose receipt it offers through receipt), or one of its slice entries by an item beginning slice:<the same slice id>:, makes the result E_INPUT_SUPERSEDED instead of E_VALUE_MISMATCH. Provided: evaluate’s value, with no lineage.
Source§

impl Store for SqliteStore

Source§

fn computed_asof_with_receipt( &self, cell_id: &str, asof: &str, ) -> Result<Option<(Version, Cow<'_, [u8]>)>>

One query: the version and its receipt’s bytes.

Source§

fn stored_asof_with_receipt( &self, cell_id: &str, asof: &str, ) -> Result<Option<(Version, Cow<'_, [u8]>)>>

One query: the version and its receipt’s bytes.

Source§

fn put_descriptor(&self, bytes: &[u8]) -> Result<String>

Stores a descriptor (checked and canonicalised by the core); returns its function hash. Idempotent.
Source§

fn put_receipt(&self, bytes: &[u8]) -> Result<String>

Stores a receipt that verifies (SPEC 10.1 steps 1-6) against the key document stored for its signer host with put_namespace, in canonical form, with an edge to each of its inputs; returns its hash. An input that is a slice entry (slice:<slice id>:<members hash>, since 0.3.1) is recorded as such (slice_entries); its manifest need not be stored, before or after (it is needed only to recompute, SPEC 10.1 step 7.5). The receipt’s cell is indexed by its typed arguments (slice_members). A receipt that does not verify is refused with verify’s code (no key document for the host: E_KEY_UNAVAILABLE). Idempotent: bytes whose canonical form is the stored copy return its hash without checking the signature again (it verified when stored), even if the key has since been revoked. Other bytes with a stored hash are verified first, then refused as Error::Conflict.
Source§

fn put_blob(&self, bytes: &[u8]) -> Result<String>

Stores blob content; returns its SHA-256 (lowercase hex). Idempotent.
Source§

fn blob(&self, sha256: &str) -> Result<Option<Cow<'_, [u8]>>>

Blob content by SHA-256.
Source§

fn put_version(&self, cell_id: &str, tx: &str, receipt_hash: &str) -> Result<()>

Appends a version: from tx on, cell_id has the value of receipt receipt_hash, which must be stored, of that cell and at that tx. tx must be later than the cell’s latest version (Error::NotLater).
Source§

fn version_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>

The cell’s latest version with tx <= asof.
Source§

fn versions(&self, cell_id: &str, from: &str, to: &str) -> Result<Vec<Version>>

The cell’s versions with from <= tx <= to, in tx order.
Source§

fn latest(&self, cell_id: &str) -> Result<Option<Version>>

The cell’s latest version.
Source§

fn dependents(&self, receipt_hash: &str) -> Result<Vec<String>>

The stored receipts that list receipt_hash among their inputs, by hash. Only as an input of its own: a receipt read as a member of a slice is found through its manifests (member_manifests, then slice_dependents).
Source§

fn inputs(&self, receipt_hash: &str) -> Result<Vec<String>>

The inputs of a stored receipt that are receipt hashes (whether or not they are stored). Its slice entries are slice_entries.
Source§

fn put_namespace( &self, host: &str, keydoc_bytes: &[u8], validated_at: &str, ) -> Result<()>

Records a host’s key document, checked as a 200 response for that host would be (SPEC 9.2, 9.3), validated at validated_at. Re-validation replaces the document; a validated_at earlier than the recorded one is Error::NotLater. Receipts already stored are not re-checked: they verified when they were stored (and putting one again stays idempotent).
Source§

fn namespace(&self, host: &str) -> Result<Option<Namespace>>

A host’s recorded key document.
Source§

fn bind_name(&self, fn_name: &str, fn_hash: &str, tx: &str) -> Result<()>

Appends a binding: from tx on, the fully qualified function name fn_name means fn_hash, whose descriptor must be stored. tx must be later than the name’s latest binding (Error::NotLater).
Source§

fn resolve_name(&self, fn_name: &str, asof: &str) -> Result<Option<String>>

The function hash fn_name meant as of asof: the hash of resolve_binding’s binding.
Source§

fn resolve_binding(&self, fn_name: &str, asof: &str) -> Result<Option<Binding>>

The binding of fn_name that answers as of asof: the one with the latest tx <= asof, with its function hash and its tx, when it began; None before the first. A name bound again to a hash it meant before (even the hash of the binding before it) begins again: the later binding’s tx. Since 0.3.0.
Source§

fn put_computed( &self, cell_id: &str, tx: &str, receipt_hash: &str, ) -> Result<()>

Records that receipt_hash (stored, a receipt of cell_id at tx) is a computed version of the cell. Insert-only, in any order (an older version may be added after a newer one): tx need not be later than anything. The version’s asof is the receipt’s. Idempotent for the same (cell_id, tx, asof, receipt_hash); another receipt for an existing (cell_id, tx, asof) is Error::Conflict (its hash is the receipt refused) and the stored one is kept. The receipt is checked as for put_version: Error::NotFound when it is not stored, Error::Mismatch when it is of another cell or at another tx. Since 0.2.0.
Source§

fn computed_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>

The computed version that answers as of asof: the one with the greatest asof <= asof (between equal asof, the greatest tx), or None. Since 0.2.0.
Source§

fn stored_asof(&self, cell_id: &str, asof: &str) -> Result<Option<Version>>

The stored version that answers as of asof: the latest version (by tx) with tx <= asof whose receipt’s asof is also <= asof, or None. A version whose receipt is late-signed (asof later than tx) answers only from its asof on; until then the version before it answers. (version_asof keeps its tx-only meaning.) Since 0.2.0.
Source§

fn cell_dependents(&self, cell_id: &str) -> Result<Vec<String>>

The cells that read cell_id: the cell ids of the stored receipts that list, among their inputs, any stored receipt of cell_id (lineage: edges joined to receipts), or (since 0.3.1) a slice entry whose stored manifest lists one as a member. Ascending, each once. Since 0.2.0.
Source§

fn put_manifest(&self, bytes: &[u8]) -> Result<String>

Stores a manifest (SPEC 15.13), {"members": [...], "slice": {...}}: parsed strictly and checked by the core (Manifest::from_json: structure, members, their order and limit, the slice object), kept in canonical form under its entry slice:<slice id>:<members hash>, which it returns, and recorded for each member (member_manifests). The members need not be stored. Idempotent; insert-only (the entry is a hash of the content, so a stored entry always has these bytes). Served by manifest. Since 0.3.1.
Source§

fn member_manifests(&self, receipt_hash: &str) -> Result<Vec<String>>

The entries of the stored manifests that list receipt_hash among their members, ascending: from a member, the slices it was read in (then slice_dependents). Since 0.3.1.
Source§

fn slice_entries(&self, receipt_hash: &str) -> Result<Vec<String>>

The slice entries among the inputs of a stored receipt, ascending. Since 0.3.1.
Source§

fn slice_dependents(&self, entry: &str) -> Result<Vec<String>>

The stored receipts whose inputs list the slice entry entry, by hash, ascending. An entry is slice: and two 64-digit hashes (E_CANON_HEX otherwise). Since 0.3.1.
Source§

fn slice_members(&self, slice: &Slice, asof: &str) -> Result<Vec<SliceMember>>

The members of slice as of asof (SPEC 15.13), with the stored version of each that answers as of asof and its receipt’s bytes. Read more
Source§

fn versions_between( &self, cell_id: &str, from: &str, to: &str, asof: &str, ) -> Result<Vec<SliceMember>>

The stored versions of cell_id with from <= tx <= to that answer as of asof (tx <= asof and the receipt’s asof <= asof), ascending by tx, each with its receipt’s bytes: SPEC 15.13’s version slice. Empty when from is after to. Since 0.3.1.
Source§

fn slice_values(&self, slice: &Slice, asof: &str) -> Result<Vec<SliceValue>>

The members slice_members gives, in its order and by its answering rule, each as its version, its receipt’s typed value and its cell (with its arguments), without the receipt’s bytes (the value is a stored column of the receipt and the cell comes from the typed-argument index, neither parsed per call). Since 0.3.2.
Source§

fn slice_changed_after(&self, slice: &Slice, asof: &str) -> Result<bool>

Whether the members of slice, or their versions, may answer differently as of some time after asof: whether a cell matching the slice has a stored version whose receipt’s asof is after asof (its tx is never later than that), for a version slice one with tx in [from, to]. false means slice_members (and slice_values) give the same answer as of every time from asof on, until a version is stored with an asof after it; true may be conservative (a late-signed version superseded before its asof never answers). Index scans only, whatever the slice’s size: two bounded probes (at most 10,001 entries each) choose whether to walk the function’s receipts with an asof after asof or the slice’s candidate cells, whichever is fewer, and one query walks it, stopping at the first match. Since 0.3.2.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more