gqlite 1.2.3 → 1.3.1

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +21 -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/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  6. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  7. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  8. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +10 -9
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +6 -4
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +27 -31
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +66 -59
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/connection.rs +42 -84
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +105 -34
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +22 -27
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +2 -2
  16. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +2 -2
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +1 -1
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/path.rs +16 -21
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +25 -2
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +6 -6
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +28 -20
  22. data/ext/gqlitedb/src/graph.rs +11 -0
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +163 -200
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +4 -3
  25. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +8 -5
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +44 -52
  27. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +1 -1
  28. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +50 -28
  29. data/ext/gqlitedb/src/parser.rs +4 -0
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  31. data/ext/gqlitedb/src/query_result.rs +88 -0
  32. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +226 -148
  33. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +111 -128
  34. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +22 -22
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +32 -76
  36. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +95 -111
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +14 -14
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  41. data/ext/gqlitedb/src/value.rs +225 -0
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +15 -5
  43. data/ext/gqliterb/Cargo.toml +12 -35
  44. data/ext/gqliterb/src/lib.rs +59 -39
  45. data/ext/graphcore/Cargo.toml +19 -0
  46. data/ext/graphcore/README.MD +4 -0
  47. data/ext/graphcore/release.toml +1 -0
  48. data/ext/graphcore/src/error.rs +28 -0
  49. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +134 -38
  50. data/ext/graphcore/src/lib.rs +15 -0
  51. data/ext/graphcore/src/prelude.rs +4 -0
  52. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  53. data/ext/graphcore/src/table.rs +272 -0
  54. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  55. data/ext/graphcore/src/value.rs +413 -0
  56. metadata +92 -88
  57. data/ext/gqliterb/.cargo/config.toml +0 -2
  58. data/ext/gqliterb/Cargo.lock +0 -1116
  59. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2115
  60. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -138
  61. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  62. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -609
  63. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  64. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  65. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  66. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  67. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +0 -0
  68. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  69. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  70. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  71. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +0 -0
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -1,4 +1,4 @@
1
- #![deny(warnings)]
1
+ use std::fmt::Display;
2
2
 
3
3
  use magnus::{
4
4
  function, method,
@@ -113,7 +113,7 @@ fn node_to_rhash(ruby: &Ruby, node: gqlitedb::Node) -> Result<magnus::Value, Err
113
113
  r_hash.aset("key", integer_from_u128(ruby, key.into())?)?;
114
114
  r_hash.aset("labels", labels)?;
115
115
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
116
- Ok(r_hash.into_value())
116
+ Ok(r_hash.into_value_with(ruby))
117
117
  }
118
118
 
119
119
  fn edge_to_rhash(ruby: &Ruby, edge: gqlitedb::Edge) -> Result<magnus::Value, Error>
@@ -124,7 +124,7 @@ fn edge_to_rhash(ruby: &Ruby, edge: gqlitedb::Edge) -> Result<magnus::Value, Err
124
124
  r_hash.aset("key", integer_from_u128(ruby, key.into())?)?;
125
125
  r_hash.aset("labels", labels)?;
126
126
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
127
- Ok(r_hash.into_value())
127
+ Ok(r_hash.into_value_with(ruby))
128
128
  }
129
129
 
130
130
  fn path_to_rhash(ruby: &Ruby, path: gqlitedb::Path) -> Result<magnus::Value, Error>
@@ -137,20 +137,21 @@ fn path_to_rhash(ruby: &Ruby, path: gqlitedb::Path) -> Result<magnus::Value, Err
137
137
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
138
138
  r_hash.aset("source", node_to_rhash(ruby, source)?)?;
139
139
  r_hash.aset("destination", node_to_rhash(ruby, destination)?)?;
140
- Ok(r_hash.into_value())
140
+ Ok(r_hash.into_value_with(ruby))
141
141
  }
142
142
 
143
143
  fn to_rvalue(ruby: &Ruby, val: gqlitedb::Value) -> Result<magnus::Value, Error>
