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<StorageBackend, SqliteError>
pub fn sqlite(path: impl AsRef<Path>) -> Result<StorageBackend, 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 sqlite_read_only(
path: impl AsRef<Path>,
) -> Result<StorageBackend, SqliteError>
pub fn sqlite_read_only( path: impl AsRef<Path>, ) -> Result<StorageBackend, 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.
Sourcepub fn memory() -> Result<StorageBackend, SqliteError>
pub fn memory() -> Result<StorageBackend, 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 notes_seq_repair_run_count(&self) -> usize
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).
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 blob_store(
&self,
config_root: Option<&Path>,
floor_bytes: Option<u64>,
) -> Result<Arc<dyn BlobStore>, SqliteError>
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.
Sourcepub fn is_file_backed(&self) -> bool
pub fn is_file_backed(&self) -> bool
Is this a file-backed backend?
Sourcepub fn data_dir(&self) -> Option<PathBuf>
pub fn data_dir(&self) -> Option<PathBuf>
Return the directory containing the backend’s database file, or None
for an in-memory 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.
Auto Trait Implementations§
impl !Freeze for StorageBackend
impl !RefUnwindSafe for StorageBackend
impl !UnwindSafe for StorageBackend
impl Send for StorageBackend
impl Sync for StorageBackend
impl Unpin for StorageBackend
impl UnsafeUnpin for StorageBackend
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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