use crate::error::Result;
use meshdb_core::{Edge, EdgeId, Node, NodeId, Property};
use meshdb_storage::{PropertyConstraintSpec, StorageEngine};
pub trait GraphReader: Send + Sync {
fn get_node(&self, id: NodeId) -> Result<Option<Node>>;
fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>>;
fn all_node_ids(&self) -> Result<Vec<NodeId>>;
fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>>;
fn nodes_by_property(
&self,
label: &str,
property: &str,
value: &Property,
) -> Result<Vec<NodeId>>;
fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
Ok(Vec::new())
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(Vec::new())
}
fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
}
impl<T: StorageEngine> GraphReader for T {
fn get_node(&self, id: NodeId) -> Result<Option<Node>> {
Ok(StorageEngine::get_node(self, id)?)
}
fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>> {
Ok(StorageEngine::get_edge(self, id)?)
}
fn all_node_ids(&self) -> Result<Vec<NodeId>> {
Ok(StorageEngine::all_node_ids(self)?)
}
fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>> {
Ok(StorageEngine::nodes_by_label(self, label)?)
}
fn nodes_by_property(
&self,
label: &str,
property: &str,
value: &Property,
) -> Result<Vec<NodeId>> {
Ok(StorageEngine::nodes_by_property(
self, label, property, value,
)?)
}
fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
Ok(StorageEngine::list_property_indexes(self)
.into_iter()
.map(|s| (s.label, s.property))
.collect())
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(StorageEngine::list_property_constraints(self))
}
fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
Ok(StorageEngine::outgoing(self, id)?)
}
fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
Ok(StorageEngine::incoming(self, id)?)
}
}
pub struct StorageReaderAdapter<'a>(pub &'a dyn StorageEngine);
impl GraphReader for StorageReaderAdapter<'_> {
fn get_node(&self, id: NodeId) -> Result<Option<Node>> {
Ok(self.0.get_node(id)?)
}
fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>> {
Ok(self.0.get_edge(id)?)
}
fn all_node_ids(&self) -> Result<Vec<NodeId>> {
Ok(self.0.all_node_ids()?)
}
fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>> {
Ok(self.0.nodes_by_label(label)?)
}
fn nodes_by_property(
&self,
label: &str,
property: &str,
value: &Property,
) -> Result<Vec<NodeId>> {
Ok(self.0.nodes_by_property(label, property, value)?)
}
fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
Ok(self
.0
.list_property_indexes()
.into_iter()
.map(|s| (s.label, s.property))
.collect())
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(self.0.list_property_constraints())
}
fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
Ok(self.0.outgoing(id)?)
}
fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
Ok(self.0.incoming(id)?)
}
}