gqlite 1.5.0 → 1.7.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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +12 -6
  3. data/ext/db-index/Cargo.toml +29 -0
  4. data/ext/db-index/src/hnsw/error.rs +66 -0
  5. data/ext/db-index/src/hnsw/graph_store.rs +272 -0
  6. data/ext/db-index/src/hnsw/id.rs +36 -0
  7. data/ext/db-index/src/hnsw/implementation.rs +1517 -0
  8. data/ext/db-index/src/hnsw/kernels.rs +1228 -0
  9. data/ext/db-index/src/hnsw/metric.rs +244 -0
  10. data/ext/db-index/src/hnsw/scalar.rs +72 -0
  11. data/ext/db-index/src/hnsw/simple_store.rs +140 -0
  12. data/ext/db-index/src/hnsw/store.rs +472 -0
  13. data/ext/db-index/src/hnsw/vector.rs +105 -0
  14. data/ext/db-index/src/hnsw/vectors.rs +568 -0
  15. data/ext/db-index/src/hnsw.rs +42 -0
  16. data/ext/db-index/src/lib.rs +3 -0
  17. data/ext/gqlitedb/Cargo.toml +19 -8
  18. data/ext/gqlitedb/benches/common/pokec.rs +62 -2
  19. data/ext/gqlitedb/benches/pokec_divan.rs +66 -2
  20. data/ext/gqlitedb/benches/pokec_iai.rs +60 -3
  21. data/ext/gqlitedb/release.toml +2 -2
  22. data/ext/gqlitedb/src/aggregators/arithmetic.rs +3 -1
  23. data/ext/gqlitedb/src/aggregators/containers.rs +1 -1
  24. data/ext/gqlitedb/src/aggregators/stats.rs +21 -12
  25. data/ext/gqlitedb/src/capi.rs +20 -24
  26. data/ext/gqlitedb/src/compiler/expression_analyser.rs +28 -20
  27. data/ext/gqlitedb/src/compiler/variables_manager.rs +104 -38
  28. data/ext/gqlitedb/src/compiler.rs +506 -227
  29. data/ext/gqlitedb/src/connection.rs +151 -11
  30. data/ext/gqlitedb/src/consts.rs +1 -2
  31. data/ext/gqlitedb/src/error.rs +123 -61
  32. data/ext/gqlitedb/src/functions/common.rs +64 -0
  33. data/ext/gqlitedb/src/functions/containers.rs +2 -46
  34. data/ext/gqlitedb/src/functions/edge.rs +1 -1
  35. data/ext/gqlitedb/src/functions/math.rs +87 -15
  36. data/ext/gqlitedb/src/functions/node.rs +1 -1
  37. data/ext/gqlitedb/src/functions/path.rs +48 -11
  38. data/ext/gqlitedb/src/functions/scalar.rs +47 -4
  39. data/ext/gqlitedb/src/functions/string.rs +123 -1
  40. data/ext/gqlitedb/src/functions/value.rs +1 -1
  41. data/ext/gqlitedb/src/functions.rs +165 -28
  42. data/ext/gqlitedb/src/graph.rs +1 -9
  43. data/ext/gqlitedb/src/interpreter/evaluators.rs +968 -130
  44. data/ext/gqlitedb/src/interpreter/instructions.rs +39 -2
  45. data/ext/gqlitedb/src/lib.rs +5 -4
  46. data/ext/gqlitedb/src/parser/gql.pest +1 -1
  47. data/ext/gqlitedb/src/planner.rs +329 -0
  48. data/ext/gqlitedb/src/prelude.rs +3 -3
  49. data/ext/gqlitedb/src/store/pgrx.rs +1 -1
  50. data/ext/gqlitedb/src/store/postgres.rs +742 -16
  51. data/ext/gqlitedb/src/store/redb/hnsw_store.rs +702 -0
  52. data/ext/gqlitedb/src/store/redb/index.rs +274 -0
  53. data/ext/gqlitedb/src/store/redb.rs +1268 -113
  54. data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +28 -0
  55. data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +103 -0
  56. data/ext/gqlitedb/src/store/sqlbase.rs +146 -16
  57. data/ext/gqlitedb/src/store/sqlite.rs +576 -14
  58. data/ext/gqlitedb/src/store/vector_extract.rs +56 -0
  59. data/ext/gqlitedb/src/store.rs +140 -29
  60. data/ext/gqlitedb/src/tests/compiler.rs +207 -10
  61. data/ext/gqlitedb/src/tests/connection/postgres.rs +38 -3
  62. data/ext/gqlitedb/src/tests/connection/redb.rs +23 -0
  63. data/ext/gqlitedb/src/tests/connection/sqlite.rs +31 -0
  64. data/ext/gqlitedb/src/tests/connection.rs +61 -1
  65. data/ext/gqlitedb/src/tests/evaluators.rs +162 -7
  66. data/ext/gqlitedb/src/tests/parser.rs +54 -23
  67. data/ext/gqlitedb/src/tests/planner.rs +511 -0
  68. data/ext/gqlitedb/src/tests/store/postgres.rs +7 -0
  69. data/ext/gqlitedb/src/tests/store/redb.rs +8 -0
  70. data/ext/gqlitedb/src/tests/store/sqlite.rs +8 -0
  71. data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +182 -0
  72. data/ext/gqlitedb/src/tests/store/vector_index/redb.rs +386 -0
  73. data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +166 -0
  74. data/ext/gqlitedb/src/tests/store/vector_index.rs +2313 -0
  75. data/ext/gqlitedb/src/tests/store.rs +78 -14
  76. data/ext/gqlitedb/src/tests/templates/ast.rs +92 -16
  77. data/ext/gqlitedb/src/tests/templates/programs.rs +14 -7
  78. data/ext/gqlitedb/src/tests.rs +15 -9
  79. data/ext/gqlitedb/src/utils.rs +6 -1
  80. data/ext/gqlitedb/src/value/compare.rs +61 -3
  81. data/ext/gqlitedb/src/value.rs +136 -7
  82. data/ext/gqlitedb/templates/sql/postgres/metadata_delete.sql +1 -0
  83. data/ext/gqlitedb/templates/sql/postgres/node_select.sql +1 -1
  84. data/ext/gqlitedb/templates/sql/sqlite/metadata_delete.sql +1 -0
  85. data/ext/gqliterb/src/lib.rs +53 -8
  86. data/ext/gqlparser/Cargo.toml +25 -0
  87. data/ext/gqlparser/README.MD +9 -0
  88. data/ext/gqlparser/benches/pokec_divan.rs +34 -0
  89. data/ext/gqlparser/src/common.rs +69 -0
  90. data/ext/gqlparser/src/gqls/ast.rs +69 -0
  91. data/ext/gqlparser/src/gqls/constraint.rs +79 -0
  92. data/ext/gqlparser/src/gqls/error.rs +22 -0
  93. data/ext/gqlparser/src/gqls/parser.rs +813 -0
  94. data/ext/gqlparser/src/gqls/prelude.rs +8 -0
  95. data/ext/gqlparser/src/gqls/properties.rs +115 -0
  96. data/ext/gqlparser/src/gqls/resolve.rs +207 -0
  97. data/ext/gqlparser/src/gqls.rs +265 -0
  98. data/ext/gqlparser/src/lib.rs +7 -0
  99. data/ext/gqlparser/src/oc/ast.rs +680 -0
  100. data/ext/gqlparser/src/oc/error.rs +172 -0
  101. data/ext/gqlparser/src/oc/lexer.rs +429 -0
  102. data/ext/gqlparser/src/oc/parser/tests.rs +2284 -0
  103. data/ext/gqlparser/src/oc/parser.rs +2005 -0
  104. data/ext/gqlparser/src/oc.rs +33 -0
  105. data/ext/gqlparser/src/prelude.rs +3 -0
  106. data/ext/graphcore/Cargo.toml +1 -0
  107. data/ext/graphcore/src/error.rs +26 -0
  108. data/ext/graphcore/src/graph.rs +177 -51
  109. data/ext/graphcore/src/lib.rs +4 -2
  110. data/ext/graphcore/src/open_cypher.rs +12 -0
  111. data/ext/graphcore/src/table.rs +50 -2
  112. data/ext/graphcore/src/timestamp.rs +127 -104
  113. data/ext/graphcore/src/value/tensor.rs +739 -0
  114. data/ext/graphcore/src/value/value_map.rs +1 -1
  115. data/ext/graphcore/src/value.rs +343 -19
  116. metadata +93 -28
  117. data/ext/gqlitedb/src/parser/ast.rs +0 -604
  118. data/ext/gqlitedb/src/parser/parser_impl.rs +0 -1213
  119. data/ext/gqlitedb/src/parser.rs +0 -4
