gqlite 1.3.0 → 1.4.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 +4 -3
- data/ext/gqlitedb/Cargo.toml +7 -4
- data/ext/gqlitedb/src/aggregators/arithmetic.rs +1 -0
- data/ext/gqlitedb/src/compiler/expression_analyser.rs +2 -0
- data/ext/gqlitedb/src/compiler.rs +31 -19
- data/ext/gqlitedb/src/connection.rs +42 -7
- data/ext/gqlitedb/src/error.rs +3 -0
- data/ext/gqlitedb/src/functions/containers.rs +1 -1
- data/ext/gqlitedb/src/functions/path.rs +1 -1
- data/ext/gqlitedb/src/functions/scalar.rs +23 -0
- data/ext/gqlitedb/src/functions.rs +8 -0
- data/ext/gqlitedb/src/interpreter/evaluators.rs +10 -10
- data/ext/gqlitedb/src/interpreter/instructions.rs +3 -3
- data/ext/gqlitedb/src/lib.rs +1 -3
- data/ext/gqlitedb/src/parser/ast.rs +1 -0
- data/ext/gqlitedb/src/parser/gql.pest +3 -1
- data/ext/gqlitedb/src/parser/parser_impl.rs +8 -0
- data/ext/gqlitedb/src/prelude.rs +3 -0
- data/ext/gqlitedb/src/store/{pgql.rs → pgrx.rs} +2 -0
- data/ext/gqlitedb/src/store/postgres.rs +0 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +117 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlqueries.rs +62 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +55 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlvalue.rs +189 -0
- data/ext/gqlitedb/src/store/sqlbase.rs +456 -0
- data/ext/gqlitedb/src/store/sqlite.rs +271 -573
- data/ext/gqlitedb/src/store.rs +7 -5
- data/ext/gqlitedb/src/tests/templates/programs.rs +10 -10
- data/ext/gqlitedb/src/utils.rs +25 -0
- data/ext/gqlitedb/src/value/compare.rs +6 -0
- data/ext/gqlitedb/src/value.rs +18 -2
- data/ext/gqlitedb/templates/sql/sqlite/edge_select.sql +18 -18
- data/ext/gqlitedb/templates/sql/sqlite/edge_update.sql +3 -3
- data/ext/gqlitedb/templates/sql/sqlite/node_select.sql +6 -6
- data/ext/gqlitedb/templates/sql/sqlite/node_update.sql +3 -3
- data/ext/gqliterb/src/lib.rs +30 -2
- data/ext/graphcore/Cargo.toml +3 -2
- data/ext/graphcore/src/error.rs +2 -0
- data/ext/graphcore/src/lib.rs +2 -1
- data/ext/graphcore/src/prelude.rs +1 -1
- data/ext/graphcore/src/table.rs +1 -1
- data/ext/graphcore/src/timestamp.rs +104 -0
- data/ext/graphcore/src/value.rs +106 -23
- metadata +10 -7
- data/ext/gqlitedb/gqlite_bench_data/README.MD +0 -6
- data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +0 -85
- data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +0 -34
- data/ext/graphcore/release.toml +0 -1
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
use std::collections::HashSet;
|
|
2
|
+
|
|
3
|
+
use crate::{prelude::*, store::EdgeResult, utils::hex};
|
|
4
|
+
|
|
5
|
+
mod sqlmetadata;
|
|
6
|
+
mod sqlqueries;
|
|
7
|
+
mod sqlstore;
|
|
8
|
+
mod sqlvalue;
|
|
9
|
+
|
|
10
|
+
pub(crate) use sqlmetadata::{SqlMetaDataQueries, SqlMetaDataStore};
|
|
11
|
+
pub(crate) use sqlqueries::SqlQueries;
|
|
12
|
+
pub(crate) use sqlstore::{Row, SqlStore};
|
|
13
|
+
pub(crate) use sqlvalue::{FromSqlValue, IntoBindings, SqlValue};
|
|
14
|
+
|
|
15
|
+
ccutils::alias!(pub(crate) PersistentKey, graph::Key, derive: Debug, PartialEq);
|
|
16
|
+
|
|
17
|
+
/// Implementation of a GQLite store for all type that implements the SqlStore trait
|
|
18
|
+
impl<TStore> store::Store for TStore
|
|
19
|
+
where
|
|
20
|
+
TStore: SqlStore + SqlMetaDataQueries + SqlQueries,
|
|
21
|
+
{
|
|
22
|
+
type TransactionBox = <Self as SqlStore>::TransactionBox;
|
|
23
|
+
fn begin_read(&self) -> Result<Self::TransactionBox>
|
|
24
|
+
{
|
|
25
|
+
<Self as SqlStore>::begin_sql_read(self)
|
|
26
|
+
}
|
|
27
|
+
fn begin_write(&self) -> Result<Self::TransactionBox>
|
|
28
|
+
{
|
|
29
|
+
<Self as SqlStore>::begin_sql_write(self)
|
|
30
|
+
}
|
|
31
|
+
fn graphs_list(&self, transaction: &mut Self::TransactionBox) -> Result<Vec<String>>
|
|
32
|
+
{
|
|
33
|
+
self.get_metadata_value_json(transaction, "graphs")
|
|
34
|
+
}
|
|
35
|
+
fn create_graph(
|
|
36
|
+
&self,
|
|
37
|
+
transaction: &mut Self::TransactionBox,
|
|
38
|
+
graph_name: impl AsRef<str>,
|
|
39
|
+
ignore_if_exists: bool,
|
|
40
|
+
) -> Result<()>
|
|
41
|
+
{
|
|
42
|
+
let graph_name = graph_name.as_ref();
|
|
43
|
+
let mut graphs_list = self.graphs_list(transaction)?;
|
|
44
|
+
if graphs_list.iter().any(|s| s == graph_name)
|
|
45
|
+
{
|
|
46
|
+
if ignore_if_exists
|
|
47
|
+
{
|
|
48
|
+
return Ok(());
|
|
49
|
+
}
|
|
50
|
+
else
|
|
51
|
+
{
|
|
52
|
+
return Err(
|
|
53
|
+
StoreError::DuplicatedGraph {
|
|
54
|
+
graph_name: graph_name.to_owned(),
|
|
55
|
+
}
|
|
56
|
+
.into(),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
self.execute_batch(transaction, Self::graph_create_query(graph_name)?)?;
|
|
61
|
+
graphs_list.push(graph_name.to_owned());
|
|
62
|
+
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
|
63
|
+
Ok(())
|
|
64
|
+
}
|
|
65
|
+
fn drop_graph(
|
|
66
|
+
&self,
|
|
67
|
+
transaction: &mut Self::TransactionBox,
|
|
68
|
+
graph_name: impl AsRef<str>,
|
|
69
|
+
if_exists: bool,
|
|
70
|
+
) -> Result<()>
|
|
71
|
+
{
|
|
72
|
+
let graph_name = graph_name.as_ref();
|
|
73
|
+
let mut graphs_list = self.graphs_list(transaction)?;
|
|
74
|
+
if graphs_list.iter().any(|s| s == graph_name)
|
|
75
|
+
{
|
|
76
|
+
self.execute_batch(transaction, Self::graph_delete(graph_name)?)?;
|
|
77
|
+
graphs_list.retain(|x| x != graph_name);
|
|
78
|
+
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
|
79
|
+
|
|
80
|
+
Ok(())
|
|
81
|
+
}
|
|
82
|
+
else if if_exists
|
|
83
|
+
{
|
|
84
|
+
Ok(())
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
{
|
|
88
|
+
Err(
|
|
89
|
+
StoreError::UnknownGraph {
|
|
90
|
+
graph_name: graph_name.to_owned(),
|
|
91
|
+
}
|
|
92
|
+
.into(),
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
fn create_nodes<'a, T: IntoIterator<Item = &'a crate::graph::Node>>(
|
|
97
|
+
&self,
|
|
98
|
+
transaction: &mut Self::TransactionBox,
|
|
99
|
+
graph_name: impl AsRef<str>,
|
|
100
|
+
nodes_iter: T,
|
|
101
|
+
) -> Result<()>
|
|
102
|
+
{
|
|
103
|
+
for x in nodes_iter
|
|
104
|
+
{
|
|
105
|
+
self.execute(
|
|
106
|
+
transaction,
|
|
107
|
+
Self::node_create_query(&graph_name)?.as_str(),
|
|
108
|
+
(
|
|
109
|
+
&x.key(),
|
|
110
|
+
&serde_json::to_string(x.labels())?,
|
|
111
|
+
&serde_json::to_string(x.properties())?,
|
|
112
|
+
),
|
|
113
|
+
)?;
|
|
114
|
+
}
|
|
115
|
+
Ok(())
|
|
116
|
+
}
|
|
117
|
+
fn delete_nodes(
|
|
118
|
+
&self,
|
|
119
|
+
transaction: &mut Self::TransactionBox,
|
|
120
|
+
graph_name: impl AsRef<str>,
|
|
121
|
+
query: store::SelectNodeQuery,
|
|
122
|
+
detach: bool,
|
|
123
|
+
) -> Result<()>
|
|
124
|
+
{
|
|
125
|
+
let graph_name = graph_name.as_ref();
|
|
126
|
+
let nodes = self.select_nodes(transaction, graph_name, query)?;
|
|
127
|
+
let nodes_keys: Vec<String> = nodes.into_iter().map(|x| hex(x.key())).collect();
|
|
128
|
+
if detach
|
|
129
|
+
{
|
|
130
|
+
self.execute(
|
|
131
|
+
transaction,
|
|
132
|
+
Self::edge_delete_by_nodes_query(graph_name, &nodes_keys)?,
|
|
133
|
+
(),
|
|
134
|
+
)?;
|
|
135
|
+
}
|
|
136
|
+
else
|
|
137
|
+
{
|
|
138
|
+
let count = self.query_row(
|
|
139
|
+
transaction,
|
|
140
|
+
Self::edge_count_for_nodes_query(graph_name, &nodes_keys)?,
|
|
141
|
+
(),
|
|
142
|
+
|row| row.get::<usize>(0),
|
|
143
|
+
)?;
|
|
144
|
+
if count > 0
|
|
145
|
+
{
|
|
146
|
+
return Err(error::RunTimeError::DeleteConnectedNode.into());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
self.execute(
|
|
150
|
+
transaction,
|
|
151
|
+
Self::node_delete_query(graph_name, nodes_keys)?,
|
|
152
|
+
(),
|
|
153
|
+
)?;
|
|
154
|
+
Ok(())
|
|
155
|
+
}
|
|
156
|
+
fn update_node(
|
|
157
|
+
&self,
|
|
158
|
+
transaction: &mut Self::TransactionBox,
|
|
159
|
+
graph_name: impl AsRef<str>,
|
|
160
|
+
node: &crate::graph::Node,
|
|
161
|
+
) -> Result<()>
|
|
162
|
+
{
|
|
163
|
+
self.execute(
|
|
164
|
+
transaction,
|
|
165
|
+
Self::node_update_query(graph_name)?,
|
|
166
|
+
(
|
|
167
|
+
&node.key(),
|
|
168
|
+
&serde_json::to_string(node.labels())?,
|
|
169
|
+
&serde_json::to_string(node.properties())?,
|
|
170
|
+
),
|
|
171
|
+
)?;
|
|
172
|
+
Ok(())
|
|
173
|
+
}
|
|
174
|
+
fn select_nodes(
|
|
175
|
+
&self,
|
|
176
|
+
transaction: &mut Self::TransactionBox,
|
|
177
|
+
graph_name: impl AsRef<str>,
|
|
178
|
+
query: store::SelectNodeQuery,
|
|
179
|
+
) -> Result<Vec<crate::graph::Node>>
|
|
180
|
+
{
|
|
181
|
+
let mut query_bindings = Vec::<SqlValue>::new();
|
|
182
|
+
let keys_var = query
|
|
183
|
+
.keys
|
|
184
|
+
.map(|keys| {
|
|
185
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
186
|
+
query_bindings.push(serde_json::to_string(&hex_keys)?.into());
|
|
187
|
+
Ok::<_, Error>(query_bindings.len())
|
|
188
|
+
})
|
|
189
|
+
.transpose()?;
|
|
190
|
+
let labels_var = query
|
|
191
|
+
.labels
|
|
192
|
+
.map(|labels| {
|
|
193
|
+
query_bindings.push(serde_json::to_string(&labels)?.into());
|
|
194
|
+
Ok::<_, Error>(query_bindings.len())
|
|
195
|
+
})
|
|
196
|
+
.transpose()?;
|
|
197
|
+
let properties_var = query
|
|
198
|
+
.properties
|
|
199
|
+
.map(|properties| {
|
|
200
|
+
query_bindings.push(serde_json::to_string(&properties)?.into());
|
|
201
|
+
Ok::<_, Error>(query_bindings.len())
|
|
202
|
+
})
|
|
203
|
+
.transpose()?;
|
|
204
|
+
let mut nodes: Vec<graph::Node> = Default::default();
|
|
205
|
+
self.query_rows(
|
|
206
|
+
transaction,
|
|
207
|
+
Self::node_select_query(graph_name, keys_var, labels_var, properties_var)?,
|
|
208
|
+
query_bindings,
|
|
209
|
+
|row| {
|
|
210
|
+
let key: graph::Key = row.get::<graph::Key>(0)?;
|
|
211
|
+
let labels = serde_json::from_str(&row.get::<String>(1)?)?;
|
|
212
|
+
let properties = serde_json::from_str(&row.get::<String>(2)?)?;
|
|
213
|
+
nodes.push(graph::Node::new(key, labels, properties));
|
|
214
|
+
Ok(())
|
|
215
|
+
},
|
|
216
|
+
)?;
|
|
217
|
+
|
|
218
|
+
Ok(nodes)
|
|
219
|
+
}
|
|
220
|
+
fn create_edges<'a, T: IntoIterator<Item = &'a crate::graph::SinglePath>>(
|
|
221
|
+
&self,
|
|
222
|
+
transaction: &mut Self::TransactionBox,
|
|
223
|
+
graph_name: impl AsRef<str>,
|
|
224
|
+
edges_iter: T,
|
|
225
|
+
) -> Result<()>
|
|
226
|
+
{
|
|
227
|
+
for x in edges_iter
|
|
228
|
+
{
|
|
229
|
+
self.execute(
|
|
230
|
+
transaction,
|
|
231
|
+
Self::edge_create_query(graph_name.as_ref())?,
|
|
232
|
+
(
|
|
233
|
+
&x.key(),
|
|
234
|
+
&serde_json::to_string(x.labels())?,
|
|
235
|
+
&serde_json::to_string(x.properties())?,
|
|
236
|
+
&x.source().key(),
|
|
237
|
+
&x.destination().key(),
|
|
238
|
+
),
|
|
239
|
+
)?;
|
|
240
|
+
}
|
|
241
|
+
Ok(())
|
|
242
|
+
}
|
|
243
|
+
fn delete_edges(
|
|
244
|
+
&self,
|
|
245
|
+
transaction: &mut Self::TransactionBox,
|
|
246
|
+
graph_name: impl AsRef<str>,
|
|
247
|
+
query: store::SelectEdgeQuery,
|
|
248
|
+
directivity: crate::graph::EdgeDirectivity,
|
|
249
|
+
) -> Result<()>
|
|
250
|
+
{
|
|
251
|
+
let graph_name = graph_name.as_ref();
|
|
252
|
+
let edges = self.select_edges(transaction, graph_name, query, directivity)?;
|
|
253
|
+
let edges_keys: Vec<String> = edges.into_iter().map(|x| hex(x.path.key())).collect();
|
|
254
|
+
self.execute(
|
|
255
|
+
transaction,
|
|
256
|
+
Self::edge_delete_query(graph_name, &edges_keys)?,
|
|
257
|
+
(),
|
|
258
|
+
)?;
|
|
259
|
+
Ok(())
|
|
260
|
+
}
|
|
261
|
+
fn update_edge(
|
|
262
|
+
&self,
|
|
263
|
+
transaction: &mut Self::TransactionBox,
|
|
264
|
+
graph_name: impl AsRef<str>,
|
|
265
|
+
edge: &crate::graph::Edge,
|
|
266
|
+
) -> Result<()>
|
|
267
|
+
{
|
|
268
|
+
self.execute(
|
|
269
|
+
transaction,
|
|
270
|
+
Self::edge_update_query(graph_name)?,
|
|
271
|
+
(
|
|
272
|
+
&edge.key(),
|
|
273
|
+
serde_json::to_string(edge.labels())?,
|
|
274
|
+
serde_json::to_string(edge.properties())?,
|
|
275
|
+
),
|
|
276
|
+
)?;
|
|
277
|
+
Ok(())
|
|
278
|
+
}
|
|
279
|
+
fn select_edges(
|
|
280
|
+
&self,
|
|
281
|
+
transaction: &mut Self::TransactionBox,
|
|
282
|
+
graph_name: impl AsRef<str>,
|
|
283
|
+
query: store::SelectEdgeQuery,
|
|
284
|
+
directivity: crate::graph::EdgeDirectivity,
|
|
285
|
+
) -> Result<Vec<store::EdgeResult>>
|
|
286
|
+
{
|
|
287
|
+
if query.source.is_select_none() || query.destination.is_select_none()
|
|
288
|
+
{
|
|
289
|
+
return Ok(Default::default());
|
|
290
|
+
}
|
|
291
|
+
let (is_undirected, table_suffix) = match directivity
|
|
292
|
+
{
|
|
293
|
+
graph::EdgeDirectivity::Directed => (false, ""),
|
|
294
|
+
graph::EdgeDirectivity::Undirected => (true, "_undirected"),
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
let mut query_bindings = Vec::<SqlValue>::new();
|
|
298
|
+
|
|
299
|
+
// Edge queries
|
|
300
|
+
let edge_keys_var = query
|
|
301
|
+
.keys
|
|
302
|
+
.map(|keys| {
|
|
303
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
304
|
+
query_bindings.push(serde_json::to_string(&hex_keys)?.into());
|
|
305
|
+
Ok::<_, Error>(query_bindings.len())
|
|
306
|
+
})
|
|
307
|
+
.transpose()?;
|
|
308
|
+
let edge_labels_var = query
|
|
309
|
+
.labels
|
|
310
|
+
.map(|labels| {
|
|
311
|
+
query_bindings.push(serde_json::to_string(&labels)?.into());
|
|
312
|
+
Ok::<_, Error>(query_bindings.len())
|
|
313
|
+
})
|
|
314
|
+
.transpose()?;
|
|
315
|
+
let edge_properties_var = query
|
|
316
|
+
.properties
|
|
317
|
+
.map(|properties| {
|
|
318
|
+
query_bindings.push(serde_json::to_string(&properties)?.into());
|
|
319
|
+
Ok::<_, Error>(query_bindings.len())
|
|
320
|
+
})
|
|
321
|
+
.transpose()?;
|
|
322
|
+
|
|
323
|
+
// Left node queries
|
|
324
|
+
let left_node_keys_var = query
|
|
325
|
+
.source
|
|
326
|
+
.keys
|
|
327
|
+
.map(|keys| {
|
|
328
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
329
|
+
query_bindings.push(serde_json::to_string(&hex_keys)?.into());
|
|
330
|
+
Ok::<_, Error>(query_bindings.len())
|
|
331
|
+
})
|
|
332
|
+
.transpose()?;
|
|
333
|
+
let left_node_labels_var = query
|
|
334
|
+
.source
|
|
335
|
+
.labels
|
|
336
|
+
.map(|labels| {
|
|
337
|
+
query_bindings.push(serde_json::to_string(&labels)?.into());
|
|
338
|
+
Ok::<_, Error>(query_bindings.len())
|
|
339
|
+
})
|
|
340
|
+
.transpose()?;
|
|
341
|
+
let left_node_properties_var = query
|
|
342
|
+
.source
|
|
343
|
+
.properties
|
|
344
|
+
.map(|properties| {
|
|
345
|
+
query_bindings.push(serde_json::to_string(&properties)?.into());
|
|
346
|
+
Ok::<_, Error>(query_bindings.len())
|
|
347
|
+
})
|
|
348
|
+
.transpose()?;
|
|
349
|
+
|
|
350
|
+
// Right node queries
|
|
351
|
+
let right_node_keys_var = query
|
|
352
|
+
.destination
|
|
353
|
+
.keys
|
|
354
|
+
.map(|keys| {
|
|
355
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
356
|
+
query_bindings.push(serde_json::to_string(&hex_keys)?.into());
|
|
357
|
+
Ok::<_, Error>(query_bindings.len())
|
|
358
|
+
})
|
|
359
|
+
.transpose()?;
|
|
360
|
+
let right_node_labels_var = query
|
|
361
|
+
.destination
|
|
362
|
+
.labels
|
|
363
|
+
.map(|labels| {
|
|
364
|
+
query_bindings.push(serde_json::to_string(&labels)?.into());
|
|
365
|
+
Ok::<_, Error>(query_bindings.len())
|
|
366
|
+
})
|
|
367
|
+
.transpose()?;
|
|
368
|
+
let right_node_properties_var = query
|
|
369
|
+
.destination
|
|
370
|
+
.properties
|
|
371
|
+
.map(|properties| {
|
|
372
|
+
query_bindings.push(serde_json::to_string(&properties)?.into());
|
|
373
|
+
Ok::<_, Error>(query_bindings.len())
|
|
374
|
+
})
|
|
375
|
+
.transpose()?;
|
|
376
|
+
|
|
377
|
+
let mut edges: Vec<EdgeResult> = Default::default();
|
|
378
|
+
let mut edges_keys: HashSet<u128> = Default::default();
|
|
379
|
+
|
|
380
|
+
// Execute query
|
|
381
|
+
self.query_rows(
|
|
382
|
+
transaction,
|
|
383
|
+
Self::edge_select_query(
|
|
384
|
+
graph_name,
|
|
385
|
+
is_undirected,
|
|
386
|
+
table_suffix,
|
|
387
|
+
edge_keys_var,
|
|
388
|
+
edge_labels_var,
|
|
389
|
+
edge_properties_var,
|
|
390
|
+
left_node_keys_var,
|
|
391
|
+
left_node_labels_var,
|
|
392
|
+
left_node_properties_var,
|
|
393
|
+
right_node_keys_var,
|
|
394
|
+
right_node_labels_var,
|
|
395
|
+
right_node_properties_var,
|
|
396
|
+
)?,
|
|
397
|
+
query_bindings,
|
|
398
|
+
|row| {
|
|
399
|
+
let edge_key: graph::Key = row.get(0)?;
|
|
400
|
+
let n_left_key: graph::Key = row.get(4)?;
|
|
401
|
+
let n_right_key: graph::Key = row.get(7)?;
|
|
402
|
+
|
|
403
|
+
// This ensure that if (a)-[]->(a) the edge is returned only once. But matching [a]-[]-[b] return the edge twice.
|
|
404
|
+
if n_left_key == n_right_key && edges_keys.contains(&edge_key.uuid())
|
|
405
|
+
{
|
|
406
|
+
return Ok(());
|
|
407
|
+
}
|
|
408
|
+
edges_keys.insert(edge_key.uuid());
|
|
409
|
+
let edge_labels = serde_json::from_str(&row.get::<String>(1)?)?;
|
|
410
|
+
let edge_properties = serde_json::from_str(&row.get::<String>(2)?)?;
|
|
411
|
+
|
|
412
|
+
let n_left_labels = serde_json::from_str(&row.get::<String>(5)?)?;
|
|
413
|
+
let n_left_properties = serde_json::from_str(&row.get::<String>(6)?)?;
|
|
414
|
+
|
|
415
|
+
let n_right_labels = serde_json::from_str(&row.get::<String>(8)?)?;
|
|
416
|
+
let n_right_properties = serde_json::from_str(&row.get::<String>(9)?)?;
|
|
417
|
+
|
|
418
|
+
let source = graph::Node::new(n_left_key, n_left_labels, n_left_properties);
|
|
419
|
+
let destination = graph::Node::new(n_right_key, n_right_labels, n_right_properties);
|
|
420
|
+
let reversed = row.get::<u32>(3)? == 1;
|
|
421
|
+
let (source, destination) = if reversed
|
|
422
|
+
{
|
|
423
|
+
(destination, source)
|
|
424
|
+
}
|
|
425
|
+
else
|
|
426
|
+
{
|
|
427
|
+
(source, destination)
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
edges.push(EdgeResult {
|
|
431
|
+
path: graph::Path::new(edge_key, source, edge_labels, edge_properties, destination),
|
|
432
|
+
reversed,
|
|
433
|
+
});
|
|
434
|
+
Ok(())
|
|
435
|
+
},
|
|
436
|
+
)?;
|
|
437
|
+
|
|
438
|
+
Ok(edges)
|
|
439
|
+
}
|
|
440
|
+
fn compute_statistics(&self, transaction: &mut Self::TransactionBox)
|
|
441
|
+
-> Result<store::Statistics>
|
|
442
|
+
{
|
|
443
|
+
let (nodes_count, edges_count, labels_nodes_count, properties_count) = self.query_row(
|
|
444
|
+
transaction,
|
|
445
|
+
Self::compute_statistics_query("default")?,
|
|
446
|
+
(),
|
|
447
|
+
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)),
|
|
448
|
+
)?;
|
|
449
|
+
Ok(store::Statistics {
|
|
450
|
+
nodes_count,
|
|
451
|
+
edges_count,
|
|
452
|
+
labels_nodes_count,
|
|
453
|
+
properties_count,
|
|
454
|
+
})
|
|
455
|
+
}
|
|
456
|
+
}
|