pub struct StorageBackend { /* private fields */ }Expand description
Concrete storage backend providing capability traits.
Implementations§
Source§impl StorageBackend
impl StorageBackend
Sourcepub fn sqlite(path: impl AsRef<Path>) -> Result<Self, SqliteError>
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.
Sourcepub fn memory() -> Result<Self, SqliteError>
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.
Sourcepub fn sql(&self) -> Arc<dyn SqlAccess>
pub fn sql(&self) -> Arc<dyn SqlAccess>
Get the SQL access capability.
Returns an Arc<dyn SqlAccess> suitable for passing to services.
Sourcepub fn apply_schema(&self, plan: &ServiceSchemaPlan) -> Result<(), SqliteError>
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.
Sourcepub fn apply_pack_ddl_statements(
&self,
statements: &[&'static str],
) -> Result<(), SqliteError>
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.
Sourcepub fn entities(&self) -> Result<Arc<dyn EntityStore>, SqliteError>
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.
Sourcepub fn entities_for_namespace(
&self,
namespace: &str,
) -> Result<Arc<dyn EntityStore>, SqliteError>
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.
Sourcepub fn graph(&self) -> Result<Arc<dyn GraphStore>, SqliteError>
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.
Sourcepub fn graph_for_namespace(
&self,
namespace: &str,
) -> Result<Arc<dyn GraphStore>, SqliteError>
pub fn graph_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn GraphStore>, SqliteError>
Get a GraphStore scoped to a namespace.
Sourcepub fn notes(&self) -> Result<Arc<dyn NoteStore>, SqliteError>
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.
Sourcepub fn notes_for_namespace(
&self,
namespace: &str,
) -> Result<Arc<dyn NoteStore>, SqliteError>
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.
Sourcepub fn events(&self) -> Result<Arc<dyn EventStore>, SqliteError>
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.
Sourcepub fn events_for_namespace(
&self,
namespace: &str,
) -> Result<Arc<dyn EventStore>, SqliteError>
pub fn events_for_namespace( &self, namespace: &str, ) -> Result<Arc<dyn EventStore>, SqliteError>
Get an EventStore scoped to a namespace.
Sourcepub fn vectors(
&self,
model_key: &str,
embedding_model: &str,
dimensions: usize,
) -> Result<Arc<dyn VectorStore>, SqliteError>
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.
Sourcepub fn vectors_for_namespace(
&self,
model_key: &str,
embedding_model: &str,
dimensions: usize,
namespace: &str,
) -> Result<Arc<dyn VectorStore>, SqliteError>
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").
Sourcepub fn register_embedding_model(
&self,
engine_name: &str,
model_id: &str,
key_version: &str,
dimensions: u32,
) -> Result<(), SqliteError>
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.
Sourcepub fn sparse(
&self,
model_key: &str,
) -> Result<Arc<dyn SparseStore>, SqliteError>
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.
Sourcepub fn sparse_for_namespace(
&self,
model_key: &str,
namespace: &str,
) -> Result<Arc<dyn SparseStore>, SqliteError>
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.
Sourcepub fn text(&self, table_key: &str) -> Result<Arc<dyn TextSearch>, SqliteError>
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.
Sourcepub fn text_with_tokenizer(
&self,
table_key: &str,
tokenizer: &str,
) -> Result<Arc<dyn TextSearch>, SqliteError>
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.
Sourcepub fn is_file_backed(&self) -> bool
pub fn is_file_backed(&self) -> bool
Is this a file-backed backend?
Sourcepub fn pool(&self) -> &ConnectionPool
pub fn pool(&self) -> &ConnectionPool
Access the underlying pool (escape hatch).
Sourcepub fn pool_arc(&self) -> Arc<ConnectionPool>
pub fn pool_arc(&self) -> Arc<ConnectionPool>
Clone the underlying pool Arc.