use crate::error::Result;
use meshdb_core::{Edge, EdgeId, Node, NodeId};
use meshdb_storage::{
ConstraintScope, PropertyConstraintKind, PropertyConstraintSpec, StorageEngine,
};
pub type PointIndexSpec = (String, String);
pub type NodeIndexSpec = (String, Vec<String>);
pub type EdgeIndexSpec = (String, Vec<String>);
pub trait GraphWriter {
fn put_node(&self, node: &Node) -> Result<()>;
fn put_edge(&self, edge: &Edge) -> Result<()>;
fn delete_edge(&self, id: EdgeId) -> Result<()>;
fn detach_delete_node(&self, id: NodeId) -> Result<()>;
fn create_property_index(&self, _label: &str, _properties: &[String]) -> Result<()> {
Err(crate::error::Error::Unsupported(
"property-index DDL is not supported by this writer".into(),
))
}
fn drop_property_index(&self, _label: &str, _properties: &[String]) -> Result<()> {
Err(crate::error::Error::Unsupported(
"property-index DDL is not supported by this writer".into(),
))
}
fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
Ok(Vec::new())
}
fn create_edge_property_index(&self, _edge_type: &str, _properties: &[String]) -> Result<()> {
Err(crate::error::Error::Unsupported(
"edge-property-index DDL is not supported by this writer".into(),
))
}
fn drop_edge_property_index(&self, _edge_type: &str, _properties: &[String]) -> Result<()> {
Err(crate::error::Error::Unsupported(
"edge-property-index DDL is not supported by this writer".into(),
))
}
fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
Ok(Vec::new())
}
fn create_point_index(&self, _label: &str, _property: &str) -> Result<()> {
Err(crate::error::Error::Unsupported(
"point-index DDL is not supported by this writer".into(),
))
}
fn drop_point_index(&self, _label: &str, _property: &str) -> Result<()> {
Err(crate::error::Error::Unsupported(
"point-index DDL is not supported by this writer".into(),
))
}
fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(Vec::new())
}
fn create_edge_point_index(&self, _edge_type: &str, _property: &str) -> Result<()> {
Err(crate::error::Error::Unsupported(
"edge-point-index DDL is not supported by this writer".into(),
))
}
fn drop_edge_point_index(&self, _edge_type: &str, _property: &str) -> Result<()> {
Err(crate::error::Error::Unsupported(
"edge-point-index DDL is not supported by this writer".into(),
))
}
fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(Vec::new())
}
fn create_property_constraint(
&self,
_name: Option<&str>,
_scope: &ConstraintScope,
_properties: &[String],
_kind: PropertyConstraintKind,
_if_not_exists: bool,
) -> Result<PropertyConstraintSpec> {
Err(crate::error::Error::Unsupported(
"constraint DDL is not supported by this writer".into(),
))
}
fn drop_property_constraint(&self, _name: &str, _if_exists: bool) -> Result<()> {
Err(crate::error::Error::Unsupported(
"constraint DDL is not supported by this writer".into(),
))
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(Vec::new())
}
fn install_trigger(&self, _name: &str, _spec_blob: &[u8]) -> Result<()> {
Err(crate::error::Error::Unsupported(
"trigger DDL is not supported by this writer".into(),
))
}
fn drop_trigger(&self, _name: &str) -> Result<()> {
Err(crate::error::Error::Unsupported(
"trigger DDL is not supported by this writer".into(),
))
}
}
impl<T: StorageEngine> GraphWriter for T {
fn put_node(&self, node: &Node) -> Result<()> {
StorageEngine::put_node(self, node)?;
Ok(())
}
fn put_edge(&self, edge: &Edge) -> Result<()> {
StorageEngine::put_edge(self, edge)?;
Ok(())
}
fn delete_edge(&self, id: EdgeId) -> Result<()> {
if StorageEngine::get_edge(self, id)?.is_some() {
StorageEngine::delete_edge(self, id)?;
}
Ok(())
}
fn detach_delete_node(&self, id: NodeId) -> Result<()> {
StorageEngine::detach_delete_node(self, id)?;
Ok(())
}
fn create_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
StorageEngine::create_property_index_composite(self, label, properties)?;
Ok(())
}
fn drop_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
StorageEngine::drop_property_index_composite(self, label, properties)?;
Ok(())
}
fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
Ok(StorageEngine::list_property_indexes(self)
.into_iter()
.map(|s| (s.label, s.properties))
.collect())
}
fn create_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
StorageEngine::create_edge_property_index_composite(self, edge_type, properties)?;
Ok(())
}
fn drop_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
StorageEngine::drop_edge_property_index_composite(self, edge_type, properties)?;
Ok(())
}
fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
Ok(StorageEngine::list_edge_property_indexes(self)
.into_iter()
.map(|s| (s.edge_type, s.properties))
.collect())
}
fn create_point_index(&self, label: &str, property: &str) -> Result<()> {
StorageEngine::create_point_index(self, label, property)?;
Ok(())
}
fn drop_point_index(&self, label: &str, property: &str) -> Result<()> {
StorageEngine::drop_point_index(self, label, property)?;
Ok(())
}
fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(StorageEngine::list_point_indexes(self)
.into_iter()
.map(|s| (s.label, s.property))
.collect())
}
fn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
StorageEngine::create_edge_point_index(self, edge_type, property)?;
Ok(())
}
fn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
StorageEngine::drop_edge_point_index(self, edge_type, property)?;
Ok(())
}
fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(StorageEngine::list_edge_point_indexes(self)
.into_iter()
.map(|s| (s.edge_type, s.property))
.collect())
}
fn create_property_constraint(
&self,
name: Option<&str>,
scope: &ConstraintScope,
properties: &[String],
kind: PropertyConstraintKind,
if_not_exists: bool,
) -> Result<PropertyConstraintSpec> {
Ok(StorageEngine::create_property_constraint(
self,
name,
scope,
properties,
kind,
if_not_exists,
)?)
}
fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
StorageEngine::drop_property_constraint(self, name, if_exists)?;
Ok(())
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(StorageEngine::list_property_constraints(self))
}
fn install_trigger(&self, name: &str, spec_blob: &[u8]) -> Result<()> {
StorageEngine::put_trigger(self, name, spec_blob)?;
Ok(())
}
fn drop_trigger(&self, name: &str) -> Result<()> {
StorageEngine::delete_trigger(self, name)?;
Ok(())
}
}
pub struct StorageWriterAdapter<'a>(pub &'a dyn StorageEngine);
impl GraphWriter for StorageWriterAdapter<'_> {
fn put_node(&self, node: &Node) -> Result<()> {
self.0.put_node(node)?;
Ok(())
}
fn put_edge(&self, edge: &Edge) -> Result<()> {
self.0.put_edge(edge)?;
Ok(())
}
fn delete_edge(&self, id: EdgeId) -> Result<()> {
if self.0.get_edge(id)?.is_some() {
self.0.delete_edge(id)?;
}
Ok(())
}
fn detach_delete_node(&self, id: NodeId) -> Result<()> {
self.0.detach_delete_node(id)?;
Ok(())
}
fn create_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
self.0.create_property_index_composite(label, properties)?;
Ok(())
}
fn drop_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
self.0.drop_property_index_composite(label, properties)?;
Ok(())
}
fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
Ok(self
.0
.list_property_indexes()
.into_iter()
.map(|s| (s.label, s.properties))
.collect())
}
fn create_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
self.0
.create_edge_property_index_composite(edge_type, properties)?;
Ok(())
}
fn drop_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
self.0
.drop_edge_property_index_composite(edge_type, properties)?;
Ok(())
}
fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
Ok(self
.0
.list_edge_property_indexes()
.into_iter()
.map(|s| (s.edge_type, s.properties))
.collect())
}
fn create_point_index(&self, label: &str, property: &str) -> Result<()> {
self.0.create_point_index(label, property)?;
Ok(())
}
fn drop_point_index(&self, label: &str, property: &str) -> Result<()> {
self.0.drop_point_index(label, property)?;
Ok(())
}
fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(self
.0
.list_point_indexes()
.into_iter()
.map(|s| (s.label, s.property))
.collect())
}
fn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
self.0.create_edge_point_index(edge_type, property)?;
Ok(())
}
fn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
self.0.drop_edge_point_index(edge_type, property)?;
Ok(())
}
fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
Ok(self
.0
.list_edge_point_indexes()
.into_iter()
.map(|s| (s.edge_type, s.property))
.collect())
}
fn create_property_constraint(
&self,
name: Option<&str>,
scope: &ConstraintScope,
properties: &[String],
kind: PropertyConstraintKind,
if_not_exists: bool,
) -> Result<PropertyConstraintSpec> {
Ok(self
.0
.create_property_constraint(name, scope, properties, kind, if_not_exists)?)
}
fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
self.0.drop_property_constraint(name, if_exists)?;
Ok(())
}
fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
Ok(self.0.list_property_constraints())
}
fn install_trigger(&self, name: &str, spec_blob: &[u8]) -> Result<()> {
self.0.put_trigger(name, spec_blob)?;
Ok(())
}
fn drop_trigger(&self, name: &str) -> Result<()> {
self.0.delete_trigger(name)?;
Ok(())
}
}