gqlite 1.2.0 → 1.2.2
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/gqliterb/.cargo/config.toml +2 -0
- data/ext/gqliterb/Cargo.lock +133 -123
- data/ext/gqliterb/Cargo.toml +3 -6
- data/ext/gqliterb/src/lib.rs +2 -2
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2060 -0
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +132 -0
- data/ext/gqliterb/vendor/gqlitedb/askama.toml +3 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/common/mod.rs +25 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/common/pokec.rs +185 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/pokec_divan.rs +137 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/pokec_iai.rs +122 -0
- data/ext/gqliterb/vendor/gqlitedb/release.toml +7 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/arithmetic.rs +96 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/containers.rs +33 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/count.rs +35 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/stats.rs +168 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators.rs +74 -0
- data/ext/gqliterb/vendor/gqlitedb/src/capi.rs +236 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +427 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +620 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1106 -0
- data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +208 -0
- data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
- data/ext/gqliterb/vendor/gqlitedb/src/error.rs +621 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/containers.rs +115 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/edge.rs +20 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/math.rs +44 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/node.rs +16 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +48 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/scalar.rs +86 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/string.rs +28 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/value.rs +99 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions.rs +412 -0
- data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +268 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1788 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +262 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
- data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +42 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +625 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +191 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1153 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +4 -0
- data/ext/gqliterb/vendor/gqlitedb/src/prelude.rs +8 -0
- data/ext/gqliterb/vendor/gqlitedb/src/serialize_with.rs +94 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/pgql.rs +121 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/redb.rs +1250 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +994 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store.rs +432 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/compiler.rs +92 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/evaluators.rs +227 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/parser.rs +81 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store/redb.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +462 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/ast.rs +356 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/programs.rs +455 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates.rs +2 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/utils.rs +28 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/compare.rs +212 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/contains.rs +47 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/value_map.rs +298 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value.rs +559 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +616 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/call_stats.sql +22 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_count_for_node.sql +3 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_create.sql +6 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete_by_nodes.sql +2 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_select.sql +139 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_update.sql +4 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_create.sql +16 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_delete.sql +3 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_create_table.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_get.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_set.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_create.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_delete.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_select.sql +42 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_update.sql +4 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/table_exists.sql +5 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_from_1_01.sql +2 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_graph_from_1_01.sql +65 -0
- metadata +82 -2
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
use crate::prelude::*;
|
|
2
|
+
use value::ValueTryIntoRef;
|
|
3
|
+
|
|
4
|
+
trait ConnectionTrait: Sync + Send
|
|
5
|
+
{
|
|
6
|
+
fn execute_query(&self, query: String, parameters: value::ValueMap) -> Result<value::Value>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
struct ConnectionImpl<TStore>
|
|
10
|
+
where
|
|
11
|
+
TStore: store::Store + Sync + Send,
|
|
12
|
+
{
|
|
13
|
+
store: TStore,
|
|
14
|
+
function_manager: functions::Manager,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
impl<TStore> ConnectionTrait for ConnectionImpl<TStore>
|
|
18
|
+
where
|
|
19
|
+
TStore: store::Store + Sync + Send,
|
|
20
|
+
{
|
|
21
|
+
fn execute_query(&self, query: String, parameters: value::ValueMap) -> Result<value::Value>
|
|
22
|
+
{
|
|
23
|
+
let query_txt: String = query.into();
|
|
24
|
+
let queries = parser::parse(query_txt.as_str())?;
|
|
25
|
+
let mut results = Vec::<value::Value>::default();
|
|
26
|
+
for query in queries
|
|
27
|
+
{
|
|
28
|
+
let program = compiler::compile(&self.function_manager, query)?;
|
|
29
|
+
let v = interpreter::evaluators::eval_program(&self.store, &program, ¶meters)?;
|
|
30
|
+
if !v.is_null()
|
|
31
|
+
{
|
|
32
|
+
results.push(v);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
match results.len()
|
|
36
|
+
{
|
|
37
|
+
0 => Ok(value::Value::Null),
|
|
38
|
+
1 => Ok(results.into_iter().next().unwrap()),
|
|
39
|
+
_ =>
|
|
40
|
+
{
|
|
41
|
+
let mut map = value::ValueMap::new();
|
|
42
|
+
map.insert("type".into(), "results".into());
|
|
43
|
+
map.insert("results".into(), results.into());
|
|
44
|
+
Ok(map.into())
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
impl<TStore: store::Store> ConnectionImpl<TStore>
|
|
51
|
+
where
|
|
52
|
+
TStore: store::Store + Sync + Send,
|
|
53
|
+
{
|
|
54
|
+
fn boxed(self) -> Box<Self>
|
|
55
|
+
{
|
|
56
|
+
Box::new(self)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// Connection is the interface to the database, and allow to execute new queries.
|
|
61
|
+
/// New connection are created with [Connection::open] and queried with [Connection::execute_query].
|
|
62
|
+
/// As shown in the example bellow:
|
|
63
|
+
///
|
|
64
|
+
/// ```rust
|
|
65
|
+
/// # use gqlitedb::{Connection, Value};
|
|
66
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
|
67
|
+
/// let connection = Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
|
|
68
|
+
/// let value = connection.execute_query("MATCH (a) RETURN a", Default::default())?;
|
|
69
|
+
/// match value
|
|
70
|
+
/// {
|
|
71
|
+
/// Value::Array(arr) =>
|
|
72
|
+
/// {
|
|
73
|
+
/// arr.iter().for_each(|row| match row
|
|
74
|
+
/// {
|
|
75
|
+
/// Value::Array(arr) =>
|
|
76
|
+
/// {
|
|
77
|
+
/// println!("{:?}", arr);
|
|
78
|
+
/// }
|
|
79
|
+
/// _ =>
|
|
80
|
+
/// {
|
|
81
|
+
/// panic!("Unexpected: {}", row);
|
|
82
|
+
/// }
|
|
83
|
+
/// });
|
|
84
|
+
/// },
|
|
85
|
+
/// _ => {
|
|
86
|
+
/// panic!("Query result should be an array, got {}!", value);
|
|
87
|
+
/// }
|
|
88
|
+
/// }
|
|
89
|
+
/// # Ok(()) }
|
|
90
|
+
/// ```
|
|
91
|
+
|
|
92
|
+
pub struct Connection
|
|
93
|
+
{
|
|
94
|
+
connection: Box<dyn ConnectionTrait>,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
ccutils::assert_impl_all!(Connection: Sync, Send);
|
|
98
|
+
|
|
99
|
+
impl Connection
|
|
100
|
+
{
|
|
101
|
+
/// Open a `path` that contains a `GQLite` database. The `options` parameter can
|
|
102
|
+
/// be used to select the backend, and configure the backend.
|
|
103
|
+
///
|
|
104
|
+
/// Supported parameters:
|
|
105
|
+
/// - `backend` can be `redb` or `sqlite`
|
|
106
|
+
///
|
|
107
|
+
/// If the `backend` is not specified, the `open` function will attempt to guess it
|
|
108
|
+
/// for existing databases. For new database, depending on availability, it will
|
|
109
|
+
/// create a `sqlite` database, or a `redb` database.
|
|
110
|
+
///
|
|
111
|
+
/// Example of use:
|
|
112
|
+
///
|
|
113
|
+
/// ```rust
|
|
114
|
+
/// # use gqlitedb::Connection;
|
|
115
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
|
116
|
+
/// let connection = Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
|
|
117
|
+
/// # Ok(()) }
|
|
118
|
+
/// ```
|
|
119
|
+
#[cfg(any(feature = "redb", feature = "sqlite"))]
|
|
120
|
+
pub fn open<P: AsRef<std::path::Path>>(path: P, options: value::ValueMap) -> Result<Connection>
|
|
121
|
+
{
|
|
122
|
+
if let Some(backend) = options.get("backend")
|
|
123
|
+
{
|
|
124
|
+
let backend: &String = backend.try_into_ref()?;
|
|
125
|
+
match backend.as_str()
|
|
126
|
+
{
|
|
127
|
+
"sqlite" => Self::open_sqlite(path),
|
|
128
|
+
"redb" => Self::open_redb(path),
|
|
129
|
+
_ => Err(
|
|
130
|
+
StoreError::UnknownBackend {
|
|
131
|
+
backend: backend.to_owned(),
|
|
132
|
+
}
|
|
133
|
+
.into(),
|
|
134
|
+
),
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else
|
|
138
|
+
{
|
|
139
|
+
Self::open_sqlite(path.as_ref().to_owned()).or_else(|sq_e| {
|
|
140
|
+
Self::open_redb(path).map_err(|rb_e| {
|
|
141
|
+
StoreError::OpeningError {
|
|
142
|
+
errors: error::vec_to_error::<ErrorType>(&vec![sq_e, rb_e]),
|
|
143
|
+
}
|
|
144
|
+
.into()
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
#[cfg(feature = "sqlite")]
|
|
150
|
+
fn open_sqlite<P: AsRef<std::path::Path>>(path: P) -> Result<Connection>
|
|
151
|
+
{
|
|
152
|
+
Ok(Connection {
|
|
153
|
+
connection: ConnectionImpl {
|
|
154
|
+
store: store::sqlite::Store::new(path)?,
|
|
155
|
+
function_manager: functions::Manager::new(),
|
|
156
|
+
}
|
|
157
|
+
.boxed(),
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
#[cfg(not(feature = "sqlite"))]
|
|
161
|
+
fn open_sqlite<P: AsRef<std::path::Path>>(_: P) -> Result<Connection>
|
|
162
|
+
{
|
|
163
|
+
Err(error::ConnectionError::UnavailableBackend { backend: "sqlite" }.into())
|
|
164
|
+
}
|
|
165
|
+
#[cfg(feature = "redb")]
|
|
166
|
+
fn open_redb<P: AsRef<std::path::Path>>(path: P) -> Result<Connection>
|
|
167
|
+
{
|
|
168
|
+
Ok(Connection {
|
|
169
|
+
connection: ConnectionImpl {
|
|
170
|
+
store: store::redb::Store::new(path)?,
|
|
171
|
+
function_manager: functions::Manager::new(),
|
|
172
|
+
}
|
|
173
|
+
.boxed(),
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
#[cfg(not(feature = "redb"))]
|
|
177
|
+
fn open_redb<P: AsRef<std::path::Path>>(_: P) -> Result<Connection>
|
|
178
|
+
{
|
|
179
|
+
Err(error::StoreError::UnavailableBackend { backend: "redb" }.into())
|
|
180
|
+
}
|
|
181
|
+
#[cfg(feature = "_pgql")]
|
|
182
|
+
pub fn create() -> Result<Connection>
|
|
183
|
+
{
|
|
184
|
+
Ok(Connection {
|
|
185
|
+
store: store::Store::new()?,
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
/// Execute the `query` (using OpenCypher), given the query `parameters` (sometimes
|
|
189
|
+
/// also referred as binding).
|
|
190
|
+
///
|
|
191
|
+
/// Example:
|
|
192
|
+
///
|
|
193
|
+
/// ```rust
|
|
194
|
+
/// # use gqlitedb::{Connection, Value};
|
|
195
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
|
196
|
+
/// # let connection = gqlitedb::Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
|
|
197
|
+
/// let result = connection.execute_query("MATCH (a { name: $name }) RETURN a", gqlitedb::map!("name" => "Joe"))?;
|
|
198
|
+
/// # Ok(()) }
|
|
199
|
+
/// ```
|
|
200
|
+
pub fn execute_query(
|
|
201
|
+
&self,
|
|
202
|
+
query: impl Into<String>,
|
|
203
|
+
parameters: value::ValueMap,
|
|
204
|
+
) -> Result<value::Value>
|
|
205
|
+
{
|
|
206
|
+
self.connection.execute_query(query.into(), parameters)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pub(crate) const SHOW_PARSE_TREE: bool = false;
|
|
2
|
+
pub(crate) const SHOW_AST: bool = false;
|
|
3
|
+
pub(crate) const SHOW_PROGRAM: bool = false;
|
|
4
|
+
pub(crate) const SHOW_EVALUATOR_STATE: bool = false;
|
|
5
|
+
|
|
6
|
+
pub(crate) const GQLITE_VERSION: crate::utils::Version = crate::utils::Version {
|
|
7
|
+
major: 1,
|
|
8
|
+
minor: 2,
|
|
9
|
+
patch: 0,
|
|
10
|
+
};
|