Skip to main content

StorageBackend

Struct StorageBackend 

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

Concrete storage backend providing capability traits.

Implementations§

Source§

impl StorageBackend

Source

pub fn sqlite(path: impl AsRef<Path>) -> Result<Self, SqliteError>

File-backed SQLite database.

Opens (or creates) the database at path. The underlying pool provides 1 writer + N readers in WAL mode for concurrent access. No schema is applied — call apply_schema() for each service.

Source

pub fn sqlite_read_only(path: impl AsRef<Path>) -> Result<Self, SqliteError>

File-backed SQLite database opened read-only.

Opens the database at path and sets PRAGMA query_only = ON on the writer connection so that any write attempt (INSERT/UPDATE/DELETE) returns an error. Reader connections are opened with SQLITE_OPEN_READ_ONLY by the pool; this PRAGMA extends that protection to the writer slot.

The database file must already exist — unlike sqlite() this constructor does not create a new file.

Source

pub fn memory() -> Result<Self, SqliteError>

In-memory SQLite database (for tests).

All data is lost when the backend is dropped. The pool degrades to single-connection mode since in-memory databases cannot be shared across multiple connections.

Source

pub fn sql(&self) -> Arc<dyn SqlAccess>

Get the SQL access capability.

Returns an Arc<dyn SqlAccess> suitable for passing to services.

Source

pub fn apply_schema(&self, plan: &ServiceSchemaPlan) -> Result<(), SqliteError>

Apply a service’s schema plan (run migrations).

Each migration in the plan’s sqlite list is applied idempotently. Already-applied migrations are skipped. The _schema_versions table tracks which migrations have been run.

Source

