Skip to main content

JsonStore

Struct JsonStore 

Source
pub struct JsonStore<T>
where T: Serialize + DeserializeOwned + Send + Sync + 'static,
{ /* private fields */ }
Expand description

Generic blob store keyed by a string id.

This is the SQLite-backed implementation of the adapter. The type name is engine-neutral on purpose: the ZLayerZQL mirror overrides this entire backend module with a ZQL-backed JsonStore exposing an identical API, so the per-resource storage files that hold a JsonStore<T> regenerate mechanically with no hand edits.

Use via a narrow wrapper type in each storage module (see notifiers.rs::SqlxNotifierStore for the pattern).

Implementations§

Source§

impl<T> JsonStore<T>
where T: Serialize + DeserializeOwned + Send + Sync + 'static,

Source

pub async fn open<P: AsRef<Path>>( path: P, table: JsonTable<T>, ) -> Result<Self, StorageError>

Open or create a SQLite database at the given path and ensure the table + indexes exist.

§Errors

Returns StorageError if the database cannot be opened or if the schema cannot be created.

Source

pub async fn in_memory(table: JsonTable<T>) -> Result<Self, StorageError>

Create an in-memory SQLite database (useful for tests) with the table + indexes in place.

§Errors

Returns StorageError if the in-memory database cannot be created.

Source

pub async fn put(&self, id: &str, value: &T) -> Result<(), StorageError>

Upsert a record by its primary key id.

  • If id is new, a row is inserted with created_at = updated_at = now — both timestamps are taken from now() at write time, NOT from any field on T, because the adapter does not know which field (if any) of T holds a timestamp.
  • If id already exists, every column is refreshed from the new blob except created_at, which is preserved.
§Errors
Source

pub async fn get(&self, id: &str) -> Result<Option<T>, StorageError>

Fetch a record by primary key.

§Errors
Source

pub async fn list(&self) -> Result<Vec<T>, StorageError>

List every record in the table, ordered by the primary-key column (primary_key, default "id") ascending.

Most callers want a domain-specific ordering (e.g. notifier name), which they can do by sorting in memory after list() returns. Doing the sort here would require knowing which field of T to order by, which the adapter cannot know generically.

§Errors
Source

pub async fn list_lossy(&self) -> Result<Vec<T>, StorageError>

List every record in the table ordered by the primary-key column ascending, tolerating rows whose data_json blob fails to deserialize: each such row is logged at error level (with its primary-key value) and skipped rather than failing the whole call.

This is the lossy counterpart to list. Use it for stores where a single corrupt/legacy row must never take down the entire listing — the deployments store relies on this so a poisoned record can’t 500 every list_deployments call and survive restart.

Because the blob can’t be decoded into T for a skipped row, the primary-key column is selected alongside data_json purely for the log line. The PK is always a TEXT column, so it decodes as a string.

§Errors

Returns StorageError::Database on sqlx failure. Per-row deserialize failures are skipped, not returned.

Source

pub async fn delete(&self, id: &str) -> Result<bool, StorageError>

Delete a record by primary key.

§Errors

Returns StorageError::Database on sqlx failure.

Source

pub async fn get_by_unique( &self, column: &str, value: &str, ) -> Result<Option<T>, StorageError>

Fetch a record by one of its peeled secondary columns.

The column must appear in the JsonTable::indexes list. Works for any indexed column — unique or non-unique. When the column is non-unique, the first matching row (by rowid) is returned.

§Errors
Source

pub async fn list_where( &self, column: &str, value: &str, ) -> Result<Vec<T>, StorageError>

List every record where a peeled column matches a specific value. Rows are ordered by id ascending, matching list.

Use list_where_opt if you need to filter on NULL — passing "" to this function binds the empty string, not SQL NULL.

§Errors
Source

pub async fn list_where_null( &self, column: &str, ) -> Result<Vec<T>, StorageError>

List every record where a peeled column is SQL NULL. Rows are ordered by id ascending.

§Errors
Source

pub async fn list_where_opt( &self, column: &str, value: Option<&str>, ) -> Result<Vec<T>, StorageError>

List every record filtered by a peeled column. Some(v) matches column = ? with v bound; None matches column IS NULL. Rows are ordered by id ascending.

This is the unified primitive used by both list_where and list_where_null.

§Errors
Source

pub fn pool(&self) -> &SqlitePool

Return a reference to the underlying SqlitePool.

Exposed pub as a temporary migration bridge: sibling stores still living in crates/zlayer-api/src/storage/ (tasks, workflows, groups) run auxiliary queries — creating companion tables (e.g. task_runs, group_members), doing cross-table transactions during cascade deletes — against the same pool without opening a second connection. It was pub(crate) while JsonStore lived inside zlayer-api; the extraction into zlayer-store requires pub so those cross-crate callers keep compiling. This is NOT a stable public API: once the companion-table stores move into zlayer-store too, this should return to a narrower visibility.

Source

pub async fn count(&self) -> Result<u64, StorageError>

Return the total number of rows in the table.

§Errors

Returns StorageError::Database on sqlx failure.

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for JsonStore<T>

§

impl<T> !UnwindSafe for JsonStore<T>

§

impl<T> Freeze for JsonStore<T>

§

impl<T> Send for JsonStore<T>

§

impl<T> Sync for JsonStore<T>

§

impl<T> Unpin for JsonStore<T>

§

impl<T> UnsafeUnpin for JsonStore<T>

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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