use std::any::Any;
use std::sync::Arc;
use anyhow::{anyhow, Result};
use lora_store::{GraphStorage, GraphStorageMut, InMemoryGraph, MutationEvent, MutationRecorder};
pub(crate) fn install_recorder_if_inmemory<S: GraphStorage + Any + Sized>(
store: &mut S,
recorder: Option<Arc<dyn MutationRecorder>>,
) {
let any: &mut dyn Any = store;
if let Some(graph) = any.downcast_mut::<InMemoryGraph>() {
graph.set_mutation_recorder(recorder);
}
}
pub(crate) fn replay_into(graph: &mut InMemoryGraph, events: Vec<MutationEvent>) -> Result<()> {
for (idx, event) in events.into_iter().enumerate() {
match event {
MutationEvent::CreateNode {
id,
labels,
properties,
} => {
graph
.replay_create_node(id, labels, properties)
.map_err(|e| anyhow!("WAL replay failed at event {idx}: {e}"))?;
}
MutationEvent::CreateRelationship {
id,
src,
dst,
rel_type,
properties,
} => {
graph
.replay_create_relationship(id, src, dst, &rel_type, properties)
.map_err(|e| anyhow!("WAL replay failed at event {idx}: {e}"))?;
}
MutationEvent::SetNodeProperty {
node_id,
key,
value,
} => {
if !graph.set_node_property(node_id, key, value) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing node {node_id} for property set"
));
}
}
MutationEvent::RemoveNodeProperty { node_id, key } => {
if !graph.remove_node_property(node_id, &key) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing node {node_id} for property removal"
));
}
}
MutationEvent::AddNodeLabel { node_id, label } => {
if !graph.add_node_label(node_id, &label) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing node {node_id} for label add"
));
}
}
MutationEvent::RemoveNodeLabel { node_id, label } => {
if !graph.remove_node_label(node_id, &label) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing node {node_id} for label removal"
));
}
}
MutationEvent::SetRelationshipProperty { rel_id, key, value } => {
if !graph.set_relationship_property(rel_id, key, value) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing relationship {rel_id} for property set"
));
}
}
MutationEvent::RemoveRelationshipProperty { rel_id, key } => {
if !graph.remove_relationship_property(rel_id, &key) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing relationship {rel_id} for property removal"
));
}
}
MutationEvent::DeleteRelationship { rel_id } => {
if !graph.delete_relationship(rel_id) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing relationship {rel_id} for delete"
));
}
}
MutationEvent::DeleteNode { node_id } => {
if !graph.delete_node(node_id) {
return Err(anyhow!(
"WAL replay failed at event {idx}: missing or attached node {node_id} for delete"
));
}
}
MutationEvent::DetachDeleteNode { node_id } => {
graph.detach_delete_node(node_id);
}
MutationEvent::Clear => {
graph.clear();
}
}
}
Ok(())
}