gqlite 1.2.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +20 -0
  3. data/ext/gqlitedb/Cargo.toml +77 -0
  4. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
  5. data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
  6. data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
  7. data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
  8. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +10 -9
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +6 -4
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +27 -31
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +37 -41
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/connection.rs +42 -84
  16. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +105 -34
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +2 -2
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +2 -2
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +1 -1
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/path.rs +15 -20
  22. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +2 -2
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +6 -6
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +20 -20
  25. data/ext/gqlitedb/src/graph.rs +11 -0
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +160 -194
  27. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +2 -1
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -4
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +44 -52
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +1 -1
  31. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +50 -28
  32. data/ext/gqlitedb/src/parser.rs +4 -0
  33. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  34. data/ext/gqlitedb/src/query_result.rs +88 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +226 -148
  36. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +111 -128
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +22 -22
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +32 -76
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +95 -111
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  44. data/ext/gqlitedb/src/value.rs +225 -0
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +15 -5
  46. data/ext/gqliterb/Cargo.toml +12 -35
  47. data/ext/gqliterb/src/lib.rs +60 -38
  48. data/ext/graphcore/Cargo.toml +19 -0
  49. data/ext/graphcore/README.MD +4 -0
  50. data/ext/graphcore/release.toml +1 -0
  51. data/ext/graphcore/src/error.rs +28 -0
  52. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +134 -38
  53. data/ext/graphcore/src/lib.rs +16 -0
  54. data/ext/graphcore/src/prelude.rs +4 -0
  55. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  56. data/ext/graphcore/src/table.rs +272 -0
  57. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  58. data/ext/graphcore/src/value.rs +413 -0
  59. metadata +94 -83
  60. data/ext/gqliterb/.cargo/config.toml +0 -2
  61. data/ext/gqliterb/Cargo.lock +0 -1116
  62. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2115
  63. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -138
  64. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  65. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -609
  66. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  67. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  68. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  69. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  70. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +0 -0
  71. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -1,5 +1,5 @@
1
1
  use ccutils::sync::ArcRwLock;
2
- use redb::{ReadableTable, ReadableTableMetadata};
2
+ use redb::{DatabaseError, ReadableDatabase as _, ReadableTable, ReadableTableMetadata as _};
3
3
  use serde::{Deserialize, Serialize};
4
4
  use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
5
5
 
@@ -16,9 +16,9 @@ use crate::{prelude::*, store::TransactionBoxable};
16
16
  #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
17
17
  struct PersistentEdge
18
18
  {
19
- pub key: graph::Key,
20
- pub source: graph::Key,
21
- pub destination: graph::Key,
19
+ pub key: PersistentKey,
20
+ pub source: PersistentKey,
21
+ pub destination: PersistentKey,
22
22
  pub labels: Vec<String>,
23
23
  pub properties: value::ValueMap,
24
24
  }
@@ -51,23 +51,54 @@ impl redb::Value for PersistentEdge
51
51
  }
52
52
  }
53
53
 
