mod branch_metadata_repository;
mod branch_repository;
pub mod decision_repository;
mod edge_repository;
pub mod embedding_repository;
mod file_ir_repository;
mod node_repository;
mod package_metadata_repository;
mod repo_metadata_repository;
mod submodule_repository;
mod symbol_index_repository;
pub use branch_metadata_repository::SqliteBranchMetadataRepository;
pub use branch_repository::SqliteBranchRepository;
pub use decision_repository::{
Decision, DecisionNature, DecisionState, DecisionWeight, ExampleEvidence,
SqliteDecisionRepository,
};
pub use edge_repository::SqliteEdgeRepository;
pub use embedding_repository::{
EmbeddingInput, EmbeddingRow, SqliteEmbeddingRepository, bytes_to_f32s, f32s_to_bytes,
};
pub use file_ir_repository::SqliteFileIRRepository;
pub use node_repository::SqliteNodeRepository;
pub use package_metadata_repository::{PackageMetadataRow, SqlitePackageMetadataRepository};
pub use repo_metadata_repository::SqliteRepoMetadataRepository;
pub use submodule_repository::{SqliteSubmoduleRepository, SubmoduleInput, SubmoduleRow};
pub use symbol_index_repository::{
SqliteSymbolIndexRepository, SymbolDefinitionRow, SymbolImportRow, SymbolKind,
extract_definitions, extract_imports,
};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, MutexGuard};
use rusqlite::Connection;
use crate::StorageError;
use seshat_core::{
BranchId, Edge, EdgeId, EdgeType, KnowledgeNature, KnowledgeNode, NodeId, ProjectFile,
};
pub(crate) fn lock_conn(
conn: &Arc<Mutex<Connection>>,
) -> Result<MutexGuard<'_, Connection>, StorageError> {
conn.lock()
.map_err(|e| StorageError::QueryError(format!("Failed to acquire connection lock: {e}")))
}
pub trait NodeRepository {
fn insert(&self, node: &KnowledgeNode) -> Result<KnowledgeNode, StorageError>;
fn get_by_id(&self, id: NodeId) -> Result<KnowledgeNode, StorageError>;
fn find_by_nature(&self, nature: KnowledgeNature) -> Result<Vec<KnowledgeNode>, StorageError>;
fn find_by_branch(&self, branch_id: &BranchId) -> Result<Vec<KnowledgeNode>, StorageError>;
fn update(&self, node: &KnowledgeNode) -> Result<(), StorageError>;
fn delete(&self, id: NodeId) -> Result<(), StorageError>;
fn delete_by_branch(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
fn delete_facts_by_branch(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
fn delete_auto_detected_by_branch(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
fn find_conventions_by_branch(
&self,
branch_id: &BranchId,
) -> Result<Vec<KnowledgeNode>, StorageError>;
}
pub trait EdgeRepository {
fn insert(&self, edge: &Edge) -> Result<Edge, StorageError>;
fn find_by_source(&self, source_id: NodeId) -> Result<Vec<Edge>, StorageError>;
fn find_by_target(&self, target_id: NodeId) -> Result<Vec<Edge>, StorageError>;
fn find_by_type(&self, edge_type: EdgeType) -> Result<Vec<Edge>, StorageError>;
fn delete(&self, id: EdgeId) -> Result<(), StorageError>;
fn delete_by_branch(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
}
pub trait FileIRRepository {
fn upsert(
&self,
branch_id: &BranchId,
file: &ProjectFile,
last_commit_date: Option<i64>,
) -> Result<(), StorageError>;
fn upsert_with_symbol_index(
&self,
branch_id: &BranchId,
file: &ProjectFile,
last_commit_date: Option<i64>,
) -> Result<(), StorageError>;
fn get_by_path(
&self,
branch_id: &BranchId,
file_path: &str,
) -> Result<ProjectFile, StorageError>;
fn get_by_branch(&self, branch_id: &BranchId) -> Result<Vec<ProjectFile>, StorageError>;
fn get_file_hashes_by_branch(
&self,
branch_id: &BranchId,
) -> Result<HashMap<String, String>, StorageError>;
fn delete_by_path(&self, branch_id: &BranchId, file_path: &str) -> Result<(), StorageError>;
fn delete_with_symbol_index(
&self,
branch_id: &BranchId,
file_path: &str,
) -> Result<(), StorageError>;
fn check_content_hash(
&self,
branch_id: &BranchId,
file_path: &str,
content_hash: &str,
) -> Result<bool, StorageError>;
fn get_file_dates_by_branch(
&self,
branch_id: &BranchId,
) -> Result<HashMap<String, Option<i64>>, StorageError>;
fn update_convention_compliance_counts(
&self,
branch_id: &BranchId,
counts: &HashMap<String, u32>,
) -> Result<(), StorageError>;
}
pub trait BranchRepository {
fn create_snapshot(
&self,
source_branch: &BranchId,
new_branch: &BranchId,
) -> Result<(), StorageError>;
fn switch_branch(&self, branch_id: &BranchId) -> Result<(), StorageError>;
fn delete_branch(&self, branch_id: &BranchId) -> Result<(), StorageError>;
fn list_branches(&self) -> Result<Vec<BranchId>, StorageError>;
fn get_current_branch(&self) -> Result<BranchId, StorageError>;
fn get_last_scanned_commit(&self, branch_id: &BranchId)
-> Result<Option<String>, StorageError>;
fn set_last_scanned_commit(
&self,
branch_id: &BranchId,
commit: &str,
) -> Result<(), StorageError>;
fn ensure_branch_exists(&self, branch_id: &BranchId) -> Result<(), StorageError>;
}
pub trait DecisionRepository {
fn upsert(&self, decision: &Decision) -> Result<(), StorageError>;
fn get_by_hash(&self, hash: &str) -> Result<Option<Decision>, StorageError>;
fn get_by_hashes(&self, hashes: &[&str]) -> Result<HashMap<String, Decision>, StorageError>;
fn delete(&self, hash: &str) -> Result<(), StorageError>;
fn find_by_hash_prefix(&self, prefix: &str) -> Result<Vec<Decision>, StorageError>;
fn rekey(&self, old_hash: &str, new_decision: &Decision) -> Result<(), StorageError>;
fn count_by_state(&self, state: DecisionState) -> Result<usize, StorageError>;
fn list(&self) -> Result<Vec<Decision>, StorageError>;
fn list_by_state(&self, state: DecisionState) -> Result<Vec<Decision>, StorageError>;
}
pub trait PackageMetadataRepository {
fn upsert(&self, row: &PackageMetadataRow) -> Result<(), StorageError>;
fn get(&self, name: &str, registry: &str) -> Result<Option<PackageMetadataRow>, StorageError>;
fn get_by_registry(&self, registry: &str) -> Result<Vec<PackageMetadataRow>, StorageError>;
fn delete_stale(&self, before_timestamp: i64) -> Result<usize, StorageError>;
}
pub trait SubmoduleRepository {
fn insert(&self, input: &SubmoduleInput) -> Result<SubmoduleRow, StorageError>;
fn update(&self, input: &SubmoduleInput) -> Result<(), StorageError>;
fn upsert(&self, input: &SubmoduleInput) -> Result<(), StorageError>;
fn delete(&self, relative_path: &str) -> Result<(), StorageError>;
fn list(&self) -> Result<Vec<SubmoduleRow>, StorageError>;
fn find_by_path(&self, relative_path: &str) -> Result<Option<SubmoduleRow>, StorageError>;
}
pub trait EmbeddingRepository {
fn upsert(&self, branch_id: &str, input: &EmbeddingInput) -> Result<(), StorageError>;
fn upsert_batch(&self, branch_id: &str, inputs: &[EmbeddingInput]) -> Result<(), StorageError>;
fn get_by_branch(&self, branch_id: &str) -> Result<Vec<EmbeddingRow>, StorageError>;
fn get_by_file(
&self,
branch_id: &str,
file_path: &str,
) -> Result<Vec<EmbeddingRow>, StorageError>;
fn delete_by_file(&self, branch_id: &str, file_path: &str) -> Result<usize, StorageError>;
fn delete_by_branch(&self, branch_id: &str) -> Result<usize, StorageError>;
fn count_by_branch(&self, branch_id: &str) -> Result<usize, StorageError>;
fn get_stored_keys(
&self,
branch_id: &str,
) -> Result<Vec<(String, String, String)>, StorageError>;
fn delete_stale(
&self,
branch_id: &str,
stale_keys: &[(String, String, String)],
) -> Result<usize, StorageError>;
}
pub trait SymbolIndexRepository {
fn replace_file(
&self,
branch_id: &BranchId,
file_path: &str,
definitions: &[symbol_index_repository::SymbolDefinitionRow],
imports: &[symbol_index_repository::SymbolImportRow],
) -> Result<(), StorageError>;
fn delete_file(&self, branch_id: &BranchId, file_path: &str) -> Result<(), StorageError>;
fn delete_branch(&self, branch_id: &BranchId) -> Result<(), StorageError>;
fn count_definitions(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
fn definitions_for_file(
&self,
branch_id: &BranchId,
file_path: &str,
) -> Result<Vec<symbol_index_repository::SymbolDefinitionRow>, StorageError>;
fn count_imports(&self, branch_id: &BranchId) -> Result<usize, StorageError>;
}
pub trait BranchMetadataRepository {
fn get(&self, branch_id: &str, key: &str) -> Result<Option<String>, StorageError>;
fn set(&self, branch_id: &str, key: &str, value: &str) -> Result<(), StorageError>;
fn list(&self, branch_id: &str) -> Result<Vec<(String, String)>, StorageError>;
fn delete(&self, branch_id: &str, key: &str) -> Result<(), StorageError>;
}
pub trait RepoMetadataRepository {
fn get(&self, key: &str) -> Result<Option<String>, StorageError>;
fn set(&self, key: &str, value: &str) -> Result<(), StorageError>;
fn get_all(&self) -> Result<Vec<(String, String)>, StorageError>;
}