pub fn apply_pack_ddl_statements( &self, statements: &[&'static str], ) -> Result<(), SqliteError>

Apply pack-auxiliary DDL statements.

Executes each DDL statement idempotently via execute_batch. Each statement MUST be self-contained and use CREATE TABLE IF NOT EXISTS (or equivalent idempotent DDL) so that calling this method more than once does not fail.

Pack auxiliary tables are NOT tracked in _schema_versions — they are non-versioned. Use apply_schema with a ServiceSchemaPlan when version tracking is needed.

This method is lower-level than PackRuntime::schema_plan() — the runtime bootstrap calls pack.schema_plan().statements and passes the slice here. The SchemaPlan type lives in khive-runtime (above this crate in the dep chain); this method accepts a plain &[&'static str] to avoid a circular dependency.

Source

pub fn entities(&self) -> Result<Arc<dyn EntityStore>, SqliteError>

Get an EntityStore. Applies the entities DDL if not already present.

Idempotent — safe to call multiple times.

Source

pub fn entities_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn EntityStore>, SqliteError>

Get an EntityStore. The namespace parameter is validated (non-empty) and the entities schema is applied, but the store itself is unscoped — namespace is the caller’s responsibility on each query/delete call.

Source

pub fn graph(&self) -> Result<Arc<dyn GraphStore>, SqliteError>

Get a GraphStore for the default namespace.

Creates the graph_edges table (with indexes) if it does not already exist. Idempotent — safe to call multiple times.

Source

pub fn graph_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn GraphStore>, SqliteError>

Get a GraphStore scoped to a namespace.

Source

pub fn notes(&self) -> Result<Arc<dyn NoteStore>, SqliteError>

Get a NoteStore. Applies the notes DDL if not already present.

Idempotent — safe to call multiple times.

Source

pub fn notes_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn NoteStore>, SqliteError>

Get a NoteStore. The namespace parameter is validated (non-empty) and the notes schema is applied, but the store itself is unscoped — namespace is the caller’s responsibility on each query/delete call.

Source

pub fn notes_seq_repair_run_count(&self) -> usize

How many times the lazy notes_seq anti-join repair has actually executed against this backend’s pool. Exposed for regression tests asserting the repair runs at most once per backend for the process’s lifetime, not once per notes_for_namespace call (khive #827).

Source

pub fn events(&self) -> Result<Arc<dyn EventStore>, SqliteError>

Get an EventStore for the default namespace.

Creates the events table (with indexes) if it does not already exist. Idempotent — safe to call multiple times.

Source

pub fn events_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn EventStore>, SqliteError>

Get an EventStore scoped to a namespace.

Source

pub fn vectors( &self, model_key: &str, embedding_model: &str, dimensions: usize, ) -> Result<Arc<dyn VectorStore>, SqliteError>

Get a VectorStore for a specific embedding model, scoped to the default namespace.

Creates the vec0 virtual table if it does not already exist. The model_key must contain only ASCII alphanumeric/underscore characters. The embedding_model is the canonical display name stored in each vector row.

Source

pub fn vectors_for_namespace( &self, model_key: &str, embedding_model: &str, dimensions: usize, namespace: &str, ) -> Result<Arc<dyn VectorStore>, SqliteError>

Get a VectorStore for a specific embedding model with a default namespace.

Creates the vec0 virtual table if it does not already exist. The namespace is a default for trait methods that lack a per-call namespace parameter (count, delete, info). Access control is enforced at the runtime layer.

The model_key must contain only ASCII alphanumeric/underscore characters. The embedding_model is the canonical display name stored in the embedding_model column of each vector row (e.g. "all-minilm-l6-v2").

Source

pub fn register_embedding_model( &self, engine_name: &str, model_id: &str, key_version: &str, dimensions: u32, ) -> Result<(), SqliteError>

Register an embedding model in the _embedding_models registry table.

Idempotent: if a row with the same canonical_key already exists, updates its status back to 'active' without changing other fields.

Source

pub fn sparse( &self, model_key: &str, ) -> Result<Arc<dyn SparseStore>, SqliteError>

Get a SparseStore for a specific model key, scoped to the default namespace.

Creates the sparse table if it does not already exist.

Source

pub fn sparse_for_namespace( &self, model_key: &str, namespace: &str, ) -> Result<Arc<dyn SparseStore>, SqliteError>

Get a SparseStore for a specific model key with an explicit default namespace.

The model_key must contain only ASCII alphanumeric/underscore characters.

Source

pub fn text(&self, table_key: &str) -> Result<Arc<dyn TextSearch>, SqliteError>

Get a TextSearch for a specific table key.

Creates the FTS5 virtual table if it does not already exist. Uses the trigram tokenizer by default (CJK-safe).

The table_key must contain only ASCII alphanumeric/underscore characters.

Source

pub fn text_with_tokenizer( &self, table_key: &str, tokenizer: &str, ) -> Result<Arc<dyn TextSearch>, SqliteError>

Get a TextSearch with an explicit FTS5 tokenizer.

Use when you need a tokenizer other than the default trigram — for example unicode61 for Latin-only corpora.

Both table_key and tokenizer must contain only ASCII alphanumeric/underscore characters.

Source

pub fn blob_store( &self, config_root: Option<&Path>, floor_bytes: Option<u64>, ) -> Result<Arc<dyn BlobStore>, SqliteError>

Get a BlobStore rooted per khive#292’s precedence chain: KHIVE_BLOB_ROOT env var > config_root (a caller-resolved khive.toml override — khive-db has no TOML parser of its own) > beside this backend’s database directory. floor_bytes overrides the default 100 GB fail-closed free-space floor (None keeps the default). Errors if none of the three roots apply — e.g. an in-memory backend with no override and no env var has nowhere to default to.

Source

pub fn is_file_backed(&self) -> bool

Is this a file-backed backend?

Source

pub fn data_dir(&self) -> Option<PathBuf>

Return the directory containing the backend’s database file, or None for an in-memory backend.

Source

pub fn pool(&self) -> &ConnectionPool

Access the underlying pool (escape hatch).

Source

pub fn pool_arc(&self) -> Arc<ConnectionPool>

Clone the underlying pool Arc.

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> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. 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