use std::collections::HashMap;
use glaredb_error::{DbError, Result};
use tracing::trace;
use super::action::{Action, ActionAddFile, ActionChangeMetadata, ActionRemoveFile};
use super::schema::StructType;
#[derive(Debug)]
pub struct Snapshot {
pub(crate) metadata: ActionChangeMetadata,
pub(crate) add: HashMap<FileKey, ActionAddFile>,
pub(crate) remove: HashMap<FileKey, ActionRemoveFile>,
}
impl Snapshot {
pub fn try_new_from_actions(actions: Vec<Action>) -> Result<Self> {
let metadata = actions
.iter()
.find_map(|action| match action {
Action::ChangeMetadata(metadata) => Some(metadata.clone()),
_ => None,
})
.ok_or_else(|| DbError::new("Cannot construct snapshop without a metadata action"))?;
let mut snapshot = Snapshot {
metadata,
add: HashMap::new(),
remove: HashMap::new(),
};
snapshot.apply_actions(actions)?;
Ok(snapshot)
}
pub fn apply_actions(&mut self, actions: impl IntoIterator<Item = Action>) -> Result<()> {
for action in actions {
trace!(?action, "reconciling action for snapshot");
match action {
Action::ChangeMetadata(metadata) => {
self.metadata = metadata;
}
Action::AddFile(add) => {
let key = FileKey {
path: add.path.clone(), dv_id: None, };
let _ = self.remove.remove(&key);
self.add.insert(key, add);
}
Action::RemoveFile(remove) => {
let key = FileKey {
path: remove.path.clone(),
dv_id: None,
};
let _ = self.add.remove(&key);
self.remove.insert(key, remove);
}
Action::AddCdcFile(_) => {
}
Action::Transaction(_txn) => {
}
Action::Protocol(_) => {
}
Action::CommitInfo(_) => {
}
}
}
Ok(())
}
pub fn schema(&self) -> Result<StructType> {
self.metadata.deserialize_schema()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FileKey {
pub(crate) path: String,
pub(crate) dv_id: Option<String>,
}