use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use ckg_core::{Error, Result};
use cozo::{DataValue, DbInstance, ScriptMutability};
use self::meta::{read_meta_bool, stamp_meta_bool, stamp_needs_reindex};
mod insert;
mod lifecycle;
mod meta;
mod registry;
mod resolve;
pub use registry::RegistryStorage;
pub(super) fn map_err(e: impl std::fmt::Display) -> Error {
Error::Storage(e.to_string())
}
pub struct Storage {
pub(super) repo_id: ckg_core::RepoId,
pub(super) db_path: PathBuf,
pub(super) db: DbInstance,
}
impl Storage {
pub fn repo_id(&self) -> &ckg_core::RepoId {
&self.repo_id
}
pub fn db_path(&self) -> &Path {
&self.db_path
}
pub fn recorded_root_path(&self) -> Result<Option<String>> {
let rows = self
.db
.run_script(
"?[v] := *Meta{key: \"root_path\", value: v}",
BTreeMap::new(),
ScriptMutability::Immutable,
)
.map_err(map_err)?;
Ok(rows.rows.first().and_then(|r| r.first()).and_then(|v| match v {
DataValue::Str(s) => Some(s.to_string()),
_ => None,
}))
}
pub fn db(&self) -> &DbInstance {
&self.db
}
pub fn run_mutable_unchecked(&self, script: &str) -> Result<cozo::NamedRows> {
self.db
.run_script(script, BTreeMap::new(), ScriptMutability::Mutable)
.map_err(map_err)
}
pub fn run_immutable(&self, script: &str) -> Result<cozo::NamedRows> {
self.db
.run_script(script, BTreeMap::new(), ScriptMutability::Immutable)
.map_err(map_err)
}
pub fn run_with(
&self,
script: &str,
params: BTreeMap<String, DataValue>,
) -> Result<cozo::NamedRows> {
self.db
.run_script(script, params, ScriptMutability::Mutable)
.map_err(map_err)
}
pub fn run_with_immutable(
&self,
script: &str,
params: BTreeMap<String, DataValue>,
) -> Result<cozo::NamedRows> {
self.db
.run_script(script, params, ScriptMutability::Immutable)
.map_err(map_err)
}
pub fn needs_reindex(&self) -> bool {
read_meta_bool(&self.db, "needs_reindex")
}
pub fn mark_index_in_progress(&self) -> Result<()> {
stamp_meta_bool(&self.db, "index_in_progress", true)
}
pub fn is_index_in_progress(&self) -> bool {
read_meta_bool(&self.db, "index_in_progress")
}
pub fn mark_indexed(&self) -> Result<()> {
stamp_needs_reindex(&self.db, false)?;
stamp_meta_bool(&self.db, "index_in_progress", false)?;
Ok(())
}
}
#[cfg(test)]
mod tests;