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.to_string(), 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.to_string(), 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(anyhow::Error::from)?;
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(anyhow::Error::from)?;
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| {
212 store
213 .try_create_node(labels, properties)
214 .ok_or_else(|| anyhow!("failed to create node because storage is exhausted"))
215 })
216 .map_err(LoraError::from_anyhow)
217 }
218
219 pub fn graph_create_relationship(
220 &self,
221 src: NodeId,
222 dst: NodeId,
223 rel_type: &str,
224 properties: BTreeMap<String, LoraValue>,
225 ) -> Result<Option<RelationshipRecord>, LoraError> {
226 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
227 self.with_logged_store_mut(|store| {
228 Ok(store.create_relationship(src, dst, rel_type, properties))
229 })
230 .map_err(LoraError::from_anyhow)
231 }
232
233 pub fn graph_set_node_property(
234 &self,
235 node_id: NodeId,
236 key: String,
237 value: LoraValue,
238 ) -> Result<bool, LoraError> {
239 let value = lora_value_to_property(value).map_err(anyhow::Error::from)?;
240 self.with_logged_store_mut(|store| Ok(store.set_node_property(node_id, key, value)))
241 .map_err(LoraError::from_anyhow)
242 }
243
244 pub fn graph_remove_node_property(
245 &self,
246 node_id: NodeId,
247 key: &str,
248 ) -> Result<bool, LoraError> {
249 self.with_logged_store_mut(|store| Ok(store.remove_node_property(node_id, key)))
250 .map_err(LoraError::from_anyhow)
251 }
252
253 pub fn graph_add_node_label(&self, node_id: NodeId, label: &str) -> Result<bool, LoraError> {
254 self.with_logged_store_mut(|store| Ok(store.add_node_label(node_id, label)))
255 .map_err(LoraError::from_anyhow)
256 }
257
258 pub fn graph_remove_node_label(&self, node_id: NodeId, label: &str) -> Result<bool, LoraError> {
259 self.with_logged_store_mut(|store| Ok(store.remove_node_label(node_id, label)))
260 .map_err(LoraError::from_anyhow)
261 }
262
263 pub fn graph_set_node_labels(
264 &self,
265 node_id: NodeId,
266 labels: Vec<String>,
267 ) -> Result<bool, LoraError> {
268 self.with_logged_store_mut(|store| Ok(store.set_node_labels(node_id, labels)))
269 .map_err(LoraError::from_anyhow)
270 }
271
272 pub fn graph_replace_node_properties(
273 &self,
274 node_id: NodeId,
275 properties: BTreeMap<String, LoraValue>,
276 ) -> Result<bool, LoraError> {
277 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
278 self.with_logged_store_mut(|store| Ok(store.replace_node_properties(node_id, properties)))
279 .map_err(LoraError::from_anyhow)
280 }
281
282 pub fn graph_merge_node_properties(
283 &self,
284 node_id: NodeId,
285 properties: BTreeMap<String, LoraValue>,
286 ) -> Result<bool, LoraError> {
287 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
288 self.with_logged_store_mut(|store| Ok(store.merge_node_properties(node_id, properties)))
289 .map_err(LoraError::from_anyhow)
290 }
291
292 pub fn graph_set_relationship_property(
293 &self,
294 rel_id: RelationshipId,
295 key: String,
296 value: LoraValue,
297 ) -> Result<bool, LoraError> {
298 let value = lora_value_to_property(value).map_err(anyhow::Error::from)?;
299 self.with_logged_store_mut(|store| Ok(store.set_relationship_property(rel_id, key, value)))
300 .map_err(LoraError::from_anyhow)
301 }
302
303 pub fn graph_remove_relationship_property(
304 &self,
305 rel_id: RelationshipId,
306 key: &str,
307 ) -> Result<bool, LoraError> {
308 self.with_logged_store_mut(|store| Ok(store.remove_relationship_property(rel_id, key)))
309 .map_err(LoraError::from_anyhow)
310 }
311
312 pub fn graph_replace_relationship_properties(
313 &self,
314 rel_id: RelationshipId,
315 properties: BTreeMap<String, LoraValue>,
316 ) -> Result<bool, LoraError> {
317 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
318 self.with_logged_store_mut(|store| {
319 Ok(store.replace_relationship_properties(rel_id, properties))
320 })
321 .map_err(LoraError::from_anyhow)
322 }
323
324 pub fn graph_merge_relationship_properties(
325 &self,
326 rel_id: RelationshipId,
327 properties: BTreeMap<String, LoraValue>,
328 ) -> Result<bool, LoraError> {
329 let properties = values_to_properties(properties).map_err(LoraError::from_anyhow)?;
330 self.with_logged_store_mut(|store| {
331 Ok(store.merge_relationship_properties(rel_id, properties))
332 })
333 .map_err(LoraError::from_anyhow)
334 }
335
336 pub fn graph_delete_relationship(&self, rel_id: RelationshipId) -> Result<bool, LoraError> {
337 self.with_logged_store_mut(|store| Ok(store.delete_relationship(rel_id)))
338 .map_err(LoraError::from_anyhow)
339 }
340
341 pub fn graph_delete_node(&self, node_id: NodeId) -> Result<bool, LoraError> {
342 self.with_logged_store_mut(|store| Ok(store.delete_node(node_id)))
343 .map_err(LoraError::from_anyhow)
344 }
345
346 pub fn graph_detach_delete_node(&self, node_id: NodeId) -> Result<bool, LoraError> {
347 self.with_logged_store_mut(|store| Ok(store.detach_delete_node(node_id)))
348 .map_err(LoraError::from_anyhow)
349 }
350}