gqlite 1.2.2 → 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 (104) 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}/release.toml +2 -2
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +34 -10
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
  16. data/ext/gqlitedb/src/connection.rs +300 -0
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
  22. data/ext/gqlitedb/src/functions/path.rs +75 -0
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
  25. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
  27. data/ext/gqlitedb/src/graph.rs +11 -0
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
  31. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
  32. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
  33. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
  34. data/ext/gqlitedb/src/parser.rs +4 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  36. data/ext/gqlitedb/src/query_result.rs +88 -0
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +260 -170
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
  44. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  46. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  47. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  48. data/ext/gqlitedb/src/value.rs +225 -0
  49. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +22 -18
  50. data/ext/gqliterb/Cargo.toml +12 -34
  51. data/ext/gqliterb/src/lib.rs +67 -39
  52. data/ext/graphcore/Cargo.toml +19 -0
  53. data/ext/graphcore/README.MD +4 -0
  54. data/ext/graphcore/release.toml +1 -0
  55. data/ext/graphcore/src/error.rs +28 -0
  56. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +146 -35
  57. data/ext/graphcore/src/lib.rs +16 -0
  58. data/ext/graphcore/src/prelude.rs +4 -0
  59. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  60. data/ext/graphcore/src/table.rs +272 -0
  61. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  62. data/ext/graphcore/src/value.rs +413 -0
  63. metadata +94 -83
  64. data/ext/gqliterb/.cargo/config.toml +0 -2
  65. data/ext/gqliterb/Cargo.lock +0 -1109
  66. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
  67. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
  68. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
  69. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
  70. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  71. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  103. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  104. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -1,5 +1,7 @@
1
1
  #![deny(warnings)]
2
2
 
3
+ use std::fmt::Display;
4
+
3
5
  use magnus::{
4
6
  function, method,
5
7
  prelude::*,
@@ -113,7 +115,7 @@ fn node_to_rhash(ruby: &Ruby, node: gqlitedb::Node) -> Result<magnus::Value, Err
113
115
  r_hash.aset("key", integer_from_u128(ruby, key.into())?)?;
114
116
  r_hash.aset("labels", labels)?;
115
117
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
116
- Ok(r_hash.into_value())
118
+ Ok(r_hash.into_value_with(ruby))
117
119
  }
118
120
 
119
121
  fn edge_to_rhash(ruby: &Ruby, edge: gqlitedb::Edge) -> Result<magnus::Value, Error>
@@ -124,7 +126,7 @@ fn edge_to_rhash(ruby: &Ruby, edge: gqlitedb::Edge) -> Result<magnus::Value, Err
124
126
  r_hash.aset("key", integer_from_u128(ruby, key.into())?)?;
125
127
  r_hash.aset("labels", labels)?;
126
128
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
127
- Ok(r_hash.into_value())
129
+ Ok(r_hash.into_value_with(ruby))
128
130
  }
129
131
 
130
132
  fn path_to_rhash(ruby: &Ruby, path: gqlitedb::Path) -> Result<magnus::Value, Error>
@@ -137,20 +139,21 @@ fn path_to_rhash(ruby: &Ruby, path: gqlitedb::Path) -> Result<magnus::Value, Err
137
139
  r_hash.aset("properties", to_rhash(ruby, properties)?)?;
138
140
  r_hash.aset("source", node_to_rhash(ruby, source)?)?;
139
141
  r_hash.aset("destination", node_to_rhash(ruby, destination)?)?;
140
- Ok(r_hash.into_value())
142
+ Ok(r_hash.into_value_with(ruby))
141
143
  }
142
144
 
143
145
  fn to_rvalue(ruby: &Ruby, val: gqlitedb::Value) -> Result<magnus::Value, Error>