54
- impl redb::Value for graph::Node
54
+ #[derive(Debug)]
55
+ enum PersistentNode<'a>
55
56
  {
56
- type AsBytes<'a> = Vec<u8>;
57
- type SelfType<'a> = graph::Node;
57
+ Reference(&'a graph::Node),
58
+ Value(graph::Node),
59
+ }
60
+
61
+ impl<'a> From<PersistentNode<'a>> for graph::Node
62
+ {
63
+ fn from(value: PersistentNode<'a>) -> Self
64
+ {
65
+ match value
66
+ {
67
+ PersistentNode::Reference(refe) => refe.to_owned(),
68
+ PersistentNode::Value(val) => val,
69
+ }
70
+ }
71
+ }
72
+
73
+ // ccutils::alias!(PersistentNode, graph::Node, derive: Debug, Deserialize, Serialize, Clone);
74
+
75
+ impl<'c> redb::Value for PersistentNode<'c>
76
+ {
77
+ type AsBytes<'a>
78
+ = Vec<u8>
79
+ where
80
+ Self: 'a;
81
+ type SelfType<'a>
82
+ = PersistentNode<'a>
83
+ where
84
+ Self: 'a;
58
85
  fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
59
86
  where
60
87
  Self: 'b,
61
88
  {
62
89
  let mut data = Vec::<u8>::new();
63
- ciborium::into_writer(value, &mut data).unwrap(); // This unwrap should not happen, unless there is a bug
90
+ match value
91
+ {
92
+ PersistentNode::Reference(refe) => ciborium::into_writer(refe, &mut data).unwrap(), // This unwrap should not happen, unless there is a bug
93
+ PersistentNode::Value(refe) => ciborium::into_writer(&refe, &mut data).unwrap(), // This unwrap should not happen, unless there is a bug
94
+ }
64
95
  data
65
96
  }
66
97
  fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
67
98
  where
68
99
  Self: 'a,
69
100
  {
70
- ciborium::from_reader(data).unwrap() // This unwrap should not happen, unless there is a bug
101
+ PersistentNode::Value(ciborium::from_reader(data).unwrap()) // This unwrap should not happen, unless there is a bug
71
102
  }
72
103
  fn fixed_width() -> Option<usize>
73
104
  {
@@ -79,15 +110,25 @@ impl redb::Value for graph::Node
79
110
  }
80
111
  }
81
112
 
82
- impl redb::Value for graph::Key
113
+ ccutils::alias!(PersistentKey, graph::Key, derive: Debug, Deserialize, Serialize, PartialEq, Clone);
114
+
115
+ impl PersistentKey
116
+ {
117
+ fn to_owned_key(&self) -> graph::Key
118
+ {
119
+ *self.clone()
120
+ }
121
+ }
122
+
123
+ impl redb::Value for PersistentKey
83
124
  {
84
125
  type AsBytes<'a> = <u128 as redb::Value>::AsBytes<'a>;
85
- type SelfType<'a> = graph::Key;
126
+ type SelfType<'a> = PersistentKey;
86
127
  fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
87
128
  where
88
129
  Self: 'b,
89
130
  {
90
- u128::as_bytes(&value.uuid)
131
+ u128::as_bytes(&value.uuid())
91
132
  }
92
133
  fn fixed_width() -> Option<usize>
93
134
  {
@@ -97,9 +138,7 @@ impl redb::Value for graph::Key
97
138
  where
98
139
  Self: 'a,
99
140
  {
100
- graph::Key {
101
- uuid: u128::from_bytes(data),
102
- }
141
+ PersistentKey(graph::Key::new(u128::from_bytes(data)))
103
142
  }
104
143
  fn type_name() -> redb::TypeName
105
144
  {
@@ -107,7 +146,7 @@ impl redb::Value for graph::Key
107
146
  }
108
147
  }
109
148
 
110
- impl redb::Key for graph::Key
149
+ impl redb::Key for PersistentKey
111
150
  {
112
151
  fn compare(data1: &[u8], data2: &[u8]) -> std::cmp::Ordering
113
152
  {
@@ -147,10 +186,10 @@ impl EdgeIdResult
147
186
  Some(v) => v,
148
187
  None => match self.source_id
149
188
  {
150
- Some(v) => self.edge_data.destination == v,
189
+ Some(v) => *self.edge_data.destination == v,
151
190
  None => match self.destination_id
152
191
  {
153
- Some(v) => self.edge_data.source == v,
192
+ Some(v) => *self.edge_data.source == v,
154
193
  None => panic!("is_reversed"),
155
194
  },
156
195
  },
@@ -176,7 +215,7 @@ where
176
215
  ) -> Result<redb::AccessGuard<'_, V>>;
177
216
  }
178
217
 
179
- impl<'txn, K, V, T> TableExtension<K, V> for T
218
+ impl<K, V, T> TableExtension<K, V> for T
180
219
  where
181
220
  T: ReadableTable<K, V>,
182
221
  K: redb::Key + 'static,
@@ -228,23 +267,27 @@ impl GraphInfo
228
267
  edges_destination_index,
229
268
  }
230
269
  }
231
- fn nodes_table_definition<'a>(&'a self) -> redb::TableDefinition<'a, graph::Key, graph::Node>
270
+ fn nodes_table_definition<'a, 'b>(
271
+ &'a self,
272
+ ) -> redb::TableDefinition<'a, PersistentKey, PersistentNode<'b>>
232
273
  {
233
274
  redb::TableDefinition::new(&self.nodes_table)
234
275
  }
235
- fn edges_table_definition<'a>(&'a self) -> redb::TableDefinition<'a, graph::Key, PersistentEdge>
276
+ fn edges_table_definition<'a>(
277
+ &'a self,
278
+ ) -> redb::TableDefinition<'a, PersistentKey, PersistentEdge>
236
279
  {
237
280
  redb::TableDefinition::new(&self.edges_table)
238
281
  }
239
282
  fn edges_source_index_definition<'a>(
240
283
  &'a self,
241
- ) -> redb::TableDefinition<'a, graph::Key, Vec<graph::Key>>
284
+ ) -> redb::TableDefinition<'a, PersistentKey, Vec<PersistentKey>>
242
285
  {
243
286
  redb::TableDefinition::new(&self.edges_source_index)
244
287
  }
245
288
  fn edges_destination_index_definition<'a>(
246
289
  &'a self,
247
- ) -> redb::TableDefinition<'a, graph::Key, Vec<graph::Key>>
290
+ ) -> redb::TableDefinition<'a, PersistentKey, Vec<PersistentKey>>
248
291
  {
249
292
  redb::TableDefinition::new(&self.edges_destination_index)
250
293
  }
@@ -302,8 +345,34 @@ impl Store
302
345
  /// Crate a new store, with a default graph
303
346
  pub(crate) fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Store>
