1use crate::error::Result;
2use meshdb_core::{Edge, EdgeId, Node, NodeId};
3use meshdb_storage::{
4 ConstraintScope, PropertyConstraintKind, PropertyConstraintSpec, StorageEngine,
5};
6
7pub type PointIndexSpec = (String, String);
12
13pub type NodeIndexSpec = (String, Vec<String>);
19
20pub type EdgeIndexSpec = (String, Vec<String>);
23
24pub trait GraphWriter {
34 fn put_node(&self, node: &Node) -> Result<()>;
35 fn put_edge(&self, edge: &Edge) -> Result<()>;
36 fn delete_edge(&self, id: EdgeId) -> Result<()>;
37 fn detach_delete_node(&self, id: NodeId) -> Result<()>;
38
39 fn create_property_index(&self, _label: &str, _properties: &[String]) -> Result<()> {
46 Err(crate::error::Error::Unsupported(
47 "property-index DDL is not supported by this writer".into(),
48 ))
49 }
50
51 fn drop_property_index(&self, _label: &str, _properties: &[String]) -> Result<()> {
53 Err(crate::error::Error::Unsupported(
54 "property-index DDL is not supported by this writer".into(),
55 ))
56 }
57
58 fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
63 Ok(Vec::new())
64 }
65
66 fn create_edge_property_index(&self, _edge_type: &str, _properties: &[String]) -> Result<()> {
69 Err(crate::error::Error::Unsupported(
70 "edge-property-index DDL is not supported by this writer".into(),
71 ))
72 }
73
74 fn drop_edge_property_index(&self, _edge_type: &str, _properties: &[String]) -> Result<()> {
77 Err(crate::error::Error::Unsupported(
78 "edge-property-index DDL is not supported by this writer".into(),
79 ))
80 }
81
82 fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
86 Ok(Vec::new())
87 }
88
89 fn create_point_index(&self, _label: &str, _property: &str) -> Result<()> {
93 Err(crate::error::Error::Unsupported(
94 "point-index DDL is not supported by this writer".into(),
95 ))
96 }
97
98 fn drop_point_index(&self, _label: &str, _property: &str) -> Result<()> {
101 Err(crate::error::Error::Unsupported(
102 "point-index DDL is not supported by this writer".into(),
103 ))
104 }
105
106 fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
109 Ok(Vec::new())
110 }
111
112 fn create_edge_point_index(&self, _edge_type: &str, _property: &str) -> Result<()> {
115 Err(crate::error::Error::Unsupported(
116 "edge-point-index DDL is not supported by this writer".into(),
117 ))
118 }
119
120 fn drop_edge_point_index(&self, _edge_type: &str, _property: &str) -> Result<()> {
123 Err(crate::error::Error::Unsupported(
124 "edge-point-index DDL is not supported by this writer".into(),
125 ))
126 }
127
128 fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
131 Ok(Vec::new())
132 }
133
134 fn create_property_constraint(
141 &self,
142 _name: Option<&str>,
143 _scope: &ConstraintScope,
144 _properties: &[String],
145 _kind: PropertyConstraintKind,
146 _if_not_exists: bool,
147 ) -> Result<PropertyConstraintSpec> {
148 Err(crate::error::Error::Unsupported(
149 "constraint DDL is not supported by this writer".into(),
150 ))
151 }
152
153 fn drop_property_constraint(&self, _name: &str, _if_exists: bool) -> Result<()> {
156 Err(crate::error::Error::Unsupported(
157 "constraint DDL is not supported by this writer".into(),
158 ))
159 }
160
161 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
164 Ok(Vec::new())
165 }
166}
167
168impl<T: StorageEngine> GraphWriter for T {
173 fn put_node(&self, node: &Node) -> Result<()> {
174 StorageEngine::put_node(self, node)?;
175 Ok(())
176 }
177
178 fn put_edge(&self, edge: &Edge) -> Result<()> {
179 StorageEngine::put_edge(self, edge)?;
180 Ok(())
181 }
182
183 fn delete_edge(&self, id: EdgeId) -> Result<()> {
184 if StorageEngine::get_edge(self, id)?.is_some() {
185 StorageEngine::delete_edge(self, id)?;
186 }
187 Ok(())
188 }
189
190 fn detach_delete_node(&self, id: NodeId) -> Result<()> {
191 StorageEngine::detach_delete_node(self, id)?;
192 Ok(())
193 }
194
195 fn create_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
196 StorageEngine::create_property_index_composite(self, label, properties)?;
197 Ok(())
198 }
199
200 fn drop_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
201 StorageEngine::drop_property_index_composite(self, label, properties)?;
202 Ok(())
203 }
204
205 fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
206 Ok(StorageEngine::list_property_indexes(self)
207 .into_iter()
208 .map(|s| (s.label, s.properties))
209 .collect())
210 }
211
212 fn create_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
213 StorageEngine::create_edge_property_index_composite(self, edge_type, properties)?;
214 Ok(())
215 }
216
217 fn drop_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
218 StorageEngine::drop_edge_property_index_composite(self, edge_type, properties)?;
219 Ok(())
220 }
221
222 fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
223 Ok(StorageEngine::list_edge_property_indexes(self)
224 .into_iter()
225 .map(|s| (s.edge_type, s.properties))
226 .collect())
227 }
228
229 fn create_point_index(&self, label: &str, property: &str) -> Result<()> {
230 StorageEngine::create_point_index(self, label, property)?;
231 Ok(())
232 }
233
234 fn drop_point_index(&self, label: &str, property: &str) -> Result<()> {
235 StorageEngine::drop_point_index(self, label, property)?;
236 Ok(())
237 }
238
239 fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
240 Ok(StorageEngine::list_point_indexes(self)
241 .into_iter()
242 .map(|s| (s.label, s.property))
243 .collect())
244 }
245
246 fn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
247 StorageEngine::create_edge_point_index(self, edge_type, property)?;
248 Ok(())
249 }
250
251 fn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
252 StorageEngine::drop_edge_point_index(self, edge_type, property)?;
253 Ok(())
254 }
255
256 fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
257 Ok(StorageEngine::list_edge_point_indexes(self)
258 .into_iter()
259 .map(|s| (s.edge_type, s.property))
260 .collect())
261 }
262
263 fn create_property_constraint(
264 &self,
265 name: Option<&str>,
266 scope: &ConstraintScope,
267 properties: &[String],
268 kind: PropertyConstraintKind,
269 if_not_exists: bool,
270 ) -> Result<PropertyConstraintSpec> {
271 Ok(StorageEngine::create_property_constraint(
272 self,
273 name,
274 scope,
275 properties,
276 kind,
277 if_not_exists,
278 )?)
279 }
280
281 fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
282 StorageEngine::drop_property_constraint(self, name, if_exists)?;
283 Ok(())
284 }
285
286 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
287 Ok(StorageEngine::list_property_constraints(self))
288 }
289}
290
291pub struct StorageWriterAdapter<'a>(pub &'a dyn StorageEngine);
294
295impl GraphWriter for StorageWriterAdapter<'_> {
296 fn put_node(&self, node: &Node) -> Result<()> {
297 self.0.put_node(node)?;
298 Ok(())
299 }
300
301 fn put_edge(&self, edge: &Edge) -> Result<()> {
302 self.0.put_edge(edge)?;
303 Ok(())
304 }
305
306 fn delete_edge(&self, id: EdgeId) -> Result<()> {
307 if self.0.get_edge(id)?.is_some() {
308 self.0.delete_edge(id)?;
309 }
310 Ok(())
311 }
312
313 fn detach_delete_node(&self, id: NodeId) -> Result<()> {
314 self.0.detach_delete_node(id)?;
315 Ok(())
316 }
317
318 fn create_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
319 self.0.create_property_index_composite(label, properties)?;
320 Ok(())
321 }
322
323 fn drop_property_index(&self, label: &str, properties: &[String]) -> Result<()> {
324 self.0.drop_property_index_composite(label, properties)?;
325 Ok(())
326 }
327
328 fn list_property_indexes(&self) -> Result<Vec<NodeIndexSpec>> {
329 Ok(self
330 .0
331 .list_property_indexes()
332 .into_iter()
333 .map(|s| (s.label, s.properties))
334 .collect())
335 }
336
337 fn create_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
338 self.0
339 .create_edge_property_index_composite(edge_type, properties)?;
340 Ok(())
341 }
342
343 fn drop_edge_property_index(&self, edge_type: &str, properties: &[String]) -> Result<()> {
344 self.0
345 .drop_edge_property_index_composite(edge_type, properties)?;
346 Ok(())
347 }
348
349 fn list_edge_property_indexes(&self) -> Result<Vec<EdgeIndexSpec>> {
350 Ok(self
351 .0
352 .list_edge_property_indexes()
353 .into_iter()
354 .map(|s| (s.edge_type, s.properties))
355 .collect())
356 }
357
358 fn create_point_index(&self, label: &str, property: &str) -> Result<()> {
359 self.0.create_point_index(label, property)?;
360 Ok(())
361 }
362
363 fn drop_point_index(&self, label: &str, property: &str) -> Result<()> {
364 self.0.drop_point_index(label, property)?;
365 Ok(())
366 }
367
368 fn list_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
369 Ok(self
370 .0
371 .list_point_indexes()
372 .into_iter()
373 .map(|s| (s.label, s.property))
374 .collect())
375 }
376
377 fn create_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
378 self.0.create_edge_point_index(edge_type, property)?;
379 Ok(())
380 }
381
382 fn drop_edge_point_index(&self, edge_type: &str, property: &str) -> Result<()> {
383 self.0.drop_edge_point_index(edge_type, property)?;
384 Ok(())
385 }
386
387 fn list_edge_point_indexes(&self) -> Result<Vec<PointIndexSpec>> {
388 Ok(self
389 .0
390 .list_edge_point_indexes()
391 .into_iter()
392 .map(|s| (s.edge_type, s.property))
393 .collect())
394 }
395
396 fn create_property_constraint(
397 &self,
398 name: Option<&str>,
399 scope: &ConstraintScope,
400 properties: &[String],
401 kind: PropertyConstraintKind,
402 if_not_exists: bool,
403 ) -> Result<PropertyConstraintSpec> {
404 Ok(self
405 .0
406 .create_property_constraint(name, scope, properties, kind, if_not_exists)?)
407 }
408
409 fn drop_property_constraint(&self, name: &str, if_exists: bool) -> Result<()> {
410 self.0.drop_property_constraint(name, if_exists)?;
411 Ok(())
412 }
413
414 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
415 Ok(self.0.list_property_constraints())
416 }
417}