1use std::any::Any;
11use std::collections::BTreeMap;
12
13use anyhow::{anyhow, Result};
14use lora_executor::{lora_value_to_property, LoraValue};
15use lora_store::{
16 GraphStorage, GraphStorageMut, NodeId, NodeRecord, RelationshipId, RelationshipRecord,
17};
18
19use crate::database::{values_to_properties, Database, GraphDirection};
20use crate::error::LoraError;
21
22impl<S> Database<S>
23where
24 S: GraphStorage + GraphStorageMut + Any + Clone + Send + Sync + 'static,
25{
26 pub fn graph_contains_node(&self, id: NodeId) -> bool {
29 self.with_store(|store| store.contains_node(id))
30 }
31
32 pub fn graph_node(&self, id: NodeId) -> Option<NodeRecord> {
33 self.with_store(|store| store.node(id))
34 }
35
36 pub fn graph_all_node_ids(&self) -> Vec<NodeId> {
37 self.with_store(|store| store.all_node_ids())
38 }
39
40 pub fn graph_node_ids_by_label(&self, label: &str) -> Vec<NodeId> {
41 self.with_store(|store| store.node_ids_by_label(label))
42 }
43
44 pub fn graph_all_nodes(&self) -> Vec<NodeRecord> {
45 self.with_store(|store| store.all_nodes())
46 }
47
48 pub fn graph_nodes_by_label(&self, label: &str) -> Vec<NodeRecord> {
49 self.with_store(|store| store.nodes_by_label(label))
50 }
51
52 pub fn graph_node_has_label(&self, id: NodeId, label: &str) -> bool {
53 self.with_store(|store| store.node_has_label(id, label))
54 }
55
56 pub fn graph_node_labels(&self, id: NodeId) -> Option<Vec<String>> {
57 self.with_store(|store| store.node_labels(id))
58 }
59
60 pub fn graph_node_properties(&self, id: NodeId) -> Option<BTreeMap<String, LoraValue>> {
61 self.with_store(|store| {
62 store.node_properties(id).map(|props| {
63 props
64 .into_iter()
65 .map(|(key, value)| (key, LoraValue::from(value)))
66 .collect()
67 })
68 })
69 }
70
71 pub fn graph_node_property(&self, id: NodeId, key: &str) -> Option<LoraValue> {
72 self.with_store(|store| store.node_property(id, key).map(LoraValue::from))
73 }
74
75 pub fn graph_contains_relationship(&self, id: RelationshipId) -> bool {
76 self.with_store(|store| store.contains_relationship(id))
77 }
78
79 pub fn graph_relationship(&self, id: RelationshipId) -> Option<RelationshipRecord> {
80 self.with_store(|store| store.relationship(id))
81 }
82
83 pub fn graph_all_relationship_ids(&self) -> Vec<RelationshipId> {
84 self.with_store(|store| store.all_rel_ids())
85 }
86
87 pub fn graph_relationship_ids_by_type(&self, rel_type: &str) -> Vec<RelationshipId> {
88 self.with_store(|store| store.rel_ids_by_type(rel_type))
89 }
90
91 pub fn graph_all_relationships(&self) -> Vec<RelationshipRecord> {
92 self.with_store(|store| store.all_relationships())
93 }
94
95 pub fn graph_relationships_by_type(&self, rel_type: &str) -> Vec<RelationshipRecord> {
96 self.with_store(|store| store.relationships_by_type(rel_type))
97 }
98
99 pub fn graph_relationship_endpoints(&self, id: RelationshipId) -> Option<(NodeId, NodeId)> {
100 self.with_store(|store| store.relationship_endpoints(id))
101 }
102
103 pub fn graph_relationship_type(&self, id: RelationshipId) -> Option<String> {
104 self.with_store(|store| store.relationship_type(id))
105 }
106
107 pub fn graph_relationship_properties(
108 &self,
109 id: RelationshipId,
110 ) -> Option<BTreeMap<String, LoraValue>> {
111 self.with_store(|store| {
112 store.relationship_properties(id).map(|props| {
113 props
114 .into_iter()
115 .map(|(key, value)| (key, LoraValue::from(value)))
116 .collect()
117 })
118 })
119 }
120
121 pub fn graph_relationship_property(&self, id: RelationshipId, key: &str) -> Option<LoraValue> {
122 self.with_store(|store| store.relationship_property(id, key).map(LoraValue::from))
123 }
124
125 pub fn graph_relationship_ids_of(
126 &self,
127 node_id: NodeId,
128 direction: GraphDirection,
129 ) -> Vec<RelationshipId> {
130 self.with_store(|store| store.relationship_ids_of(node_id, direction.as_store_direction()))
131 }
132
133 pub fn graph_degree(&self, node_id: NodeId, direction: GraphDirection) -> usize {
134 self.with_store(|store| store.degree(node_id, direction.as_store_direction()))
135 }
136
137 pub fn graph_neighbors(
138 &self,
139 node_id: NodeId,
140 direction: GraphDirection,
141 types: &[String],
142 ) -> Vec<NodeRecord> {
143 self.with_store(|store| store.neighbors(node_id, direction.as_store_direction(), types))
144 }
145
146 pub fn graph_expand_ids(
147 &self,
148 node_id: NodeId,
149 direction: GraphDirection,
150 types: &[String],
151 ) -> Vec<(RelationshipId, NodeId)> {
152 self.with_store(|store| store.expand_ids(node_id, direction.as_store_direction(), types))
153 }
154
155 pub fn graph_all_labels(&self) -> Vec<String> {
156 self.with_store(|store| store.all_labels())
157 }
158
159 pub fn graph_all_relationship_types(&self) -> Vec<String> {
160 self.with_store(|store| store.all_relationship_types())
161 }
162
163 pub fn graph_all_property_keys(&self) -> Vec<String> {
164 self.with_store(|store| store.all_property_keys())
165 }
166
167 pub fn graph_all_node_property_keys(&self) -> Vec<String> {
168 self.with_store(|store| store.all_node_property_keys())
169 }
170
171 pub fn graph_all_relationship_property_keys(&self) -> Vec<String> {
172 self.with_store(|store| store.all_relationship_property_keys())
173 }
174
175 pub fn graph_label_property_keys(&self, label: &str) -> Vec<String> {
176 self.with_store(|store| store.label_property_keys(label))
177 }
178
179 pub fn graph_relationship_type_property_keys(&self, rel_type: &str) -> Vec<String> {
180 self.with_store(|store| store.rel_type_property_keys(rel_type))
181 }
182
183 pub fn graph_find_node_ids_by_property(
184 &self,
185 label: Option<&str>,
186 key: &str,
187 value: LoraValue,
188 ) -> Result<Vec<NodeId>> {
189 let value = lora_value_to_property(value).map_err(|e| anyhow!(e))?;
190 Ok(self.with_store(|store| store.find_node_ids_by_property(label, key, &value)))
191 }
192
193 pub fn graph_find_relationship_ids_by_property(
194 &self,
195 rel_type: Option<&str>,
196 key: &str,
197 value: LoraValue,
198 ) -> Result<Vec<RelationshipId>> {
199 let value = lora_value_to_property(value).map_err(|e| anyhow!(e))?;
200 Ok(self.with_store(|store| store.find_relationship_ids_by_property(rel_type, key, &value)))
201 }
202
203 pub fn graph_create_node(
206 &self,
207 labels: Vec<String>,
208 properties: BTreeMap<String, LoraValue>,
209 ) -> Result<NodeRecord, LoraError> {
210 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
211 self.with_logged_store_mut(|store| Ok(store.create_node(labels, properties)))
212 .map_err(LoraError::from_anyhow)
213 }
214
215 pub fn graph_create_relationship(
216 &self,
217 src: NodeId,
218 dst: NodeId,
219 rel_type: &str,
220 properties: BTreeMap<String, LoraValue>,
221 ) -> Result<Option<RelationshipRecord>, LoraError> {
222 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
223 self.with_logged_store_mut(|store| {
224 Ok(store.create_relationship(src, dst, rel_type, properties))
225 })
226 .map_err(LoraError::from_anyhow)
227 }
228
229 pub fn graph_set_node_property(
230 &self,
231 node_id: NodeId,
232 key: String,
233 value: LoraValue,
234 ) -> Result<bool, LoraError> {
235 let value = lora_value_to_property(value).map_err(|e| anyhow!(e))?;
236 self.with_logged_store_mut(|store| Ok(store.set_node_property(node_id, key, value)))
237 .map_err(LoraError::from_anyhow)
238 }
239
240 pub fn graph_remove_node_property(
241 &self,
242 node_id: NodeId,
243 key: &str,
244 ) -> Result<bool, LoraError> {
245 self.with_logged_store_mut(|store| Ok(store.remove_node_property(node_id, key)))
246 .map_err(LoraError::from_anyhow)
247 }
248
249 pub fn graph_add_node_label(&self, node_id: NodeId, label: &str) -> Result<bool, LoraError> {
250 self.with_logged_store_mut(|store| Ok(store.add_node_label(node_id, label)))
251 .map_err(LoraError::from_anyhow)
252 }
253
254 pub fn graph_remove_node_label(&self, node_id: NodeId, label: &str) -> Result<bool, LoraError> {
255 self.with_logged_store_mut(|store| Ok(store.remove_node_label(node_id, label)))
256 .map_err(LoraError::from_anyhow)
257 }
258
259 pub fn graph_set_node_labels(
260 &self,
261 node_id: NodeId,
262 labels: Vec<String>,
263 ) -> Result<bool, LoraError> {
264 self.with_logged_store_mut(|store| Ok(store.set_node_labels(node_id, labels)))
265 .map_err(LoraError::from_anyhow)
266 }
267
268 pub fn graph_replace_node_properties(
269 &self,
270 node_id: NodeId,
271 properties: BTreeMap<String, LoraValue>,
272 ) -> Result<bool, LoraError> {
273 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
274 self.with_logged_store_mut(|store| Ok(store.replace_node_properties(node_id, properties)))
275 .map_err(LoraError::from_anyhow)
276 }
277
278 pub fn graph_merge_node_properties(
279 &self,
280 node_id: NodeId,
281 properties: BTreeMap<String, LoraValue>,
282 ) -> Result<bool, LoraError> {
283 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
284 self.with_logged_store_mut(|store| Ok(store.merge_node_properties(node_id, properties)))
285 .map_err(LoraError::from_anyhow)
286 }
287
288 pub fn graph_set_relationship_property(
289 &self,
290 rel_id: RelationshipId,
291 key: String,
292 value: LoraValue,
293 ) -> Result<bool, LoraError> {
294 let value = lora_value_to_property(value).map_err(|e| anyhow!(e))?;
295 self.with_logged_store_mut(|store| Ok(store.set_relationship_property(rel_id, key, value)))
296 .map_err(LoraError::from_anyhow)
297 }
298
299 pub fn graph_remove_relationship_property(
300 &self,
301 rel_id: RelationshipId,
302 key: &str,
303 ) -> Result<bool, LoraError> {
304 self.with_logged_store_mut(|store| Ok(store.remove_relationship_property(rel_id, key)))
305 .map_err(LoraError::from_anyhow)
306 }
307
308 pub fn graph_replace_relationship_properties(
309 &self,
310 rel_id: RelationshipId,
311 properties: BTreeMap<String, LoraValue>,
312 ) -> Result<bool, LoraError> {
313 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
314 self.with_logged_store_mut(|store| {
315 Ok(store.replace_relationship_properties(rel_id, properties))
316 })
317 .map_err(LoraError::from_anyhow)
318 }
319
320 pub fn graph_merge_relationship_properties(
321 &self,
322 rel_id: RelationshipId,
323 properties: BTreeMap<String, LoraValue>,
324 ) -> Result<bool, LoraError> {
325 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
326 self.with_logged_store_mut(|store| {
327 Ok(store.merge_relationship_properties(rel_id, properties))
328 })
329 .map_err(LoraError::from_anyhow)
330 }
331
332 pub fn graph_delete_relationship(&self, rel_id: RelationshipId) -> Result<bool, LoraError> {
333 self.with_logged_store_mut(|store| Ok(store.delete_relationship(rel_id)))
334 .map_err(LoraError::from_anyhow)
335 }
336
337 pub fn graph_delete_node(&self, node_id: NodeId) -> Result<bool, LoraError> {
338 self.with_logged_store_mut(|store| Ok(store.delete_node(node_id)))
339 .map_err(LoraError::from_anyhow)
340 }
341
342 pub fn graph_detach_delete_node(&self, node_id: NodeId) -> Result<bool, LoraError> {
343 self.with_logged_store_mut(|store| Ok(store.detach_delete_node(node_id)))
344 .map_err(LoraError::from_anyhow)
345 }
346}