144
144
  {
145
145
  match val
146
146
  {
147
- gqlitedb::Value::Array(arr) => Ok(to_rarray(ruby, arr)?.into_value()),
148
- gqlitedb::Value::Boolean(b) => Ok(b.into_value()),
149
- gqlitedb::Value::Integer(i) => Ok(i.into_value()),
150
- gqlitedb::Value::Float(f) => Ok(f.into_value()),
151
- gqlitedb::Value::String(s) => Ok(s.into_value()),
152
- gqlitedb::Value::Map(m) => Ok(to_rhash(ruby, m)?.into_value()),
153
- gqlitedb::Value::Null => Ok(ruby.qnil().into_value()),
147
+ gqlitedb::Value::Array(arr) => Ok(to_rarray(ruby, arr)?.into_value_with(ruby)),
148
+ gqlitedb::Value::Boolean(b) => Ok(b.into_value_with(ruby)),
149
+ gqlitedb::Value::Key(k) => Ok(integer_from_u128(ruby, k.into())?.into_value_with(ruby)),
150
+ gqlitedb::Value::Integer(i) => Ok(i.into_value_with(ruby)),
151
+ gqlitedb::Value::Float(f) => Ok(f.into_value_with(ruby)),
152
+ gqlitedb::Value::String(s) => Ok(s.into_value_with(ruby)),
153
+ gqlitedb::Value::Map(m) => Ok(to_rhash(ruby, m)?.into_value_with(ruby)),
154
+ gqlitedb::Value::Null => Ok(ruby.qnil().into_value_with(ruby)),
154
155
  gqlitedb::Value::Edge(e) => Ok(edge_to_rhash(ruby, e)?),
155
156
  gqlitedb::Value::Node(n) => Ok(node_to_rhash(ruby, n)?),
156
157
  gqlitedb::Value::Path(p) => Ok(path_to_rhash(ruby, p)?),
@@ -169,7 +170,7 @@ fn to_rhash(ruby: &Ruby, map: gqlitedb::ValueMap) -> Result<r_hash::RHash, Error
169
170
 
170
171
  fn to_rarray(ruby: &Ruby, arr: Vec<gqlitedb::Value>) -> Result<r_array::RArray, Error>
171
172
  {
172
- let r_arr = r_array::RArray::with_capacity(arr.len());
173
+ let r_arr = ruby.ary_new_capa(arr.len());
173
174
 
174
175
  for value in arr.into_iter()
175
176
  {
@@ -179,7 +180,9 @@ fn to_rarray(ruby: &Ruby, arr: Vec<gqlitedb::Value>) -> Result<r_array::RArray,
179
180
  Ok(r_arr)
180
181
  }
181
182
 
182
- fn map_err<T>(ruby: &Ruby, result: gqlitedb::Result<T>) -> Result<T, Error>
183
+ fn map_err<T, E>(ruby: &Ruby, result: Result<T, E>) -> Result<T, Error>
184
+ where
185
+ E: Display,
183
186
  {
184
187
  result.map_err(|e| Error::new(ruby.get_inner(&ERROR), format!("{}", e)))
185
188
  }
@@ -187,7 +190,7 @@ fn map_err<T>(ruby: &Ruby, result: gqlitedb::Result<T>) -> Result<T, Error>
187
190
  #[magnus::wrap(class = "GQLite::Connection")]
188
191
  struct Connection
189
192
  {
190
- dbhandle: gqlitedb::Connection,
193
+ dbhandle: std::sync::RwLock<Option<gqlitedb::Connection>>,
191
194
  }
192
195
 
193
196
  impl Connection
@@ -201,7 +204,7 @@ impl Connection
201
204
  let filename: String = map_err(
202
205
  ruby,
203
206
  options
204
- .get("filename".into())
207
+ .get("filename")
205
208
  .ok_or_else(|| Error::new(ruby.get_inner(&ERROR), "Missing filename."))?
206
209
  .to_owned()
207
210
  .try_into(),
@@ -213,7 +216,9 @@ impl Connection
213
216
  .path(filename)
214
217
  .create(),
215
218
  )?;
216
- Ok(Self { dbhandle })
219
+ Ok(Self {
220
+ dbhandle: std::sync::RwLock::new(Some(dbhandle)),
221
+ })
217
222
  }
218
223
  fn execute_oc_query(
219
224
  ruby: &Ruby,
@@ -221,32 +226,46 @@ impl Connection
221
226
  args: &[magnus::Value],
222
227
  ) -> Result<magnus::Value, Error>
223
228
  {
224
- let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
225
- let (query,): (String,) = args.required;
229
+ match &*rb_self.dbhandle.read().unwrap()
230
+ {
231
+ Some(connection) =>
232
+ {
233
+ let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
234
+ let (query,): (String,) = args.required;
226
235
 
227
- let kw = scan_args::get_kwargs::<_, (), (Option<magnus::Value>,), ()>(
228
- args.keywords,
229
- &[],
230
- &["bindings"],
231
- )?;
232
- let (bindings,) = kw.optional;
236
+ let kw = scan_args::get_kwargs::<_, (), (Option<magnus::Value>,), ()>(
237
+ args.keywords,
238
+ &[],
239
+ &["bindings"],
240
+ )?;
241
+ let (bindings,) = kw.optional;
233
242
 
234
- let bindings = bindings
235
- .map(|bindings| {
236
- if bindings.is_nil()
237
- {
238
- Ok(Default::default())
239
- }
240
- else
241
- {
242
- from_rhash(ruby, r_hash::RHash::try_convert(bindings)?)
243
- }
244
- })
245
- .transpose()?
246
- .unwrap_or_default();
247
- let result = map_err(ruby, rb_self.dbhandle.execute_query(query, bindings))?;
243
+ let bindings = bindings
244
+ .map(|bindings| {
245
+ if bindings.is_nil()
246
+ {
247
+ Ok(Default::default())
248
+ }
249
+ else
250
+ {
251
+ from_rhash(ruby, r_hash::RHash::try_convert(bindings)?)
252
+ }
253
+ })
254
+ .transpose()?
255
+ .unwrap_or_default();
256
+ let result = map_err(ruby, connection.execute_oc_query(query, bindings))?;
248
257
 
249
- to_rvalue(ruby, result)
258
+ to_rvalue(ruby, result.into_value())
259
+ }
260
+ None => Err(Error::new(
261
+ ruby.get_inner(&ERROR),
262
+ "Connection is closed.".to_string(),
263
+ )),
264
+ }
265
+ }
266
+ fn close(&self)
267
+ {
268
+ *self.dbhandle.write().unwrap() = None;
250
269
  }
251
270
  }
252
271
 
@@ -262,5 +281,6 @@ fn init(ruby: &Ruby) -> Result<(), Error>
262
281
  "execute_oc_query",
263
282
  method!(Connection::execute_oc_query, -1),
264
283
  )?;