@@ -0,0 +1,33 @@
1
+ //! OpenCypher parser
2
+
3
+ use nom::Finish;
4
+
5
+ pub mod ast;
6
+ mod error;
7
+ mod lexer;
8
+ mod parser;
9
+
10
+ pub use error::{Error, ErrorKind};
11
+
12
+ /// Result type used by this crate
13
+ pub type Result<T, E = error::Error> = std::result::Result<T, E>;
14
+
15
+ /// Parse an OpenCypher into an AST.
16
+ pub fn parse_oc_query(source: &str) -> Result<ast::Queries>
17
+ {
18
+ let context = parser::Context::new(source);
19
+ let tokens = lexer::tokenize(source)?;
20
+ let input = parser::Input(&tokens, &context);
21
+ // Parse schema
22
+ let (rem, parse_tree) = parser::queries(input.clone()).finish()?;
23
+
24
+ if !rem.0.is_empty()
25
+ {
26
+ return Err(Error::new(
27
+ error::ErrorKind::UnexpectedToken,
28
+ rem.first().map_or(Default::default(), |x| x.span.clone()),
29
+ ));
30
+ }
31
+
32
+ Ok(parse_tree)
33
+ }
@@ -0,0 +1,3 @@
1
+ //! Import this prelude for base types
2
+
3
+ pub use crate::{gqls, oc};
@@ -15,6 +15,7 @@ jiff = { version = "0.2" }
15
15
  serde = { workspace = true, features = ["derive"] }