144
146
  {
145
147
  match val
146
148
  {
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()),
149
+ gqlitedb::Value::Array(arr) => Ok(to_rarray(ruby, arr)?.into_value_with(ruby)),
150
+ gqlitedb::Value::Boolean(b) => Ok(b.into_value_with(ruby)),
151
+ gqlitedb::Value::Key(k) => Ok(integer_from_u128(ruby, k.into())?.into_value_with(ruby)),
152
+ gqlitedb::Value::Integer(i) => Ok(i.into_value_with(ruby)),
153
+ gqlitedb::Value::Float(f) => Ok(f.into_value_with(ruby)),
154
+ gqlitedb::Value::String(s) => Ok(s.into_value_with(ruby)),
155
+ gqlitedb::Value::Map(m) => Ok(to_rhash(ruby, m)?.into_value_with(ruby)),
156
+ gqlitedb::Value::Null => Ok(ruby.qnil().into_value_with(ruby)),
154
157
  gqlitedb::Value::Edge(e) => Ok(edge_to_rhash(ruby, e)?),
155
158
  gqlitedb::Value::Node(n) => Ok(node_to_rhash(ruby, n)?),
156
159
  gqlitedb::Value::Path(p) => Ok(path_to_rhash(ruby, p)?),
@@ -169,7 +172,7 @@ fn to_rhash(ruby: &Ruby, map: gqlitedb::ValueMap) -> Result<r_hash::RHash, Error
169
172
 
170
173
  fn to_rarray(ruby: &Ruby, arr: Vec<gqlitedb::Value>) -> Result<r_array::RArray, Error>
171
174
  {
172
- let r_arr = r_array::RArray::with_capacity(arr.len());
175
+ let r_arr = ruby.ary_new_capa(arr.len());
173
176
 
174
177
  for value in arr.into_iter()
175
178
  {
@@ -179,7 +182,9 @@ fn to_rarray(ruby: &Ruby, arr: Vec<gqlitedb::Value>) -> Result<r_array::RArray,
179
182
  Ok(r_arr)
180
183
  }
181
184
 
182
- fn map_err<T>(ruby: &Ruby, result: gqlitedb::Result<T>) -> Result<T, Error>
185
+ fn map_err<T, E>(ruby: &Ruby, result: Result<T, E>) -> Result<T, Error>
186
+ where
187
+ E: Display,
183
188
  {
184
189
  result.map_err(|e| Error::new(ruby.get_inner(&ERROR), format!("{}", e)))
185
190
  }
@@ -187,7 +192,7 @@ fn map_err<T>(ruby: &Ruby, result: gqlitedb::Result<T>) -> Result<T, Error>
187
192
  #[magnus::wrap(class = "GQLite::Connection")]
188
193
  struct Connection
189
194
  {
190
- dbhandle: gqlitedb::Connection,
195
+ dbhandle: std::sync::RwLock<Option<gqlitedb::Connection>>,
191
196
  }
192
197
 
193
198
  impl Connection
@@ -201,13 +206,21 @@ impl Connection
201
206
  let filename: String = map_err(
202
207
  ruby,
203
208
  options
204
- .get("filename".into())
209
+ .get("filename")
205
210
  .ok_or_else(|| Error::new(ruby.get_inner(&ERROR), "Missing filename."))?
206
211
  .to_owned()
207
212
  .try_into(),
208
213
  )?;
209
- let dbhandle = map_err(ruby, gqlitedb::Connection::open(filename, options))?;
210
- Ok(Self { dbhandle })
214
+ let dbhandle = map_err(
215
+ ruby,
216
+ gqlitedb::Connection::builder()
217
+ .options(options)
218
+ .path(filename)
219
+ .create(),
220
+ )?;
221
+ Ok(Self {
222
+ dbhandle: std::sync::RwLock::new(Some(dbhandle)),
223
+ })
211
224
  }
212
225
  fn execute_oc_query(
213
226
  ruby: &Ruby,
@@ -215,32 +228,46 @@ impl Connection
215
228
  args: &[magnus::Value],
216
229
  ) -> Result<magnus::Value, Error>
217
230
  {
218
- let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
219
- let (query,): (String,) = args.required;
231
+ match &*rb_self.dbhandle.read().unwrap()
232
+ {
233
+ Some(connection) =>
234
+ {
235
+ let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
236
+ let (query,): (String,) = args.required;
220
237
 
221
- let kw = scan_args::get_kwargs::<_, (), (Option<magnus::Value>,), ()>(
222
- args.keywords,
223
- &[],
224
- &["bindings"],
225
- )?;
226
- let (bindings,) = kw.optional;
238
+ let kw = scan_args::get_kwargs::<_, (), (Option<magnus::Value>,), ()>(
239
+ args.keywords,
240
+ &[],
241
+ &["bindings"],
242
+ )?;
243
+ let (bindings,) = kw.optional;
227
244
 
228
- let bindings = bindings
229
- .map(|bindings| {
230
- if bindings.is_nil()
231
- {
232
- Ok(Default::default())
233
- }
234
- else
235
- {
236
- from_rhash(ruby, r_hash::RHash::try_convert(bindings)?)
237
- }
238
- })
239
- .transpose()?
240
- .unwrap_or_default();
241
- let result = map_err(ruby, rb_self.dbhandle.execute_query(query, bindings))?;
245
+ let bindings = bindings
246
+ .map(|bindings| {
247
+ if bindings.is_nil()
248
+ {
249
+ Ok(Default::default())
250
+ }
251
+ else
252
+ {
253
+ from_rhash(ruby, r_hash::RHash::try_convert(bindings)?)
254
+ }
255
+ })
256
+ .transpose()?
257
+ .unwrap_or_default();
258
+ let result = map_err(ruby, connection.execute_oc_query(query, bindings))?;
242
259
 
243
- to_rvalue(ruby, result)
260
+ to_rvalue(ruby, result.into_value())
261
+ }
262
+ None => Err(Error::new(
263
+ ruby.get_inner(&ERROR),
264
+ "Connection is closed.".to_string(),
265
+ )),
266
+ }
267
+ }
268
+ fn close(&self)
269
+ {
270
+ *self.dbhandle.write().unwrap() = None;
244
271
  }
245
272
  }
246
273
 
