use crate::error::Result;
use crate::schema_induction::{
match_schemas, observe_episode, schema_maintenance, ContextSnapshot, EpisodeData, SchemaId,
SchemaMaintenanceReport, SchemaStore,
};
use super::YantrikDB;
const SCHEMA_STORE_META_KEY: &str = "induced_schema_store";
impl YantrikDB {
pub fn load_induced_schema_store(&self) -> Result<SchemaStore> {
let meta = Self::get_meta(&self.conn(), SCHEMA_STORE_META_KEY)?;
match meta {
Some(json) => serde_json::from_str(&json).map_err(|e| {
crate::error::YantrikDbError::Database(rusqlite::Error::ToSqlConversionFailure(
Box::new(e),
))
}),
None => Ok(SchemaStore::default()),
}
}
pub fn save_induced_schema_store(&self, store: &SchemaStore) -> Result<()> {
let json = serde_json::to_string(store).map_err(|e| {
crate::error::YantrikDbError::Database(rusqlite::Error::ToSqlConversionFailure(
Box::new(e),
))
})?;
self.conn().execute(
"INSERT OR REPLACE INTO meta (key, value) VALUES (?1, ?2)",
rusqlite::params![SCHEMA_STORE_META_KEY, json],
)?;
Ok(())
}
pub fn observe_episode_for_schema(&self, episode: &EpisodeData) -> Result<()> {
let mut store = self.load_induced_schema_store()?;
observe_episode(episode, &mut store);
self.save_induced_schema_store(&store)?;
Ok(())
}
pub fn find_matching_schemas(&self, context: &ContextSnapshot) -> Result<Vec<(SchemaId, f64)>> {
let store = self.load_induced_schema_store()?;
Ok(match_schemas(context, &store))
}
pub fn run_schema_maintenance(
&self,
now_ms: u64,
max_age_ms: u64,
) -> Result<SchemaMaintenanceReport> {
let mut store = self.load_induced_schema_store()?;
let report = schema_maintenance(&mut store, now_ms, max_age_ms);
self.save_induced_schema_store(&store)?;
Ok(report)
}
}
#[cfg(test)]
mod tests {
use crate::engine::YantrikDB;
fn test_db() -> YantrikDB {
YantrikDB::new(":memory:", 8).unwrap()
}
#[test]
fn test_schema_store_save_load_roundtrip() {
let db = test_db();
let store = db.load_induced_schema_store().unwrap();
assert!(store.is_empty());
db.save_induced_schema_store(&store).unwrap();
let loaded = db.load_induced_schema_store().unwrap();
assert!(loaded.is_empty());
}
#[test]
fn test_schema_store_default_on_missing() {
let db = test_db();
let store = db.load_induced_schema_store().unwrap();
assert!(store.is_empty());
}
}