1use crate::error::Result;
2use meshdb_core::{Edge, EdgeId, Node, NodeId, Property};
3use meshdb_storage::{PropertyConstraintSpec, StorageEngine};
4
5pub trait GraphReader: Send + Sync {
17 fn get_node(&self, id: NodeId) -> Result<Option<Node>>;
18 fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>>;
19 fn all_node_ids(&self) -> Result<Vec<NodeId>>;
20 fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>>;
21 fn nodes_by_property(
29 &self,
30 label: &str,
31 property: &str,
32 value: &Property,
33 ) -> Result<Vec<NodeId>>;
34 fn nodes_by_properties(
43 &self,
44 label: &str,
45 properties: &[String],
46 values: &[Property],
47 ) -> Result<Vec<NodeId>> {
48 if properties.len() == 1 && values.len() == 1 {
49 return self.nodes_by_property(label, &properties[0], &values[0]);
50 }
51 Ok(Vec::new())
52 }
53 fn edges_by_property(
61 &self,
62 _edge_type: &str,
63 _property: &str,
64 _value: &Property,
65 ) -> Result<Vec<EdgeId>> {
66 Ok(Vec::new())
67 }
68 fn list_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
74 Ok(Vec::new())
75 }
76 fn list_edge_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
81 Ok(Vec::new())
82 }
83 fn list_point_indexes(&self) -> Result<Vec<(String, String)>> {
88 Ok(Vec::new())
89 }
90 fn list_edge_point_indexes(&self) -> Result<Vec<(String, String)>> {
93 Ok(Vec::new())
94 }
95 fn nodes_in_bbox(
108 &self,
109 label: &str,
110 property: &str,
111 srid: i32,
112 xlo: f64,
113 ylo: f64,
114 xhi: f64,
115 yhi: f64,
116 ) -> Result<Vec<NodeId>> {
117 let (lox, hix) = if xlo <= xhi { (xlo, xhi) } else { (xhi, xlo) };
118 let (loy, hiy) = if ylo <= yhi { (ylo, yhi) } else { (yhi, ylo) };
119 let mut result: Vec<NodeId> = Vec::new();
120 for id in self.nodes_by_label(label)? {
121 let Some(node) = self.get_node(id)? else {
122 continue;
123 };
124 if let Some(Property::Point(p)) = node.properties.get(property) {
125 if p.srid == srid && p.x >= lox && p.x <= hix && p.y >= loy && p.y <= hiy {
126 result.push(id);
127 }
128 }
129 }
130 Ok(result)
131 }
132 fn edges_in_bbox(
140 &self,
141 _edge_type: &str,
142 _property: &str,
143 _srid: i32,
144 _xlo: f64,
145 _ylo: f64,
146 _xhi: f64,
147 _yhi: f64,
148 ) -> Result<Vec<EdgeId>> {
149 Ok(Vec::new())
150 }
151 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
155 Ok(Vec::new())
156 }
157 fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
158 fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>>;
159}
160
161impl<T: StorageEngine> GraphReader for T {
173 fn get_node(&self, id: NodeId) -> Result<Option<Node>> {
174 Ok(StorageEngine::get_node(self, id)?)
175 }
176
177 fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>> {
178 Ok(StorageEngine::get_edge(self, id)?)
179 }
180
181 fn all_node_ids(&self) -> Result<Vec<NodeId>> {
182 Ok(StorageEngine::all_node_ids(self)?)
183 }
184
185 fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>> {
186 Ok(StorageEngine::nodes_by_label(self, label)?)
187 }
188
189 fn nodes_by_property(
190 &self,
191 label: &str,
192 property: &str,
193 value: &Property,
194 ) -> Result<Vec<NodeId>> {
195 Ok(StorageEngine::nodes_by_property(
196 self, label, property, value,
197 )?)
198 }
199
200 fn nodes_by_properties(
201 &self,
202 label: &str,
203 properties: &[String],
204 values: &[Property],
205 ) -> Result<Vec<NodeId>> {
206 Ok(StorageEngine::nodes_by_properties(
207 self, label, properties, values,
208 )?)
209 }
210
211 fn edges_by_property(
212 &self,
213 edge_type: &str,
214 property: &str,
215 value: &Property,
216 ) -> Result<Vec<EdgeId>> {
217 Ok(StorageEngine::edges_by_property(
218 self, edge_type, property, value,
219 )?)
220 }
221
222 fn list_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
223 Ok(StorageEngine::list_property_indexes(self)
224 .into_iter()
225 .map(|s| (s.label, s.properties))
226 .collect())
227 }
228
229 fn list_edge_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
230 Ok(StorageEngine::list_edge_property_indexes(self)
231 .into_iter()
232 .map(|s| (s.edge_type, s.properties))
233 .collect())
234 }
235
236 fn list_point_indexes(&self) -> Result<Vec<(String, String)>> {
237 Ok(StorageEngine::list_point_indexes(self)
238 .into_iter()
239 .map(|s| (s.label, s.property))
240 .collect())
241 }
242
243 fn list_edge_point_indexes(&self) -> Result<Vec<(String, String)>> {
244 Ok(StorageEngine::list_edge_point_indexes(self)
245 .into_iter()
246 .map(|s| (s.edge_type, s.property))
247 .collect())
248 }
249
250 fn nodes_in_bbox(
251 &self,
252 label: &str,
253 property: &str,
254 srid: i32,
255 xlo: f64,
256 ylo: f64,
257 xhi: f64,
258 yhi: f64,
259 ) -> Result<Vec<NodeId>> {
260 Ok(StorageEngine::nodes_in_bbox(
263 self, label, property, srid, xlo, ylo, xhi, yhi,
264 )?)
265 }
266
267 fn edges_in_bbox(
268 &self,
269 edge_type: &str,
270 property: &str,
271 srid: i32,
272 xlo: f64,
273 ylo: f64,
274 xhi: f64,
275 yhi: f64,
276 ) -> Result<Vec<EdgeId>> {
277 Ok(StorageEngine::edges_in_bbox(
278 self, edge_type, property, srid, xlo, ylo, xhi, yhi,
279 )?)
280 }
281
282 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
283 Ok(StorageEngine::list_property_constraints(self))
284 }
285
286 fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
287 Ok(StorageEngine::outgoing(self, id)?)
288 }
289
290 fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
291 Ok(StorageEngine::incoming(self, id)?)
292 }
293}
294
295pub struct StorageReaderAdapter<'a>(pub &'a dyn StorageEngine);
301
302impl GraphReader for StorageReaderAdapter<'_> {
303 fn get_node(&self, id: NodeId) -> Result<Option<Node>> {
304 Ok(self.0.get_node(id)?)
305 }
306
307 fn get_edge(&self, id: EdgeId) -> Result<Option<Edge>> {
308 Ok(self.0.get_edge(id)?)
309 }
310
311 fn all_node_ids(&self) -> Result<Vec<NodeId>> {
312 Ok(self.0.all_node_ids()?)
313 }
314
315 fn nodes_by_label(&self, label: &str) -> Result<Vec<NodeId>> {
316 Ok(self.0.nodes_by_label(label)?)
317 }
318
319 fn nodes_by_property(
320 &self,
321 label: &str,
322 property: &str,
323 value: &Property,
324 ) -> Result<Vec<NodeId>> {
325 Ok(self.0.nodes_by_property(label, property, value)?)
326 }
327
328 fn edges_by_property(
329 &self,
330 edge_type: &str,
331 property: &str,
332 value: &Property,
333 ) -> Result<Vec<EdgeId>> {
334 Ok(self.0.edges_by_property(edge_type, property, value)?)
335 }
336
337 fn list_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
338 Ok(self
339 .0
340 .list_property_indexes()
341 .into_iter()
342 .map(|s| (s.label, s.properties))
343 .collect())
344 }
345
346 fn list_edge_property_indexes(&self) -> Result<Vec<(String, Vec<String>)>> {
347 Ok(self
348 .0
349 .list_edge_property_indexes()
350 .into_iter()
351 .map(|s| (s.edge_type, s.properties))
352 .collect())
353 }
354
355 fn list_point_indexes(&self) -> Result<Vec<(String, String)>> {
356 Ok(self
357 .0
358 .list_point_indexes()
359 .into_iter()
360 .map(|s| (s.label, s.property))
361 .collect())
362 }
363
364 fn list_edge_point_indexes(&self) -> Result<Vec<(String, String)>> {
365 Ok(self
366 .0
367 .list_edge_point_indexes()
368 .into_iter()
369 .map(|s| (s.edge_type, s.property))
370 .collect())
371 }
372
373 fn nodes_in_bbox(
374 &self,
375 label: &str,
376 property: &str,
377 srid: i32,
378 xlo: f64,
379 ylo: f64,
380 xhi: f64,
381 yhi: f64,
382 ) -> Result<Vec<NodeId>> {
383 Ok(self
384 .0
385 .nodes_in_bbox(label, property, srid, xlo, ylo, xhi, yhi)?)
386 }
387
388 fn edges_in_bbox(
389 &self,
390 edge_type: &str,
391 property: &str,
392 srid: i32,
393 xlo: f64,
394 ylo: f64,
395 xhi: f64,
396 yhi: f64,
397 ) -> Result<Vec<EdgeId>> {
398 Ok(self
399 .0
400 .edges_in_bbox(edge_type, property, srid, xlo, ylo, xhi, yhi)?)
401 }
402
403 fn list_property_constraints(&self) -> Result<Vec<PropertyConstraintSpec>> {
404 Ok(self.0.list_property_constraints())
405 }
406
407 fn outgoing(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
408 Ok(self.0.outgoing(id)?)
409 }
410
411 fn incoming(&self, id: NodeId) -> Result<Vec<(EdgeId, NodeId)>> {
412 Ok(self.0.incoming(id)?)
413 }
414}