304
347
  {
348
+ let redb_store = redb::Database::create(path.as_ref());
349
+ let redb_store = match redb_store
350
+ {
351
+ Ok(redb_store) => redb_store,
352
+ Err(e) => match e
353
+ {
354
+ DatabaseError::UpgradeRequired(v) =>
355
+ {
356
+ if v == 2
357
+ {
358
+ std::fs::copy(path.as_ref(), path.as_ref().with_extension("redb2.bak"))
359
+ .map_err(InternalError::IOError)?;
360
+ redb2::Database::create(path.as_ref())?.upgrade()?;
361
+ redb::Database::create(path.as_ref())?
362
+ }
363
+ else
364
+ {
365
+ Err(StoreError::InvalidFormat(format!(
366
+ "Unsupported redb version {}.",
367
+ v
368
+ )))?
369
+ }
370
+ }
371
+ o => Err(o)?,
372
+ },
373
+ };
305
374
  let s = Self {
306
- redb_store: redb::Database::create(path.as_ref())?,
375
+ redb_store,
307
376
  graphs: Default::default(),
308
377
  };
309
378
  s.initialise()?;
@@ -324,7 +393,7 @@ impl Store
324
393
  {
325
394
  use crate::store::Store;
326
395
  let mut tx = self.begin_write()?;
327
- self.create_graph(&mut tx, &"default".to_string(), true)?;
396
+ self.create_graph(&mut tx, "default", true)?;
328
397
  self.set_metadata_value(&mut tx, "version", &consts::GQLITE_VERSION)?;
329
398
  tx.close()?;
330
399
  Ok(())
@@ -342,7 +411,7 @@ impl Store
342
411
  let key = key.into();
343
412
  let value = table
344
413
  .get(&key)?
345
- .ok_or_else(|| InternalError::MissingMetadata { key: key })?;
414
+ .ok_or_else(|| InternalError::MissingMetadata { key })?;
346
415
  Ok(ciborium::from_reader(value.value().as_slice())?)
347
416
  }
348
417
  #[allow(dead_code)]
@@ -419,8 +488,9 @@ impl Store
419
488
  metadata_table.insert(&key, data)?;
420
489
  Ok(())
421
490
  }
422
- fn get_graph_info(&self, graph_name: &String) -> Result<Arc<GraphInfo>>
491
+ fn get_graph_info(&self, graph_name: impl AsRef<str>) -> Result<Arc<GraphInfo>>
423
492
  {
493
+ let graph_name = graph_name.as_ref();
424
494
  let graphs = self.graphs.read()?;
425
495
  let graph_info = graphs.get(graph_name);
426
496
  match graph_info
@@ -429,7 +499,7 @@ impl Store
429
499
  None =>
430
500
  {
431
501
  drop(graphs);
432
- let graph_info = Arc::new(GraphInfo::new(graph_name));
502
+ let graph_info = Arc::new(GraphInfo::new(graph_name.to_owned()));
433
503
  self
434
504
  .graphs
435
505
  .write()?
@@ -438,31 +508,32 @@ impl Store
438
508
  }
439
509
  }
440
510
  }
441
- fn select_nodes_from_table<'txn, T>(
511
+ fn select_nodes_from_table<T>(
442
512
  &self,
443
- nodes_table: &'txn T,
444
- query: super::SelectNodeQuery,
513
+ nodes_table: &T,
514
+ query: &super::SelectNodeQuery,
445
515
  ) -> Result<Vec<crate::graph::Node>>
446
516
  where
