use anyhow::Result;
use super::types::{FieldDef, Filter, Record, ScoredRecord};
pub use brainwires_core::{ChunkMetadata, DatabaseStats, SearchResult};
#[async_trait::async_trait]
pub trait StorageBackend: Send + Sync {
async fn ensure_table(&self, table_name: &str, schema: &[FieldDef]) -> Result<()>;
async fn insert(&self, table_name: &str, records: Vec<Record>) -> Result<()>;
async fn query(
&self,
table_name: &str,
filter: Option<&Filter>,
limit: Option<usize>,
) -> Result<Vec<Record>>;
async fn delete(&self, table_name: &str, filter: &Filter) -> Result<()>;
async fn count(&self, table_name: &str, filter: Option<&Filter>) -> Result<usize> {
Ok(self.query(table_name, filter, None).await?.len())
}
async fn vector_search(
&self,
table_name: &str,
vector_column: &str,
vector: Vec<f32>,
limit: usize,
filter: Option<&Filter>,
) -> Result<Vec<ScoredRecord>>;
}
#[async_trait::async_trait]
pub trait VectorDatabase: Send + Sync {
async fn initialize(&self, dimension: usize) -> Result<()>;
async fn store_embeddings(
&self,
embeddings: Vec<Vec<f32>>,
metadata: Vec<ChunkMetadata>,
contents: Vec<String>,
root_path: &str,
) -> Result<usize>;
#[allow(clippy::too_many_arguments)]
async fn search(
&self,
query_vector: Vec<f32>,
query_text: &str,
limit: usize,
min_score: f32,
project: Option<String>,
root_path: Option<String>,
hybrid: bool,
) -> Result<Vec<SearchResult>>;
#[allow(clippy::too_many_arguments)]
async fn search_filtered(
&self,
query_vector: Vec<f32>,
query_text: &str,
limit: usize,
min_score: f32,
project: Option<String>,
root_path: Option<String>,
hybrid: bool,
file_extensions: Vec<String>,
languages: Vec<String>,
path_patterns: Vec<String>,
) -> Result<Vec<SearchResult>>;
async fn delete_by_file(&self, file_path: &str) -> Result<usize>;
async fn clear(&self) -> Result<()>;
async fn get_statistics(&self) -> Result<DatabaseStats>;
async fn flush(&self) -> Result<()>;
async fn count_by_root_path(&self, root_path: &str) -> Result<usize>;
async fn get_indexed_files(&self, root_path: &str) -> Result<Vec<String>>;
#[allow(clippy::too_many_arguments)]
async fn search_with_embeddings(
&self,
query_vector: Vec<f32>,
query_text: &str,
limit: usize,
min_score: f32,
project: Option<String>,
root_path: Option<String>,
hybrid: bool,
) -> Result<(Vec<SearchResult>, Vec<Vec<f32>>)> {
let results = self
.search(
query_vector,
query_text,
limit,
min_score,
project,
root_path,
hybrid,
)
.await?;
let empty_embeddings = vec![Vec::new(); results.len()];
Ok((results, empty_embeddings))
}
}