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
@@ -43,11 +43,7 @@ fn compare_map(lhs: &value::ValueMap, rhs: &value::ValueMap) -> Ordering
43
43
  o => o.into(),
44
44
  }
45
45
  })
46
- .find(|p| match p
47
- {
48
- Ordering::Equal => false,
49
- _ => true,
50
- })
46
+ .find(|p| !matches!(p, Ordering::Equal))
51
47
  .unwrap_or(Ordering::Equal)
52
48
  }
53
49
  else if lhs.len() < rhs.len()
@@ -74,7 +70,7 @@ fn compare_f64(lhs: &f64, rhs: &f64) -> Ordering
74
70
 
75
71
  fn compare_node(lhs: &graph::Node, rhs: &graph::Node) -> Ordering
76
72
  {
77
- lhs.key.uuid.cmp(&rhs.key.uuid).into()
73
+ lhs.key().uuid().cmp(&rhs.key().uuid()).into()
78
74
  }
79
75
 
80
76
  pub(crate) fn compare(lhs: &value::Value, rhs: &value::Value) -> Ordering
@@ -83,6 +79,12 @@ pub(crate) fn compare(lhs: &value::Value, rhs: &value::Value) -> Ordering
83
79
  match lhs
84
80
  {
85
81
  Value::Null => Ordering::ComparedNull,
82
+ Value::Key(kl) => match rhs
83
+ {
84
+ Value::Key(kr) => kl.uuid().cmp(&kr.uuid()).into(),
85
+ Value::Null => Ordering::ComparedNull,
86
+ _ => Ordering::Null,
87
+ },
86
88
  Value::Boolean(bl) => match rhs
87
89
  {
88
90
  Value::Boolean(br) => bl.cmp(br).into(),
@@ -175,30 +177,21 @@ pub(crate) fn compare(lhs: &value::Value, rhs: &value::Value) -> Ordering
175
177
  },
176
178
  Value::Edge(lhs) => match rhs
177
179
  {
178
- Value::Edge(rhs) =>
179
- {
180
- lhs.key.uuid.cmp(&rhs.key.uuid).into()
181
- // let labels_cmp = lhs.labels.cmp(&rhs.labels);
182
- // match labels_cmp
183
- // {
184
- // std::cmp::Ordering::Equal => compare_map(&lhs.properties, &rhs.properties),
185
- // o => o.into(),
186
- // }
187
- }
180
+ Value::Edge(rhs) => lhs.key().uuid().cmp(&rhs.key().uuid()).into(),
188
181
  _ => Ordering::Null,
189
182
  },
190
183
  Value::Path(lhs) => match rhs
191
184
  {
192
185
  Value::Path(rhs) =>
193
186
  {
194
- let labels_cmp = lhs.labels.cmp(&rhs.labels);
187
+ let labels_cmp = lhs.labels().cmp(rhs.labels());
195
188
  match labels_cmp
196
189
  {
197
- std::cmp::Ordering::Equal => match compare_map(&lhs.properties, &rhs.properties)
190
+ std::cmp::Ordering::Equal => match compare_map(lhs.properties(), rhs.properties())
198
191
  {
199
- Ordering::Equal => match compare_node(&lhs.source, &rhs.source)
192
+ Ordering::Equal => match compare_node(lhs.source(), rhs.source())
200
193
  {
201
- Ordering::Equal => compare_node(&lhs.destination, &rhs.destination),
194
+ Ordering::Equal => compare_node(lhs.destination(), rhs.destination()),
202
195
  o => o,
203
196
  },
204
197
  o => o,
@@ -8,7 +8,7 @@ pub(crate) enum ContainResult
8
8
  }
9
9
 
10
10
  /// Compute contains, according to OpenCypher specification, specifically handling the comparison with null.
11
- pub(crate) fn contains(container: &Vec<value::Value>, value: &value::Value) -> ContainResult
11
+ pub(crate) fn contains(container: &[value::Value], value: &value::Value) -> ContainResult
12
12
  {
13
13
  if value.is_null()
14
14
  {
@@ -27,7 +27,7 @@ pub(crate) fn contains(container: &Vec<value::Value>, value: &value::Value) -> C
27
27
  for v_c in container.iter()
28
28
  {
29
29
  use value::ContainResult;
30
- match value::compare(v_c, &value)
30
+ match value::compare(v_c, value)
31
31
  {
32
32
  value::Ordering::Equal => return ContainResult::True,
33
33
  value::Ordering::ComparedNull => has_compared_to_null = true,
@@ -0,0 +1,225 @@
1
+ mod compare;
2
+ mod contains;
3
+
4
+ pub(crate) use compare::{compare, Ordering};
5
+ pub(crate) use contains::{contains, ContainResult};
6
+
7
+ pub use graphcore::{array, value_map, Value, ValueMap, ValueTryIntoRef};
8
+
9
+ pub(crate) trait ValueExt
10
+ {
11
+ fn access<'a>(&self, path: impl Iterator<Item = &'a String>) -> Value;
12
+ fn compare(&self, rhs: &Value) -> crate::value::Ordering;
13
+
14
+ /// Compute the order between self and rhs, for OrderBy, according to the OpenCypher specification.
15
+ /// This order is total.
16
+ fn orderability(&self, rhs: &Value) -> std::cmp::Ordering;
17
+ }
18
+
19
+ fn orderability_map(lhs: &ValueMap, rhs: &ValueMap) -> std::cmp::Ordering
20
+ {
21
+ let o = lhs.len().cmp(&rhs.len());
22
+ match o
23
+ {
24
+ std::cmp::Ordering::Equal => lhs
25
+ .iter()
26
+ .map(|(key, value)| value.orderability(rhs.get(key).unwrap_or(&Value::Null)))
27
+ .find(|p| *p != std::cmp::Ordering::Equal)
28
+ .unwrap_or(std::cmp::Ordering::Equal),
29
+ o => o,
30
+ }
31
+ }
32
+ fn orderability_float(lhs: &f64, rhs: &f64) -> std::cmp::Ordering
33
+ {
34
+ if lhs.is_nan()
35
+ {
36
+ if rhs.is_nan()
37
+ {
38
+ std::cmp::Ordering::Equal
39
+ }
40
+ else
41
+ {
42
+ std::cmp::Ordering::Greater
43
+ }
44
+ }
45
+ else if rhs.is_nan()
46
+ {
47
+ std::cmp::Ordering::Less
48
+ }
49
+ else
50
+ {
51
+ lhs.total_cmp(rhs)
52
+ }
53
+ }
54
+ impl ValueExt for Value
55
+ {
56
+ fn access<'a>(&self, mut path: impl Iterator<Item = &'a String>) -> Value
57
+ {
58
+ match path.next()
59
+ {
60
+ Some(name) => match self
61
+ {
62
+ Value::Node(node) => match node.properties().get(name)
63
+ {
64
+ Some(val) => val.access(path),
65
+ None => Value::Null,
66
+ },
67
+ Value::Edge(edge) => match edge.properties().get(name)
68
+ {
69
+ Some(val) => val.access(path),
70
+ None => Value::Null,
71
+ },
72
+ Value::Map(obj) => match obj.get(name)
73
+ {
74
+ Some(val) => val.access(path),
75
+ None => Value::Null,
76
+ },
77
+ _ => Value::Null,
78
+ },
79
+ None => self.to_owned(),
80
+ }
81
+ }
82
+ fn compare(&self, rhs: &Value) -> crate::value::Ordering
83
+ {
84
+ crate::value::compare(self, rhs)
85
+ }
86
+
87
+ /// Compute the order between self and rhs, for OrderBy, according to the OpenCypher specification.
88
+ /// This order is total.
89
+ fn orderability(&self, rhs: &Value) -> std::cmp::Ordering
90
+ {
91
+ match self
92
+ {
93
+ Value::Null => match rhs
94
+ {
95
+ Value::Null => std::cmp::Ordering::Equal,
96
+ _ => std::cmp::Ordering::Greater,
97
+ },
98
+ Value::Key(lhs) => match rhs
99
+ {
100
+ Value::Null => std::cmp::Ordering::Less,
101
+ Value::Key(rhs) => lhs.uuid().cmp(&rhs.uuid()),
102
+ _ => std::cmp::Ordering::Greater,
103
+ },
104
+ Value::Integer(lhs) => match rhs
105
+ {
106
+ Value::Null | Value::Key(..) => std::cmp::Ordering::Less,
107
+ Value::Integer(rhs) => lhs.cmp(rhs),
108
+ Value::Float(rhs) => orderability_float(&(*lhs as f64), rhs),
109
+ _ => std::cmp::Ordering::Greater,
110
+ },
111
+ Value::Float(lhs) => match rhs
112
+ {
113
+ Value::Null | Value::Key(..) => std::cmp::Ordering::Less,
114
+ Value::Integer(rhs) => orderability_float(lhs, &(*rhs as f64)),
115
+ Value::Float(rhs) => orderability_float(lhs, rhs),
116
+ _ => std::cmp::Ordering::Greater,
117
+ },
118
+ Value::Boolean(lhs) => match rhs
119
+ {
120
+ Value::Null | Value::Key(..) | Value::Integer(..) | Value::Float(..) =>
121
+ {
122
+ std::cmp::Ordering::Less
123
+ }
124
+ Value::Boolean(rhs) => lhs.cmp(rhs),
125
+ _ => std::cmp::Ordering::Greater,
126
+ },
127
+ Value::String(lhs) => match rhs
128
+ {
129
+ Value::Null
130
+ | Value::Key(..)
131
+ | Value::Integer(..)
132
+ | Value::Float(..)
133
+ | Value::Boolean(..) => std::cmp::Ordering::Less,
134
+ Value::String(rhs) => lhs.cmp(rhs),
135
+ _ => std::cmp::Ordering::Greater,
136
+ },
137
+ Value::Path(lhs) => match rhs
138
+ {
139
+ Value::Null
140
+ | Value::Key(..)
141
+ | Value::Integer(..)
142
+ | Value::Float(..)
143
+ | Value::Boolean(..)
144
+ | Value::String(..) => std::cmp::Ordering::Less,
145
+ Value::Path(rhs) =>
146
+ {
147
+ match orderability_map(lhs.source().properties(), rhs.source().properties())
148
+ {
149
+ std::cmp::Ordering::Equal =>
150
+ {
151
+ match orderability_map(lhs.properties(), rhs.properties())
152
+ {
153
+ std::cmp::Ordering::Equal => orderability_map(
154
+ lhs.destination().properties(),
155
+ rhs.destination().properties(),
156
+ ),
157
+ o => o,
158
+ }
159
+ }
160
+ o => o,
161
+ }
162
+ }
163
+ _ => std::cmp::Ordering::Greater,
164
+ },
165
+ Value::Array(lhs) => match rhs
166
+ {
167
+ Value::Null
168
+ | Value::Key(..)
169
+ | Value::Integer(..)
170
+ | Value::Float(..)
171
+ | Value::Boolean(..)
172
+ | Value::String(..)
173
+ | Value::Path(..) => std::cmp::Ordering::Less,
174
+ Value::Array(rhs) => lhs
175
+ .iter()
176
+ .zip(rhs.iter())
177
+ .map(|(lhs, rhs)| Self::orderability(lhs, rhs))
178
+ .find(|p| *p != std::cmp::Ordering::Equal)
179
+ .unwrap_or(lhs.len().cmp(&rhs.len())),
180
+ _ => std::cmp::Ordering::Greater,
181
+ },
182
+ Value::Edge(lhs) => match rhs
183
+ {
184
+ Value::Null
185
+ | Value::Key(..)
186
+ | Value::Integer(..)
187
+ | Value::Float(..)
188
+ | Value::Boolean(..)
189
+ | Value::String(..)
190
+ | Value::Path(..)
191
+ | Value::Array(..) => std::cmp::Ordering::Less,
192
+ Value::Edge(rhs) => orderability_map(lhs.properties(), rhs.properties()),
193
+ _ => std::cmp::Ordering::Greater,
194
+ },
195
+ Value::Node(lhs) => match rhs
196
+ {
197
+ Value::Null
198
+ | Value::Key(..)
199
+ | Value::Integer(..)
200
+ | Value::Float(..)
201
+ | Value::Boolean(..)
202
+ | Value::String(..)
203
+ | Value::Path(..)
204
+ | Value::Array(..)
205
+ | Value::Edge(..) => std::cmp::Ordering::Less,
206
+ Value::Node(rhs) => orderability_map(lhs.properties(), rhs.properties()),
207
+ _ => std::cmp::Ordering::Greater,
208
+ },
209
+ Value::Map(lhs) => match rhs
210
+ {
211
+ Value::Null
212
+ | Value::Key(..)
213
+ | Value::Integer(..)
214
+ | Value::Float(..)
215
+ | Value::Boolean(..)
216
+ | Value::String(..)
217
+ | Value::Path(..)
218
+ | Value::Array(..)
219
+ | Value::Edge(..)
220
+ | Value::Node(..) => std::cmp::Ordering::Less,
221
+ Value::Map(rhs) => orderability_map(lhs, rhs),
222
+ },
223
+ }
224
+ }
225
+ }
@@ -53,7 +53,7 @@ impl Row
53
53
  {
54
54
  Err(
55
55
  InternalError::InvalidIndex {
56
- index: index,
56
+ index,
57
57
  length: self.values.len(),
58
58
  }
59
59
  .into(),
@@ -138,11 +138,11 @@ impl MutableRowInterface for Row
138
138
  }
139
139
  }
140
140
 
141
- impl Into<value::Value> for Row
141
+ impl From<Row> for value::Value
142
142
  {
143
- fn into(self) -> value::Value
143
+ fn from(v: Row) -> Self
144
144
  {
145
- value::Value::Array(self.values)
145
+ value::Value::Array(v.values)
146
146
  }
147
147
  }
148
148
 
@@ -154,6 +154,16 @@ impl FromIterator<value::Value> for Row
154
154
  }
155
155
  }
156
156
 
157
+ impl IntoIterator for Row
158
+ {
159
+ type Item = value::Value;
160
+ type IntoIter = <Vec<Self::Item> as IntoIterator>::IntoIter;
161
+ fn into_iter(self) -> Self::IntoIter
162
+ {
163
+ self.values.into_iter()
164
+ }
165
+ }
166
+
157
167
  pub(crate) trait Header
158
168
  {
159
169
  fn columns(&self) -> usize;
@@ -443,7 +453,7 @@ impl Iterator for IntoRowIter
443
453
  else
444
454
  {
445
455
  let v: Vec<_> = self.data.by_ref().take(self.columns).collect();
446
- if v.len() == 0
456
+ if v.is_empty()
447
457
  {
448
458
  None
449
459
  }
@@ -1,44 +1,21 @@
1
- # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
2
- #
3
- # When uploading crates to the registry Cargo will automatically
4
- # "normalize" Cargo.toml files for maximal compatibility
5
- # with all versions of Cargo and also rewrite `path` dependencies
6
- # to registry (e.g., crates.io) dependencies.
7
- #
8
- # If you are reading this file be aware that the original Cargo.toml
9
- # will likely look very different (and much more reasonable).
10
- # See Cargo.toml.orig for the original contents.
11
-
12
1
  [package]
13
- edition = "2021"
14
2
  name = "gqliterb"
15
- version = "0.5.3"
16
- build = false
17
- autolib = false
18
- autobins = false
19
- autoexamples = false
20
- autotests = false
21
- autobenches = false
22
3
  description = "Crate with the Ruby bindings for GQLite."
23
- homepage = "https://gqlite.org"
24
- readme = false
25
- license = "MIT"
26
- repository = "https://gitlab.com/gqlite/gqlite"
27
-
28
- [package.metadata.release]
29
- release = false
4
+ version.workspace = true
5
+ edition.workspace = true
6
+ license.workspace = true
7
+ homepage.workspace = true
8
+ repository.workspace = true
30
9
 
31
10
  [lib]
32
- name = "gqliterb"
33
11
  crate-type = ["cdylib"]
34
- path = "src/lib.rs"
35
12
 
36
- [dependencies.gqlitedb]
37
- version = "0.5.3"
38
- features = []
13
+ [dependencies]
14
+ gqlitedb = { workspace = true }
15
+ magnus = "0.8"
39
16
 
40
- [dependencies.magnus]
41
- version = "0.7"
17
+ [build-dependencies]
18
+ rb-sys-env = "0.2"
42
19
 
43
- [build-dependencies.rb-sys-env]
44
- version = "0.2"
20
+ [package.metadata.release]
21
+ release = false
@@ -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,7 +206,7 @@ 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(),
@@ -213,7 +218,9 @@ impl Connection
213
218
  .path(filename)
214
219
  .create(),
215
220
  )?;
216
- Ok(Self { dbhandle })
221
+ Ok(Self {
222
+ dbhandle: std::sync::RwLock::new(Some(dbhandle)),
223
+ })
217
224
  }
218
225
  fn execute_oc_query(
219
226
  ruby: &Ruby,
@@ -221,32 +228,46 @@ impl Connection
221
228
  args: &[magnus::Value],
222
229
  ) -> Result<magnus::Value, Error>
223
230
  {
224
- let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
225
- 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;
226
237
 
227
- let kw = scan_args::get_kwargs::<_, (), (Option<magnus::Value>,), ()>(
228
- args.keywords,
229
- &[],
230
- &["bindings"],
231
- )?;
232
- 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;
233
244
 
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))?;
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))?;
248
259
 
249
- 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;
250
271
  }
251
272
  }
252
273
 
@@ -262,5 +283,6 @@ fn init(ruby: &Ruby) -> Result<(), Error>
262
283
  "execute_oc_query",
263
284
  method!(Connection::execute_oc_query, -1),
264
285
  )?;
286
+ class.define_method("close", method!(Connection::close, 0))?;
265
287
  Ok(())
266
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
+ }