447
- T: ReadableTable<graph::Key, graph::Node>,
517
+ T: ReadableTable<PersistentKey, PersistentNode<'static>>,
448
518
  {
449
- let r = match query.keys
519
+ let r = match &query.keys
450
520
  {
451
- Some(keys) => Box::new(keys.into_iter().map(|key| {
521
+ Some(keys) => Box::new(keys.iter().map(|key| {
452
522
  Ok(
453
523
  nodes_table
454
- .get_required(key, || InternalError::UnknownNode)?
455
- .value(),
524
+ .get_required(PersistentKey(key.to_owned()), || InternalError::UnknownNode)?
525
+ .value()
526
+ .into(),
456
527
  )
457
528
  })) as Box<dyn Iterator<Item = Result<graph::Node>>>,
458
529
  None => Box::new({
459
- nodes_table.range::<graph::Key>(..)?.into_iter().map(|r| {
530
+ nodes_table.range::<PersistentKey>(..)?.map(|r| {
460
531
  let (_, v) = r?;
461
- Ok(v.value())
532
+ Ok(v.value().into())
462
533
  })
463
534
  }) as Box<dyn Iterator<Item = Result<graph::Node>>>,
464
535
  };
465
- let r = match query.labels
536
+ let r = match &query.labels
466
537
  {
467
538
  Some(labels) => Box::new(r.filter(move |n| match n
468
539
  {
@@ -470,7 +541,7 @@ impl Store
470
541
  {
471
542
  for l in labels.iter()
472
543
  {
473
- if !n.labels.contains(l)
544
+ if !n.labels().contains(l)
474
545
  {
475
546
  return false;
476
547
  }
@@ -481,7 +552,7 @@ impl Store
481
552
  })) as Box<dyn Iterator<Item = Result<crate::graph::Node>>>,
482
553
  None => Box::new(r) as Box<dyn Iterator<Item = Result<crate::graph::Node>>>,
483
554
  };
484
- let r = match query.properties
555
+ let r = match &query.properties
485
556
  {
486
557
  Some(properties) => Box::new(r.filter(move |n| match n
487
558
  {
@@ -489,7 +560,7 @@ impl Store
489
560
  {
490
561
  for (k, v) in properties.iter()
491
562
  {
492
- match n.properties.get(k)
563
+ match n.properties().get(k)
493
564
  {
494
565
  Some(val) =>
495
566
  {
@@ -523,9 +594,9 @@ impl Store
523
594
  edges_destination_index: Rc<RefCell<TEdgesIndex>>,
524
595
  ) -> Result<Vec<super::EdgeResult>>
525
596
  where
526
- TEdges: ReadableTable<graph::Key, PersistentEdge>,
527
- TNodes: ReadableTable<graph::Key, graph::Node>,
528
- TEdgesIndex: ReadableTable<graph::Key, Vec<graph::Key>>,
597
+ TEdges: ReadableTable<PersistentKey, PersistentEdge>,
598
+ TNodes: ReadableTable<PersistentKey, PersistentNode<'static>>,
599
+ TEdgesIndex: ReadableTable<PersistentKey, Vec<PersistentKey>>,
529
600
  {
530
601
  let edges_uuid_indices = match directivity
531
602
  {
@@ -543,12 +614,11 @@ impl Store
543
614
  {
544
615
  Some(keys) =>
545
616
  {
546
- for key in keys.into_iter()
617
+ for key in keys.iter()
547
618
  {
548
619
  edges_raw.push(EdgeIdResult::new(
549
620
  edges_table
550
- .get(key)?
551
- .ok_or_else(|| InternalError::UnknownNode)?
621
+ .get_required(PersistentKey(key.to_owned()), || InternalError::UnknownNode)?
552
622
  .value(),
553
623
  Some(false),
554
624
  None,
@@ -561,8 +631,7 @@ impl Store
561
631
  if query.source.is_select_all() && query.destination.is_select_all()
562
632
  {
563
633
  edges_raw = edges_table
564
- .range::<graph::Key>(..)?
565
- .into_iter()
634
+ .range::<PersistentKey>(..)?
566
635
  .map(|r| {
567
636
  let (_, v) = r?;
568
637
  Ok(EdgeIdResult::new(v.value(), Some(false), None, None))
@@ -576,33 +645,36 @@ impl Store
576
645
  {
577
646
  if !query.destination.is_select_all() && !query.source.is_select_all()
578
647
  {
579
- let dest_it =
580
- self.select_nodes_from_table(&nodes_table, query.destination.clone())?;
648
+ let dest_it = self.select_nodes_from_table(&nodes_table, &query.destination)?;
581
649
  let dest_it: Vec<graph::Key> = dest_it
582
650
  .into_iter()
583
651
  .map(|n| {
584
652
  edges_destination_uuid_index
653
+ .as_ref()
585
654
  .borrow()
586
- .get_required(n.key, || InternalError::UnknownNode)
587
- .map(|x| x.value())
655
+ .get_required(PersistentKey(n.key()), || InternalError::UnknownNode)
656
+ .map(|x| -> Vec<graph::Key> {
657
+ x.value().into_iter().map(|x| x.into()).collect()
658
+ })
588
659
  })
589
660
  .collect::<Result<Vec<_>>>()?
590
661
  .into_iter()
591
662
  .flatten()
592
663
  .collect();
593
- let nodes = self.select_nodes_from_table(&nodes_table, query.source.clone())?;
664
+ let nodes = self.select_nodes_from_table(&nodes_table, &query.source)?;
594
665
  for n in nodes.iter()
595
666
  {
596
- let nkey = n.key;
667
+ let nkey = n.key();
597
668
  for k in edges_source_uuid_index
669
+ .as_ref()
598
670
  .borrow()
599
- .get_required(nkey, || InternalError::UnknownNode)?
671
+ .get_required(PersistentKey(nkey), || InternalError::UnknownNode)?
600
672
  .value()
601
673
  .iter()
602
674
  {
603
675
  if dest_it.contains(k)
604
676
  {
605
- let uniq_k = (k.to_owned(), Some(nkey), None);
677
+ let uniq_k: (graph::Key, _, _) = ((**k), Some(nkey), None);
606
678
  if !edge_ids.contains(&uniq_k)
607
679
  {
608
680
  edges_raw.push(EdgeIdResult::new(
@@ -621,18 +693,19 @@ impl Store
621
693
  }
622
694
  else if !query.source.is_select_all()
623
695
  {
624
- let nodes = self.select_nodes_from_table(&nodes_table, query.source.clone())?;
696
+ let nodes = self.select_nodes_from_table(&nodes_table, &query.source)?;
625
697
 
626
698
  for n in nodes.into_iter()
627
699
  {
628
- let nkey = n.key;
700
+ let nkey = n.key();
629
701
  for k in edges_source_uuid_index
702
+ .as_ref()
630
703
  .borrow()
631
- .get_required(nkey, || InternalError::UnknownNode)?
704
+ .get_required(PersistentKey(nkey), || InternalError::UnknownNode)?
632
705
  .value()
633
706
  .iter()
634
707
  {
635
- let uniq_k = (k.to_owned(), Some(nkey), None);
708
+ let uniq_k = (k.to_owned_key(), Some(nkey), None);
636
709
  if !edge_ids.contains(&uniq_k)
637
710
  {
638
711
  edges_raw.push(EdgeIdResult::new(
@@ -650,17 +723,18 @@ impl Store
650
723
  }
651
724
  else
652
725
  {
653
- let nodes = self.select_nodes_from_table(&nodes_table, query.destination.clone())?;
726
+ let nodes = self.select_nodes_from_table(&nodes_table, &query.destination)?;
654
727
  for n in nodes.into_iter()
655
728
  {
656
- let nkey = n.key;
729
+ let nkey = n.key();
657
730
  for k in edges_destination_uuid_index
731
+ .as_ref()
658
732
  .borrow()
659
- .get_required(nkey, || InternalError::UnknownNode)?
733
+ .get_required(PersistentKey(nkey), || InternalError::UnknownNode)?
660
734
  .value()
661
735
  .iter()
662
736
  {
663
- let uniq_k = (k.to_owned(), None, Some(nkey));
737
+ let uniq_k = (k.to_owned_key(), None, Some(nkey));
664
738
  if !edge_ids.contains(&uniq_k)
665
739
  {
666
740
  edges_raw.push(EdgeIdResult::new(
@@ -688,20 +762,26 @@ impl Store
688
762
  let edge = v.edge_data;
689
763
 
690
764
  let source = nodes_table
691
- .get_required(edge.source, || InternalError::UnknownNode)?
692
- .value();
765
+ .get(edge.source)?
766
+ .ok_or(InternalError::UnknownNode)?
767
+ .value()
768
+ .into();
693
769
  let destination = nodes_table
694
770
  .get_required(edge.destination, || InternalError::UnknownNode)?
695
- .value();
771
+ .value()
772
+ .into();
696
773
 
697
- let edge = graph::Edge {
698
- key: edge.key,
774
+ let edge = graph::Path::new(
775
+ edge.key.into(),
699
776
  source,
777
+ edge.labels,
778
+ edge.properties,
700
779
  destination,
701
- labels: edge.labels,
702
- properties: edge.properties,
703
- };
704
- super::EdgeResult { edge, reversed }
780
+ );
781
+ super::EdgeResult {
782
+ path: edge,
783
+ reversed,
784
+ }
705
785
  })
706
786
  });
707
787
  // Filter using the labels
@@ -713,7 +793,7 @@ impl Store
713
793
  {
714
794
  for l in labels.iter()
715
795
  {
716
- if !e.edge.labels.contains(l)
796
+ if !e.path.labels().contains(l)
717
797
  {
718
798
  return false;
719
799
  }
@@ -732,7 +812,7 @@ impl Store
732
812
  {
733
813
  for (k, v) in properties.iter()
734
814
  {
735
- match e.edge.properties.get(k)
815
+ match e.path.properties().get(k)
736
816
  {
737
817
  Some(val) =>
738
818
  {
@@ -758,11 +838,11 @@ impl Store
758
838
  r.filter(|e| {
759
839
  if let Ok(e) = &e
760
840
  {
761
- query.is_match(&e.edge)
841
+ query.is_match(&e.path)
762
842
  }
763
843
  else
764
844
  {
765
- return true;
845
+ true
766
846
  }
767
847
  })
768
848
  .collect()
@@ -790,17 +870,18 @@ impl store::Store for Store
790
870
  }
791
871
  fn graphs_list(&self, transaction: &mut Self::TransactionBox) -> Result<Vec<String>>
792
872
  {
793
- self.get_metadata_value_or_else(transaction, "graphs".to_string(), || vec![])
873
+ self.get_metadata_value_or_else(transaction, "graphs".to_string(), Vec::new)
794
874
  }
795
875
  fn create_graph(
796
876
  &self,
797
877
  transaction: &mut Self::TransactionBox,
798
- graph_name: &String,
878
+ graph_name: impl AsRef<str>,
799
879
  ignore_if_exists: bool,
800
880
  ) -> Result<()>
801
881
  {
882
+ let graph_name = graph_name.as_ref();
802
883
  let mut graphs_list = self.graphs_list(transaction)?;
803
- if graphs_list.contains(graph_name)
884
+ if graphs_list.iter().any(|s| s == graph_name)
804
885
  {
805
886
  if ignore_if_exists
806
887
  {
@@ -828,7 +909,7 @@ impl store::Store for Store
828
909
 
829
910
  self.graphs.write()?.insert(graph_name.to_owned(), gi);
830
911
  }
831
- graphs_list.push(graph_name.clone());
912
+ graphs_list.push(graph_name.to_owned());
832
913
  self.set_metadata_value(transaction, "graphs", &graphs_list)?;
833
914
 
834
915
  Ok(())
@@ -836,12 +917,13 @@ impl store::Store for Store
836
917
  fn drop_graph(
837
918
  &self,
838
919
  transaction: &mut Self::TransactionBox,
839
- graph_name: &String,
920
+ graph_name: impl AsRef<str>,
840
921
  if_exists: bool,
841
922
  ) -> Result<()>
842
923
  {
924
+ let graph_name = graph_name.as_ref();
843
925
  let mut graphs_list = self.graphs_list(transaction)?;
844
- if graphs_list.contains(graph_name)
926
+ if graphs_list.iter().any(|s| s == graph_name)
845
927
  {
846
928
  {
847
929
  let tx = transaction.try_into_write()?;
@@ -871,10 +953,10 @@ impl store::Store for Store
871
953
  }
872
954
  }
873
955
  /// Create nodes and add them to a graph
874
- fn create_nodes<'a, T: Iterator<Item = &'a crate::graph::Node>>(
956
+ fn create_nodes<'a, T: IntoIterator<Item = &'a crate::graph::Node>>(
875
957
  &self,
876
958
  transaction: &mut Self::TransactionBox,
877
- graph_name: &String,
959
+ graph_name: impl AsRef<str>,
878
960
  nodes_iter: T,
879
961
  ) -> Result<()>
880
962
  {
@@ -886,9 +968,10 @@ impl store::Store for Store
886
968
  transaction.open_table(graph_info.edges_destination_index_definition())?;
887
969
  for x in nodes_iter
888
970
  {
889
- table.insert(x.key, x)?;
890
- table_source.insert(x.key, vec![])?;
891
- table_destination.insert(x.key, vec![])?;
971
+ let pk = PersistentKey(x.key());
972
+ table.insert(&pk, PersistentNode::Reference(x))?;
973
+ table_source.insert(&pk, vec![])?;
974
+ table_destination.insert(&pk, vec![])?;
892
975
  }
893
976
  Ok(())
894
977
  }
@@ -896,25 +979,26 @@ impl store::Store for Store
896
979
  fn update_node(
897
980
  &self,
898
981
  transaction: &mut Self::TransactionBox,
899
- graph_name: &String,
982
+ graph_name: impl AsRef<str>,
900
983
  node: &graph::Node,
901
984
  ) -> Result<()>
902
985
  {
903
986
  let graph_info = self.get_graph_info(graph_name)?;
904
987
  let transaction = transaction.try_into_write()?;
905
988
  let mut table = transaction.open_table(graph_info.nodes_table_definition())?;
906
- table.insert(node.key, node)?;
989
+ table.insert(PersistentKey(node.key()), PersistentNode::Reference(node))?;
907
990
  Ok(())
908
991
  }
909
992
  /// Delete nodes according to a given query
910
993
  fn delete_nodes(
911
994
  &self,
912
995
  transaction: &mut Self::TransactionBox,
913
- graph_name: &String,
996
+ graph_name: impl AsRef<str>,
914
997
  query: super::SelectNodeQuery,
915
998
  detach: bool,
916
999
  ) -> Result<()>
917
1000
  {
1001
+ let graph_name = graph_name.as_ref();
918
1002
  let graph_info = self.get_graph_info(graph_name)?;
919
1003
 
920
1004
  if query.is_select_all()
@@ -955,7 +1039,7 @@ impl store::Store for Store
955
1039
  self
956
1040
  .select_nodes(transaction, graph_name, query)?
957
1041
  .into_iter()
958
- .map(|x| x.key)
1042
+ .map(|x| x.key())
959
1043
  .collect()
960
1044
  };
961
1045
 
@@ -983,11 +1067,11 @@ impl store::Store for Store
983
1067
  for key in node_keys.iter()
984
1068
  {
985
1069
  if !table_source
986
- .get_required(key, || InternalError::UnknownNode)?
1070
+ .get_required(PersistentKey(key.to_owned()), || InternalError::UnknownNode)?
987
1071
  .value()
988
1072
  .is_empty()
989
1073
  || !table_destination
990
- .get_required(key, || InternalError::UnknownNode)?
1074
+ .get_required(PersistentKey(key.to_owned()), || InternalError::UnknownNode)?
991
1075
  .value()
992
1076
  .is_empty()
993
1077
  {
@@ -1004,9 +1088,9 @@ impl store::Store for Store
1004
1088
  write_transaction.open_table(graph_info.edges_destination_index_definition())?;
1005
1089
  for key in node_keys.into_iter()
1006
1090
  {
1007
- table_nodes.remove(key)?;
1008
- table_source.remove(key)?;
1009
- table_destination.remove(key)?;
1091
+ table_nodes.remove(PersistentKey(key))?;
1092
+ table_source.remove(PersistentKey(key))?;
1093
+ table_destination.remove(PersistentKey(key))?;
1010
1094
  }
1011
1095
  }
1012
1096
  Ok(())
@@ -1015,30 +1099,31 @@ impl store::Store for Store
1015
1099
  fn select_nodes(
1016
1100
  &self,
1017
1101
  transaction: &mut Self::TransactionBox,
1018
- graph_name: &String,
1102
+ graph_name: impl AsRef<str>,
1019
1103
  query: super::SelectNodeQuery,
1020
1104
  ) -> Result<Vec<crate::graph::Node>>
1021
1105
  {
1106
+ let graph_name = graph_name.as_ref();
1022
1107
  let graph_info = self.get_graph_info(graph_name)?;
1023
1108
  match transaction
1024
1109
  {
1025
1110
  store::TransactionBox::Read(read) =>
1026
1111
  {
1027
1112
  let nodes_table = read.open_table(graph_info.nodes_table_definition())?;
1028
- self.select_nodes_from_table(&nodes_table, query)
1113
+ self.select_nodes_from_table(&nodes_table, &query)
1029
1114
  }
1030
1115
  store::TransactionBox::Write(write) =>
1031
1116
  {
1032
1117
  let nodes_table = write.open_table(graph_info.nodes_table_definition())?;
1033
- self.select_nodes_from_table(&nodes_table, query)
1118
+ self.select_nodes_from_table(&nodes_table, &query)
1034
1119
  }
1035
1120
  }
1036
1121
  }
1037
1122
  /// Add edge
1038
- fn create_edges<'a, T: Iterator<Item = &'a crate::graph::Edge>>(
1123
+ fn create_edges<'a, T: IntoIterator<Item = &'a crate::graph::SinglePath>>(
1039
1124
  &self,
1040
1125
  transaction: &mut Self::TransactionBox,
1041
- graph_name: &String,
1126
+ graph_name: impl AsRef<str>,
1042
1127
  edges_iter: T,
1043
1128
  ) -> Result<()>
1044
1129
  {
@@ -1052,62 +1137,59 @@ impl store::Store for Store
1052
1137
  for x in edges_iter
1053
1138
  {
1054
1139
  let mut keys_source = table_source
1055
- .remove(x.source.key)?
1140
+ .remove(PersistentKey(x.source().key()))?
1056
1141
  .ok_or(InternalError::UnknownNode)?
1057
1142
  .value();
1058
- keys_source.push(x.key);
1143
+ keys_source.push(x.key().into());
1059
1144
  let mut keys_destination = table_destination
1060
- .remove(x.destination.key)?
1145
+ .remove(PersistentKey(x.destination().key()))?
1061
1146
  .ok_or(InternalError::UnknownNode)?
1062
1147
  .value();
1063
- keys_destination.push(x.key);
1148
+ keys_destination.push(x.key().into());
1064
1149
 
1065
1150
  table.insert(
1066
- x.key,
1151
+ PersistentKey(x.key()),
1067
1152
  &PersistentEdge {
1068
- key: x.key,
1069
- source: x.source.key,
1070
- destination: x.destination.key,
1071
- labels: x.labels.clone(),
1072
- properties: x.properties.clone(),
1153
+ key: x.key().into(),
1154
+ source: x.source().key().into(),
1155
+ destination: x.destination().key().into(),
1156
+ labels: x.labels().clone(),
1157
+ properties: x.properties().clone(),
1073
1158
  },
1074
1159
  )?;
1075
- table_source.insert(x.source.key, keys_source)?;
1076
- table_destination.insert(x.destination.key, keys_destination)?;
1160
+ table_source.insert(PersistentKey(x.source().key()), keys_source)?;
1161
+ table_destination.insert(PersistentKey(x.destination().key()), keys_destination)?;
1077
1162
  }
1078
1163
  Ok(())
1079
1164
  }
1080
1165
  fn update_edge(
1081
1166
  &self,
1082
1167
  transaction: &mut Self::TransactionBox,
1083
- graph_name: &String,
1168
+ graph_name: impl AsRef<str>,
1084
1169
  edge: &graph::Edge,
1085
1170
  ) -> Result<()>
1086
1171
  {
1087
1172
  let transaction = transaction.try_into_write()?;
1088
1173
  let graph_info = self.get_graph_info(graph_name)?;
1089
1174
  let mut table = transaction.open_table(graph_info.edges_table_definition())?;
1090
- table.insert(
1091
- edge.key,
1092
- &PersistentEdge {
1093
- key: edge.key,
1094
- source: edge.source.key,
1095
- destination: edge.destination.key,
1096
- labels: edge.labels.to_owned(),
1097
- properties: edge.properties.to_owned(),
1098
- },
1099
- )?;
1175
+ let mut pe = table
1176
+ .get_required(&edge.key().into(), || InternalError::UnknownEdge)?
1177
+ .value();
1178
+ pe.labels = edge.labels().to_owned();
1179
+ pe.properties = edge.properties().to_owned();
1180
+ table.insert(PersistentKey(edge.key()), &pe)?;
1100
1181
  Ok(())
1101
1182
  }
1102
1183
  /// Delete nodes according to a given query
1103
1184
  fn delete_edges(
1104
1185
  &self,
1105
1186
  transaction: &mut Self::TransactionBox,
1106
- graph_name: &String,
1187
+ graph_name: impl AsRef<str>,
1107
1188
  query: super::SelectEdgeQuery,
1108
1189
  directivity: graph::EdgeDirectivity,
1109
1190
  ) -> Result<()>
1110
1191
  {
1192
+ let graph_name = graph_name.as_ref();
1111
1193
  let graph_info = self.get_graph_info(graph_name)?;
1112
1194
  let edges = self.select_edges(transaction, graph_name, query, directivity)?;
1113
1195
 
@@ -1120,29 +1202,29 @@ impl store::Store for Store
1120
1202
 
1121
1203
  for e in edges
1122
1204
  {
1123
- table.remove(e.edge.key)?;
1205
+ table.remove(PersistentKey(e.path.key()))?;
1124
1206
  let (sk, dk) = if e.reversed
1125
1207
  {
1126
- (e.edge.destination.key, e.edge.source.key)
1208
+ (e.path.destination().key(), e.path.source().key())
1127
1209
  }
1128
1210
  else
1129
1211
  {
1130
- (e.edge.source.key, e.edge.destination.key)
1212
+ (e.path.source().key(), e.path.destination().key())
1131
1213
  };
1132
1214
 
1133
1215
  let mut v = table_source
1134
- .remove(sk)?
1216
+ .remove(PersistentKey(sk))?
1135
1217
  .ok_or_else(|| InternalError::UnknownNode)?
1136
1218
  .value();
1137
- v.retain(|x| *x != e.edge.key);
1138
- table_source.insert(sk, v)?;
1219
+ v.retain(|x| *x != e.path.key().into());
1220
+ table_source.insert(PersistentKey(sk), v)?;
1139
1221
 
1140
1222
  let mut v = table_destination
1141
- .remove(dk)?
1223
+ .remove(PersistentKey(dk))?
1142
1224
  .ok_or_else(|| InternalError::UnknownNode)?
1143
1225
  .value();
1144
- v.retain(|x| *x != e.edge.key);
1145
- table_destination.insert(dk, v)?;
1226
+ v.retain(|x| *x != e.path.key().into());
1227
+ table_destination.insert(PersistentKey(dk), v)?;
1146
1228
  }
1147
1229
  Ok(())
1148
1230
  }
@@ -1150,7 +1232,7 @@ impl store::Store for Store
1150
1232
  fn select_edges(
1151
1233
  &self,
1152
1234
  transaction: &mut Self::TransactionBox,
1153
- graph_name: &String,
1235
+ graph_name: impl AsRef<str>,
1154
1236
  query: super::SelectEdgeQuery,
1155
1237
  directivity: graph::EdgeDirectivity,
1156
1238
  ) -> Result<Vec<super::EdgeResult>>
@@ -1215,14 +1297,10 @@ impl store::Store for Store
1215
1297
  let mut labels = Vec::new();
1216
1298
  let mut properties_count = 0;
1217
1299
 
1218
- for n in self.select_nodes(
1219
- transaction,
1220
- &"default".into(),
1221
- super::SelectNodeQuery::select_all(),
1222
- )?
1300
+ for n in self.select_nodes(transaction, "default", super::SelectNodeQuery::select_all())?
1223
1301
  {
1224
1302
  nodes_count += 1;
1225
- for l in n.labels.iter()
1303
+ for l in n.labels().iter()
1226
1304
  {
1227
1305
  if !labels.contains(l)
1228
1306
  {
@@ -1230,14 +1308,14 @@ impl store::Store for Store
1230
1308
  }
1231
1309
  }
1232
1310
  properties_count += n
1233
- .properties
1311
+ .properties()
1234
1312
  .iter()
1235
1313
  .filter(|(_, v)| **v != value::Value::Null)
1236
1314
  .count();
1237
1315
  }
1238
1316
  for e in self.select_edges(
1239
1317
  transaction,
1240
- &"default".into(),
1318
+ "default",
1241
1319
  super::SelectEdgeQuery::select_all(),
1242
1320
  graph::EdgeDirectivity::Directed,
1243
1321
  )?
@@ -1245,8 +1323,8 @@ impl store::Store for Store
1245
1323
  edges_count += 1;
1246
1324
 
1247
1325
  properties_count += e
1248
- .edge
1249
- .properties
1326
+ .path
1327
+ .properties()
1250
1328
  .iter()
1251
1329
  .filter(|(_, v)| **v != value::Value::Null)
1252
1330
  .count();