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.
- checksums.yaml +4 -4
- data/ext/Cargo.toml +20 -0
- data/ext/gqlitedb/Cargo.toml +77 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
- data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
- data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
- data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +10 -9
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +6 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +27 -31
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +37 -41
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/connection.rs +42 -84
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +105 -34
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +2 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +2 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +1 -1
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/path.rs +15 -20
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +2 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +6 -6
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +20 -20
- data/ext/gqlitedb/src/graph.rs +11 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +160 -194
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +2 -1
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +44 -52
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +1 -1
- data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +50 -28
- data/ext/gqlitedb/src/parser.rs +4 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
- data/ext/gqlitedb/src/query_result.rs +88 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +226 -148
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +111 -128
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +22 -22
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +32 -76
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +95 -111
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
- data/ext/gqlitedb/src/value.rs +225 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +15 -5
- data/ext/gqliterb/Cargo.toml +12 -35
- data/ext/gqliterb/src/lib.rs +60 -38
- data/ext/graphcore/Cargo.toml +19 -0
- data/ext/graphcore/README.MD +4 -0
- data/ext/graphcore/release.toml +1 -0
- data/ext/graphcore/src/error.rs +28 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +134 -38
- data/ext/graphcore/src/lib.rs +16 -0
- data/ext/graphcore/src/prelude.rs +4 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
- data/ext/graphcore/src/table.rs +272 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
- data/ext/graphcore/src/value.rs +413 -0
- metadata +94 -83
- data/ext/gqliterb/.cargo/config.toml +0 -2
- data/ext/gqliterb/Cargo.lock +0 -1116
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2115
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -138
- data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
- data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -609
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
- /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|
|
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(
|
187
|
+
let labels_cmp = lhs.labels().cmp(rhs.labels());
|
195
188
|
match labels_cmp
|
196
189
|
{
|
197
|
-
std::cmp::Ordering::Equal => match compare_map(
|
190
|
+
std::cmp::Ordering::Equal => match compare_map(lhs.properties(), rhs.properties())
|
198
191
|
{
|
199
|
-
Ordering::Equal => match compare_node(
|
192
|
+
Ordering::Equal => match compare_node(lhs.source(), rhs.source())
|
200
193
|
{
|
201
|
-
Ordering::Equal => compare_node(
|
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: &
|
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,
|
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
|
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
|
141
|
+
impl From<Row> for value::Value
|
142
142
|
{
|
143
|
-
fn
|
143
|
+
fn from(v: Row) -> Self
|
144
144
|
{
|
145
|
-
value::Value::Array(
|
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.
|
456
|
+
if v.is_empty()
|
447
457
|
{
|
448
458
|
None
|
449
459
|
}
|
data/ext/gqliterb/Cargo.toml
CHANGED
@@ -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
|
-
|
24
|
-
|
25
|
-
license =
|
26
|
-
|
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
|
37
|
-
|
38
|
-
|
13
|
+
[dependencies]
|
14
|
+
gqlitedb = { workspace = true }
|
15
|
+
magnus = "0.8"
|
39
16
|
|
40
|
-
[dependencies
|
41
|
-
|
17
|
+
[build-dependencies]
|
18
|
+
rb-sys-env = "0.2"
|
42
19
|
|
43
|
-
[
|
44
|
-
|
20
|
+
[package.metadata.release]
|
21
|
+
release = false
|
data/ext/gqliterb/src/lib.rs
CHANGED
@@ -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.
|
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.
|
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.
|
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)?.
|
148
|
-
gqlitedb::Value::Boolean(b) => Ok(b.
|
149
|
-
gqlitedb::Value::
|
150
|
-
gqlitedb::Value::
|
151
|
-
gqlitedb::Value::
|
152
|
-
gqlitedb::Value::
|
153
|
-
gqlitedb::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 =
|
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:
|
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"
|
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 {
|
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
|
-
|
225
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
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
|
-
|
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
|
+
 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
|
+
}
|