gqlite 1.3.1 → 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 +3 -3
- data/ext/gqlitedb/Cargo.toml +5 -2
- 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 +1 -0
- data/ext/gqlitedb/src/connection.rs +42 -7
- data/ext/gqlitedb/src/error.rs +3 -0
- data/ext/gqlitedb/src/interpreter/evaluators.rs +5 -2
- data/ext/gqlitedb/src/interpreter/instructions.rs +1 -1
- data/ext/gqlitedb/src/lib.rs +1 -1
- 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/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 -0
- data/ext/graphcore/Cargo.toml +3 -2
- data/ext/graphcore/src/error.rs +2 -0
- data/ext/graphcore/src/lib.rs +2 -0
- data/ext/graphcore/src/prelude.rs +1 -1
- data/ext/graphcore/src/timestamp.rs +104 -0
- data/ext/graphcore/src/value.rs +106 -23
- metadata +15 -5
- data/ext/graphcore/release.toml +0 -1
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
use std::{cell::RefCell,
|
|
1
|
+
use std::{cell::RefCell, path::PathBuf};
|
|
2
2
|
|
|
3
|
-
use askama::Template;
|
|
4
3
|
use ccutils::pool::{self, Pool};
|
|
5
|
-
use rusqlite::{named_params, types::FromSql, OptionalExtension, ToSql};
|
|
6
|
-
use serde::{Deserialize, Serialize};
|
|
7
4
|
|
|
8
5
|
use crate::{
|
|
9
6
|
prelude::*,
|
|
10
|
-
store::{
|
|
7
|
+
store::{sqlbase::SqlValue, TransactionBoxable},
|
|
11
8
|
};
|
|
12
9
|
|
|
10
|
+
ccutils::assert_impl_all!(Store: Sync, Send);
|
|
11
|
+
|
|
12
|
+
use askama::Template;
|
|
13
|
+
use rusqlite::named_params;
|
|
14
|
+
|
|
13
15
|
// _____ _____ ____ _
|
|
14
16
|
// |_ _|__ | ___| __ ___ _ __ ___ / ___| __ _| |
|
|
15
17
|
// | |/ _ \| |_ | '__/ _ \| '_ ` _ \\___ \ / _` | |
|
|
@@ -17,31 +19,38 @@ use crate::{
|
|
|
17
19
|
// |_|\___/|_| |_| \___/|_| |_| |_|____/ \__, |_|
|
|
18
20
|
// |_|
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
impl rusqlite::ToSql for PersistentKey
|
|
22
|
+
impl<'a> rusqlite::ToSql for SqlValue<'a>
|
|
23
23
|
{
|
|
24
24
|
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>>
|
|
25
25
|
{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
match self
|
|
27
|
+
{
|
|
28
|
+
SqlValue::String(string) => string.to_sql(),
|
|
29
|
+
SqlValue::StringRef(string) => string.to_sql(),
|
|
30
|
+
SqlValue::Key(key) => Ok(rusqlite::types::ToSqlOutput::Owned(
|
|
31
|
+
rusqlite::types::Value::Blob(key.uuid().to_be_bytes().into()),
|
|
32
|
+
)),
|
|
33
|
+
SqlValue::Blob(data) => data.to_sql(),
|
|
34
|
+
SqlValue::Text(text) => std::str::from_utf8(text).unwrap().to_sql(),
|
|
35
|
+
SqlValue::Float(fl) => fl.to_sql(),
|
|
36
|
+
SqlValue::Integer(it) => it.to_sql(),
|
|
37
|
+
SqlValue::Null => rusqlite::types::Null.to_sql(),
|
|
38
|
+
}
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
impl
|
|
42
|
+
impl<'a> sqlbase::Row for rusqlite::Row<'a>
|
|
41
43
|
{
|
|
42
|
-
fn
|
|
44
|
+
fn get_value(&self, index: usize) -> Result<SqlValue<'_>>
|
|
43
45
|
{
|
|
44
|
-
|
|
46
|
+
match self.get_ref(index)?
|
|
47
|
+
{
|
|
48
|
+
rusqlite::types::ValueRef::Blob(blob) => Ok(SqlValue::Blob(blob)),
|
|
49
|
+
rusqlite::types::ValueRef::Integer(int) => Ok(SqlValue::Integer(int)),
|
|
50
|
+
rusqlite::types::ValueRef::Null => Ok(SqlValue::Null),
|
|
51
|
+
rusqlite::types::ValueRef::Real(f) => Ok(SqlValue::Float(f)),
|
|
52
|
+
rusqlite::types::ValueRef::Text(txt) => Ok(SqlValue::Text(txt)),
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
|
|
@@ -186,9 +195,9 @@ mod templates
|
|
|
186
195
|
pub(super) struct NodeSelect<'a>
|
|
187
196
|
{
|
|
188
197
|
pub graph_name: &'a str,
|
|
189
|
-
pub
|
|
190
|
-
pub
|
|
191
|
-
pub
|
|
198
|
+
pub keys_var: &'a Option<usize>,
|
|
199
|
+
pub labels_var: &'a Option<usize>,
|
|
200
|
+
pub properties_var: &'a Option<usize>,
|
|
192
201
|
}
|
|
193
202
|
// Edge queries
|
|
194
203
|
#[derive(Template)]
|
|
@@ -231,15 +240,15 @@ mod templates
|
|
|
231
240
|
pub graph_name: &'a str,
|
|
232
241
|
pub is_undirected: bool,
|
|
233
242
|
pub table_suffix: &'a str,
|
|
234
|
-
pub
|
|
235
|
-
pub
|
|
236
|
-
pub
|
|
237
|
-
pub
|
|
238
|
-
pub
|
|
239
|
-
pub
|
|
240
|
-
pub
|
|
241
|
-
pub
|
|
242
|
-
pub
|
|
243
|
+
pub edge_keys_var: Option<usize>,
|
|
244
|
+
pub edge_labels_var: Option<usize>,
|
|
245
|
+
pub edge_properties_var: Option<usize>,
|
|
246
|
+
pub left_keys_var: Option<usize>,
|
|
247
|
+
pub left_labels_var: Option<usize>,
|
|
248
|
+
pub left_properties_var: Option<usize>,
|
|
249
|
+
pub right_keys_var: Option<usize>,
|
|
250
|
+
pub right_labels_var: Option<usize>,
|
|
251
|
+
pub right_properties_var: Option<usize>,
|
|
243
252
|
}
|
|
244
253
|
#[derive(Template)]
|
|
245
254
|
#[template(path = "sql/sqlite/call_stats.sql", escape = "none")]
|
|
@@ -257,16 +266,10 @@ mod templates
|
|
|
257
266
|
|
|
258
267
|
type TransactionBox = store::TransactionBox<ReadTransaction, WriteTransaction>;
|
|
259
268
|
|
|
260
|
-
fn hex(key: impl Into<graph::Key>) -> String
|
|
261
|
-
{
|
|
262
|
-
format!("{:032X}", key.into().uuid())
|
|
263
|
-
}
|
|
264
|
-
|
|
265
269
|
pub(crate) struct Store
|
|
266
270
|
{
|
|
267
271
|
connection: Pool<rusqlite::Connection, ErrorType>,
|
|
268
272
|
}
|
|
269
|
-
|
|
270
273
|
ccutils::assert_impl_all!(Store: Sync, Send);
|
|
271
274
|
|
|
272
275
|
impl Store
|
|
@@ -299,49 +302,6 @@ impl Store
|
|
|
299
302
|
s.initialise()?;
|
|
300
303
|
Ok(s)
|
|
301
304
|
}
|
|
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")?
|
|
307
|
-
{
|
|
308
|
-
// gqlite version 1.1 incorrectly use ' instead of " in the version number
|
|
309
|
-
let version_raw = self
|
|
310
|
-
.get_metadata_value::<String>(&mut tx, "version")?
|
|
311
|
-
.replace("'", "\"");
|
|
312
|
-
let version: utils::Version = serde_json::from_str(&version_raw)?;
|
|
313
|
-
if version.major != consts::GQLITE_VERSION.major
|
|
314
|
-
|| version.minor != consts::GQLITE_VERSION.minor
|
|
315
|
-
{
|
|
316
|
-
self.upgrade_database(&mut tx, version)?;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
else if !self.check_if_table_exists(&mut tx, "gqlite_metadata")?
|
|
320
|
-
&& self.check_if_table_exists(&mut tx, "gqlite_default_nodes")?
|
|
321
|
-
{
|
|
322
|
-
// 1.0 didn't have the metadata table
|
|
323
|
-
self.upgrade_database(
|
|
324
|
-
&mut tx,
|
|
325
|
-
utils::Version {
|
|
326
|
-
major: 1,
|
|
327
|
-
minor: 0,
|
|
328
|
-
patch: 0,
|
|
329
|
-
},
|
|
330
|
-
)?;
|
|
331
|
-
}
|
|
332
|
-
else
|
|
333
|
-
{
|
|
334
|
-
tx.get_connection().execute(
|
|
335
|
-
include_str!("../../templates/sql/sqlite/metadata_create_table.sql"),
|
|
336
|
-
(),
|
|
337
|
-
)?;
|
|
338
|
-
self.set_metadata_value_json(&mut tx, "graphs", &Vec::<String>::new())?;
|
|
339
|
-
self.create_graph(&mut tx, "default", true)?;
|
|
340
|
-
}
|
|
341
|
-
self.set_metadata_value_json(&mut tx, "version", &consts::GQLITE_VERSION)?;
|
|
342
|
-
tx.close()?;
|
|
343
|
-
Ok(())
|
|
344
|
-
}
|
|
345
305
|
fn upgrade_database(&self, transaction: &mut TransactionBox, from: utils::Version) -> Result<()>
|
|
346
306
|
{
|
|
347
307
|
use crate::store::Store;
|
|
@@ -405,100 +365,68 @@ impl Store
|
|
|
405
365
|
|row| Ok(row.get::<_, i32>(0)? == 1),
|
|
406
366
|
)?)
|
|
407
367
|
}
|
|
408
|
-
|
|
409
|
-
&self,
|
|
410
|
-
transaction: &mut TransactionBox,
|
|
411
|
-
key: impl Into<String>,
|
|
412
|
-
) -> Result<T>
|
|
413
|
-
{
|
|
414
|
-
Ok(transaction.get_connection().query_row(
|
|
415
|
-
include_str!("../../templates/sql/sqlite/metadata_get.sql"),
|
|
416
|
-
named_params! {":name": key.into()},
|
|
417
|
-
|row| row.get(0),
|
|
418
|
-
)?)
|
|
419
|
-
}
|
|
420
|
-
#[allow(dead_code)]
|
|
421
|
-
pub(crate) fn get_metadata_value_or_else<T: FromSql>(
|
|
422
|
-
&self,
|
|
423
|
-
transaction: &mut TransactionBox,
|
|
424
|
-
key: impl Into<String>,
|
|
425
|
-
f: impl FnOnce() -> T,
|
|
426
|
-
) -> Result<T>
|
|
427
|
-
{
|
|
428
|
-
Ok(
|
|
429
|
-
transaction
|
|
430
|
-
.get_connection()
|
|
431
|
-
.query_row(
|
|
432
|
-
include_str!("../../templates/sql/sqlite/metadata_get.sql"),
|
|
433
|
-
named_params! { ":name": key.into()},
|
|
434
|
-
|row| row.get(0),
|
|
435
|
-
)
|
|
436
|
-
.optional()
|
|
437
|
-
.map(|v| v.unwrap_or_else(f))?,
|
|
438
|
-
)
|
|
439
|
-
}
|
|
440
|
-
pub(crate) fn set_metadata_value(
|
|
441
|
-
&self,
|
|
442
|
-
transaction: &mut TransactionBox,
|
|
443
|
-
key: impl Into<String>,
|
|
444
|
-
value: &impl ToSql,
|
|
445
|
-
) -> Result<()>
|
|
446
|
-
{
|
|
447
|
-
transaction.get_connection().execute(
|
|
448
|
-
include_str!("../../templates/sql/sqlite/metadata_set.sql"),
|
|
449
|
-
named_params! { ":name": key.into(), ":value": value },
|
|
450
|
-
)?;
|
|
451
|
-
Ok(())
|
|
452
|
-
}
|
|
368
|
+
}
|
|
453
369
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
key: impl Into<String>,
|
|
458
|
-
) -> Result<T>
|
|
459
|
-
{
|
|
460
|
-
Ok(serde_json::from_str(
|
|
461
|
-
&self.get_metadata_value::<String>(transaction, key)?,
|
|
462
|
-
)?)
|
|
463
|
-
}
|
|
464
|
-
#[allow(dead_code)]
|
|
465
|
-
pub(crate) fn get_metadata_value_json_or_else<T: for<'a> Deserialize<'a>>(
|
|
466
|
-
&self,
|
|
467
|
-
transaction: &mut TransactionBox,
|
|
468
|
-
key: impl Into<String>,
|
|
469
|
-
f: impl FnOnce() -> T,
|
|
470
|
-
) -> Result<T>
|
|
370
|
+
impl super::sqlbase::SqlMetaDataQueries for Store
|
|
371
|
+
{
|
|
372
|
+
fn metadata_get_query() -> Result<String>
|
|
471
373
|
{
|
|
472
|
-
Ok(
|
|
473
|
-
transaction
|
|
474
|
-
.get_connection()
|
|
475
|
-
.query_row(
|
|
476
|
-
include_str!("../../templates/sql/sqlite/metadata_get.sql"),
|
|
477
|
-
named_params! {":name": key.into()},
|
|
478
|
-
|row| row.get::<_, String>(0),
|
|
479
|
-
)
|
|
480
|
-
.optional()
|
|
481
|
-
.map(|v| {
|
|
482
|
-
v.map(|x| serde_json::from_str(&x))
|
|
483
|
-
.unwrap_or_else(|| Ok(f()))
|
|
484
|
-
})??,
|
|
485
|
-
)
|
|
374
|
+
Ok(include_str!("../../templates/sql/sqlite/metadata_get.sql").to_string())
|
|
486
375
|
}
|
|
487
|
-
|
|
488
|
-
&self,
|
|
489
|
-
transaction: &mut TransactionBox,
|
|
490
|
-
key: impl Into<String>,
|
|
491
|
-
value: &impl Serialize,
|
|
492
|
-
) -> Result<()>
|
|
376
|
+
fn metadata_set_query() -> Result<String>
|
|
493
377
|
{
|
|
494
|
-
|
|
378
|
+
Ok(include_str!("../../templates/sql/sqlite/metadata_set.sql").to_string())
|
|
495
379
|
}
|
|
496
380
|
}
|
|
497
381
|
|
|
498
|
-
impl
|
|
382
|
+
impl super::sqlbase::SqlStore for Store
|
|
499
383
|
{
|
|
500
384
|
type TransactionBox = TransactionBox;
|
|
501
|
-
|
|
385
|
+
type Row<'a> = rusqlite::Row<'a>;
|
|
386
|
+
fn initialise(&self) -> Result<()>
|
|
387
|
+
{
|
|
388
|
+
use store::Store;
|
|
389
|
+
let mut tx = self.begin_sql_write()?;
|
|
390
|
+
if self.check_if_table_exists(&mut tx, "gqlite_metadata")?
|
|
391
|
+
{
|
|
392
|
+
// gqlite version 1.1 incorrectly use ' instead of " in the version number
|
|
393
|
+
let version_raw = self
|
|
394
|
+
.get_metadata_value::<String>(&mut tx, "version")?
|
|
395
|
+
.replace("'", "\"");
|
|
396
|
+
let version: utils::Version = serde_json::from_str(&version_raw)?;
|
|
397
|
+
if version.major != consts::GQLITE_VERSION.major
|
|
398
|
+
|| version.minor != consts::GQLITE_VERSION.minor
|
|
399
|
+
{
|
|
400
|
+
self.upgrade_database(&mut tx, version)?;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else if !self.check_if_table_exists(&mut tx, "gqlite_metadata")?
|
|
404
|
+
&& self.check_if_table_exists(&mut tx, "gqlite_default_nodes")?
|
|
405
|
+
{
|
|
406
|
+
// 1.0 didn't have the metadata table
|
|
407
|
+
self.upgrade_database(
|
|
408
|
+
&mut tx,
|
|
409
|
+
utils::Version {
|
|
410
|
+
major: 1,
|
|
411
|
+
minor: 0,
|
|
412
|
+
patch: 0,
|
|
413
|
+
},
|
|
414
|
+
)?;
|
|
415
|
+
}
|
|
416
|
+
else
|
|
417
|
+
{
|
|
418
|
+
tx.get_connection().execute(
|
|
419
|
+
include_str!("../../templates/sql/sqlite/metadata_create_table.sql"),
|
|
420
|
+
(),
|
|
421
|
+
)?;
|
|
422
|
+
self.set_metadata_value_json(&mut tx, "graphs", &Vec::<String>::new())?;
|
|
423
|
+
self.create_graph(&mut tx, "default", true)?;
|
|
424
|
+
}
|
|
425
|
+
self.set_metadata_value_json(&mut tx, "version", &consts::GQLITE_VERSION)?;
|
|
426
|
+
tx.close()?;
|
|
427
|
+
Ok(())
|
|
428
|
+
}
|
|
429
|
+
fn begin_sql_read(&self) -> Result<Self::TransactionBox>
|
|
502
430
|
{
|
|
503
431
|
let connection = self.connection.get()?;
|
|
504
432
|
connection.execute("BEGIN", ())?;
|
|
@@ -509,7 +437,7 @@ impl store::Store for Store
|
|
|
509
437
|
},
|
|
510
438
|
}))
|
|
511
439
|
}
|
|
512
|
-
fn
|
|
440
|
+
fn begin_sql_write(&self) -> Result<Self::TransactionBox>
|
|
513
441
|
{
|
|
514
442
|
let connection = self.connection.get()?;
|
|
515
443
|
connection.execute("BEGIN", ())?;
|
|
@@ -520,475 +448,245 @@ impl store::Store for Store
|
|
|
520
448
|
},
|
|
521
449
|
}))
|
|
522
450
|
}
|
|
523
|
-
|
|
451
|
+
|
|
452
|
+
fn execute_batch(
|
|
453
|
+
&self,
|
|
454
|
+
transaction: &mut Self::TransactionBox,
|
|
455
|
+
sql: impl AsRef<str>,
|
|
456
|
+
) -> Result<()>
|
|
524
457
|
{
|
|
525
|
-
|
|
458
|
+
Ok(transaction.get_connection().execute_batch(sql.as_ref())?)
|
|
526
459
|
}
|
|
527
|
-
fn
|
|
460
|
+
fn execute<'a>(
|
|
528
461
|
&self,
|
|
529
462
|
transaction: &mut Self::TransactionBox,
|
|
530
|
-
|
|
531
|
-
|
|
463
|
+
sql: impl AsRef<str>,
|
|
464
|
+
bindings: impl sqlbase::IntoBindings<'a>,
|
|
532
465
|
) -> Result<()>
|
|
533
466
|
{
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
467
|
+
transaction.get_connection().execute(
|
|
468
|
+
sql.as_ref(),
|
|
469
|
+
rusqlite::params_from_iter(bindings.into_bindings_iter()),
|
|
470
|
+
)?;
|
|
471
|
+
Ok(())
|
|
472
|
+
}
|
|
473
|
+
fn query_rows<'a, 'tx>(
|
|
474
|
+
&self,
|
|
475
|
+
transaction: &'tx mut Self::TransactionBox,
|
|
476
|
+
sql: impl AsRef<str>,
|
|
477
|
+
bindings: impl sqlbase::IntoBindings<'a>,
|
|
478
|
+
mut f: impl for<'b> FnMut(&Self::Row<'b>) -> Result<()>,
|
|
479
|
+
) -> Result<()>
|
|
480
|
+
{
|
|
481
|
+
let mut statement = transaction.get_connection().prepare(sql.as_ref())?;
|
|
482
|
+
let mut rows = statement.query(rusqlite::params_from_iter(bindings.into_bindings_iter()))?;
|
|
483
|
+
loop
|
|
537
484
|
{
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
return Ok(());
|
|
541
|
-
}
|
|
542
|
-
else
|
|
485
|
+
let row = rows.next()?;
|
|
486
|
+
match row
|
|
543
487
|
{
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
graph_name: graph_name.to_owned(),
|
|
547
|
-
}
|
|
548
|
-
.into(),
|
|
549
|
-
);
|
|
488
|
+
Some(row) => f(row)?,
|
|
489
|
+
None => break,
|
|
550
490
|
}
|
|
551
491
|
}
|
|
552
|
-
transaction
|
|
553
|
-
.get_connection()
|
|
554
|
-
.execute_batch(templates::GraphCreate { graph_name }.render()?.as_str())?;
|
|
555
|
-
graphs_list.push(graph_name.to_owned());
|
|
556
|
-
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
|
557
492
|
Ok(())
|
|
558
493
|
}
|
|
559
|
-
fn
|
|
494
|
+
fn query_row<'a, 'tx, T>(
|
|
560
495
|
&self,
|
|
561
|
-
transaction: &mut Self::TransactionBox,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
496
|
+
transaction: &'tx mut Self::TransactionBox,
|
|
497
|
+
sql: impl AsRef<str>,
|
|
498
|
+
bindings: impl sqlbase::IntoBindings<'a>,
|
|
499
|
+
f: impl for<'b> FnOnce(&Self::Row<'b>) -> Result<T>,
|
|
500
|
+
) -> Result<T>
|
|
565
501
|
{
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
graphs_list.retain(|x| x != graph_name);
|
|
574
|
-
self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
|
|
502
|
+
transaction.get_connection().query_row(
|
|
503
|
+
sql.as_ref(),
|
|
504
|
+
rusqlite::params_from_iter(bindings.into_bindings_iter()),
|
|
505
|
+
|row| Ok(f(row)),
|
|
506
|
+
)?
|
|
507
|
+
}
|
|
508
|
+
}
|
|
575
509
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
graph_name: graph_name.to_owned(),
|
|
587
|
-
}
|
|
588
|
-
.into(),
|
|
589
|
-
)
|
|
590
|
-
}
|
|
510
|
+
impl super::sqlbase::SqlQueries for Store
|
|
511
|
+
{
|
|
512
|
+
fn graph_create_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
513
|
+
{
|
|
514
|
+
Ok(
|
|
515
|
+
templates::GraphCreate {
|
|
516
|
+
graph_name: graph_name.as_ref(),
|
|
517
|
+
}
|
|
518
|
+
.render()?,
|
|
519
|
+
)
|
|
591
520
|
}
|
|
592
|
-
fn
|
|
593
|
-
|
|
594
|
-
|
|
521
|
+
fn graph_delete(graph_name: impl AsRef<str>) -> Result<String>
|
|
522
|
+
{
|
|
523
|
+
Ok(
|
|
524
|
+
templates::GraphDelete {
|
|
525
|
+
graph_name: graph_name.as_ref(),
|
|
526
|
+
}
|
|
527
|
+
.render()?,
|
|
528
|
+
)
|
|
529
|
+
}
|
|
530
|
+
fn node_create_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
531
|
+
{
|
|
532
|
+
Ok(
|
|
533
|
+
templates::NodeCreate {
|
|
534
|
+
graph_name: graph_name.as_ref(),
|
|
535
|
+
}
|
|
536
|
+
.render()?,
|
|
537
|
+
)
|
|
538
|
+
}
|
|
539
|
+
fn edge_delete_by_nodes_query(
|
|
595
540
|
graph_name: impl AsRef<str>,
|
|
596
|
-
|
|
597
|
-
) -> Result<
|
|
541
|
+
keys: impl AsRef<Vec<String>>,
|
|
542
|
+
) -> Result<String>
|
|
598
543
|
{
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
.as_str(),
|
|
607
|
-
(
|
|
608
|
-
PersistentKey(x.key()),
|
|
609
|
-
serde_json::to_string(x.labels())?,
|
|
610
|
-
serde_json::to_string(x.properties())?,
|
|
611
|
-
),
|
|
612
|
-
)?;
|
|
613
|
-
}
|
|
614
|
-
Ok(())
|
|
544
|
+
Ok(
|
|
545
|
+
templates::EdgeDeleteByNodes {
|
|
546
|
+
graph_name: graph_name.as_ref(),
|
|
547
|
+
keys: keys.as_ref(),
|
|
548
|
+
}
|
|
549
|
+
.render()?,
|
|
550
|
+
)
|
|
615
551
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
transaction: &mut Self::TransactionBox,
|
|
552
|
+
|
|
553
|
+
fn edge_count_for_nodes_query(
|
|
619
554
|
graph_name: impl AsRef<str>,
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
) -> Result<()>
|
|
555
|
+
keys: impl AsRef<Vec<String>>,
|
|
556
|
+
) -> Result<String>
|
|
623
557
|
{
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
{
|
|
629
|
-
transaction.get_connection().execute(
|
|
630
|
-
templates::EdgeDeleteByNodes {
|
|
631
|
-
graph_name,
|
|
632
|
-
keys: &nodes_keys,
|
|
633
|
-
}
|
|
634
|
-
.render()?
|
|
635
|
-
.as_str(),
|
|
636
|
-
(),
|
|
637
|
-
)?;
|
|
638
|
-
}
|
|
639
|
-
else
|
|
640
|
-
{
|
|
641
|
-
let count = transaction.get_connection().query_row(
|
|
642
|
-
templates::EdgeCountForNode {
|
|
643
|
-
graph_name,
|
|
644
|
-
keys: &nodes_keys,
|
|
645
|
-
}
|
|
646
|
-
.render()?
|
|
647
|
-
.as_str(),
|
|
648
|
-
(),
|
|
649
|
-
|row| row.get::<_, usize>(0),
|
|
650
|
-
)?;
|
|
651
|
-
if count > 0
|
|
652
|
-
{
|
|
653
|
-
return Err(error::RunTimeError::DeleteConnectedNode.into());
|
|
558
|
+
Ok(
|
|
559
|
+
templates::EdgeCountForNode {
|
|
560
|
+
graph_name: graph_name.as_ref(),
|
|
561
|
+
keys: keys.as_ref(),
|
|
654
562
|
}
|
|
655
|
-
|
|
656
|
-
|
|
563
|
+
.render()?,
|
|
564
|
+
)
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
fn node_delete_query(graph_name: impl AsRef<str>, keys: impl AsRef<Vec<String>>)
|
|
568
|
+
-> Result<String>
|
|
569
|
+
{
|
|
570
|
+
Ok(
|
|
657
571
|
templates::NodeDelete {
|
|
658
|
-
graph_name,
|
|
659
|
-
keys:
|
|
572
|
+
graph_name: graph_name.as_ref(),
|
|
573
|
+
keys: keys.as_ref(),
|
|
660
574
|
}
|
|
661
|
-
.render()
|
|
662
|
-
|
|
663
|
-
(),
|
|
664
|
-
)?;
|
|
665
|
-
Ok(())
|
|
575
|
+
.render()?,
|
|
576
|
+
)
|
|
666
577
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
transaction: &mut Self::TransactionBox,
|
|
670
|
-
graph_name: impl AsRef<str>,
|
|
671
|
-
node: &crate::graph::Node,
|
|
672
|
-
) -> Result<()>
|
|
578
|
+
|
|
579
|
+
fn node_update_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
673
580
|
{
|
|
674
|
-
|
|
581
|
+
Ok(
|
|
675
582
|
templates::NodeUpdate {
|
|
676
583
|
graph_name: graph_name.as_ref(),
|
|
677
584
|
}
|
|
678
|
-
.render()
|
|
679
|
-
|
|
680
|
-
named_params! {
|
|
681
|
-
":key": PersistentKey(node.key()),
|
|
682
|
-
":labels": serde_json::to_string(node.labels())?,
|
|
683
|
-
":properties": serde_json::to_string(node.properties())?
|
|
684
|
-
},
|
|
685
|
-
)?;
|
|
686
|
-
Ok(())
|
|
585
|
+
.render()?,
|
|
586
|
+
)
|
|
687
587
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
transaction: &mut Self::TransactionBox,
|
|
588
|
+
|
|
589
|
+
fn node_select_query(
|
|
691
590
|
graph_name: impl AsRef<str>,
|
|
692
|
-
|
|
693
|
-
|
|
591
|
+
keys_var: Option<usize>,
|
|
592
|
+
labels_var: Option<usize>,
|
|
593
|
+
properties_var: Option<usize>,
|
|
594
|
+
) -> Result<String>
|
|
694
595
|
{
|
|
695
|
-
|
|
596
|
+
Ok(
|
|
696
597
|
templates::NodeSelect {
|
|
697
598
|
graph_name: graph_name.as_ref(),
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
599
|
+
keys_var: &keys_var,
|
|
600
|
+
labels_var: &labels_var,
|
|
601
|
+
properties_var: &properties_var,
|
|
701
602
|
}
|
|
702
|
-
.render()
|
|
703
|
-
|
|
704
|
-
)?;
|
|
705
|
-
let mut bindings = Vec::<(&'static str, String)>::new();
|
|
706
|
-
if let Some(keys) = query.keys
|
|
707
|
-
{
|
|
708
|
-
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
709
|
-
bindings.push((":keys", serde_json::to_string(&hex_keys)?));
|
|
710
|
-
}
|
|
711
|
-
if let Some(labels) = query.labels
|
|
712
|
-
{
|
|
713
|
-
bindings.push((":labels", serde_json::to_string(&labels)?));
|
|
714
|
-
}
|
|
715
|
-
if let Some(properties) = query.properties
|
|
716
|
-
{
|
|
717
|
-
bindings.push((":properties", serde_json::to_string(&properties)?));
|
|
718
|
-
}
|
|
719
|
-
let mut it = prepared_query.query(
|
|
720
|
-
bindings
|
|
721
|
-
.iter()
|
|
722
|
-
.map(|(k, v)| (*k, v as &dyn rusqlite::ToSql))
|
|
723
|
-
.collect::<Vec<_>>()
|
|
724
|
-
.as_slice(),
|
|
725
|
-
)?;
|
|
726
|
-
let mut nodes: Vec<graph::Node> = Default::default();
|
|
727
|
-
while let Some(row) = it.next()?
|
|
728
|
-
{
|
|
729
|
-
let key: graph::Key = row.get::<_, PersistentKey>(0)?.into();
|
|
730
|
-
let labels = serde_json::from_str(&row.get::<_, String>(1)?)?;
|
|
731
|
-
let properties = serde_json::from_str(&row.get::<_, String>(2)?)?;
|
|
732
|
-
nodes.push(graph::Node::new(key, labels, properties));
|
|
733
|
-
}
|
|
734
|
-
Ok(nodes)
|
|
603
|
+
.render()?,
|
|
604
|
+
)
|
|
735
605
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
transaction: &mut Self::TransactionBox,
|
|
739
|
-
graph_name: impl AsRef<str>,
|
|
740
|
-
edges_iter: T,
|
|
741
|
-
) -> Result<()>
|
|
606
|
+
|
|
607
|
+
fn edge_create_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
742
608
|
{
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
.render()?
|
|
750
|
-
.as_str(),
|
|
751
|
-
(
|
|
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()),
|
|
757
|
-
),
|
|
758
|
-
)?;
|
|
759
|
-
}
|
|
760
|
-
Ok(())
|
|
609
|
+
Ok(
|
|
610
|
+
templates::EdgeCreate {
|
|
611
|
+
graph_name: graph_name.as_ref(),
|
|
612
|
+
}
|
|
613
|
+
.render()?,
|
|
614
|
+
)
|
|
761
615
|
}
|
|
762
|
-
fn
|
|
763
|
-
|
|
764
|
-
transaction: &mut Self::TransactionBox,
|
|
765
|
-
graph_name: impl AsRef<str>,
|
|
766
|
-
query: store::SelectEdgeQuery,
|
|
767
|
-
directivity: crate::graph::EdgeDirectivity,
|
|
768
|
-
) -> Result<()>
|
|
616
|
+
fn edge_delete_query(graph_name: impl AsRef<str>, keys: impl AsRef<Vec<String>>)
|
|
617
|
+
-> Result<String>
|
|
769
618
|
{
|
|
770
|
-
|
|
771
|
-
let edges = self.select_edges(transaction, graph_name, query, directivity)?;
|
|
772
|
-
let edges_keys: Vec<String> = edges.into_iter().map(|x| hex(x.path.key())).collect();
|
|
773
|
-
transaction.get_connection().execute(
|
|
619
|
+
Ok(
|
|
774
620
|
templates::EdgeDelete {
|
|
775
|
-
graph_name,
|
|
776
|
-
keys:
|
|
621
|
+
graph_name: graph_name.as_ref(),
|
|
622
|
+
keys: keys.as_ref(),
|
|
777
623
|
}
|
|
778
|
-
.render()
|
|
779
|
-
|
|
780
|
-
(),
|
|
781
|
-
)?;
|
|
782
|
-
Ok(())
|
|
624
|
+
.render()?,
|
|
625
|
+
)
|
|
783
626
|
}
|
|
784
|
-
fn
|
|
785
|
-
&self,
|
|
786
|
-
transaction: &mut Self::TransactionBox,
|
|
787
|
-
graph_name: impl AsRef<str>,
|
|
788
|
-
edge: &crate::graph::Edge,
|
|
789
|
-
) -> Result<()>
|
|
627
|
+
fn edge_update_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
790
628
|
{
|
|
791
|
-
|
|
629
|
+
Ok(
|
|
792
630
|
templates::EdgeUpdate {
|
|
793
631
|
graph_name: graph_name.as_ref(),
|
|
794
632
|
}
|
|
795
|
-
.render()
|
|
796
|
-
|
|
797
|
-
named_params! {
|
|
798
|
-
":key": PersistentKey(edge.key().to_owned()),
|
|
799
|
-
":labels": serde_json::to_string(edge.labels())?,
|
|
800
|
-
":properties": serde_json::to_string(edge.properties())?
|
|
801
|
-
},
|
|
802
|
-
)?;
|
|
803
|
-
Ok(())
|
|
633
|
+
.render()?,
|
|
634
|
+
)
|
|
804
635
|
}
|
|
805
|
-
fn
|
|
806
|
-
&self,
|
|
807
|
-
transaction: &mut Self::TransactionBox,
|
|
636
|
+
fn edge_select_query(
|
|
808
637
|
graph_name: impl AsRef<str>,
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
638
|
+
is_undirected: bool,
|
|
639
|
+
table_suffix: impl AsRef<str>,
|
|
640
|
+
edge_keys_var: Option<usize>,
|
|
641
|
+
edge_labels_var: Option<usize>,
|
|
642
|
+
edge_properties_var: Option<usize>,
|
|
643
|
+
left_keys_var: Option<usize>,
|
|
644
|
+
left_labels_var: Option<usize>,
|
|
645
|
+
left_properties_var: Option<usize>,
|
|
646
|
+
right_keys_var: Option<usize>,
|
|
647
|
+
right_labels_var: Option<usize>,
|
|
648
|
+
right_properties_var: Option<usize>,
|
|
649
|
+
) -> Result<String>
|
|
812
650
|
{
|
|
813
|
-
|
|
814
|
-
{
|
|
815
|
-
return Ok(Default::default());
|
|
816
|
-
}
|
|
817
|
-
let (is_undirected, table_suffix) = match directivity
|
|
818
|
-
{
|
|
819
|
-
graph::EdgeDirectivity::Directed => (false, ""),
|
|
820
|
-
graph::EdgeDirectivity::Undirected => (true, "_undirected"),
|
|
821
|
-
};
|
|
822
|
-
let mut prepared_query = transaction.get_connection().prepare(
|
|
651
|
+
Ok(
|
|
823
652
|
templates::EdgeSelect {
|
|
824
653
|
graph_name: graph_name.as_ref(),
|
|
825
654
|
is_undirected,
|
|
826
|
-
table_suffix,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
837
|
-
.render()?
|
|
838
|
-
.as_str(),
|
|
839
|
-
)?;
|
|
840
|
-
|
|
841
|
-
let mut bindings = Vec::<(&'static str, String)>::new();
|
|
842
|
-
|
|
843
|
-
// Edge queries
|
|
844
|
-
if let Some(keys) = query.keys
|
|
845
|
-
{
|
|
846
|
-
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
847
|
-
bindings.push((":edge_keys", serde_json::to_string(&hex_keys)?));
|
|
848
|
-
}
|
|
849
|
-
if let Some(labels) = query.labels
|
|
850
|
-
{
|
|
851
|
-
bindings.push((":edge_labels", serde_json::to_string(&labels)?));
|
|
852
|
-
}
|
|
853
|
-
if let Some(properties) = query.properties
|
|
854
|
-
{
|
|
855
|
-
bindings.push((":edge_properties", serde_json::to_string(&properties)?));
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
// Left queries
|
|
859
|
-
if let Some(keys) = query.source.keys
|
|
860
|
-
{
|
|
861
|
-
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
862
|
-
bindings.push((":n_left_keys", serde_json::to_string(&hex_keys)?));
|
|
863
|
-
}
|
|
864
|
-
if let Some(labels) = query.source.labels
|
|
865
|
-
{
|
|
866
|
-
bindings.push((":n_left_labels", serde_json::to_string(&labels)?));
|
|
867
|
-
}
|
|
868
|
-
if let Some(properties) = query.source.properties
|
|
869
|
-
{
|
|
870
|
-
bindings.push((":n_left_properties", serde_json::to_string(&properties)?));
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// Right queries
|
|
874
|
-
if let Some(keys) = query.destination.keys
|
|
875
|
-
{
|
|
876
|
-
let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
|
|
877
|
-
bindings.push((":n_right_keys", serde_json::to_string(&hex_keys)?));
|
|
878
|
-
}
|
|
879
|
-
if let Some(labels) = query.destination.labels
|
|
880
|
-
{
|
|
881
|
-
bindings.push((":n_right_labels", serde_json::to_string(&labels)?));
|
|
882
|
-
}
|
|
883
|
-
if let Some(properties) = query.destination.properties
|
|
884
|
-
{
|
|
885
|
-
bindings.push((":n_right_properties", serde_json::to_string(&properties)?));
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
// Execute query
|
|
889
|
-
let mut it = prepared_query.query(
|
|
890
|
-
bindings
|
|
891
|
-
.iter()
|
|
892
|
-
.map(|(k, v)| (*k, v as &dyn rusqlite::ToSql))
|
|
893
|
-
.collect::<Vec<_>>()
|
|
894
|
-
.as_slice(),
|
|
895
|
-
)?;
|
|
896
|
-
|
|
897
|
-
let mut edges: Vec<EdgeResult> = Default::default();
|
|
898
|
-
let mut edges_keys: HashSet<u128> = Default::default();
|
|
899
|
-
while let Some(row) = it.next()?
|
|
900
|
-
{
|
|
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)?;
|
|
904
|
-
|
|
905
|
-
// This ensure that if (a)-[]->(a) the edge is returned only once. But matching [a]-[]-[b] return the edge twice.
|
|
906
|
-
if n_left_key == n_right_key && edges_keys.contains(&edge_key.uuid())
|
|
907
|
-
{
|
|
908
|
-
continue;
|
|
655
|
+
table_suffix: table_suffix.as_ref(),
|
|
656
|
+
edge_keys_var,
|
|
657
|
+
edge_labels_var,
|
|
658
|
+
edge_properties_var,
|
|
659
|
+
left_keys_var,
|
|
660
|
+
left_labels_var,
|
|
661
|
+
left_properties_var,
|
|
662
|
+
right_keys_var,
|
|
663
|
+
right_labels_var,
|
|
664
|
+
right_properties_var,
|
|
909
665
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
let edge_properties = serde_json::from_str(&row.get::<_, String>(2)?)?;
|
|
913
|
-
|
|
914
|
-
let n_left_labels = serde_json::from_str(&row.get::<_, String>(5)?)?;
|
|
915
|
-
let n_left_properties = serde_json::from_str(&row.get::<_, String>(6)?)?;
|
|
916
|
-
|
|
917
|
-
let n_right_labels = serde_json::from_str(&row.get::<_, String>(8)?)?;
|
|
918
|
-
let n_right_properties = serde_json::from_str(&row.get::<_, String>(9)?)?;
|
|
919
|
-
|
|
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);
|
|
922
|
-
let reversed = row.get::<_, u32>(3)? == 1;
|
|
923
|
-
let (source, destination) = if reversed
|
|
924
|
-
{
|
|
925
|
-
(destination, source)
|
|
926
|
-
}
|
|
927
|
-
else
|
|
928
|
-
{
|
|
929
|
-
(source, destination)
|
|
930
|
-
};
|
|
931
|
-
|
|
932
|
-
edges.push(EdgeResult {
|
|
933
|
-
path: graph::Path::new(
|
|
934
|
-
edge_key.into(),
|
|
935
|
-
source,
|
|
936
|
-
edge_labels,
|
|
937
|
-
edge_properties,
|
|
938
|
-
destination,
|
|
939
|
-
),
|
|
940
|
-
reversed,
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
Ok(edges)
|
|
666
|
+
.render()?,
|
|
667
|
+
)
|
|
944
668
|
}
|
|
945
|
-
fn
|
|
946
|
-
-> Result<store::Statistics>
|
|
669
|
+
fn compute_statistics_query(graph_name: impl AsRef<str>) -> Result<String>
|
|
947
670
|
{
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
.as_str(),
|
|
955
|
-
(),
|
|
956
|
-
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)),
|
|
957
|
-
)?;
|
|
958
|
-
Ok(store::Statistics {
|
|
959
|
-
nodes_count,
|
|
960
|
-
edges_count,
|
|
961
|
-
labels_nodes_count,
|
|
962
|
-
properties_count,
|
|
963
|
-
})
|
|
671
|
+
Ok(
|
|
672
|
+
templates::CallStats {
|
|
673
|
+
graph_name: graph_name.as_ref(),
|
|
674
|
+
}
|
|
675
|
+
.render()?,
|
|
676
|
+
)
|
|
964
677
|
}
|
|
965
678
|
}
|
|
966
679
|
|
|
967
680
|
#[cfg(test)]
|
|
968
681
|
mod tests
|
|
969
682
|
{
|
|
970
|
-
use crate::{
|
|
971
|
-
prelude::*,
|
|
972
|
-
store::{Store, TransactionBoxable},
|
|
973
|
-
};
|
|
974
|
-
#[test]
|
|
975
|
-
fn test_hex()
|
|
976
|
-
{
|
|
977
|
-
assert_eq!(
|
|
978
|
-
super::hex(graph::Key::new(18580062510968287067562660977870108180)),
|
|
979
|
-
"0DFA63CEE7484B0DBFC407697F77F614"
|
|
980
|
-
);
|
|
981
|
-
assert_eq!(
|
|
982
|
-
super::hex(graph::Key::new(0)),
|
|
983
|
-
"00000000000000000000000000000000"
|
|
984
|
-
);
|
|
985
|
-
}
|
|
683
|
+
use crate::{prelude::*, store::TransactionBoxable};
|
|
986
684
|
#[test]
|
|
987
685
|
fn test_sqlite_metadata()
|
|
988
686
|
{
|
|
989
687
|
let temp_file = crate::tests::create_tmp_file();
|
|
990
688
|
let store = super::Store::open(temp_file.path()).unwrap();
|
|
991
|
-
let mut tx = store.
|
|
689
|
+
let mut tx = store.begin_sql_read().unwrap();
|
|
992
690
|
let version: utils::Version = store.get_metadata_value_json(&mut tx, "version").unwrap();
|
|
993
691
|
assert_eq!(version.major, consts::GQLITE_VERSION.major);
|
|
994
692
|
assert_eq!(version.minor, consts::GQLITE_VERSION.minor);
|
|
@@ -998,7 +696,7 @@ mod tests
|
|
|
998
696
|
|
|
999
697
|
// Try to reopen
|
|
1000
698
|
let store = super::Store::open(temp_file.path()).unwrap();
|
|
1001
|
-
let mut tx = store.
|
|
699
|
+
let mut tx = store.begin_sql_read().unwrap();
|
|
1002
700
|
let version: utils::Version = store.get_metadata_value_json(&mut tx, "version").unwrap();
|
|
1003
701
|
assert_eq!(version.major, consts::GQLITE_VERSION.major);
|
|
1004
702
|
assert_eq!(version.minor, consts::GQLITE_VERSION.minor);
|