1use crate::error::Result;
2use meshdb_core::{Edge, EdgeId, Node, NodeId};
3use meshdb_storage::{
4 ConstraintScope, PropertyConstraintKind, PropertyConstraintSpec, StorageEngine,
5};
6
7pub trait GraphWriter {
17 fn put_node(&self, node: &Node) -> Result<()>;
18 fn put_edge(&self, edge: &Edge) -> Result<()>;
19 fn delete_edge(&self, id: EdgeId) -> Result<()>;
20 fn detach_delete_node(&self, id: NodeId) -> Result<()>;
21
22 fn create_property_index(&self, _label: &str, _property: &str) -> Result<()> {
27 Err(crate::error::Error::Unsupported(
28 "property-index DDL is not supported by this writer".into(),
29 ))
30 }
31
32 fn drop_property_index(&self, _label: &str, _property: &str) -> Result<()> {
34 Err(crate::error::Error::Unsupported(
35 "property-index DDL is not supported by this writer".into(),
36 ))
37 }
38
39 fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
44 Ok(Vec::new())
45 }
46
47 fn create_property_constraint(
54 &self,
55 _name: Option<&str>,
56 _scope: &ConstraintScope,
57 _properties: &[String],
58 _kind: PropertyConstraintKind,
59 _if_not_exists: bool,
60 ) -> Result<PropertyConstraintSpec> {
61 Err(crate::error::Error::Unsupported(
62 "constraint DDL is not supported by this writer".into(),
63 ))
64 }
65
66 fn drop_property_constraint(&self, _name: &str, _if_exists: bool) -> Result<()> {
69 Err(crate::error::Error::Unsupported(
70 "constraint DDL is not supported by this writer".into(),
71 ))
72 }
73
74 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
77 Ok(Vec::new())
78 }
79}
80
81impl<T: StorageEngine> GraphWriter for T {
86 fn put_node(&self, node: &Node) -> Result<()> {
87 StorageEngine::put_node(self, node)?;
88 Ok(())
89 }
90
91 fn put_edge(&self, edge: &Edge) -> Result<()> {
92 StorageEngine::put_edge(self, edge)?;
93 Ok(())
94 }
95
96 fn delete_edge(&self, id: EdgeId) -> Result<()> {
97 if StorageEngine::get_edge(self, id)?.is_some() {
98 StorageEngine::delete_edge(self, id)?;
99 }
100 Ok(())
101 }
102
103 fn detach_delete_node(&self, id: NodeId) -> Result<()> {
104 StorageEngine::detach_delete_node(self, id)?;
105 Ok(())
106 }
107
108 fn create_property_index(&self, label: &str, property: &str) -> Result<()> {
109 StorageEngine::create_property_index(self, label, property)?;
110 Ok(())
111 }
112
113 fn drop_property_index(&self, label: &str, property: &str) -> Result<()> {
114 StorageEngine::drop_property_index(self, label, property)?;
115 Ok(())
116 }
117
118 fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
119 Ok(StorageEngine::list_property_indexes(self)
120 .into_iter()
121 .map(|s| (s.label, s.property))
122 .collect())
123 }
124
125 fn create_property_constraint(
126 &self,
127 name: Option<&str>,
128 scope: &ConstraintScope,
129 properties: &[String],
130 kind: PropertyConstraintKind,
131 if_not_exists: bool,
132 ) -> Result<PropertyConstraintSpec> {
133 Ok(StorageEngine::create_property_constraint(
134 self,
135 name,
136 scope,
137 properties,
138 kind,
139 if_not_exists,
140 )?)
141 }
142
143 fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
144 StorageEngine::drop_property_constraint(self, name, if_exists)?;
145 Ok(())
146 }
147
148 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
149 Ok(StorageEngine::list_property_constraints(self))
150 }
151}
152
153pub struct StorageWriterAdapter<'a>(pub &'a dyn StorageEngine);
156
157impl GraphWriter for StorageWriterAdapter<'_> {
158 fn put_node(&self, node: &Node) -> Result<()> {
159 self.0.put_node(node)?;
160 Ok(())
161 }
162
163 fn put_edge(&self, edge: &Edge) -> Result<()> {
164 self.0.put_edge(edge)?;
165 Ok(())
166 }
167
168 fn delete_edge(&self, id: EdgeId) -> Result<()> {
169 if self.0.get_edge(id)?.is_some() {
170 self.0.delete_edge(id)?;
171 }
172 Ok(())
173 }
174
175 fn detach_delete_node(&self, id: NodeId) -> Result<()> {
176 self.0.detach_delete_node(id)?;
177 Ok(())
178 }
179
180 fn create_property_index(&self, label: &str, property: &str) -> Result<()> {
181 self.0.create_property_index(label, property)?;
182 Ok(())
183 }
184
185 fn drop_property_index(&self, label: &str, property: &str) -> Result<()> {
186 self.0.drop_property_index(label, property)?;
187 Ok(())
188 }
189
190 fn list_property_indexes(&self) -> Result<Vec<(String, String)>> {
191 Ok(self
192 .0
193 .list_property_indexes()
194 .into_iter()
195 .map(|s| (s.label, s.property))
196 .collect())
197 }
198
199 fn create_property_constraint(
200 &self,
201 name: Option<&str>,
202 scope: &ConstraintScope,
203 properties: &[String],
204 kind: PropertyConstraintKind,
205 if_not_exists: bool,
206 ) -> Result<PropertyConstraintSpec> {
207 Ok(self
208 .0
209 .create_property_constraint(name, scope, properties, kind, if_not_exists)?)
210 }
211
212 fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
213 self.0.drop_property_constraint(name, if_exists)?;
214 Ok(())
215 }
216
217 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
218 Ok(self.0.list_property_constraints())
219 }
220}