284
+ class.define_method("close", method!(Connection::close, 0))?;
265
285
  Ok(())
266
286
  }
@@ -0,0 +1,19 @@
1
+ [package]
2
+ name = "graphcore"
3
+ description = "Base data structure to represent and manipulate property graph."
4
+ # version.workspace = true
5
+ version = "0.2.1"
6
+ readme = "README.MD"
7
+ edition.workspace = true
8
+ license.workspace = true
9
+ homepage.workspace = true
10
+ repository.workspace = true
11
+
12
+ [dependencies]
13
+ itertools = { workspace = true }
14
+ serde = { workspace = true, features = ["derive"] }
15
+ thiserror = { workspace = true }
16
+ uuid = { workspace = true }
17
+
18
+ [target.'cfg(target_arch = "wasm32")'.dependencies]
19
+ uuid = { version = "1", features = ["js"] }
@@ -0,0 +1,4 @@
1
+ ![GQLite logo](https://gqlite.org/assets/images/logo-88x88.png) graphcore
2
+ =========================================================================
3
+
4
+ `GraphCore` is part of the [GQLite project](https://gqlite.org) project, it provides base type for representing values, nodes and edges in a property graph.
@@ -0,0 +1 @@
1
+ tag = false
@@ -0,0 +1,28 @@
1
+ /// Represent errors.
2
+ #[derive(thiserror::Error, Debug)]
3
+ #[allow(missing_docs)]
4
+ #[non_exhaustive]
5
+ pub enum Error
6
+ {
7
+ #[error("InvalidBinaryOperands: operands for binary operation are not compatible.")]
8
+ InvalidBinaryOperands,
9
+ #[error("InvalidNegationOperands: operands for negation operation are not compatible.")]
10
+ InvalidNegationOperands,
11
+ #[error("Invalid value cast, cannot cast {value} to {typename}.")]
12
+ InvalidValueCast
13
+ {
14
+ value: Box<crate::Value>,
15
+ typename: &'static str,
16
+ },
17
+ #[error("Key {key} cannot be found in a path in a ValueMap.")]
18
+ MissingKeyInPath
19
+ {
20
+ key: String
21
+ },
22
+ #[error("Path cannot have null key.")]
23
+ MissingKey,
24
+ #[error("Invalid table dimensions.")]
25
+ InvalidTableDimensions,
26
+ #[error("Out of range access.")]
27
+ InvalidRange,
28
+ }
@@ -3,19 +3,27 @@ use std::borrow::Borrow;
3
3
 
4
4
  use crate::prelude::*;
5
5
 
6
- #[derive(Debug, Clone, Copy)]
7
- pub(crate) enum EdgeDirectivity
8
- {
9
- Undirected,
10
- Directed,
11
- }
12
-
6
+ /// Uuid of a graph element (node, edge...).
13
7
  #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
14
8
  pub struct Key
15
9
  {
16
10
  pub(crate) uuid: u128,
17
11
  }
18
12
 
13
+ impl Key
14
+ {
15
+ /// New key from a given uuid
16
+ pub fn new(uuid: u128) -> Self
17
+ {
18
+ Self { uuid }
19
+ }
20
+ /// Return the 128bits uuid value.
21
+ pub fn uuid(&self) -> u128
22
+ {
23
+ self.uuid
24
+ }
25
+ }
26
+
19
27
  impl Serialize for Key
20
28
  {
21
29
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -79,6 +87,15 @@ pub struct Node
79
87
 
80
88
  impl Node
81
89
  {
90
+ /// Create a new node object
91
+ pub fn new(key: Key, labels: Vec<String>, properties: value::ValueMap) -> Node
92
+ {
93
+ Self {
94
+ key,
95
+ labels,
96
+ properties,
97
+ }
98
+ }
82
99
  /// uuid for the Node.
83
100
  pub fn key(&self) -> Key
84
101
  {
@@ -89,11 +106,33 @@ impl Node
89
106
  {
90
107
  &self.labels
91
108
  }
109
+ /// Mutable labels
110
+ pub fn labels_mut(&mut self) -> &mut Vec<String>
111
+ {
112
+ &mut self.labels
113
+ }
114
+ /// Edit labels
115
+ pub fn labels_edit(&mut self, editor: impl FnOnce(Vec<String>) -> Vec<String>)
116
+ {
117
+ let mut tmp = Default::default();
118
+ std::mem::swap(&mut self.labels, &mut tmp);
119
+ self.labels = editor(tmp);
120
+ }
92
121
  /// Properties.
93
122
  pub fn properties(&self) -> &value::ValueMap
94
123
  {
95
124
  &self.properties
96
125
  }
126
+ /// Properties.
127
+ pub fn take_properties(self) -> value::ValueMap
128
+ {
129
+ self.properties
130
+ }
131
+ /// Properties.
132
+ pub fn properties_mut(&mut self) -> &mut value::ValueMap
133
+ {
134
+ &mut self.properties
135
+ }
97
136
  /// Unpack Node in key, labels and properties.
98
137
  pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
99
138
  {
@@ -102,7 +141,7 @@ impl Node
102
141
  /// Convert into value map representation
103
142
  pub fn into_value_map(self) -> value::ValueMap
104
143
  {
105
- crate::map!("labels" => self.labels, "properties" => self.properties, "type" => "node")
144
+ crate::value_map!("key" => self.key, "labels" => self.labels, "properties" => self.properties, "type" => "node")
106
145
  }
107
146
  }
108
147
 
@@ -130,12 +169,6 @@ pub struct Edge
130
169
  {
131
170
  /// uuid for the Edge.
132
171
  pub(crate) key: Key,
133
- #[serde(skip_serializing)]
134
- /// source node for the Edge, this property is used internally by the engine, but is not exported in query results, and not part of the public API.
135
- pub(crate) source: Node,
136
- /// destination node for the Edge, this property is used internally by the engine, but is not exported in query results, and not part of the public API.
137
- #[serde(skip_serializing)]
138
- pub(crate) destination: Node,
139
172
  /// Labels for the Edge.
140
173
  pub(crate) labels: Vec<String>,
141
174
  /// Properties for the Edge.
@@ -144,6 +177,16 @@ pub struct Edge
144
177
 
145
178
  impl Edge
146
179
  {
180
+ /// Create a new node object
181
+ pub fn new(key: Key, labels: Vec<String>, properties: value::ValueMap) -> Edge
182
+ {
183
+ Self {
184
+ key,
185
+ labels,
186
+ properties,
187
+ }
188
+ }
189
+
147
190
  /// uuid for the Node.
148
191
  pub fn key(&self) -> Key
149
192
  {
@@ -154,11 +197,33 @@ impl Edge
154
197
  {
155
198
  &self.labels
156
199
  }
200
+ /// Mutable labels
201
+ pub fn labels_mut(&mut self) -> &mut Vec<String>
202
+ {
203
+ &mut self.labels
204
+ }
205
+ /// Edit labels
206
+ pub fn labels_edit(&mut self, editor: impl FnOnce(Vec<String>) -> Vec<String>)
207
+ {
208
+ let mut tmp = Default::default();
209
+ std::mem::swap(&mut self.labels, &mut tmp);
210
+ self.labels = editor(tmp);
211
+ }
157
212
  /// Properties.
158
213
  pub fn properties(&self) -> &value::ValueMap
159
214
  {
160
215
  &self.properties
161
216
  }
217
+ /// Properties.
218
+ pub fn properties_mut(&mut self) -> &mut value::ValueMap
219
+ {
220
+ &mut self.properties
221
+ }
222
+ /// Properties.
223
+ pub fn take_properties(self) -> value::ValueMap
224
+ {
225
+ self.properties
226
+ }
162
227
  /// Unpack Edge in key, labels and properties.
163
228
  pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
164
229
  {
@@ -167,7 +232,7 @@ impl Edge
167
232
  /// Convert into value map representation
168
233
  pub fn into_value_map(self) -> value::ValueMap
169
234
  {
170
- crate::map!( "labels" => self.labels, "properties" => self.properties, "type" => "edge")
235
+ crate::value_map!("key" => self.key, "labels" => self.labels, "properties" => self.properties, "type" => "edge")
171
236
  }
172
237
  }
173
238
 
@@ -181,24 +246,10 @@ impl std::fmt::Display for Edge
181
246
  }
182
247
  }
183
248
 
184
- impl Into<Path> for Edge
185
- {
186
- fn into(self) -> Path
187
- {
188
- Path {
189
- key: self.key,
190
- source: self.source,
191
- destination: self.destination,
192
- labels: self.labels,
193
- properties: self.properties,
194
- }
195
- }
196
- }
197
-
198
- /// Path in the graph.
249
+ /// SinglePath in the graph. A SinglePath contains an edge, source and destination.
199
250
  #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
200
251
  #[serde(tag = "type", rename = "path")]
201
- pub struct Path
252
+ pub struct SinglePath
202
253
  {
203
254
  /// uuid for the path.
204
255
  pub(crate) key: Key,
@@ -212,8 +263,25 @@ pub struct Path
212
263
  pub(crate) properties: value::ValueMap,
213
264
  }
214
265
 
215
- impl Path
266
+ impl SinglePath
216
267
  {
268
+ /// 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
276
+ {
277
+ SinglePath {
278
+ key,
279
+ source,
280
+ destination,
281
+ labels,
282
+ properties,
283
+ }
284
+ }
217
285
  /// uuid for the Node.
218
286
  pub fn key(&self) -> Key
219
287
  {
@@ -250,14 +318,32 @@ impl Path
250
318
  self.destination,
251
319
  )
252
320
  }
321
+ /// Convert into an Edge
322
+ pub fn to_edge(&self) -> Edge
323
+ {
324
+ Edge {
325
+ key: self.key,
326
+ labels: self.labels.clone(),
327
+ properties: self.properties.clone(),
328
+ }
329
+ }
330
+ /// Convert into an Edge
331
+ pub fn into_edge(self) -> Edge
332
+ {
333
+ Edge {
334
+ key: self.key,
335
+ labels: self.labels,
336
+ properties: self.properties,
337
+ }
338
+ }
253
339
  /// Convert into value map representation
254
340
  pub fn into_value_map(self) -> value::ValueMap
255
341
  {
256
- crate::map!( "source" => self.source, "labels" => self.labels, "properties" => self.properties, "destination" => self.destination, "type" => "path")
342
+ crate::value_map!("key" => self.key, "source" => self.source, "labels" => self.labels, "properties" => self.properties, "destination" => self.destination, "type" => "path")
257
343
  }
258
344
  }
259
345
 
260
- impl std::fmt::Display for Path
346
+ impl std::fmt::Display for SinglePath
261
347
  {
262
348
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
263
349
  {
@@ -267,7 +353,20 @@ impl std::fmt::Display for Path
267
353
  }
268
354
  }
269
355
 
270
- #[cfg(test)]
356
+ impl From<SinglePath> for Edge
357
+ {
358
+ fn from(val: SinglePath) -> Self
359
+ {
360
+ Edge {
361
+ key: val.key,
362
+ labels: val.labels,
363
+ properties: val.properties,
364
+ }
365
+ }
366
+ }
367
+
368
+ /// Convenient macro to create a vector of label, from &str.
369
+ #[macro_export]
271
370
  macro_rules! labels {
272
371
  // match a list of expressions separated by comma:
273
372
  ($($str:expr),*) => (
@@ -278,6 +377,3 @@ macro_rules! labels {
278
377
  }
279
378
  );
280
379
  }
281
-
282
- #[cfg(test)]
283
- pub(crate) use labels;
@@ -0,0 +1,15 @@
1
+ #![doc = include_str!("../README.MD")]
2
+ #![warn(missing_docs)]
3
+ #![allow(clippy::result_large_err)]
4
+
5
+ mod error;
6
+ mod graph;
7
+ mod prelude;
8
+ mod serialize_with;
9
+ mod table;
10
+ mod value;
11
+
12
+ pub use error::Error;
13
+ pub use graph::{Edge, Key, Node, SinglePath};
14
+ pub use table::Table;
15
+ pub use value::{Value, ValueMap, ValueTryIntoRef};
@@ -0,0 +1,4 @@
1
+ pub(crate) use crate::{error, graph, serialize_with, value};
2
+ pub(crate) use error::Error;
3
+
4
+ pub type Result<T, E = Error> = std::result::Result<T, E>;
@@ -2,7 +2,7 @@ use serde::de::{self, Visitor};
2
2
  use serde::{Deserializer, Serializer};
3
3
  use std::fmt;
4
4
 
5
- const NAN: f64 = std::f64::NAN;
5
+ const NAN: f64 = f64::NAN;
6
6
 
7
7
  pub fn serialize_float<S>(x: &f64, serializer: S) -> Result<S::Ok, S::Error>
8
8
  where
@@ -68,7 +68,7 @@ impl<'de> Visitor<'de> for FloatDeserializeVisitor
68
68
  where
69
69
  E: de::Error,
70
70
  {
71
- Ok(v as f64)
71
+ Ok(v)
72
72
  }
73
73
 
74
74
  fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>