16
16
  thiserror = { workspace = true }
17
17
  uuid = { workspace = true }
18
+ bytemuck = "1"
18
19
 
19
20
  [target.'cfg(target_arch = "wasm32")'.dependencies]
20
21
  uuid = { version = "1", features = ["js"] }
@@ -27,4 +27,30 @@ pub enum Error
27
27
  InvalidRange,
28
28
  #[error("TimeStamp error {0}.")]
29
29
  TimeError(#[from] jiff::Error),
30
+ #[error("QueryExecutionError {0}.")]
31
+ QueryExecutionError(String),
32
+ // Tensor decode errors
33
+ #[error("Tensor decode: too short")]
34
+ TensorTooShort,
35
+ #[error("Tensor decode: unknown version {0}")]
36
+ TensorUnknownVersion(u8),
37
+ #[error("Tensor decode: unknown flags {0}")]
38
+ TensorUnknownFlags(u8),
39
+ #[error("Tensor decode: unknown dtype {0}")]
40
+ TensorUnknownDType(u8),
41
+ #[error("Tensor decode: numel overflow")]
42
+ TensorNumelOverflow,
43
+ #[error("Tensor decode: data length mismatch")]
44
+ TensorDataLengthMismatch,
45
+ // Tensor shape errors
46
+ #[error("Tensor: rank too large")]
47
+ TensorRankTooLarge,
48
+ #[error("Tensor: dimension too large")]
49
+ TensorDimensionTooLarge,
50
+ #[error("Tensor: numel overflow")]
51
+ TensorShapeNumelOverflow,
52
+ #[error("Tensor: data length mismatch")]
53
+ TensorShapeDataLengthMismatch,
54
+ #[error("Tensor: shape mismatch")]
55
+ TensorShapeMismatch,
30
56
  }
@@ -3,6 +3,17 @@ use std::borrow::Borrow;
3
3
 
4
4
  use crate::prelude::*;
5
5
 
