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.
- 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}/release.toml +2 -2
- 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 +34 -10
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
- data/ext/gqlitedb/src/connection.rs +300 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
- data/ext/gqlitedb/src/functions/path.rs +75 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
- data/ext/gqlitedb/src/graph.rs +11 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
- data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
- 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 +260 -170
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
- 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 +22 -18
- data/ext/gqliterb/Cargo.toml +12 -34
- data/ext/gqliterb/src/lib.rs +67 -39
- 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 +146 -35
- 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 -1109
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
- data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
- data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
- data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
- data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
- /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}/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/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/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
@@ -17,23 +17,31 @@ use crate::{
|
|
17
17
|
// |_|\___/|_| |_| \___/|_| |_| |_|____/ \__, |_|
|
18
18
|
// |_|
|
19
19
|
|
20
|
-
|
20
|
+
ccutils::alias!(PersistentKey, graph::Key, derive: Debug, PartialEq);
|
21
|
+
|
22
|
+
impl rusqlite::ToSql for PersistentKey
|
21
23
|
{
|
22
24
|
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>>
|
23
25
|
{
|
24
26
|
Ok(rusqlite::types::ToSqlOutput::Owned(
|
25
|
-
rusqlite::types::Value::Blob(self.uuid.to_be_bytes().into()),
|
27
|
+
rusqlite::types::Value::Blob(self.uuid().to_be_bytes().into()),
|
26
28
|
))
|
27
29
|
}
|
28
30
|
}
|
29
31
|
|
30
|
-
impl rusqlite::types::FromSql for
|
32
|
+
impl rusqlite::types::FromSql for PersistentKey
|
31
33
|
{
|
32
34
|
fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self>
|
33
35
|
{
|
34
|
-
Ok(
|
35
|
-
|
36
|
-
|
36
|
+
Ok(u128::from_be_bytes(<[u8; 16]>::column_result(value)?).into())
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
impl From<u128> for PersistentKey
|
41
|
+
{
|
42
|
+
fn from(value: u128) -> Self
|
43
|
+
{
|
44
|
+
Self(graph::Key::new(value))
|
37
45
|
}
|
38
46
|
}
|
39
47
|
|
@@ -139,45 +147,45 @@ mod templates
|
|
139
147
|
#[template(path = "sql/sqlite/upgrade_graph_from_1_01.sql", escape = "none")]
|
140
148
|
pub(super) struct UpgradeGraphFrom1_01<'a>
|
141
149
|
{
|
142
|
-
pub graph_name: &'a
|
150
|
+
pub graph_name: &'a str,
|
143
151
|
}
|
144
152
|
#[derive(Template)]
|
145
153
|
#[template(path = "sql/sqlite/graph_create.sql", escape = "none")]
|
146
154
|
pub(super) struct GraphCreate<'a>
|
147
155
|
{
|
148
|
-
pub graph_name: &'a
|
156
|
+
pub graph_name: &'a str,
|
149
157
|
}
|
150
158
|
#[derive(Template)]
|
151
159
|
#[template(path = "sql/sqlite/graph_delete.sql", escape = "none")]
|
152
160
|
pub(super) struct GraphDelete<'a>
|
153
161
|
{
|
154
|
-
pub graph_name: &'a
|
162
|
+
pub graph_name: &'a str,
|
155
163
|
}
|
156
164
|
// Node related templates
|
157
165
|
#[derive(Template)]
|
158
166
|
#[template(path = "sql/sqlite/node_create.sql", escape = "none")]
|
159
167
|
pub(super) struct NodeCreate<'a>
|
160
168
|
{
|
161
|
-
pub graph_name: &'a
|
169
|
+
pub graph_name: &'a str,
|
162
170
|
}
|
163
171
|
#[derive(Template)]
|
164
172
|
#[template(path = "sql/sqlite/node_delete.sql", escape = "none")]
|
165
173
|
pub(super) struct NodeDelete<'a>
|
166
174
|
{
|
167
|
-
pub graph_name: &'a
|
175
|
+
pub graph_name: &'a str,
|
168
176
|
pub keys: &'a Vec<String>,
|
169
177
|
}
|
170
178
|
#[derive(Template)]
|
171
179
|
#[template(path = "sql/sqlite/node_update.sql", escape = "none")]
|
172
180
|
pub(super) struct NodeUpdate<'a>
|
173
181
|
{
|
174
|
-
pub graph_name: &'a
|
182
|
+
pub graph_name: &'a str,
|
175
183
|
}
|
176
184
|
#[derive(Template)]
|
177
185
|
#[template(path = "sql/sqlite/node_select.sql", escape = "none")]
|
178
186
|
pub(super) struct NodeSelect<'a>
|
179
187
|
{
|
180
|
-
pub graph_name: &'a
|
188
|
+
pub graph_name: &'a str,
|
181
189
|
pub has_keys: bool,
|
182
190
|
pub has_labels: bool,
|
183
191
|
pub has_properties: bool,
|
@@ -187,40 +195,40 @@ mod templates
|
|
187
195
|
#[template(path = "sql/sqlite/edge_count_for_node.sql", escape = "none")]
|
188
196
|
pub(super) struct EdgeCountForNode<'a>
|
189
197
|
{
|
190
|
-
pub graph_name: &'a
|
198
|
+
pub graph_name: &'a str,
|
191
199
|
pub keys: &'a Vec<String>,
|
192
200
|
}
|
193
201
|
#[derive(Template)]
|
194
202
|
#[template(path = "sql/sqlite/edge_create.sql", escape = "none")]
|
195
203
|
pub(super) struct EdgeCreate<'a>
|
196
204
|
{
|
197
|
-
pub graph_name: &'a
|
205
|
+
pub graph_name: &'a str,
|
198
206
|
}
|
199
207
|
#[derive(Template)]
|
200
208
|
#[template(path = "sql/sqlite/edge_delete_by_nodes.sql", escape = "none")]
|
201
209
|
pub(super) struct EdgeDeleteByNodes<'a>
|
202
210
|
{
|
203
|
-
pub graph_name: &'a
|
211
|
+
pub graph_name: &'a str,
|
204
212
|
pub keys: &'a Vec<String>,
|
205
213
|
}
|
206
214
|
#[derive(Template)]
|
207
215
|
#[template(path = "sql/sqlite/edge_delete.sql", escape = "none")]
|
208
216
|
pub(super) struct EdgeDelete<'a>
|
209
217
|
{
|
210
|
-
pub graph_name: &'a
|
218
|
+
pub graph_name: &'a str,
|
211
219
|
pub keys: &'a Vec<String>,
|
212
220
|
}
|
213
221
|
#[derive(Template)]
|
214
222
|
#[template(path = "sql/sqlite/edge_update.sql", escape = "none")]
|
215
223
|
pub(super) struct EdgeUpdate<'a>
|
216
224
|
{
|
217
|
-
pub graph_name: &'a
|
225
|
+
pub graph_name: &'a str,
|
218
226
|
}
|
219
227
|
#[derive(Template)]
|
220
228
|
#[template(path = "sql/sqlite/edge_select.sql", escape = "none")]
|
221
229
|
pub(super) struct EdgeSelect<'a>
|
222
230
|
{
|
223
|
-
pub graph_name: &'a
|
231
|
+
pub graph_name: &'a str,
|
224
232
|
pub is_undirected: bool,
|
225
233
|
pub table_suffix: &'a str,
|
226
234
|
pub has_edge_keys: bool,
|
@@ -237,7 +245,7 @@ mod templates
|
|
237
245
|
#[template(path = "sql/sqlite/call_stats.sql", escape = "none")]
|
238
246
|
pub(super) struct CallStats<'a>
|
239
247
|
{
|
240
|
-
pub graph_name: &'a
|
248
|
+
pub graph_name: &'a str,
|
241
249
|
}
|
242
250
|
}
|
243
251
|
|
@@ -249,14 +257,14 @@ mod templates
|
|
249
257
|
|
250
258
|
type TransactionBox = store::TransactionBox<ReadTransaction, WriteTransaction>;
|
251
259
|
|
252
|
-
fn hex(key:
|
260
|
+
fn hex(key: impl Into<graph::Key>) -> String
|
253
261
|
{
|
254
|
-
format!("{:032X}", key.uuid)
|
262
|
+
format!("{:032X}", key.into().uuid())
|
255
263
|
}
|
256
264
|
|
257
265
|
pub(crate) struct Store
|
258
266
|
{
|
259
|
-
connection: Pool<rusqlite::Connection,
|
267
|
+
connection: Pool<rusqlite::Connection, ErrorType>,
|
260
268
|
}
|
261
269
|
|
262
270
|
ccutils::assert_impl_all!(Store: Sync, Send);
|
@@ -264,35 +272,55 @@ ccutils::assert_impl_all!(Store: Sync, Send);
|
|
264
272
|
impl Store
|
265
273
|
{
|
266
274
|
/// Crate a new store, with a default graph
|
267
|
-
pub(crate) fn
|
275
|
+
pub(crate) fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Store>
|
268
276
|
{
|
269
|
-
use store::Store;
|
270
277
|
let path: PathBuf = path.as_ref().into();
|
271
278
|
let connection = Pool::new(
|
272
279
|
move || Ok(rusqlite::Connection::open(&path)?),
|
273
280
|
pool::Options::default().minimum_pool_size(1).pool_size(3),
|
274
281
|
)?;
|
275
282
|
let s = Self { connection };
|
276
|
-
|
277
|
-
|
278
|
-
|
283
|
+
s.initialise()?;
|
284
|
+
Ok(s)
|
285
|
+
}
|
286
|
+
pub(crate) fn in_memory() -> Result<Store>
|
287
|
+
{
|
288
|
+
let id = uuid::Uuid::new_v4().as_u128();
|
289
|
+
let connection = Pool::new(
|
290
|
+
move || {
|
291
|
+
Ok(rusqlite::Connection::open_with_flags(
|
292
|
+
format!("file:{}?mode=memory&cache=shared", id),
|
293
|
+
rusqlite::OpenFlags::default(),
|
294
|
+
)?)
|
295
|
+
},
|
296
|
+
pool::Options::default().minimum_pool_size(1).pool_size(3),
|
297
|
+
)?;
|
298
|
+
let s = Self { connection };
|
299
|
+
s.initialise()?;
|
300
|
+
Ok(s)
|
301
|
+
}
|
302
|
+
fn initialise(&self) -> Result<()>
|
303
|
+
{
|
304
|
+
use store::Store;
|
305
|
+
let mut tx = self.begin_write()?;
|
306
|
+
if self.check_if_table_exists(&mut tx, "gqlite_metadata")?
|
279
307
|
{
|
280
308
|
// gqlite version 1.1 incorrectly use ' instead of " in the version number
|
281
|
-
let version_raw =
|
309
|
+
let version_raw = self
|
282
310
|
.get_metadata_value::<String>(&mut tx, "version")?
|
283
311
|
.replace("'", "\"");
|
284
312
|
let version: utils::Version = serde_json::from_str(&version_raw)?;
|
285
313
|
if version.major != consts::GQLITE_VERSION.major
|
286
314
|
|| version.minor != consts::GQLITE_VERSION.minor
|
287
315
|
{
|
288
|
-
|
316
|
+
self.upgrade_database(&mut tx, version)?;
|
289
317
|
}
|
290
318
|
}
|
291
|
-
else if !
|
292
|
-
&&
|
319
|
+
else if !self.check_if_table_exists(&mut tx, "gqlite_metadata")?
|
320
|
+
&& self.check_if_table_exists(&mut tx, "gqlite_default_nodes")?
|
293
321
|
{
|
294
322
|
// 1.0 didn't have the metadata table
|
295
|
-
|
323
|
+
self.upgrade_database(
|
296
324
|
&mut tx,
|
297
325
|
utils::Version {
|
298
326
|
major: 1,
|
@@ -307,29 +335,24 @@ impl Store
|
|
307
335
|
include_str!("../../templates/sql/sqlite/metadata_create_table.sql"),
|
308
336
|
(),
|
309
337
|
)?;
|
310
|
-
|
311
|
-
|
338
|
+
self.set_metadata_value_json(&mut tx, "graphs", &Vec::<String>::new())?;
|
339
|
+
self.create_graph(&mut tx, "default", true)?;
|
312
340
|
}
|
313
|
-
|
341
|
+
self.set_metadata_value_json(&mut tx, "version", &consts::GQLITE_VERSION)?;
|
314
342
|
tx.close()?;
|
315
|
-
Ok(
|
343
|
+
Ok(())
|
316
344
|
}
|
317
345
|
fn upgrade_database(&self, transaction: &mut TransactionBox, from: utils::Version) -> Result<()>
|
318
346
|
{
|
319
347
|
use crate::store::Store;
|
320
|
-
|
348
|
+
if let (1, 0) = (from.major, from.minor)
|
321
349
|
{
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
)?;
|
329
|
-
self.set_metadata_value_json(transaction, "graphs", &vec!["default".to_string()])?;
|
330
|
-
}
|
331
|
-
_ =>
|
332
|
-
{}
|
350
|
+
// Create a metadata table and add the default graph.
|
351
|
+
transaction.get_connection().execute(
|
352
|
+
include_str!("../../templates/sql/sqlite/metadata_create_table.sql"),
|
353
|
+
(),
|
354
|
+
)?;
|
355
|
+
self.set_metadata_value_json(transaction, "graphs", &vec!["default".to_string()])?;
|
333
356
|
}
|
334
357
|
match (from.major, from.minor)
|
335
358
|
{
|
@@ -394,6 +417,7 @@ impl Store
|
|
394
417
|
|row| row.get(0),
|
395
418
|
)?)
|
396
419
|
}
|
420
|
+
#[allow(dead_code)]
|
397
421
|
pub(crate) fn get_metadata_value_or_else<T: FromSql>(
|
398
422
|
&self,
|
399
423
|
transaction: &mut TransactionBox,
|
@@ -437,6 +461,7 @@ impl Store
|
|
437
461
|
&self.get_metadata_value::<String>(transaction, key)?,
|
438
462
|
)?)
|
439
463
|
}
|
464
|
+
#[allow(dead_code)]
|
440
465
|
pub(crate) fn get_metadata_value_json_or_else<T: for<'a> Deserialize<'a>>(
|
441
466
|
&self,
|
442
467
|
transaction: &mut TransactionBox,
|
@@ -502,12 +527,13 @@ impl store::Store for Store
|
|
502
527
|
fn create_graph(
|
503
528
|
&self,
|
504
529
|
transaction: &mut Self::TransactionBox,
|
505
|
-
graph_name:
|
530
|
+
graph_name: impl AsRef<str>,
|
506
531
|
ignore_if_exists: bool,
|
507
532
|
) -> Result<()>
|
508
533
|
{
|
534
|
+
let graph_name = graph_name.as_ref();
|
509
535
|
let mut graphs_list = self.graphs_list(transaction)?;
|
510
|
-
if graphs_list.
|
536
|
+
if graphs_list.iter().any(|s| s == graph_name)
|
511
537
|
{
|
512
538
|
if ignore_if_exists
|
513
539
|
{
|
@@ -523,35 +549,36 @@ impl store::Store for Store
|
|
523
549
|
);
|
524
550
|
}
|
525
551
|
}
|
526
|
-
transaction
|
527
|
-
|
528
|
-
|
529
|
-
}
|
530
|
-
.render()?
|
531
|
-
.as_str(),
|
532
|
-
)?;
|
552
|
+
transaction
|
553
|
+
.get_connection()
|
554
|
+
.execute_batch(templates::GraphCreate { graph_name }.render()?.as_str())?;
|
533
555
|
graphs_list.push(graph_name.to_owned());
|
534
556
|
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
535
557
|
Ok(())
|
536
558
|
}
|
537
|
-
fn
|
538
|
-
|
559
|
+
fn drop_graph(
|
560
|
+
&self,
|
561
|
+
transaction: &mut Self::TransactionBox,
|
562
|
+
graph_name: impl AsRef<str>,
|
563
|
+
if_exists: bool,
|
564
|
+
) -> Result<()>
|
539
565
|
{
|
566
|
+
let graph_name = graph_name.as_ref();
|
540
567
|
let mut graphs_list = self.graphs_list(transaction)?;
|
541
|
-
if graphs_list.
|
568
|
+
if graphs_list.iter().any(|s| s == graph_name)
|
542
569
|
{
|
543
|
-
transaction
|
544
|
-
|
545
|
-
|
546
|
-
}
|
547
|
-
.render()?
|
548
|
-
.as_str(),
|
549
|
-
)?;
|
570
|
+
transaction
|
571
|
+
.get_connection()
|
572
|
+
.execute_batch(templates::GraphDelete { graph_name }.render()?.as_str())?;
|
550
573
|
graphs_list.retain(|x| x != graph_name);
|
551
574
|
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
552
575
|
|
553
576
|
Ok(())
|
554
577
|
}
|
578
|
+
else if if_exists
|
579
|
+
{
|
580
|
+
Ok(())
|
581
|
+
}
|
555
582
|
else
|
556
583
|
{
|
557
584
|
Err(
|
@@ -562,10 +589,10 @@ impl store::Store for Store
|
|
562
589
|
)
|
563
590
|
}
|
564
591
|
}
|
565
|
-
fn create_nodes<'a, T:
|
592
|
+
fn create_nodes<'a, T: IntoIterator<Item = &'a crate::graph::Node>>(
|
566
593
|
&self,
|
567
594
|
transaction: &mut Self::TransactionBox,
|
568
|
-
graph_name:
|
595
|
+
graph_name: impl AsRef<str>,
|
569
596
|
nodes_iter: T,
|
570
597
|
) -> Result<()>
|
571
598
|
{
|
@@ -573,14 +600,14 @@ impl store::Store for Store
|
|
573
600
|
{
|
574
601
|
transaction.get_connection().execute(
|
575
602
|
templates::NodeCreate {
|
576
|
-
graph_name: graph_name.
|
603
|
+
graph_name: graph_name.as_ref(),
|
577
604
|
}
|
578
605
|
.render()?
|
579
606
|
.as_str(),
|
580
607
|
(
|
581
|
-
x.key,
|
582
|
-
serde_json::to_string(
|
583
|
-
serde_json::to_string(
|
608
|
+
PersistentKey(x.key()),
|
609
|
+
serde_json::to_string(x.labels())?,
|
610
|
+
serde_json::to_string(x.properties())?,
|
584
611
|
),
|
585
612
|
)?;
|
586
613
|
}
|
@@ -589,18 +616,19 @@ impl store::Store for Store
|
|
589
616
|
fn delete_nodes(
|
590
617
|
&self,
|
591
618
|
transaction: &mut Self::TransactionBox,
|
592
|
-
graph_name:
|
619
|
+
graph_name: impl AsRef<str>,
|
593
620
|
query: store::SelectNodeQuery,
|
594
621
|
detach: bool,
|
595
622
|
) -> Result<()>
|
596
623
|
{
|
624
|
+
let graph_name = graph_name.as_ref();
|
597
625
|
let nodes = self.select_nodes(transaction, graph_name, query)?;
|
598
|
-
let nodes_keys: Vec<String> = nodes.into_iter().map(|x| hex(
|
626
|
+
let nodes_keys: Vec<String> = nodes.into_iter().map(|x| hex(x.key())).collect();
|
599
627
|
if detach
|
600
628
|
{
|
601
629
|
transaction.get_connection().execute(
|
602
630
|
templates::EdgeDeleteByNodes {
|
603
|
-
graph_name
|
631
|
+
graph_name,
|
604
632
|
keys: &nodes_keys,
|
605
633
|
}
|
606
634
|
.render()?
|
@@ -612,7 +640,7 @@ impl store::Store for Store
|
|
612
640
|
{
|
613
641
|
let count = transaction.get_connection().query_row(
|
614
642
|
templates::EdgeCountForNode {
|
615
|
-
graph_name
|
643
|
+
graph_name,
|
616
644
|
keys: &nodes_keys,
|
617
645
|
}
|
618
646
|
.render()?
|
@@ -627,7 +655,7 @@ impl store::Store for Store
|
|
627
655
|
}
|
628
656
|
transaction.get_connection().execute(
|
629
657
|
templates::NodeDelete {
|
630
|
-
graph_name
|
658
|
+
graph_name,
|
631
659
|
keys: &nodes_keys,
|
632
660
|
}
|
633
661
|
.render()?
|
@@ -639,20 +667,20 @@ impl store::Store for Store
|
|
639
667
|
fn update_node(
|
640
668
|
&self,
|
641
669
|
transaction: &mut Self::TransactionBox,
|
642
|
-
graph_name:
|
670
|
+
graph_name: impl AsRef<str>,
|
643
671
|
node: &crate::graph::Node,
|
644
672
|
) -> Result<()>
|
645
673
|
{
|
646
674
|
transaction.get_connection().execute(
|
647
675
|
templates::NodeUpdate {
|
648
|
-
graph_name:
|
676
|
+
graph_name: graph_name.as_ref(),
|
649
677
|
}
|
650
678
|
.render()?
|
651
679
|
.as_str(),
|
652
680
|
named_params! {
|
653
|
-
":key": node.key,
|
654
|
-
":labels": serde_json::to_string(
|
655
|
-
":properties": serde_json::to_string(
|
681
|
+
":key": PersistentKey(node.key()),
|
682
|
+
":labels": serde_json::to_string(node.labels())?,
|
683
|
+
":properties": serde_json::to_string(node.properties())?
|
656
684
|
},
|
657
685
|
)?;
|
658
686
|
Ok(())
|
@@ -660,13 +688,13 @@ impl store::Store for Store
|
|
660
688
|
fn select_nodes(
|
661
689
|
&self,
|
662
690
|
transaction: &mut Self::TransactionBox,
|
663
|
-
graph_name:
|
691
|
+
graph_name: impl AsRef<str>,
|
664
692
|
query: store::SelectNodeQuery,
|
665
693
|
) -> Result<Vec<crate::graph::Node>>
|
666
694
|
{
|
667
695
|
let mut prepared_query = transaction.get_connection().prepare(
|
668
696
|
templates::NodeSelect {
|
669
|
-
graph_name: graph_name.
|
697
|
+
graph_name: graph_name.as_ref(),
|
670
698
|
has_keys: query.keys.is_some(),
|
671
699
|
has_labels: query.labels.is_some(),
|
672
700
|
has_properties: query.properties.is_some(),
|
@@ -677,7 +705,7 @@ impl store::Store for Store
|
|
677
705
|
let mut bindings = Vec::<(&'static str, String)>::new();
|
678
706
|
if let Some(keys) = query.keys
|
679
707
|
{
|
680
|
-
let hex_keys = keys.iter().map(|key| hex(key)).collect::<Vec<_>>();
|
708
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
681
709
|
bindings.push((":keys", serde_json::to_string(&hex_keys)?));
|
682
710
|
}
|
683
711
|
if let Some(labels) = query.labels
|
@@ -698,21 +726,17 @@ impl store::Store for Store
|
|
698
726
|
let mut nodes: Vec<graph::Node> = Default::default();
|
699
727
|
while let Some(row) = it.next()?
|
700
728
|
{
|
701
|
-
let key = row.get(0)
|
729
|
+
let key: graph::Key = row.get::<_, PersistentKey>(0)?.into();
|
702
730
|
let labels = serde_json::from_str(&row.get::<_, String>(1)?)?;
|
703
731
|
let properties = serde_json::from_str(&row.get::<_, String>(2)?)?;
|
704
|
-
nodes.push(graph::Node
|
705
|
-
key,
|
706
|
-
labels,
|
707
|
-
properties,
|
708
|
-
});
|
732
|
+
nodes.push(graph::Node::new(key, labels, properties));
|
709
733
|
}
|
710
734
|
Ok(nodes)
|
711
735
|
}
|
712
|
-
fn create_edges<'a, T:
|
736
|
+
fn create_edges<'a, T: IntoIterator<Item = &'a crate::graph::SinglePath>>(
|
713
737
|
&self,
|
714
738
|
transaction: &mut Self::TransactionBox,
|
715
|
-
graph_name:
|
739
|
+
graph_name: impl AsRef<str>,
|
716
740
|
edges_iter: T,
|
717
741
|
) -> Result<()>
|
718
742
|
{
|
@@ -720,16 +744,16 @@ impl store::Store for Store
|
|
720
744
|
{
|
721
745
|
transaction.get_connection().execute(
|
722
746
|
templates::EdgeCreate {
|
723
|
-
graph_name: graph_name.
|
747
|
+
graph_name: graph_name.as_ref(),
|
724
748
|
}
|
725
749
|
.render()?
|
726
750
|
.as_str(),
|
727
751
|
(
|
728
|
-
x.key,
|
729
|
-
serde_json::to_string(
|
730
|
-
serde_json::to_string(
|
731
|
-
x.source.key,
|
732
|
-
x.destination.key,
|
752
|
+
PersistentKey(x.key()),
|
753
|
+
serde_json::to_string(x.labels())?,
|
754
|
+
serde_json::to_string(x.properties())?,
|
755
|
+
PersistentKey(x.source().key()),
|
756
|
+
PersistentKey(x.destination().key()),
|
733
757
|
),
|
734
758
|
)?;
|
735
759
|
}
|
@@ -738,16 +762,17 @@ impl store::Store for Store
|
|
738
762
|
fn delete_edges(
|
739
763
|
&self,
|
740
764
|
transaction: &mut Self::TransactionBox,
|
741
|
-
graph_name:
|
765
|
+
graph_name: impl AsRef<str>,
|
742
766
|
query: store::SelectEdgeQuery,
|
743
767
|
directivity: crate::graph::EdgeDirectivity,
|
744
768
|
) -> Result<()>
|
745
769
|
{
|
770
|
+
let graph_name = graph_name.as_ref();
|
746
771
|
let edges = self.select_edges(transaction, graph_name, query, directivity)?;
|
747
|
-
let edges_keys: Vec<String> = edges.into_iter().map(|x| hex(
|
772
|
+
let edges_keys: Vec<String> = edges.into_iter().map(|x| hex(x.path.key())).collect();
|
748
773
|
transaction.get_connection().execute(
|
749
774
|
templates::EdgeDelete {
|
750
|
-
graph_name
|
775
|
+
graph_name,
|
751
776
|
keys: &edges_keys,
|
752
777
|
}
|
753
778
|
.render()?
|
@@ -759,20 +784,20 @@ impl store::Store for Store
|
|
759
784
|
fn update_edge(
|
760
785
|
&self,
|
761
786
|
transaction: &mut Self::TransactionBox,
|
762
|
-
graph_name:
|
787
|
+
graph_name: impl AsRef<str>,
|
763
788
|
edge: &crate::graph::Edge,
|
764
789
|
) -> Result<()>
|
765
790
|
{
|
766
791
|
transaction.get_connection().execute(
|
767
792
|
templates::EdgeUpdate {
|
768
|
-
graph_name:
|
793
|
+
graph_name: graph_name.as_ref(),
|
769
794
|
}
|
770
795
|
.render()?
|
771
796
|
.as_str(),
|
772
797
|
named_params! {
|
773
|
-
":key": edge.key,
|
774
|
-
":labels": serde_json::to_string(
|
775
|
-
":properties": serde_json::to_string(
|
798
|
+
":key": PersistentKey(edge.key().to_owned()),
|
799
|
+
":labels": serde_json::to_string(edge.labels())?,
|
800
|
+
":properties": serde_json::to_string(edge.properties())?
|
776
801
|
},
|
777
802
|
)?;
|
778
803
|
Ok(())
|
@@ -780,7 +805,7 @@ impl store::Store for Store
|
|
780
805
|
fn select_edges(
|
781
806
|
&self,
|
782
807
|
transaction: &mut Self::TransactionBox,
|
783
|
-
graph_name:
|
808
|
+
graph_name: impl AsRef<str>,
|
784
809
|
query: store::SelectEdgeQuery,
|
785
810
|
directivity: crate::graph::EdgeDirectivity,
|
786
811
|
) -> Result<Vec<store::EdgeResult>>
|
@@ -796,9 +821,9 @@ impl store::Store for Store
|
|
796
821
|
};
|
797
822
|
let mut prepared_query = transaction.get_connection().prepare(
|
798
823
|
templates::EdgeSelect {
|
799
|
-
graph_name: graph_name,
|
824
|
+
graph_name: graph_name.as_ref(),
|
800
825
|
is_undirected,
|
801
|
-
table_suffix
|
826
|
+
table_suffix,
|
802
827
|
has_edge_keys: query.keys.is_some(),
|
803
828
|
has_edge_labels: query.labels.is_some(),
|
804
829
|
has_edge_properties: query.properties.is_some(),
|
@@ -818,7 +843,7 @@ impl store::Store for Store
|
|
818
843
|
// Edge queries
|
819
844
|
if let Some(keys) = query.keys
|
820
845
|
{
|
821
|
-
let hex_keys = keys.iter().map(|key| hex(
|
846
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
822
847
|
bindings.push((":edge_keys", serde_json::to_string(&hex_keys)?));
|
823
848
|
}
|
824
849
|
if let Some(labels) = query.labels
|
@@ -833,7 +858,7 @@ impl store::Store for Store
|
|
833
858
|
// Left queries
|
834
859
|
if let Some(keys) = query.source.keys
|
835
860
|
{
|
836
|
-
let hex_keys = keys.iter().map(|key| hex(
|
861
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
837
862
|
bindings.push((":n_left_keys", serde_json::to_string(&hex_keys)?));
|
838
863
|
}
|
839
864
|
if let Some(labels) = query.source.labels
|
@@ -848,7 +873,7 @@ impl store::Store for Store
|
|
848
873
|
// Right queries
|
849
874
|
if let Some(keys) = query.destination.keys
|
850
875
|
{
|
851
|
-
let hex_keys = keys.iter().map(|key| hex(
|
876
|
+
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
852
877
|
bindings.push((":n_right_keys", serde_json::to_string(&hex_keys)?));
|
853
878
|
}
|
854
879
|
if let Some(labels) = query.destination.labels
|
@@ -873,16 +898,16 @@ impl store::Store for Store
|
|
873
898
|
let mut edges_keys: HashSet<u128> = Default::default();
|
874
899
|
while let Some(row) = it.next()?
|
875
900
|
{
|
876
|
-
let edge_key:
|
877
|
-
let n_left_key = row.get(4)?;
|
878
|
-
let n_right_key = row.get(7)?;
|
901
|
+
let edge_key: PersistentKey = row.get(0)?;
|
902
|
+
let n_left_key: PersistentKey = row.get(4)?;
|
903
|
+
let n_right_key: PersistentKey = row.get(7)?;
|
879
904
|
|
880
905
|
// This ensure that if (a)-[]->(a) the edge is returned only once. But matching [a]-[]-[b] return the edge twice.
|
881
|
-
if n_left_key == n_right_key && edges_keys.contains(&edge_key.uuid)
|
906
|
+
if n_left_key == n_right_key && edges_keys.contains(&edge_key.uuid())
|
882
907
|
{
|
883
908
|
continue;
|
884
909
|
}
|
885
|
-
edges_keys.insert(edge_key.uuid);
|
910
|
+
edges_keys.insert(edge_key.uuid());
|
886
911
|
let edge_labels = serde_json::from_str(&row.get::<_, String>(1)?)?;
|
887
912
|
let edge_properties = serde_json::from_str(&row.get::<_, String>(2)?)?;
|
888
913
|
|
@@ -892,16 +917,8 @@ impl store::Store for Store
|
|
892
917
|
let n_right_labels = serde_json::from_str(&row.get::<_, String>(8)?)?;
|
893
918
|
let n_right_properties = serde_json::from_str(&row.get::<_, String>(9)?)?;
|
894
919
|
|
895
|
-
let source = graph::Node
|
896
|
-
|
897
|
-
labels: n_left_labels,
|
898
|
-
properties: n_left_properties,
|
899
|
-
};
|
900
|
-
let destination = graph::Node {
|
901
|
-
key: n_right_key,
|
902
|
-
labels: n_right_labels,
|
903
|
-
properties: n_right_properties,
|
904
|
-
};
|
920
|
+
let source = graph::Node::new(n_left_key.into(), n_left_labels, n_left_properties);
|
921
|
+
let destination = graph::Node::new(n_right_key.into(), n_right_labels, n_right_properties);
|
905
922
|
let reversed = row.get::<_, u32>(3)? == 1;
|
906
923
|
let (source, destination) = if reversed
|
907
924
|
{
|
@@ -913,13 +930,13 @@ impl store::Store for Store
|
|
913
930
|
};
|
914
931
|
|
915
932
|
edges.push(EdgeResult {
|
916
|
-
|
917
|
-
|
918
|
-
labels: edge_labels,
|
919
|
-
properties: edge_properties,
|
933
|
+
path: graph::Path::new(
|
934
|
+
edge_key.into(),
|
920
935
|
source,
|
936
|
+
edge_labels,
|
937
|
+
edge_properties,
|
921
938
|
destination,
|
922
|
-
|
939
|
+
),
|
923
940
|
reversed,
|
924
941
|
});
|
925
942
|
}
|
@@ -931,7 +948,7 @@ impl store::Store for Store
|
|
931
948
|
let (nodes_count, edges_count, labels_nodes_count, properties_count) =
|
932
949
|
transaction.get_connection().query_row(
|
933
950
|
templates::CallStats {
|
934
|
-
graph_name:
|
951
|
+
graph_name: "default",
|
935
952
|
}
|
936
953
|
.render()?
|
937
954
|
.as_str(),
|
@@ -958,13 +975,11 @@ mod tests
|
|
958
975
|
fn test_hex()
|
959
976
|
{
|
960
977
|
assert_eq!(
|
961
|
-
super::hex(
|
962
|
-
uuid: 18580062510968287067562660977870108180
|
963
|
-
}),
|
978
|
+
super::hex(graph::Key::new(18580062510968287067562660977870108180)),
|
964
979
|
"0DFA63CEE7484B0DBFC407697F77F614"
|
965
980
|
);
|
966
981
|
assert_eq!(
|
967
|
-
super::hex(
|
982
|
+
super::hex(graph::Key::new(0)),
|
968
983
|
"00000000000000000000000000000000"
|
969
984
|
);
|
970
985
|
}
|
@@ -972,7 +987,7 @@ mod tests
|
|
972
987
|
fn test_sqlite_metadata()
|
973
988
|
{
|
974
989
|
let temp_file = crate::tests::create_tmp_file();
|
975
|
-
let store = super::Store::
|
990
|
+
let store = super::Store::open(temp_file.path()).unwrap();
|
976
991
|
let mut tx = store.begin_read().unwrap();
|
977
992
|
let version: utils::Version = store.get_metadata_value_json(&mut tx, "version").unwrap();
|
978
993
|
assert_eq!(version.major, consts::GQLITE_VERSION.major);
|
@@ -982,7 +997,7 @@ mod tests
|
|
982
997
|
drop(store);
|
983
998
|
|
984
999
|
// Try to reopen
|
985
|
-
let store = super::Store::
|
1000
|
+
let store = super::Store::open(temp_file.path()).unwrap();
|
986
1001
|
let mut tx = store.begin_read().unwrap();
|
987
1002
|
let version: utils::Version = store.get_metadata_value_json(&mut tx, "version").unwrap();
|
988
1003
|
assert_eq!(version.major, consts::GQLITE_VERSION.major);
|