@@ -256,5 +283,6 @@ fn init(ruby: &Ruby) -> Result<(), Error>
256
283
  "execute_oc_query",
257
284
  method!(Connection::execute_oc_query, -1),
258
285
  )?;
286
+ class.define_method("close", method!(Connection::close, 0))?;
259
287
  Ok(())
260
288
  }
@@ -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.0"
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,16 +106,43 @@ 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
  {
100
139
  (self.key, self.labels, self.properties)
101
140
  }
141
+ /// Convert into value map representation
142
+ pub fn into_value_map(self) -> value::ValueMap
143
+ {
144
+ crate::value_map!("key" => self.key, "labels" => self.labels, "properties" => self.properties, "type" => "node")
145
+ }
102
146
  }
103
147
 
104
148
  impl std::fmt::Display for Node
@@ -125,12 +169,6 @@ pub struct Edge
125
169
  {
126
170
  /// uuid for the Edge.
127
171
  pub(crate) key: Key,
128
- #[serde(skip_serializing)]
129
- /// 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.
130
- pub(crate) source: Node,
131
- /// 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.
132
- #[serde(skip_serializing)]
133
- pub(crate) destination: Node,
134
172
  /// Labels for the Edge.
135
173
  pub(crate) labels: Vec<String>,
136
174
  /// Properties for the Edge.
@@ -139,6 +177,16 @@ pub struct Edge
139
177
 
140
178
  impl Edge
141
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
+
142
190
  /// uuid for the Node.
143
191
  pub fn key(&self) -> Key
144
192
  {
@@ -149,16 +197,43 @@ impl Edge
149
197
  {
150
198
  &self.labels
151
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
+ }
152
212
  /// Properties.
153
213
  pub fn properties(&self) -> &value::ValueMap
154
214
  {
155
215
  &self.properties
156
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
+ }
157
227
  /// Unpack Edge in key, labels and properties.
158
228
  pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
159
229
  {
160
230
  (self.key, self.labels, self.properties)
161
231
  }
232
+ /// Convert into value map representation
233
+ pub fn into_value_map(self) -> value::ValueMap
234
+ {
235
+ crate::value_map!("key" => self.key, "labels" => self.labels, "properties" => self.properties, "type" => "edge")
236
+ }
162
237
  }
163
238
 
164
239
  impl std::fmt::Display for Edge
@@ -171,24 +246,10 @@ impl std::fmt::Display for Edge
171
246
  }
172
247
  }
173
248
 
174
- impl Into<Path> for Edge
175
- {
176
- fn into(self) -> Path
177
- {
178
- Path {
179
- key: self.key,
180
- source: self.source,
181
- destination: self.destination,
182
- labels: self.labels,
183
- properties: self.properties,
184
- }
185
- }
186
- }
187
-
188
- /// Path in the graph.
249
+ /// SinglePath in the graph. A SinglePath contains an edge, source and destination.
189
250
  #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
190
251
  #[serde(tag = "type", rename = "path")]
191
- pub struct Path
252
+ pub struct SinglePath
192
253
  {
193
254
  /// uuid for the path.
194
255
  pub(crate) key: Key,
@@ -202,8 +263,25 @@ pub struct Path
202
263
  pub(crate) properties: value::ValueMap,
203
264
  }
204
265
 
205
- impl Path
266
+ impl SinglePath
206
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
+ }
207
285
  /// uuid for the Node.
208
286
  pub fn key(&self) -> Key
209
287
  {
@@ -240,9 +318,32 @@ impl Path
240
318
  self.destination,
241
319
  )
242
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
+ }
339
+ /// Convert into value map representation
340
+ pub fn into_value_map(self) -> value::ValueMap
341
+ {
342
+ crate::value_map!("key" => self.key, "source" => self.source, "labels" => self.labels, "properties" => self.properties, "destination" => self.destination, "type" => "path")
343
+ }
243
344
  }
244
345
 
245
- impl std::fmt::Display for Path
346
+ impl std::fmt::Display for SinglePath
246
347
  {
247
348
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
248
349
  {
@@ -252,7 +353,20 @@ impl std::fmt::Display for Path
252
353
  }
253
354
  }
254
355
 
255
- #[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]
256
370
  macro_rules! labels {
257
371
  // match a list of expressions separated by comma:
258
372
  ($($str:expr),*) => (
@@ -263,6 +377,3 @@ macro_rules! labels {
263
377
  }
264
378
  );
265
379
  }
266
-
267
- #[cfg(test)]
268
- pub(crate) use labels;
@@ -0,0 +1,16 @@
1
+ #![doc = include_str!("../README.MD")]
2
+ #![warn(missing_docs)]
3
+ #![deny(warnings)]
4
+ #![allow(clippy::result_large_err)]
5
+
6
+ mod error;
7
+ mod graph;
8
+ mod prelude;
9
+ mod serialize_with;
10
+ mod table;
11
+ mod value;
12
+
13
+ pub use error::Error;
14
+ pub use graph::{Edge, Key, Node, SinglePath};
15
+ pub use table::Table;
16
+ 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>