6
+ /// Directivity of an edge, usually used in query to indicate the matching
7
+ /// direction is not important.
8
+ #[derive(Debug, Clone, Copy)]
9
+ pub enum EdgeDirectivity
10
+ {
11
+ /// Undirected edge
12
+ Undirected,
13
+ /// Directed edge
14
+ Directed,
15
+ }
16
+
6
17
  /// Uuid of a graph element (node, edge...).
7
18
  #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
8
19
  pub struct Key
@@ -77,6 +88,8 @@ impl From<Key> for u128
77
88
  #[serde(tag = "type", rename = "node")]
78
89
  pub struct Node
79
90
  {
91
+ /// Name of the graph.
92
+ pub(crate) graph_name: Option<String>,
80
93
  /// uuid for the Node.
81
94
  pub(crate) key: Key,
82
95
  /// Vector of labels.
@@ -88,14 +101,31 @@ pub struct Node
88
101
  impl Node
89
102
  {
90
103
  /// Create a new node object
91
- pub fn new(key: Key, labels: Vec<String>, properties: value::ValueMap) -> Node
104
+ pub fn new(
105
+ graph_name: Option<String>,
106
+ key: Key,
107
+ labels: Vec<String>,
108
+ properties: value::ValueMap,
109
+ ) -> Node
92
110
  {
93
111
  Self {
112
+ graph_name,
94
113
  key,
95
114
  labels,
96
115
  properties,
97
116
  }
98
117
  }
118
+ /// Name of the graph that contains the path
119
+ pub fn graph_name(&self) -> &Option<String>
120
+ {
121
+ &self.graph_name
122
+ }
123
+ /// Set the graph name
124
+ pub fn with_graph_name(mut self, graph_name: impl Into<String>) -> Self
125
+ {
126
+ self.graph_name = Some(graph_name.into());
127
+ self
128
+ }
99
129
  /// uuid for the Node.
100
130
  pub fn key(&self) -> Key
101
131
  {
@@ -134,9 +164,9 @@ impl Node
134
164
  &mut self.properties
135
165
  }
136
166
  /// Unpack Node in key, labels and properties.
137
- pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
167
+ pub fn unpack(self) -> (Option<String>, Key, Vec<String>, value::ValueMap)
138
168
  {
139
- (self.key, self.labels, self.properties)
169
+ (self.graph_name, self.key, self.labels, self.properties)
140
170
  }
141
171
  /// Convert into value map representation
142
172
  pub fn into_value_map(self) -> value::ValueMap
@@ -162,11 +192,21 @@ impl std::fmt::Display for Node
162
192
  }
163
193
  }
164
194
 
195
+ impl AsRef<Node> for Node
196
+ {
197
+ fn as_ref(&self) -> &Node
198
+ {
199
+ self
200
+ }
201
+ }
202
+
165
203
  /// Directed edge of the graph.
166
204
  #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
167
205
  #[serde(tag = "type", rename = "edge")]
168
206
  pub struct Edge
