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
@@ -0,0 +1,300 @@
|
|
1
|
+
use std::path::Path;
|
2
|
+
|
3
|
+
use crate::{prelude::*, QueryResult};
|
4
|
+
use value::ValueTryIntoRef;
|
5
|
+
|
6
|
+
/// Backend
|
7
|
+
pub enum Backend
|
8
|
+
{
|
9
|
+
/// Select the first available backend.
|
10
|
+
Automatic,
|
11
|
+
/// SQLite backend.
|
12
|
+
#[cfg(feature = "sqlite")]
|
13
|
+
SQLite,
|
14
|
+
/// Redb backend.
|
15
|
+
#[cfg(feature = "redb")]
|
16
|
+
Redb,
|
17
|
+
}
|
18
|
+
|
19
|
+
/// Builder with high-level API for creating connection.
|
20
|
+
pub struct ConnectionBuilder
|
21
|
+
{
|
22
|
+
map: value::ValueMap,
|
23
|
+
}
|
24
|
+
|
25
|
+
impl ConnectionBuilder
|
26
|
+
{
|
27
|
+
/// Merge options. This might overwrite value from the builder
|
28
|
+
pub fn options(mut self, options: value::ValueMap) -> Self
|
29
|
+
{
|
30
|
+
for (k, v) in options.into_iter()
|
31
|
+
{
|
32
|
+
self.map.insert(k, v);
|
33
|
+
}
|
34
|
+
self
|
35
|
+
}
|
36
|
+
/// Set path
|
37
|
+
pub fn path<P: AsRef<Path>>(mut self, p: P) -> Self
|
38
|
+
{
|
39
|
+
self.map.insert(
|
40
|
+
"path".to_string(),
|
41
|
+
p.as_ref().to_string_lossy().as_ref().into(),
|
42
|
+
);
|
43
|
+
self
|
44
|
+
}
|
45
|
+
/// Set backend
|
46
|
+
pub fn backend(mut self, backend: Backend) -> Self
|
47
|
+
{
|
48
|
+
let key = "backend".into();
|
49
|
+
match backend
|
50
|
+
{
|
51
|
+
Backend::Automatic =>
|
52
|
+
{
|
53
|
+
self.map.insert(key, "automatic".into());
|
54
|
+
}
|
55
|
+
#[cfg(feature = "sqlite")]
|
56
|
+
Backend::SQLite =>
|
57
|
+
{
|
58
|
+
self.map.insert(key, "sqlite".into());
|
59
|
+
}
|
60
|
+
#[cfg(feature = "redb")]
|
61
|
+
Backend::Redb =>
|
62
|
+
{
|
63
|
+
self.map.insert(key, "redb".into());
|
64
|
+
}
|
65
|
+
}
|
66
|
+
self
|
67
|
+
}
|
68
|
+
/// Create the connection
|
69
|
+
pub fn create(self) -> Result<Connection>
|
70
|
+
{
|
71
|
+
Connection::create(self.map)
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
trait ConnectionTrait: Sync + Send
|
76
|
+
{
|
77
|
+
fn execute_oc_query(&self, query: &str, parameters: value::ValueMap) -> Result<QueryResult>;
|
78
|
+
}
|
79
|
+
|
80
|
+
struct ConnectionImpl<TStore>
|
81
|
+
where
|
82
|
+
TStore: store::Store + Sync + Send,
|
83
|
+
{
|
84
|
+
store: TStore,
|
85
|
+
function_manager: functions::Manager,
|
86
|
+
}
|
87
|
+
|
88
|
+
impl<TStore> ConnectionTrait for ConnectionImpl<TStore>
|
89
|
+
where
|
90
|
+
TStore: store::Store + Sync + Send,
|
91
|
+
{
|
92
|
+
fn execute_oc_query(&self, query: &str, parameters: value::ValueMap) -> Result<QueryResult>
|
93
|
+
{
|
94
|
+
let queries = parser::parse(query)?;
|
95
|
+
let mut results = Vec::<QueryResult>::default();
|
96
|
+
for query in queries
|
97
|
+
{
|
98
|
+
let program = compiler::compile(&self.function_manager, query)?;
|
99
|
+
results.push(interpreter::evaluators::eval_program(
|
100
|
+
&self.store,
|
101
|
+
&program,
|
102
|
+
¶meters,
|
103
|
+
)?)
|
104
|
+
}
|
105
|
+
match results.len()
|
106
|
+
{
|
107
|
+
0 => Ok(QueryResult::Empty),
|
108
|
+
1 => Ok(results.into_iter().next().unwrap()), // Guarantee to pass since we check for length
|
109
|
+
_ => Ok(QueryResult::Array(results)),
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
impl<TStore: store::Store> ConnectionImpl<TStore>
|
115
|
+
where
|
116
|
+
TStore: store::Store + Sync + Send,
|
117
|
+
{
|
118
|
+
fn boxed(self) -> Box<Self>
|
119
|
+
{
|
120
|
+
Box::new(self)
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
/// Connection is the interface to the database, and allow to execute new queries.
|
125
|
+
/// New connection are created with [Connection::create] or [Connection::builder] and queried with
|
126
|
+
/// [Connection::execute_oc_query]. As shown in the example bellow:
|
127
|
+
///
|
128
|
+
/// ```rust
|
129
|
+
/// # use gqlitedb::{Backend, Connection, QueryResult};
|
130
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
131
|
+
/// let connection = Connection::builder().path("filename.db").backend(Backend::Redb).create()?;
|
132
|
+
/// let value = connection.execute_oc_query("MATCH (a) RETURN a", Default::default())?;
|
133
|
+
/// match value
|
134
|
+
/// {
|
135
|
+
/// QueryResult::Table(table) =>
|
136
|
+
/// {
|
137
|
+
/// println!("{:?}", table);
|
138
|
+
/// },
|
139
|
+
/// _ => {
|
140
|
+
/// panic!("Query result should be a table!");
|
141
|
+
/// }
|
142
|
+
/// }
|
143
|
+
/// # Ok(()) }
|
144
|
+
/// ```
|
145
|
+
pub struct Connection
|
146
|
+
{
|
147
|
+
connection: Box<dyn ConnectionTrait>,
|
148
|
+
}
|
149
|
+
|
150
|
+
ccutils::assert_impl_all!(Connection: Sync, Send);
|
151
|
+
|
152
|
+
impl Connection
|
153
|
+
{
|
154
|
+
/// Create a new connection to a `GQLite` database. The `options` parameter can
|
155
|
+
/// be used to select the backend, and configure the backend.
|
156
|
+
///
|
157
|
+
/// Supported parameters:
|
158
|
+
/// - `path` a path to a file, if not present, an in-memory database is created
|
159
|
+
/// - `backend` for instance `redb` or `sqlite` (the [Self::available_backends] function contains the list of compiled backends)
|
160
|
+
///
|
161
|
+
/// If the `backend` is not specified, the `create` function will attempt to guess it
|
162
|
+
/// for existing databases. For new database, depending on availability, it will
|
163
|
+
/// create a `sqlite` database, or a `redb` database.
|
164
|
+
///
|
165
|
+
/// Example of use, this will create an in-memory database:
|
166
|
+
///
|
167
|
+
/// ```rust
|
168
|
+
/// # use gqlitedb::Connection;
|
169
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
170
|
+
/// let connection = Connection::create(gqlitedb::value_map!("backend" => "redb"))?;
|
171
|
+
/// # Ok(()) }
|
172
|
+
/// ```
|
173
|
+
pub fn create(options: value::ValueMap) -> Result<Connection>
|
174
|
+
{
|
175
|
+
let backend = options.get("backend").map_or_else(
|
176
|
+
|| Ok("automatic".to_string()),
|
177
|
+
|x| x.try_into_ref().map(|x: &String| x.to_owned()),
|
178
|
+
)?;
|
179
|
+
match backend.as_str()
|
180
|
+
{
|
181
|
+
"automatic" =>
|
182
|
+
{
|
183
|
+
#[cfg(feature = "sqlite")]
|
184
|
+
let sq_e = {
|
185
|
+
let mut options = options.clone();
|
186
|
+
options.insert("backend".into(), "sqlite".into());
|
187
|
+
Self::create(options)
|
188
|
+
};
|
189
|
+
#[cfg(not(feature = "sqlite"))]
|
190
|
+
let sq_e = Err(error::StoreError::UnavailableBackend { backend: "sqlite" }.into());
|
191
|
+
match sq_e
|
192
|
+
{
|
193
|
+
Ok(sq) => Ok(sq),
|
194
|
+
Err(sq_e) =>
|
195
|
+
{
|
196
|
+
#[cfg(feature = "redb")]
|
197
|
+
let sq_r = {
|
198
|
+
let mut options = options;
|
199
|
+
options.insert("backend".into(), "redb".into());
|
200
|
+
Self::create(options)
|
201
|
+
};
|
202
|
+
#[cfg(not(feature = "redb"))]
|
203
|
+
let sq_r = Err(error::StoreError::UnavailableBackend { backend: "redb" }.into());
|
204
|
+
|
205
|
+
sq_r.map_err(|rb_e| {
|
206
|
+
StoreError::OpeningError {
|
207
|
+
errors: error::vec_to_error(&vec![sq_e, rb_e]),
|
208
|
+
}
|
209
|
+
.into()
|
210
|
+
})
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}
|
214
|
+
#[cfg(feature = "sqlite")]
|
215
|
+
"sqlite" =>
|
216
|
+
{
|
217
|
+
let store = if let Some(path) = options.get("path")
|
218
|
+
{
|
219
|
+
let path: &String = path.try_into_ref()?;
|
220
|
+
store::sqlite::Store::open(path)?
|
221
|
+
}
|
222
|
+
else
|
223
|
+
{
|
224
|
+
store::sqlite::Store::in_memory()?
|
225
|
+
};
|
226
|
+
Ok(Connection {
|
227
|
+
connection: ConnectionImpl {
|
228
|
+
store,
|
229
|
+
function_manager: functions::Manager::new(),
|
230
|
+
}
|
231
|
+
.boxed(),
|
232
|
+
})
|
233
|
+
}
|
234
|
+
#[cfg(feature = "redb")]
|
235
|
+
"redb" =>
|
236
|
+
{
|
237
|
+
let store = if let Some(path) = options.get("path")
|
238
|
+
{
|
239
|
+
let path: &String = path.try_into_ref()?;
|
240
|
+
store::redb::Store::open(path)?
|
241
|
+
}
|
242
|
+
else
|
243
|
+
{
|
244
|
+
store::redb::Store::in_memory()?
|
245
|
+
};
|
246
|
+
Ok(Connection {
|
247
|
+
connection: ConnectionImpl {
|
248
|
+
store,
|
249
|
+
function_manager: functions::Manager::new(),
|
250
|
+
}
|
251
|
+
.boxed(),
|
252
|
+
})
|
253
|
+
}
|
254
|
+
_ => Err(StoreError::UnknownBackend { backend }.into()),
|
255
|
+
}
|
256
|
+
}
|
257
|
+
/// Create a builder, with a high-level API to set the options.
|
258
|
+
/// Example of use:
|
259
|
+
/// ```no_run
|
260
|
+
/// # use gqlitedb::{Connection, Backend};
|
261
|
+
/// let connection = Connection::builder().path("path/to/file").backend(Backend::SQLite).create().unwrap();
|
262
|
+
/// ```
|
263
|
+
pub fn builder() -> ConnectionBuilder
|
264
|
+
{
|
265
|
+
ConnectionBuilder {
|
266
|
+
map: Default::default(),
|
267
|
+
}
|
268
|
+
}
|
269
|
+
/// List of available backends
|
270
|
+
pub fn available_backends() -> Vec<String>
|
271
|
+
{
|
272
|
+
vec![
|
273
|
+
#[cfg(feature = "sqlite")]
|
274
|
+
"sqlite".to_string(),
|
275
|
+
#[cfg(feature = "redb")]
|
276
|
+
"redb".to_string(),
|
277
|
+
]
|
278
|
+
}
|
279
|
+
|
280
|
+
/// Execute the `query` (using OpenCypher), given the query `parameters` (sometimes
|
281
|
+
/// also referred as binding).
|
282
|
+
///
|
283
|
+
/// Example:
|
284
|
+
///
|
285
|
+
/// ```rust
|
286
|
+
/// # use gqlitedb::{Backend, Connection, Value};
|
287
|
+
/// # fn example() -> gqlitedb::Result<()> {
|
288
|
+
/// # let connection = Connection::builder().path("filename.db").backend(Backend::Redb).create()?;
|
289
|
+
/// let result = connection.execute_oc_query("MATCH (a { name: $name }) RETURN a", gqlitedb::value_map!("name" => "Joe"))?;
|
290
|
+
/// # Ok(()) }
|
291
|
+
/// ```
|
292
|
+
pub fn execute_oc_query(
|
293
|
+
&self,
|
294
|
+
query: impl AsRef<str>,
|
295
|
+
parameters: value::ValueMap,
|
296
|
+
) -> Result<QueryResult>
|
297
|
+
{
|
298
|
+
self.connection.execute_oc_query(query.as_ref(), parameters)
|
299
|
+
}
|
300
|
+
}
|
@@ -21,7 +21,7 @@ pub enum CompileTimeError
|
|
21
21
|
},
|
22
22
|
/// Parse error
|
23
23
|
#[error("ParseError: '{0}'")]
|
24
|
-
ParseError(#[from] pest::error::Error<crate::parser::
|
24
|
+
ParseError(#[from] Box<pest::error::Error<crate::parser::parser_impl::Rule>>),
|
25
25
|
/// Variable is not defined
|
26
26
|
#[error("UndefinedVariable: Unknown variable '{name}'.")]
|
27
27
|
UndefinedVariable
|
@@ -52,7 +52,7 @@ pub enum CompileTimeError
|
|
52
52
|
NoSingleRelationshipType,
|
53
53
|
#[error("NotComparable: values are not comparable.")]
|
54
54
|
NotComparable,
|
55
|
-
#[error("UnknownFunction: {name}")]
|
55
|
+
#[error("UnknownFunction: {name}.")]
|
56
56
|
UnknownFunction
|
57
57
|
{
|
58
58
|
name: String
|
@@ -120,7 +120,7 @@ pub enum RunTimeError
|
|
120
120
|
/// Edge has no label
|
121
121
|
#[error("MissingEdgeLabel")]
|
122
122
|
MissingEdgeLabel,
|
123
|
-
#[error("UnknownFunction: {name}")]
|
123
|
+
#[error("UnknownFunction: {name}.")]
|
124
124
|
UnknownFunction
|
125
125
|
{
|
126
126
|
name: String
|
@@ -129,6 +129,12 @@ pub enum RunTimeError
|
|
129
129
|
InvalidBinaryOperands,
|
130
130
|
#[error("InvalidNegationOperands: operands for negation operation are not compatible.")]
|
131
131
|
InvalidNegationOperands,
|
132
|
+
#[error("Invalid value cast, cannot cast {value} to {typename}.")]
|
133
|
+
InvalidValueCast
|
134
|
+
{
|
135
|
+
value: Box<crate::Value>,
|
136
|
+
typename: &'static str,
|
137
|
+
},
|
132
138
|
#[error("InvalidDelete: invalid delete argument, expected node or edge.")]
|
133
139
|
InvalidDelete,
|
134
140
|
#[error("DeleteConnectedNode: node is still connected and cannot be deleted.")]
|
@@ -149,6 +155,13 @@ pub enum RunTimeError
|
|
149
155
|
{
|
150
156
|
graph_name: String
|
151
157
|
},
|
158
|
+
#[error("Key {key} cannot be found in a path in a ValueMap.")]
|
159
|
+
MissingKeyInPath
|
160
|
+
{
|
161
|
+
key: String
|
162
|
+
},
|
163
|
+
#[error("Path cannot have null key.")]
|
164
|
+
MissingKey,
|
152
165
|
}
|
153
166
|
|
154
167
|
/// Internal errors, should be treated as bugs.
|
@@ -214,12 +227,6 @@ pub enum InternalError
|
|
214
227
|
},
|
215
228
|
#[error("Empty stack.")]
|
216
229
|
EmptyStack,
|
217
|
-
#[error("Invalid value cast, cannot cast {value} to {typename}.")]
|
218
|
-
InvalidValueCast
|
219
|
-
{
|
220
|
-
value: crate::Value,
|
221
|
-
typename: &'static str,
|
222
|
-
},
|
223
230
|
#[error("Code is not reachable in {context}.")]
|
224
231
|
Unreachable
|
225
232
|
{
|
@@ -263,19 +270,13 @@ pub enum InternalError
|
|
263
270
|
#[error("Invalid aggregation state")]
|
264
271
|
InvalidAggregationState,
|
265
272
|
|
273
|
+
#[error("Invalid query result cast")]
|
274
|
+
InvalidQueryResultCast,
|
275
|
+
|
266
276
|
// Third-party
|
267
277
|
#[error("Missing element in iterator.")]
|
268
278
|
MissingElementIterator,
|
269
279
|
|
270
|
-
#[cfg(feature = "redb")]
|
271
|
-
#[error("redb: {0}")]
|
272
|
-
RedbError(#[from] redb::Error),
|
273
|
-
|
274
|
-
// Errors from sqlite
|
275
|
-
#[cfg(feature = "sqlite")]
|
276
|
-
#[error("Sqlite: {0}")]
|
277
|
-
SqliteError(#[from] rusqlite::Error),
|
278
|
-
|
279
280
|
// Errors from askama
|
280
281
|
#[cfg(feature = "sqlite")]
|
281
282
|
#[error("Askama: {0}")]
|
@@ -310,6 +311,8 @@ pub enum InternalError
|
|
310
311
|
Infallible(#[from] std::convert::Infallible),
|
311
312
|
#[error("Poison error {0}.")]
|
312
313
|
Poison(String),
|
314
|
+
#[error("IOError: {0}.")]
|
315
|
+
IOError(#[from] std::io::Error),
|
313
316
|
}
|
314
317
|
|
315
318
|
/// Error in the store backend.
|
@@ -318,6 +321,19 @@ pub enum InternalError
|
|
318
321
|
#[non_exhaustive]
|
319
322
|
pub enum StoreError
|
320
323
|
{
|
324
|
+
// Errors from sqlite
|
325
|
+
#[cfg(feature = "sqlite")]
|
326
|
+
#[error("Sqlite: {0}")]
|
327
|
+
SqliteError(#[from] rusqlite::Error),
|
328
|
+
|
329
|
+
#[cfg(feature = "redb")]
|
330
|
+
#[error("redb: {0}")]
|
331
|
+
RedbError(#[from] redb::Error),
|
332
|
+
|
333
|
+
#[cfg(feature = "redb")]
|
334
|
+
#[error("redb: {0}")]
|
335
|
+
Redb2Error(#[from] redb2::Error),
|
336
|
+
|
321
337
|
#[error("UnknownBackend: backend '{backend}' is unknown.")]
|
322
338
|
UnknownBackend
|
323
339
|
{
|
@@ -351,6 +367,8 @@ pub enum StoreError
|
|
351
367
|
actual: utils::Version,
|
352
368
|
expected: utils::Version,
|
353
369
|
},
|
370
|
+
#[error("Invalid database format: {0}.")]
|
371
|
+
InvalidFormat(String),
|
354
372
|
}
|
355
373
|
|
356
374
|
/// GQLite errors
|
@@ -372,11 +390,7 @@ pub enum Error
|
|
372
390
|
Internal(#[from] InternalError),
|
373
391
|
}
|
374
392
|
|
375
|
-
|
376
|
-
fn _check_error_send_sync()
|
377
|
-
{
|
378
|
-
assert_send_sync::<Error>();
|
379
|
-
}
|
393
|
+
ccutils::assert_impl_all!(Error: Send, Sync);
|
380
394
|
|
381
395
|
impl Error
|
382
396
|
{
|
@@ -385,16 +399,37 @@ impl Error
|
|
385
399
|
{
|
386
400
|
self
|
387
401
|
}
|
402
|
+
#[cfg(not(feature = "_backtrace"))]
|
388
403
|
pub(crate) fn split_error(self) -> (Error, ())
|
389
404
|
{
|
390
405
|
(self, ())
|
391
406
|
}
|
407
|
+
#[cfg(not(feature = "_backtrace"))]
|
392
408
|
pub(crate) fn make_error(error: Error, _: ()) -> Error
|
393
409
|
{
|
394
410
|
error
|
395
411
|
}
|
396
412
|
}
|
397
413
|
|
414
|
+
impl From<graphcore::Error> for Error
|
415
|
+
{
|
416
|
+
fn from(value: graphcore::Error) -> Self
|
417
|
+
{
|
418
|
+
match value
|
419
|
+
{
|
420
|
+
graphcore::Error::InvalidBinaryOperands => RunTimeError::InvalidBinaryOperands.into(),
|
421
|
+
graphcore::Error::InvalidNegationOperands => RunTimeError::InvalidNegationOperands.into(),
|
422
|
+
graphcore::Error::InvalidValueCast { value, typename } =>
|
423
|
+
{
|
424
|
+
RunTimeError::InvalidValueCast { value, typename }.into()
|
425
|
+
}
|
426
|
+
graphcore::Error::MissingKey => RunTimeError::MissingKey.into(),
|
427
|
+
graphcore::Error::MissingKeyInPath { key } => RunTimeError::MissingKeyInPath { key }.into(),
|
428
|
+
_ => InternalError::Unimplemented("From graphcore::Error to graphcore::Error.").into(),
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
|
398
433
|
// _____ __ ___ _ _ ____ _ _
|
399
434
|
// | ____|_ __ _ __ ___ _ _\ \ / (_) |_| |__ | __ ) __ _ ___| | __ |_ _ __ __ _ ___ ___
|
400
435
|
// | _| | '__| '__/ _ \| '__\ \ /\ / /| | __| '_ \| _ \ / _` |/ __| |/ / __| '__/ _` |/ __/ _ \
|
@@ -402,12 +437,14 @@ impl Error
|
|
402
437
|
// |_____|_| |_| \___/|_| \_/\_/ |_|\__|_| |_|____/ \__,_|\___|_|\_\\__|_| \__,_|\___\___|
|
403
438
|
|
404
439
|
#[derive(Debug)]
|
440
|
+
#[cfg(feature = "_backtrace")]
|
405
441
|
pub struct ErrorWithBacktrace
|
406
442
|
{
|
407
443
|
error: Error,
|
408
444
|
backtrace: std::backtrace::Backtrace,
|
409
445
|
}
|
410
446
|
|
447
|
+
#[cfg(feature = "_backtrace")]
|
411
448
|
impl ErrorWithBacktrace
|
412
449
|
{
|
413
450
|
/// Return the underlying error
|
@@ -425,6 +462,7 @@ impl ErrorWithBacktrace
|
|
425
462
|
}
|
426
463
|
}
|
427
464
|
|
465
|
+
#[cfg(feature = "_backtrace")]
|
428
466
|
impl std::fmt::Display for ErrorWithBacktrace
|
429
467
|
{
|
430
468
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
@@ -432,6 +470,8 @@ impl std::fmt::Display for ErrorWithBacktrace
|
|
432
470
|
self.error.fmt(f)
|
433
471
|
}
|
434
472
|
}
|
473
|
+
|
474
|
+
#[cfg(feature = "_backtrace")]
|
435
475
|
impl<T> From<T> for ErrorWithBacktrace
|
436
476
|
where
|
437
477
|
T: Into<Error>,
|
@@ -459,11 +499,11 @@ impl<T> From<std::sync::PoisonError<T>> for Error
|
|
459
499
|
}
|
460
500
|
}
|
461
501
|
|
462
|
-
impl From<pest::error::Error<crate::parser::
|
502
|
+
impl From<pest::error::Error<crate::parser::parser_impl::Rule>> for Error
|
463
503
|
{
|
464
|
-
fn from(value: pest::error::Error<crate::parser::
|
504
|
+
fn from(value: pest::error::Error<crate::parser::parser_impl::Rule>) -> Self
|
465
505
|
{
|
466
|
-
CompileTimeError::from(value).into()
|
506
|
+
CompileTimeError::from(Box::new(value)).into()
|
467
507
|
}
|
468
508
|
}
|
469
509
|
|
@@ -480,52 +520,83 @@ macro_rules! error_as_internal {
|
|
480
520
|
};
|
481
521
|
}
|
482
522
|
|
523
|
+
pub(crate) use error_as_internal;
|
524
|
+
|
525
|
+
macro_rules! error_as_store {
|
526
|
+
($err_type:ty) => {
|
527
|
+
impl From<$err_type> for crate::prelude::ErrorType
|
528
|
+
{
|
529
|
+
fn from(value: $err_type) -> Self
|
530
|
+
{
|
531
|
+
let err: crate::error::StoreError = value.into();
|
532
|
+
err.into()
|
533
|
+
}
|
534
|
+
}
|
535
|
+
};
|
536
|
+
}
|
537
|
+
|
538
|
+
pub(crate) use error_as_store;
|
539
|
+
|
483
540
|
error_as_internal! {ciborium::ser::Error<std::io::Error>}
|
484
541
|
error_as_internal! {ciborium::de::Error<std::io::Error>}
|
485
542
|
error_as_internal! {serde_json::Error}
|
486
543
|
error_as_internal! {std::num::ParseFloatError}
|
487
544
|
|
488
|
-
pub(crate) use error_as_internal;
|
489
|
-
|
490
545
|
#[cfg(feature = "redb")]
|
491
546
|
mod _trait_impl_redb
|
492
547
|
{
|
493
|
-
super::
|
494
|
-
macro_rules!
|
548
|
+
super::error_as_store! {redb::Error}
|
549
|
+
macro_rules! redb_error_as_store {
|
495
550
|
($err_type:ty) => {
|
496
551
|
impl From<$err_type> for crate::prelude::ErrorType
|
497
552
|
{
|
498
553
|
fn from(value: $err_type) -> Self
|
499
554
|
{
|
500
555
|
let redb_err: redb::Error = value.into();
|
501
|
-
let err: crate::error::
|
556
|
+
let err: crate::error::StoreError = redb_err.into();
|
557
|
+
err.into()
|
558
|
+
}
|
559
|
+
}
|
560
|
+
};
|
561
|
+
}
|
562
|
+
super::error_as_store! {redb2::Error}
|
563
|
+
macro_rules! redb2_error_as_store {
|
564
|
+
($err_type:ty) => {
|
565
|
+
impl From<$err_type> for crate::prelude::ErrorType
|
566
|
+
{
|
567
|
+
fn from(value: $err_type) -> Self
|
568
|
+
{
|
569
|
+
let redb_err: redb2::Error = value.into();
|
570
|
+
let err: crate::error::StoreError = redb_err.into();
|
502
571
|
err.into()
|
503
572
|
}
|
504
573
|
}
|
505
574
|
};
|
506
575
|
}
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
576
|
+
redb_error_as_store! {redb::StorageError}
|
577
|
+
redb_error_as_store! {redb::DatabaseError}
|
578
|
+
redb_error_as_store! {redb::TransactionError}
|
579
|
+
redb_error_as_store! {redb::TableError}
|
580
|
+
redb_error_as_store! {redb::CommitError}
|
581
|
+
redb2_error_as_store! {redb2::DatabaseError}
|
582
|
+
redb2_error_as_store! {redb2::UpgradeError}
|
512
583
|
}
|
513
584
|
#[cfg(feature = "sqlite")]
|
514
585
|
mod _trait_impl_sqlite
|
515
586
|
{
|
516
|
-
|
587
|
+
error_as_store! {rusqlite::Error}
|
517
588
|
error_as_internal! {askama::Error}
|
518
589
|
}
|
519
590
|
|
520
591
|
/// Merge a list of error into a string error message
|
521
|
-
pub(crate) fn vec_to_error
|
592
|
+
pub(crate) fn vec_to_error(errs: &[ErrorType]) -> String
|
522
593
|
{
|
523
594
|
let errs: Vec<String> = errs.iter().map(|x| format!("'{}'", x)).collect();
|
524
595
|
errs.join(", ")
|
525
596
|
}
|
526
597
|
|
527
|
-
pub(crate) fn parse_int_error_to_compile_error
|
528
|
-
text: &
|
598
|
+
pub(crate) fn parse_int_error_to_compile_error(
|
599
|
+
text: &str,
|
529
600
|
e: std::num::ParseIntError,
|
530
601
|
) -> crate::prelude::ErrorType
|
531
602
|
{
|
@@ -549,7 +620,8 @@ pub(crate) fn parse_int_error_to_compile_error<'a>(
|
|
549
620
|
macro_rules! map_error {
|
550
621
|
($err:expr, $source:pat => $destination:expr) => {{
|
551
622
|
use crate::error::*;
|
552
|
-
let
|
623
|
+
let error: crate::prelude::ErrorType = $err;
|
624
|
+
let (error, meta) = error.split_error();
|
553
625
|
match error
|
554
626
|
{
|
555
627
|
$source => ErrorType::make_error($destination.into(), meta),
|
@@ -579,7 +651,6 @@ impl From<std::convert::Infallible> for Error
|
|
579
651
|
pub(crate) trait GenericErrors: Into<Error>
|
580
652
|
{
|
581
653
|
fn unknown_function(name: impl Into<String>) -> Self;
|
582
|
-
fn not_comparable() -> Self;
|
583
654
|
}
|
584
655
|
|
585
656
|
impl GenericErrors for CompileTimeError
|
@@ -588,10 +659,6 @@ impl GenericErrors for CompileTimeError
|
|
588
659
|
{
|
589
660
|
Self::UnknownFunction { name: name.into() }
|
590
661
|
}
|
591
|
-
fn not_comparable() -> Self
|
592
|
-
{
|
593
|
-
Self::NotComparable
|
594
|
-
}
|
595
662
|
}
|
596
663
|
|
597
664
|
impl GenericErrors for RunTimeError
|
@@ -600,10 +667,6 @@ impl GenericErrors for RunTimeError
|
|
600
667
|
{
|
601
668
|
Self::UnknownFunction { name: name.into() }
|
602
669
|
}
|
603
|
-
fn not_comparable() -> Self
|
604
|
-
{
|
605
|
-
Self::NotComparable
|
606
|
-
}
|
607
670
|
}
|
608
671
|
|
609
672
|
/// GQLite Result
|