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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1b7eba40745af114ff57ca358b2e03c67a7adb9717ad7c7b81ddd7444503fbb1
|
|
4
|
+
data.tar.gz: 3ae6e7c7b038a2caeaf728ff7ce98c49266160d181f478c8259b98d7d8157ba5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6674d35ca4d0ec02090ef1521f9f8bb2a4025a050ed312e9c20d50033c8a3472a6a31bdb73dfe6fa9ec99612518c5f5edd72d3ea9d8ead7885c39ed106ac6056
|
|
7
|
+
data.tar.gz: e200b7d2a4203cf803a65bcd6eef82a990fc8c1fa2e2846148673109731353898dacd7b388fe23c9c5b8e5eeae2b56768912408f6f916805111d322c0a83d5ac
|
data/ext/Cargo.toml
CHANGED
|
@@ -3,15 +3,15 @@ resolver = "2"
|
|
|
3
3
|
members = ["gqliterb", "gqlitedb", "graphcore"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.7.0"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
homepage = "https://gqlite.org"
|
|
10
10
|
repository = "https://gitlab.com/gqlite/gqlite"
|
|
11
11
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
|
-
graphcore = { version = "0.
|
|
14
|
-
gqlitedb = { version = "0.
|
|
13
|
+
graphcore = { version = "0.7.0", path = "graphcore" }
|
|
14
|
+
gqlitedb = { version = "0.7.0", path = "gqlitedb" }
|
|
15
15
|
|
|
16
16
|
askama = { version = "0.14" }
|
|
17
17
|
ccutils = { version = "0.4" }
|
data/ext/gqlitedb/Cargo.toml
CHANGED
|
@@ -16,12 +16,13 @@ default = ["redb", "capi", "sqlite"]
|
|
|
16
16
|
_backtrace = []
|
|
17
17
|
capi = []
|
|
18
18
|
redb = ["dep:redb", "dep:redb2"]
|
|
19
|
-
|
|
19
|
+
_pgrx = ["dep:pgrx"]
|
|
20
20
|
_pg13 = ["pgrx/pg13"]
|
|
21
21
|
_pg14 = ["pgrx/pg14"]
|
|
22
22
|
_pg15 = ["pgrx/pg15"]
|
|
23
23
|
_pg16 = ["pgrx/pg16"]
|
|
24
24
|
_pg17 = ["pgrx/pg17"]
|
|
25
|
+
postgres = ["dep:postgres"]
|
|
25
26
|
sqlite = ["dep:rusqlite", "dep:askama"]
|
|
26
27
|
_value_private = []
|
|
27
28
|
bundled = ["rusqlite/bundled"]
|
|
@@ -33,9 +34,10 @@ askama = { workspace = true, optional = true }
|
|
|
33
34
|
ccutils = { workspace = true, features = ["alias", "pool", "sync"] }
|
|
34
35
|
ciborium = "0.2"
|
|
35
36
|
itertools = { workspace = true }
|
|
36
|
-
pgrx = { version = "0.16", optional = true }
|
|
37
37
|
pest = "2"
|
|
38
38
|
pest_derive = "2"
|
|
39
|
+
pgrx = { version = "0.16", optional = true }
|
|
40
|
+
postgres = { version = "0.19", optional = true }
|
|
39
41
|
rand = "0.9"
|
|
40
42
|
redb = { version = "3", optional = true }
|
|
41
43
|
redb2 = { version = "2", optional = true, package = "redb" }
|
|
@@ -52,6 +54,7 @@ uuid = { workspace = true }
|
|
|
52
54
|
ccutils = { workspace = true, features = ["alias", "temporary"] }
|
|
53
55
|
divan = "0.1"
|
|
54
56
|
iai-callgrind = { version = "0.16" }
|
|
57
|
+
pgtemp = "0.6"
|
|
55
58
|
regex = "1"
|
|
56
59
|
|
|
57
60
|
# web:
|
|
@@ -21,6 +21,7 @@ pub(crate) enum ExpressionType
|
|
|
21
21
|
Float,
|
|
22
22
|
Path,
|
|
23
23
|
String,
|
|
24
|
+
TimeStamp,
|
|
24
25
|
Variant,
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -419,6 +420,7 @@ impl<'b> Analyser<'b>
|
|
|
419
420
|
value::Value::Map(_) => ExpressionType::Map,
|
|
420
421
|
value::Value::Path(_) => ExpressionType::Path,
|
|
421
422
|
value::Value::String(_) => ExpressionType::String,
|
|
423
|
+
value::Value::TimeStamp(_) => ExpressionType::TimeStamp,
|
|
422
424
|
},
|
|
423
425
|
true,
|
|
424
426
|
false,
|
|
@@ -942,6 +942,7 @@ pub(crate) fn compile(
|
|
|
942
942
|
{
|
|
943
943
|
ast::Statement::CreateGraph(create_graph) => Ok(Block::CreateGraph {
|
|
944
944
|
name: create_graph.name.to_owned(),
|
|
945
|
+
if_not_exists: create_graph.if_not_exists,
|
|
945
946
|
}),
|
|
946
947
|
ast::Statement::DropGraph(drop_graph) => Ok(Block::DropGraph {
|
|
947
948
|
name: drop_graph.name.to_owned(),
|
|
@@ -8,12 +8,15 @@ pub enum Backend
|
|
|
8
8
|
{
|
|
9
9
|
/// Select the first available backend.
|
|
10
10
|
Automatic,
|
|
11
|
-
///
|
|
12
|
-
#[cfg(feature = "
|
|
13
|
-
|
|
11
|
+
/// Postgres backend.
|
|
12
|
+
#[cfg(feature = "postgres")]
|
|
13
|
+
Postgres,
|
|
14
14
|
/// Redb backend.
|
|
15
15
|
#[cfg(feature = "redb")]
|
|
16
16
|
Redb,
|
|
17
|
+
/// SQLite backend.
|
|
18
|
+
#[cfg(feature = "sqlite")]
|
|
19
|
+
SQLite,
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
/// Builder with high-level API for creating connection.
|
|
@@ -52,16 +55,21 @@ impl ConnectionBuilder
|
|
|
52
55
|
{
|
|
53
56
|
self.map.insert(key, "automatic".into());
|
|
54
57
|
}
|
|
55
|
-
#[cfg(feature = "
|
|
56
|
-
Backend::
|
|
58
|
+
#[cfg(feature = "postgres")]
|
|
59
|
+
Backend::Postgres =>
|
|
57
60
|
{
|
|
58
|
-
self.map.insert(key, "
|
|
61
|
+
self.map.insert(key, "postgres".into());
|
|
59
62
|
}
|
|
60
63
|
#[cfg(feature = "redb")]
|
|
61
64
|
Backend::Redb =>
|
|
62
65
|
{
|
|
63
66
|
self.map.insert(key, "redb".into());
|
|
64
67
|
}
|
|
68
|
+
#[cfg(feature = "sqlite")]
|
|
69
|
+
Backend::SQLite =>
|
|
70
|
+
{
|
|
71
|
+
self.map.insert(key, "sqlite".into());
|
|
72
|
+
}
|
|
65
73
|
}
|
|
66
74
|
self
|
|
67
75
|
}
|
|
@@ -204,7 +212,7 @@ impl Connection
|
|
|
204
212
|
|
|
205
213
|
sq_r.map_err(|rb_e| {
|
|
206
214
|
StoreError::OpeningError {
|
|
207
|
-
errors: error::vec_to_error(&
|
|
215
|
+
errors: error::vec_to_error(&[sq_e, rb_e]),
|
|
208
216
|
}
|
|
209
217
|
.into()
|
|
210
218
|
})
|
|
@@ -251,6 +259,33 @@ impl Connection
|
|
|
251
259
|
.boxed(),
|
|
252
260
|
})
|
|
253
261
|
}
|
|
262
|
+
#[cfg(feature = "postgres")]
|
|
263
|
+
"postgres" =>
|
|
264
|
+
{
|
|
265
|
+
let mut config = postgres::Config::new();
|
|
266
|
+
if let Some(host) = options.get("host")
|
|
267
|
+
{
|
|
268
|
+
let host: &String = host.try_into_ref()?;
|
|
269
|
+
config.host(host);
|
|
270
|
+
}
|
|
271
|
+
if let Some(user) = options.get("user")
|
|
272
|
+
{
|
|
273
|
+
let user: &String = user.try_into_ref()?;
|
|
274
|
+
config.user(user);
|
|
275
|
+
}
|
|
276
|
+
if let Some(password) = options.get("password")
|
|
277
|
+
{
|
|
278
|
+
let password: &String = password.try_into_ref()?;
|
|
279
|
+
config.password(password);
|
|
280
|
+
}
|
|
281
|
+
let store = store::postgres::Store::connect(config)?;
|
|
282
|
+
Ok(Connection {
|
|
283
|
+
connection: ConnectionImpl {
|
|
284
|
+
store,
|
|
285
|
+
function_manager: functions::Manager::new(),
|
|
286
|
+
},
|
|
287
|
+
})
|
|
288
|
+
}
|
|
254
289
|
_ => Err(StoreError::UnknownBackend { backend }.into()),
|
|
255
290
|
}
|
|
256
291
|
}
|
data/ext/gqlitedb/src/error.rs
CHANGED
|
@@ -313,6 +313,8 @@ pub enum InternalError
|
|
|
313
313
|
Poison(String),
|
|
314
314
|
#[error("IOError: {0}.")]
|
|
315
315
|
IOError(#[from] std::io::Error),
|
|
316
|
+
#[error("Utf8Error: {0}.")]
|
|
317
|
+
Utf8Error(#[from] std::str::Utf8Error),
|
|
316
318
|
}
|
|
317
319
|
|
|
318
320
|
/// Error in the store backend.
|
|
@@ -541,6 +543,7 @@ error_as_internal! {ciborium::ser::Error<std::io::Error>}
|
|
|
541
543
|
error_as_internal! {ciborium::de::Error<std::io::Error>}
|
|
542
544
|
error_as_internal! {serde_json::Error}
|
|
543
545
|
error_as_internal! {std::num::ParseFloatError}
|
|
546
|
+
error_as_internal! {std::str::Utf8Error}
|
|
544
547
|
|
|
545
548
|
#[cfg(feature = "redb")]
|
|
546
549
|
mod _trait_impl_redb
|
|
@@ -1212,10 +1212,13 @@ pub(crate) fn eval_program<TStore: store::Store>(
|
|
|
1212
1212
|
}
|
|
1213
1213
|
match block
|
|
1214
1214
|
{
|
|
1215
|
-
instructions::Block::CreateGraph {
|
|
1215
|
+
instructions::Block::CreateGraph {
|
|
1216
|
+
name,
|
|
1217
|
+
if_not_exists,
|
|
1218
|
+
} =>
|
|
1216
1219
|
{
|
|
1217
1220
|
store
|
|
1218
|
-
.create_graph(&mut tx, name,
|
|
1221
|
+
.create_graph(&mut tx, name, *if_not_exists)
|
|
1219
1222
|
.map_err(|e|
|
|
1220
1223
|
error::map_error!(e, Error::StoreError(StoreError::DuplicatedGraph { graph_name }) => RunTimeError::DuplicatedGraph {
|
|
1221
1224
|
graph_name: graph_name.clone(),
|
data/ext/gqlitedb/src/lib.rs
CHANGED
|
@@ -35,7 +35,7 @@ pub use {
|
|
|
35
35
|
error::{CompileTimeError, Error, RunTimeError, StoreError},
|
|
36
36
|
graph::{labels, Edge, Node, Path},
|
|
37
37
|
query_result::QueryResult,
|
|
38
|
-
value::{array, value_map, Value, ValueMap, ValueTryIntoRef},
|
|
38
|
+
value::{array, value_map, TimeStamp, Value, ValueMap, ValueTryIntoRef},
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
pub use graphcore::{table, Table};
|
|
@@ -63,7 +63,8 @@ where_modifier = { "WHERE" ~ expression }
|
|
|
63
63
|
|
|
64
64
|
// Statements
|
|
65
65
|
statement = {
|
|
66
|
-
|
|
66
|
+
create_graph_if_not_exists_statement
|
|
67
|
+
| create_graph_statement
|
|
67
68
|
| drop_graph_if_exists_statement
|
|
68
69
|
| drop_graph_statement
|
|
69
70
|
| use_graph_statement
|
|
@@ -83,6 +84,7 @@ statement = {
|
|
|
83
84
|
star = { "*" }
|
|
84
85
|
|
|
85
86
|
create_graph_statement = { "CREATE" ~ "GRAPH" ~ ident }
|
|
87
|
+
create_graph_if_not_exists_statement = { "CREATE" ~ "GRAPH" ~ "IF" ~ "NOT" ~ "EXISTS" ~ ident }
|
|
86
88
|
drop_graph_statement = { "DROP" ~ "GRAPH" ~ ident }
|
|
87
89
|
drop_graph_if_exists_statement = { "DROP" ~ "GRAPH" ~ "IF" ~ "EXISTS" ~ ident }
|
|
88
90
|
use_graph_statement = { "USE" ~ ident }
|
|
@@ -909,7 +909,15 @@ impl AstBuilder
|
|
|
909
909
|
{
|
|
910
910
|
Rule::create_graph_statement => Ok(ast::Statement::CreateGraph(ast::CreateGraph {
|
|
911
911
|
name: self.build_ident(&mut pair.into_inner())?,
|
|
912
|
+
if_not_exists: false,
|
|
912
913
|
})),
|
|
914
|
+
Rule::create_graph_if_not_exists_statement =>
|
|
915
|
+
{
|
|
916
|
+
Ok(ast::Statement::CreateGraph(ast::CreateGraph {
|
|
917
|
+
name: self.build_ident(&mut pair.into_inner())?,
|
|
918
|
+
if_not_exists: true,
|
|
919
|
+
}))
|
|
920
|
+
}
|
|
913
921
|
Rule::drop_graph_statement => Ok(ast::Statement::DropGraph(ast::DropGraph {
|
|
914
922
|
name: self.build_ident(&mut pair.into_inner())?,
|
|
915
923
|
if_exists: false,
|
data/ext/gqlitedb/src/prelude.rs
CHANGED
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
|
2
|
+
|
|
3
|
+
use super::{FromSqlValue, SqlValue};
|
|
4
|
+
use crate::prelude::*;
|
|
5
|
+
|
|
6
|
+
pub(crate) trait SqlMetaDataQueries
|
|
7
|
+
{
|
|
8
|
+
fn metadata_get_query() -> Result<String>;
|
|
9
|
+
fn metadata_set_query() -> Result<String>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
pub(crate) trait SqlMetaDataStore: super::SqlStore
|
|
13
|
+
{
|
|
14
|
+
/// Get the metavalue
|
|
15
|
+
fn get_optional_metadata_value<T: FromSqlValue>(
|
|
16
|
+
&self,
|
|
17
|
+
transaction: &mut Self::TransactionBox,
|
|
18
|
+
key: impl Into<String>,
|
|
19
|
+
) -> Result<Option<T>>;
|
|
20
|
+
fn get_metadata_value<T: FromSqlValue>(
|
|
21
|
+
&self,
|
|
22
|
+
transaction: &mut Self::TransactionBox,
|
|
23
|
+
key: impl Into<String>,
|
|
24
|
+
) -> Result<T>
|
|
25
|
+
{
|
|
26
|
+
let key = key.into();
|
|
27
|
+
self
|
|
28
|
+
.get_optional_metadata_value(transaction, &key)?
|
|
29
|
+
.ok_or_else(|| InternalError::MissingMetadata { key }.into())
|
|
30
|
+
}
|
|
31
|
+
#[allow(dead_code)]
|
|
32
|
+
fn get_metadata_value_or_else<T: FromSqlValue>(
|
|
33
|
+
&self,
|
|
34
|
+
transaction: &mut Self::TransactionBox,
|
|
35
|
+
key: impl Into<String>,
|
|
36
|
+
f: impl FnOnce() -> T,
|
|
37
|
+
) -> Result<T>
|
|
38
|
+
{
|
|
39
|
+
let v = self.get_optional_metadata_value(transaction, key)?;
|
|
40
|
+
Ok(v.unwrap_or_else(f))
|
|
41
|
+
}
|
|
42
|
+
/// Get the metadata value and deserialize it from JSON.
|
|
43
|
+
fn get_metadata_value_json<T: for<'a> Deserialize<'a>>(
|
|
44
|
+
&self,
|
|
45
|
+
transaction: &mut Self::TransactionBox,
|
|
46
|
+
key: impl Into<String>,
|
|
47
|
+
) -> Result<T>
|
|
48
|
+
{
|
|
49
|
+
Ok(serde_json::from_str(
|
|
50
|
+
&self.get_metadata_value::<String>(transaction, key)?,
|
|
51
|
+
)?)
|
|
52
|
+
}
|
|
53
|
+
#[allow(dead_code)]
|
|
54
|
+
fn get_metadata_value_json_or_else<T: for<'a> Deserialize<'a>>(
|
|
55
|
+
&self,
|
|
56
|
+
transaction: &mut Self::TransactionBox,
|
|
57
|
+
key: impl Into<String>,
|
|
58
|
+
f: impl FnOnce() -> T,
|
|
59
|
+
) -> Result<T>
|
|
60
|
+
{
|
|
61
|
+
let v = self.get_optional_metadata_value::<String>(transaction, key)?;
|
|
62
|
+
v.map_or_else(|| Ok(f()), |x| Ok(serde_json::from_str(&x)?))
|
|
63
|
+
}
|
|
64
|
+
fn set_metadata_value<'a>(
|
|
65
|
+
&self,
|
|
66
|
+
transaction: &mut Self::TransactionBox,
|
|
67
|
+
key: impl Into<String>,
|
|
68
|
+
value: impl Into<SqlValue<'a>>,
|
|
69
|
+
) -> Result<()>;
|
|
70
|
+
/// Serialize a value to JSON and store the result in the database.
|
|
71
|
+
fn set_metadata_value_json(
|
|
72
|
+
&self,
|
|
73
|
+
transaction: &mut Self::TransactionBox,
|
|
74
|
+
key: impl Into<String>,
|
|
75
|
+
value: &impl Serialize,
|
|
76
|
+
) -> Result<()>
|
|
77
|
+
{
|
|
78
|
+
self.set_metadata_value(transaction, key, &serde_json::to_string(value)?)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
impl<TStore> SqlMetaDataStore for TStore
|
|
83
|
+
where
|
|
84
|
+
TStore: super::SqlStore + SqlMetaDataQueries,
|
|
85
|
+
{
|
|
86
|
+
fn get_optional_metadata_value<T: FromSqlValue>(
|
|
87
|
+
&self,
|
|
88
|
+
transaction: &mut Self::TransactionBox,
|
|
89
|
+
key: impl Into<String>,
|
|
90
|
+
) -> Result<Option<T>>
|
|
91
|
+
{
|
|
92
|
+
let mut res = None;
|
|
93
|
+
self.query_rows(
|
|
94
|
+
transaction,
|
|
95
|
+
Self::metadata_get_query()?,
|
|
96
|
+
(&key.into(),),
|
|
97
|
+
|x| {
|
|
98
|
+
res = Some(x.get(0)?);
|
|
99
|
+
Ok(())
|
|
100
|
+
},
|
|
101
|
+
)?;
|
|
102
|
+
Ok(res)
|
|
103
|
+
}
|
|
104
|
+
fn set_metadata_value<'a>(
|
|
105
|
+
&self,
|
|
106
|
+
transaction: &mut Self::TransactionBox,
|
|
107
|
+
key: impl Into<String>,
|
|
108
|
+
value: impl Into<SqlValue<'a>>,
|
|
109
|
+
) -> Result<()>
|
|
110
|
+
{
|
|
111
|
+
self.execute(
|
|
112
|
+
transaction,
|
|
113
|
+
Self::metadata_set_query()?,
|
|
114
|
+
(&key.into(), value.into()),
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
use crate::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) trait SqlQueries
|
|
4
|
+
{
|
|
5
|
+
/// Query for creating a new graph.
|
|
6
|
+
fn graph_create_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
7
|
+
/// Query for deleting a graph.
|
|
8
|
+
fn graph_delete(graph_name: impl AsRef<str>) -> Result<String>;
|
|
9
|
+
/// Query for creating a new node
|
|
10
|
+
fn node_create_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
11
|
+
/// Query for deleting the nodes.
|
|
12
|
+
fn node_delete_query(
|
|
13
|
+
graph_name: impl AsRef<str>,
|
|
14
|
+
keys: impl AsRef<Vec<String>>,
|
|
15
|
+
) -> Result<String>;
|
|
16
|
+
/// Query for updating a node.
|
|
17
|
+
fn node_update_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
18
|
+
/// Query for selecting a node.
|
|
19
|
+
fn node_select_query(
|
|
20
|
+
graph_name: impl AsRef<str>,
|
|
21
|
+
keys_var: Option<usize>,
|
|
22
|
+
labels_var: Option<usize>,
|
|
23
|
+
properties_var: Option<usize>,
|
|
24
|
+
) -> Result<String>;
|
|
25
|
+
/// Query for createing an edge.
|
|
26
|
+
fn edge_create_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
27
|
+
/// Query for deleting the edges.
|
|
28
|
+
fn edge_delete_query(
|
|
29
|
+
graph_name: impl AsRef<str>,
|
|
30
|
+
keys: impl AsRef<Vec<String>>,
|
|
31
|
+
) -> Result<String>;
|
|
32
|
+
/// Query for updating a node.
|
|
33
|
+
fn edge_update_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
34
|
+
/// Query for deleting edges for the given nodes.
|
|
35
|
+
fn edge_delete_by_nodes_query(
|
|
36
|
+
graph_name: impl AsRef<str>,
|
|
37
|
+
keys: impl AsRef<Vec<String>>,
|
|
38
|
+
) -> Result<String>;
|
|
39
|
+
/// Query for the number of edges connected to the nodes.
|
|
40
|
+
fn edge_count_for_nodes_query(
|
|
41
|
+
graph_name: impl AsRef<str>,
|
|
42
|
+
keys: impl AsRef<Vec<String>>,
|
|
43
|
+
) -> Result<String>;
|
|
44
|
+
/// Query for selecting an edge.
|
|
45
|
+
#[allow(clippy::too_many_arguments)]
|
|
46
|
+
fn edge_select_query(
|
|
47
|
+
graph_name: impl AsRef<str>,
|
|
48
|
+
is_undirected: bool,
|
|
49
|
+
table_suffix: impl AsRef<str>,
|
|
50
|
+
edge_keys_var: Option<usize>,
|
|
51
|
+
edge_labels_var: Option<usize>,
|
|
52
|
+
edge_properties_var: Option<usize>,
|
|
53
|
+
left_keys_var: Option<usize>,
|
|
54
|
+
left_labels_var: Option<usize>,
|
|
55
|
+
left_properties_var: Option<usize>,
|
|
56
|
+
right_keys_var: Option<usize>,
|
|
57
|
+
right_labels_var: Option<usize>,
|
|
58
|
+
right_properties_var: Option<usize>,
|
|
59
|
+
) -> Result<String>;
|
|
60
|
+
/// Query for computing statistics.
|
|
61
|
+
fn compute_statistics_query(graph_name: impl AsRef<str>) -> Result<String>;
|
|
62
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
use crate::{prelude::*, store::TransactionBoxable};
|
|
2
|
+
|
|
3
|
+
use super::{FromSqlValue, IntoBindings, SqlValue};
|
|
4
|
+
|
|
5
|
+
pub(crate) trait Row: Sized
|
|
6
|
+
{
|
|
7
|
+
fn get<T: FromSqlValue>(&self, index: usize) -> Result<T>
|
|
8
|
+
{
|
|
9
|
+
T::from_sql_value(self.get_value(index)?)
|
|
10
|
+
}
|
|
11
|
+
fn get_value(&self, index: usize) -> Result<SqlValue<'_>>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// Base trait for SQL Store.
|
|
15
|
+
pub(crate) trait SqlStore
|
|
16
|
+
{
|
|
17
|
+
type TransactionBox: TransactionBoxable;
|
|
18
|
+
type Row<'a>: Row;
|
|
19
|
+
/// Initialise an SQL store
|
|
20
|
+
fn initialise(&self) -> Result<()>;
|
|
21
|
+
|
|
22
|
+
/// Begin a read transaction.
|
|
23
|
+
fn begin_sql_read(&self) -> Result<Self::TransactionBox>;
|
|
24
|
+
/// Begin a write transaction.
|
|
25
|
+
fn begin_sql_write(&self) -> Result<Self::TransactionBox>;
|
|
26
|
+
/// Execute a batch of SQL queries for the given transaction.
|
|
27
|
+
fn execute_batch(
|
|
28
|
+
&self,
|
|
29
|
+
transaction: &mut Self::TransactionBox,
|
|
30
|
+
sql: impl AsRef<str>,
|
|
31
|
+
) -> Result<()>;
|
|
32
|
+
/// Execute a single SQL query for the given transaction.
|
|
33
|
+
fn execute<'a>(
|
|
34
|
+
&self,
|
|
35
|
+
transaction: &mut Self::TransactionBox,
|
|
36
|
+
sql: impl AsRef<str>,
|
|
37
|
+
bindings: impl IntoBindings<'a>,
|
|
38
|
+
) -> Result<()>;
|
|
39
|
+
/// Execute a SQL Query that return a single row.
|
|
40
|
+
fn query_row<'a, 'tx, T>(
|
|
41
|
+
&self,
|
|
42
|
+
transaction: &'tx mut Self::TransactionBox,
|
|
43
|
+
sql: impl AsRef<str>,
|
|
44
|
+
bindings: impl IntoBindings<'a>,
|
|
45
|
+
f: impl for<'b> FnOnce(&Self::Row<'b>) -> Result<T>,
|
|
46
|
+
) -> Result<T>;
|
|
47
|
+
/// Execute a SQL Query that return multiple rows.
|
|
48
|
+
fn query_rows<'a, 'tx>(
|
|
49
|
+
&self,
|
|
50
|
+
transaction: &'tx mut Self::TransactionBox,
|
|
51
|
+
sql: impl AsRef<str>,
|
|
52
|
+
bindings: impl IntoBindings<'a>,
|
|
53
|
+
f: impl for<'b> FnMut(&Self::Row<'b>) -> Result<()>,
|
|
54
|
+
) -> Result<()>;
|
|
55
|
+
}
|