169
207
  {
208
+ /// Name of the graph.
209
+ pub(crate) graph_name: Option<String>,
170
210
  /// uuid for the Edge.
171
211
  pub(crate) key: Key,
172
212
  /// Labels for the Edge.
@@ -178,15 +218,32 @@ pub struct Edge
178
218
  impl Edge
179
219
  {
180
220
  /// Create a new node object
181
- pub fn new(key: Key, labels: Vec<String>, properties: value::ValueMap) -> Edge
221
+ pub fn new(
222
+ graph_name: Option<String>,
223
+ key: Key,
224
+ labels: Vec<String>,
225
+ properties: value::ValueMap,
226
+ ) -> Edge
182
227
  {
183
228
  Self {
229
+ graph_name,
184
230
  key,
185
231
  labels,
186
232
  properties,
187
233
  }
188
234
  }
189
235
 
236
+ /// Name of the graph that contains the path
237
+ pub fn graph_name(&self) -> &Option<String>
238
+ {
239
+ &self.graph_name
240
+ }
241
+ /// Set the graph name
242
+ pub fn with_graph_name(mut self, graph_name: impl Into<String>) -> Self
243
+ {
244
+ self.graph_name = Some(graph_name.into());
245
+ self
246
+ }
190
247
  /// uuid for the Node.
191
248
  pub fn key(&self) -> Key
192
249
  {
@@ -225,9 +282,9 @@ impl Edge
225
282
  self.properties
226
283
  }
227
284
  /// Unpack Edge in key, labels and properties.
228
- pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
285
+ pub fn unpack(self) -> (Option<String>, Key, Vec<String>, value::ValueMap)
229
286
  {
230
- (self.key, self.labels, self.properties)
287
+ (self.graph_name, self.key, self.labels, self.properties)
231
288
  }
232
289
  /// Convert into value map representation
233
290
  pub fn into_value_map(self) -> value::ValueMap
@@ -251,41 +308,43 @@ impl std::fmt::Display for Edge
251
308
  #[serde(tag = "type", rename = "path")]
252
309
  pub struct SinglePath
253
310
  {
254
- /// uuid for the path.
255
- pub(crate) key: Key,
256
311
  /// source node for the path.
257
312
  pub(crate) source: Node,
258
313
  /// destination node for the path.
259
314
  pub(crate) destination: Node,
260
- /// Labels for the path.
261
- pub(crate) labels: Vec<String>,
262
- /// Properties for the path.
263
- pub(crate) properties: value::ValueMap,
315
+ /// Edge for the path
316
+ pub(crate) edge: Edge,
264
317
  }
265
318
 
266
319
  impl SinglePath
267
320
  {
268
321
  /// Create new single path
269
- pub fn new(
270
- key: Key,
271
- source: Node,
272
- labels: Vec<String>,
273
- properties: value::ValueMap,
274
- destination: Node,
275
- ) -> SinglePath
322
+ pub fn new(source: Node, edge: Edge, destination: Node) -> SinglePath
276
323
  {
277
324
  SinglePath {
278
- key,
279
325
  source,
326
+ edge,
280
327
  destination,
281
- labels,
282
- properties,
283
328
  }
284
329
  }
330
+ /// Name of the graph that contains the path
331
+ pub fn graph_name(&self) -> &Option<String>
332
+ {
333
+ &self.edge.graph_name
334
+ }
335
+ /// Set the graph name
336
+ pub fn with_graph_name(mut self, graph_name: impl Into<String>) -> Self
337
+ {
338
+ let graph_name = graph_name.into();
339
+ self.source.graph_name = Some(graph_name.clone());
340
+ self.edge.graph_name = Some(graph_name.clone());
341
+ self.destination.graph_name = Some(graph_name);
342
+ self
343
+ }
285
344
  /// uuid for the Node.
286
345
  pub fn key(&self) -> Key
287
346
  {
288
- self.key
347
+ self.edge.key
289
348
  }
290
349
  /// uuid for the Node.
291
350
  pub fn source(&self) -> &Node
@@ -300,46 +359,32 @@ impl SinglePath
300
359
  /// Vector of labels.
301
360
  pub fn labels(&self) -> &Vec<String>
302
361
  {
303
- &self.labels
362
+ &self.edge.labels
304
363
  }
305
364
  /// Properties.
306
365
  pub fn properties(&self) -> &value::ValueMap
307
366
  {
308
- &self.properties
367
+ &self.edge.properties
309
368
  }
310
369
  /// Unpack Node in key, labels and properties.
311
- pub fn unpack(self) -> (Key, Node, Vec<String>, value::ValueMap, Node)
370
+ pub fn unpack(self) -> (Node, Edge, Node)
312
371
  {
313
- (
314
- self.key,
315
- self.source,
316
- self.labels,
317
- self.properties,
318
- self.destination,
319
- )
372
+ (self.source, self.edge, self.destination)
320
373
  }
321
374
  /// Convert into an Edge
322
375
  pub fn to_edge(&self) -> Edge
323
376
  {
324
- Edge {
325
- key: self.key,
326
- labels: self.labels.clone(),
327
- properties: self.properties.clone(),
328
- }
377
+ self.edge.clone()
329
378
  }
330
379
  /// Convert into an Edge
331
380
  pub fn into_edge(self) -> Edge
332
381
  {
333
- Edge {
334
- key: self.key,
335
- labels: self.labels,
336
- properties: self.properties,
337
- }
382
+ self.edge
338
383
  }
339
384
  /// Convert into value map representation
340
385
  pub fn into_value_map(self) -> value::ValueMap
341
386
  {
342
- crate::value_map!("key" => self.key, "source" => self.source, "labels" => self.labels, "properties" => self.properties, "destination" => self.destination, "type" => "path")
387
+ crate::value_map!("graph_name" => self.edge.graph_name, "key" => self.edge.key, "source" => self.source, "labels" => self.edge.labels, "properties" => self.edge.properties, "destination" => self.destination, "type" => "path")
343
388
  }
344
389
  }
345
390
 
@@ -347,9 +392,7 @@ impl std::fmt::Display for SinglePath
347
392
  {
348
393
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
349
394
  {
350
- write!(f, "{}-[:{} ", self.source, self.labels.join(":"))?;
351
- write!(f, "{}", self.properties.borrow())?;
352
- write!(f, "])->{}", self.destination)
395
+ write!(f, "{}-{}->{} ", self.source, self.edge, self.destination)
353
396
  }
354
397
  }
355
398
 
@@ -357,11 +400,94 @@ impl From<SinglePath> for Edge
357
400
  {
358
401
  fn from(val: SinglePath) -> Self
359
402
  {
360
- Edge {
361
- key: val.key,
362
- labels: val.labels,
363
- properties: val.properties,
403
+ val.into_edge()
404
+ }
405
+ }
406
+
407
+ impl From<Box<SinglePath>> for Edge
408
+ {
409
+ fn from(val: Box<SinglePath>) -> Self
410
+ {
411
+ val.into_edge()
412
+ }
413
+ }
414
+
415
+ /// Path in the graph. A Path contains a source, and multiple edges and destinations.
416
+ #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
417
+ #[serde(tag = "type", rename = "path")]
418
+ pub struct Path
419
+ {
420
+ /// source node for the path.
421
+ pub(crate) source: Node,
422
+ // elements of the path
423
+ pub(crate) elements: Vec<(Edge, Node)>,
424
+ }
425
+
426
+ impl Path
427
+ {
428
+ /// Create new single path
429
+ pub fn new(source: Node, elements: Vec<(Edge, Node)>) -> Path
430
+ {
431
+ Path { source, elements }
432
+ }
433
+ /// Name of the graph that contains the path
434
+ pub fn graph_name(&self) -> &Option<String>
435
+ {
436
+ &self.source.graph_name
437
+ }
438
+ /// Set the graph name
439
+ pub fn with_graph_name(mut self, graph_name: impl Into<String>) -> Self
440
+ {
441
+ let graph_name = graph_name.into();
442
+ self.source.graph_name = Some(graph_name.clone());
443
+ for (edge, destination) in self.elements.iter_mut()
444
+ {
445
+ edge.graph_name = Some(graph_name.clone());
446
+ destination.graph_name = Some(graph_name.clone());
447
+ }
448
+ self
449
+ }
450
+ /// Source for the Path.
451
+ pub fn source(&self) -> &Node
452
+ {
453
+ &self.source
454
+ }
455
+ /// Elements of the Path.
456
+ pub fn elements(&self) -> &Vec<(Edge, Node)>
457
+ {
458
+ &self.elements
459
+ }
460
+ /// Number of hops (edges) in the path.
461
+ pub fn elements_count(&self) -> usize
462
+ {
463
+ self.elements.len()
464
+ }
465
+ /// Unpack Node in key, labels and properties.
466
+ pub fn unpack(self) -> (Node, Vec<(Edge, Node)>)
467
+ {
468
+ (self.source, self.elements)
469
+ }
470
+ /// Convert into value map representation
471
+ pub fn into_value_map(self) -> value::ValueMap
472
+ {
473
+ crate::value_map!("source" => self.source, "elements" => self.elements.into_iter().map(|(e,d)|
474
+ {
475
+ crate::value_map!("edge" => e.into_value_map(), "destination" => d.into_value_map())
476
+ }
477
+ ).collect::<Vec<_>>())
478
+ }
479
+ }
480
+
481
+ impl std::fmt::Display for Path
482
+ {
483
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
484
+ {
485
+ write!(f, "{}", self.source)?;
486
+ for (edge, destination) in self.elements.iter()
487
+ {
488
+ write!(f, "-{}->{} ", edge, destination)?;
364
489
  }
490
+ Ok(())
365
491
  }
366
492
  }
367
493
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  mod error;
6
6
  mod graph;
7
+ mod open_cypher;
7
8
  mod prelude;
8
9
  mod serialize_with;
9
10
  mod table;
@@ -11,7 +12,8 @@ mod timestamp;
11
12
  mod value;
12
13
 
13
14
  pub use error::Error;
14
- pub use graph::{Edge, Key, Node, SinglePath};
15
+ pub use graph::{Edge, EdgeDirectivity, Key, Node, Path, SinglePath};
16
+ pub use open_cypher::OpenCypherQueryExecutor;
15
17
  pub use table::Table;
16
18
  pub use timestamp::TimeStamp;
17
- pub use value::{FromValueResult, Value, ValueMap, ValueTryIntoRef};
19
+ pub use value::{DType, FromValueResult, Tensor, Value, ValueMap, ValueTryIntoRef};
@@ -0,0 +1,12 @@
1
+ use crate::prelude::*;
2
+
3
+ /// Trait for executing OpenCypher queries
4
+ pub trait OpenCypherQueryExecutor
5
+ {
6
+ /// Execute an OpenCypher query on the database.
7
+ fn execute_oc_query(
8
+ &self,
9
+ query: &str,
10
+ parameters: crate::ValueMap,
11
+ ) -> Result<Option<crate::Table>, crate::Error>;
12
+ }
@@ -1,4 +1,4 @@
1
- use crate::{prelude::*, Value, ValueTryIntoRef};
1
+ use crate::{Value, ValueTryIntoRef, prelude::*};
2
2
 
3
3
  /// Table of values
4
4
  #[derive(Debug, Default, Clone, PartialEq)]
@@ -81,6 +81,18 @@ impl Table
81
81
  .ok_or(error::Error::InvalidRange)
82
82
  }
83
83
  }
84
+ /// Transform into an iterator over the rows in the table
85
+ pub fn into_row_iter(self) -> IntoRowIter
86
+ {
87
+ let columns = self.columns();
88
+ let row_count = self.rows();
89
+ IntoRowIter {
90
+ data: self.data.into_iter(),
91
+ columns,
92
+ index: 0,
93
+ row_count,
94
+ }
95
+ }
84
96
  /// Create an iterator over the rows in the table
85
97
  pub fn row_iter(&self) -> RowIter<'_>
86
98
  {
@@ -161,7 +173,43 @@ impl<'a> RowView<'a>
161
173
  }
162
174
  }
163
175
 
164
- /// Iteratpr over rows of a table
176
+ /// Iterator over rows of a table
177
+ pub struct IntoRowIter
178
+ {
179
+ data: std::vec::IntoIter<value::Value>,
180
+ columns: usize,
181
+ /// index used to output empty rows, when columns is 0
182
+ index: usize,
183
+ row_count: usize,
184
+ }
185
+
186
+ impl Iterator for IntoRowIter
187
+ {
188
+ type Item = Vec<value::Value>;
189
+
190
+ fn next(&mut self) -> Option<Self::Item>
191
+ {
192
+ if self.columns == 0
193
+ {
194
+ if self.index < self.row_count
195
+ {
196
+ self.index += 1;
197
+ Some(Default::default())
198
+ }
199
+ else
200
+ {
201
+ None
202
+ }
203
+ }
204
+ else
205
+ {
206
+ let v: Vec<_> = self.data.by_ref().take(self.columns).collect();
207
+ if v.is_empty() { None } else { Some(v) }
208
+ }
209
+ }
210
+ }
211
+
212
+ /// Iterator over rows of a table
165
213
  pub struct RowIter<'a>
166
214
  {
167
215
  data: &'a Vec<value::Value>,