#[cfg(feature = "sqlite-memory")]
use crate::memory::hyperbolic::{HyperbolicConfig, HyperbolicEmbedding};
#[cfg(feature = "sqlite-memory")]
use anyhow::Result;
#[cfg(feature = "sqlite-memory")]
use super::store::SqliteMemoryStore;
#[cfg(feature = "sqlite-memory")]
pub async fn build_from_sqlite(
store: &SqliteMemoryStore,
config: HyperbolicConfig,
) -> HyperbolicEmbedding {
let mut he = HyperbolicEmbedding::new(config);
for mt in crate::memory::MemoryType::all() {
if let Ok(entries) = store.list(*mt, 10_000) {
for entry in entries {
if let Ok(Some(vec)) = store.get_query_vector(&entry.content).await {
he.add(&entry.id, &vec);
}
}
}
}
tracing::debug!(count = he.len(), "Built hyperbolic embedding from SQLite");
he
}
#[cfg(feature = "sqlite-memory")]
pub fn persist_to_sqlite(he: &HyperbolicEmbedding, store: &SqliteMemoryStore) -> Result<()> {
let data: Vec<(&String, &Vec<f32>)> =
he.all_embeddings().iter().map(|(id, v)| (id, v)).collect();
let json = serde_json::to_string(&data)?;
let conn = store.db().conn();
conn.execute(
"INSERT OR REPLACE INTO dream_state (key, value) VALUES ('hyperbolic_embeddings', ?1)",
rusqlite::params![json],
)?;
tracing::debug!(
count = he.len(),
"Hyperbolic embeddings persisted to SQLite"
);
Ok(())
}
#[cfg(feature = "sqlite-memory")]
pub fn restore_from_sqlite(
store: &SqliteMemoryStore,
config: HyperbolicConfig,
) -> Result<HyperbolicEmbedding> {
let conn = store.db().conn();
let json: Option<String> = conn
.query_row(
"SELECT value FROM dream_state WHERE key = 'hyperbolic_embeddings'",
[],
|row| row.get(0),
)
.ok();
let he = if let Some(data) = json {
if let Ok(pairs) = serde_json::from_str::<Vec<(String, Vec<f32>)>>(&data) {
HyperbolicEmbedding::from_pairs(pairs)
} else {
HyperbolicEmbedding::new(config)
}
} else {
HyperbolicEmbedding::new(config)
};
tracing::debug!(
count = he.len(),
"Hyperbolic embeddings restored from SQLite"
);
Ok(he)
}