gqlite 1.2.3 → 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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +20 -0
  3. data/ext/gqlitedb/Cargo.toml +77 -0
  4. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
  5. data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
  6. data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
  7. data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
  8. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +10 -9
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +6 -4
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +27 -31
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +37 -41
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/connection.rs +42 -84
  16. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +105 -34
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +2 -2
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +2 -2
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +1 -1
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/path.rs +15 -20
  22. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +2 -2
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +6 -6
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +20 -20
  25. data/ext/gqlitedb/src/graph.rs +11 -0
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +160 -194
  27. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +2 -1
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -4
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +44 -52
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +1 -1
  31. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +50 -28
  32. data/ext/gqlitedb/src/parser.rs +4 -0
  33. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  34. data/ext/gqlitedb/src/query_result.rs +88 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +226 -148
  36. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +111 -128
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +22 -22
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +32 -76
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +95 -111
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  44. data/ext/gqlitedb/src/value.rs +225 -0
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +15 -5
  46. data/ext/gqliterb/Cargo.toml +12 -35
  47. data/ext/gqliterb/src/lib.rs +60 -38
  48. data/ext/graphcore/Cargo.toml +19 -0
  49. data/ext/graphcore/README.MD +4 -0
  50. data/ext/graphcore/release.toml +1 -0
  51. data/ext/graphcore/src/error.rs +28 -0
  52. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +134 -38
  53. data/ext/graphcore/src/lib.rs +16 -0
  54. data/ext/graphcore/src/prelude.rs +4 -0
  55. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  56. data/ext/graphcore/src/table.rs +272 -0
  57. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  58. data/ext/graphcore/src/value.rs +413 -0
  59. metadata +94 -83
  60. data/ext/gqliterb/.cargo/config.toml +0 -2
  61. data/ext/gqliterb/Cargo.lock +0 -1116
  62. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2115
  63. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -138
  64. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  65. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -609
  66. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  67. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  68. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  69. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  70. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +0 -0
  71. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -1,6 +1,6 @@
1
1
  use std::path::Path;
2
2
 
3
- use crate::prelude::*;
3
+ use crate::{prelude::*, QueryResult};
4
4
  use value::ValueTryIntoRef;
5
5
 
6
6
  /// Backend
@@ -74,7 +74,7 @@ impl ConnectionBuilder
74
74
 
75
75
  trait ConnectionTrait: Sync + Send
76
76
  {
77
- fn execute_query(&self, query: String, parameters: value::ValueMap) -> Result<value::Value>;
77
+ fn execute_oc_query(&self, query: &str, parameters: value::ValueMap) -> Result<QueryResult>;
78
78
  }
79
79
 
80
80
  struct ConnectionImpl<TStore>
@@ -89,31 +89,24 @@ impl<TStore> ConnectionTrait for ConnectionImpl<TStore>
89
89
  where
90
90
  TStore: store::Store + Sync + Send,
91
91
  {
92
- fn execute_query(&self, query: String, parameters: value::ValueMap) -> Result<value::Value>
92
+ fn execute_oc_query(&self, query: &str, parameters: value::ValueMap) -> Result<QueryResult>
93
93
  {
94
- let query_txt: String = query.into();
95
- let queries = parser::parse(query_txt.as_str())?;
96
- let mut results = Vec::<value::Value>::default();
94
+ let queries = parser::parse(query)?;
95
+ let mut results = Vec::<QueryResult>::default();
97
96
  for query in queries
98
97
  {
99
98
  let program = compiler::compile(&self.function_manager, query)?;
100
- let v = interpreter::evaluators::eval_program(&self.store, &program, &parameters)?;
101
- if !v.is_null()
102
- {
103
- results.push(v);
104
- }
99
+ results.push(interpreter::evaluators::eval_program(
100
+ &self.store,
101
+ &program,
102
+ &parameters,
103
+ )?)
105
104
  }
106
105
  match results.len()
107
106
  {
108
- 0 => Ok(value::Value::Null),
109
- 1 => Ok(results.into_iter().next().unwrap()),
110
- _ =>
111
- {
112
- let mut map = value::ValueMap::new();
113
- map.insert("type".into(), "results".into());
114
- map.insert("results".into(), results.into());
115
- Ok(map.into())
116
- }
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)),
117
110
  }
118
111
  }
119
112
  }
@@ -129,37 +122,26 @@ where
129
122
  }
130
123
 
131
124
  /// Connection is the interface to the database, and allow to execute new queries.
132
- /// New connection are created with [Connection::open] and queried with [Connection::execute_query].
133
- /// As shown in the example bellow:
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:
134
127
  ///
135
128
  /// ```rust
136
- /// # use gqlitedb::{Connection, Value};
129
+ /// # use gqlitedb::{Backend, Connection, QueryResult};
137
130
  /// # fn example() -> gqlitedb::Result<()> {
138
- /// let connection = Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
139
- /// let value = connection.execute_query("MATCH (a) RETURN a", Default::default())?;
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())?;
140
133
  /// match value
141
134
  /// {
142
- /// Value::Array(arr) =>
135
+ /// QueryResult::Table(table) =>
143
136
  /// {
144
- /// arr.iter().for_each(|row| match row
145
- /// {
146
- /// Value::Array(arr) =>
147
- /// {
148
- /// println!("{:?}", arr);
149
- /// }
150
- /// _ =>
151
- /// {
152
- /// panic!("Unexpected: {}", row);
153
- /// }
154
- /// });
137
+ /// println!("{:?}", table);
155
138
  /// },
156
139
  /// _ => {
157
- /// panic!("Query result should be an array, got {}!", value);
140
+ /// panic!("Query result should be a table!");
158
141
  /// }
159
142
  /// }
160
143
  /// # Ok(()) }
161
144
  /// ```
162
-
163
145
  pub struct Connection
164
146
  {
165
147
  connection: Box<dyn ConnectionTrait>,
@@ -176,7 +158,7 @@ impl Connection
176
158
  /// - `path` a path to a file, if not present, an in-memory database is created
177
159
  /// - `backend` for instance `redb` or `sqlite` (the [Self::available_backends] function contains the list of compiled backends)
178
160
  ///
179
- /// If the `backend` is not specified, the `open` function will attempt to guess it
161
+ /// If the `backend` is not specified, the `create` function will attempt to guess it
180
162
  /// for existing databases. For new database, depending on availability, it will
181
163
  /// create a `sqlite` database, or a `redb` database.
182
164
  ///
@@ -185,7 +167,7 @@ impl Connection
185
167
  /// ```rust
186
168
  /// # use gqlitedb::Connection;
187
169
  /// # fn example() -> gqlitedb::Result<()> {
188
- /// let connection = Connection::create(gqlitedb::map!("backend" => "redb"))?;
170
+ /// let connection = Connection::create(gqlitedb::value_map!("backend" => "redb"))?;
189
171
  /// # Ok(()) }
190
172
  /// ```
191
173
  pub fn create(options: value::ValueMap) -> Result<Connection>
@@ -206,7 +188,7 @@ impl Connection
206
188
  };
207
189
  #[cfg(not(feature = "sqlite"))]
208
190
  let sq_e = Err(error::StoreError::UnavailableBackend { backend: "sqlite" }.into());
209
- let sq_r = match sq_e
191
+ match sq_e
210
192
  {
211
193
  Ok(sq) => Ok(sq),
212
194
  Err(sq_e) =>
@@ -222,13 +204,12 @@ impl Connection
222
204
 
223
205
  sq_r.map_err(|rb_e| {
224
206
  StoreError::OpeningError {
225
- errors: error::vec_to_error::<ErrorType>(&vec![sq_e, rb_e]),
207
+ errors: error::vec_to_error(&vec![sq_e, rb_e]),
226
208
  }
227
209
  .into()
228
210
  })
229
211
  }
230
- };
231
- sq_r
212
+ }
232
213
  }
233
214
  #[cfg(feature = "sqlite")]
234
215
  "sqlite" =>
@@ -275,8 +256,9 @@ impl Connection
275
256
  }
276
257
  /// Create a builder, with a high-level API to set the options.
277
258
  /// Example of use:
278
- /// ```
279
- /// let connection = Connection::builder().path("path/to/file").backend(Backend::SQLite).create()?;
259
+ /// ```no_run
260
+ /// # use gqlitedb::{Connection, Backend};
261
+ /// let connection = Connection::builder().path("path/to/file").backend(Backend::SQLite).create().unwrap();
280
262
  /// ```
281
263
  pub fn builder() -> ConnectionBuilder
282
264
  {
@@ -287,56 +269,32 @@ impl Connection
287
269
  /// List of available backends
288
270
  pub fn available_backends() -> Vec<String>
289
271
  {
290
- let mut backends = vec![];
291
- #[cfg(feature = "sqlite")]
292
- backends.push("sqlite".to_string());
293
- #[cfg(feature = "redb")]
294
- backends.push("redb".to_string());
295
- backends
272
+ vec![
273
+ #[cfg(feature = "sqlite")]
274
+ "sqlite".to_string(),
275
+ #[cfg(feature = "redb")]
276
+ "redb".to_string(),
277
+ ]
296
278
  }
297
279
 
298
- /// Open a `path` that contains a `GQLite` database. The `options` parameter can
299
- /// be used to select the backend, and configure the backend.
300
- ///
301
- /// Supported parameters:
302
- /// - `backend` can be `redb` or `sqlite`
303
- ///
304
- /// If the `backend` is not specified, the `open` function will attempt to guess it
305
- /// for existing databases. For new database, depending on availability, it will
306
- /// create a `sqlite` database, or a `redb` database.
307
- ///
308
- /// Example of use:
309
- ///
310
- /// ```rust
311
- /// # use gqlitedb::Connection;
312
- /// # fn example() -> gqlitedb::Result<()> {
313
- /// let connection = Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
314
- /// # Ok(()) }
315
- /// ```
316
- #[cfg(any(feature = "redb", feature = "sqlite"))]
317
- #[deprecated = "Use create or builder instead."]
318
- pub fn open<P: AsRef<std::path::Path>>(path: P, options: value::ValueMap) -> Result<Connection>
319
- {
320
- Self::builder().options(options).path(path).create()
321
- }
322
280
  /// Execute the `query` (using OpenCypher), given the query `parameters` (sometimes
323
281
  /// also referred as binding).
324
282
  ///
325
283
  /// Example:
326
284
  ///
327
285
  /// ```rust
328
- /// # use gqlitedb::{Connection, Value};
286
+ /// # use gqlitedb::{Backend, Connection, Value};
329
287
  /// # fn example() -> gqlitedb::Result<()> {
330
- /// # let connection = gqlitedb::Connection::open("filename.db", gqlitedb::map!("backend" => "redb"))?;
331
- /// let result = connection.execute_query("MATCH (a { name: $name }) RETURN a", gqlitedb::map!("name" => "Joe"))?;
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"))?;
332
290
  /// # Ok(()) }
333
291
  /// ```
334
- pub fn execute_query(
292
+ pub fn execute_oc_query(
335
293
  &self,
336
- query: impl Into<String>,
294
+ query: impl AsRef<str>,
337
295
  parameters: value::ValueMap,
338
- ) -> Result<value::Value>
296
+ ) -> Result<QueryResult>
339
297
  {
340
- self.connection.execute_query(query.into(), parameters)
298
+ self.connection.execute_oc_query(query.as_ref(), parameters)
341
299
  }
342
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::parser::Rule>),
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
@@ -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
@@ -381,16 +399,37 @@ impl Error
381
399
  {
382
400
  self
383
401
  }
402
+ #[cfg(not(feature = "_backtrace"))]
384
403
  pub(crate) fn split_error(self) -> (Error, ())
385
404
  {
386
405
  (self, ())
387
406
  }
407
+ #[cfg(not(feature = "_backtrace"))]
388
408
  pub(crate) fn make_error(error: Error, _: ()) -> Error
389
409
  {
390
410
  error
391
411
  }
392
412
  }
393
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
+
394
433
  // _____ __ ___ _ _ ____ _ _
395
434
  // | ____|_ __ _ __ ___ _ _\ \ / (_) |_| |__ | __ ) __ _ ___| | __ |_ _ __ __ _ ___ ___
396
435
  // | _| | '__| '__/ _ \| '__\ \ /\ / /| | __| '_ \| _ \ / _` |/ __| |/ / __| '__/ _` |/ __/ _ \
@@ -460,11 +499,11 @@ impl<T> From<std::sync::PoisonError<T>> for Error
460
499
  }
461
500
  }
462
501
 
463
- impl From<pest::error::Error<crate::parser::parser::Rule>> for Error
502
+ impl From<pest::error::Error<crate::parser::parser_impl::Rule>> for Error
464
503
  {
465
- fn from(value: pest::error::Error<crate::parser::parser::Rule>) -> Self
504
+ fn from(value: pest::error::Error<crate::parser::parser_impl::Rule>) -> Self
466
505
  {
467
- CompileTimeError::from(value).into()
506
+ CompileTimeError::from(Box::new(value)).into()
468
507
  }
469
508
  }
470
509
 
@@ -481,52 +520,83 @@ macro_rules! error_as_internal {
481
520
  };
482
521
  }
483
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
+
484
540
  error_as_internal! {ciborium::ser::Error<std::io::Error>}
485
541
  error_as_internal! {ciborium::de::Error<std::io::Error>}
486
542
  error_as_internal! {serde_json::Error}
487
543
  error_as_internal! {std::num::ParseFloatError}
488
544
 
489
- pub(crate) use error_as_internal;
490
-
491
545
  #[cfg(feature = "redb")]
492
546
  mod _trait_impl_redb
493
547
  {
494
- super::error_as_internal! {redb::Error}
495
- macro_rules! redb_error_as_internal {
548
+ super::error_as_store! {redb::Error}
549
+ macro_rules! redb_error_as_store {
496
550
  ($err_type:ty) => {
497
551
  impl From<$err_type> for crate::prelude::ErrorType
498
552
  {
499
553
  fn from(value: $err_type) -> Self
500
554
  {
501
555
  let redb_err: redb::Error = value.into();
502
- let err: crate::error::InternalError = redb_err.into();
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();
503
571
  err.into()
504
572
  }
505
573
  }
506
574
  };
507
575
  }
508
- redb_error_as_internal! {redb::StorageError}
509
- redb_error_as_internal! {redb::DatabaseError}
510
- redb_error_as_internal! {redb::TransactionError}
511
- redb_error_as_internal! {redb::TableError}
512
- redb_error_as_internal! {redb::CommitError}
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}
513
583
  }
514
584
  #[cfg(feature = "sqlite")]
515
585
  mod _trait_impl_sqlite
516
586
  {
517
- error_as_internal! {rusqlite::Error}
587
+ error_as_store! {rusqlite::Error}
518
588
  error_as_internal! {askama::Error}
519
589
  }
520
590
 
521
591
  /// Merge a list of error into a string error message
522
- pub(crate) fn vec_to_error<E: std::fmt::Display>(errs: &Vec<ErrorType>) -> String
592
+ pub(crate) fn vec_to_error(errs: &[ErrorType]) -> String
523
593
  {
524
594
  let errs: Vec<String> = errs.iter().map(|x| format!("'{}'", x)).collect();
525
595
  errs.join(", ")
526
596
  }
527
597
 
528
- pub(crate) fn parse_int_error_to_compile_error<'a>(
529
- text: &'a str,
598
+ pub(crate) fn parse_int_error_to_compile_error(
599
+ text: &str,
530
600
  e: std::num::ParseIntError,
531
601
  ) -> crate::prelude::ErrorType
532
602
  {
@@ -550,7 +620,8 @@ pub(crate) fn parse_int_error_to_compile_error<'a>(
550
620
  macro_rules! map_error {
551
621
  ($err:expr, $source:pat => $destination:expr) => {{
552
622
  use crate::error::*;
553
- let (error, meta) = $err.split_error();
623
+ let error: crate::prelude::ErrorType = $err;
624
+ let (error, meta) = error.split_error();
554
625
  match error
555
626
  {
556
627
  $source => ErrorType::make_error($destination.into(), meta),
@@ -6,6 +6,7 @@ pub(super) struct Head {}
6
6
 
7
7
  impl Head
8
8
  {
9
+ #[allow(clippy::ptr_arg)]
9
10
  fn call_impl(array: &Vec<value::Value>) -> FResult<value::Value>
10
11
  {
11
12
  Ok(
@@ -34,20 +35,17 @@ impl Keys
34
35
  match container
35
36
  {
36
37
  value::Value::Map(obj) => Ok(obj.keys().map(|x| x.to_owned().into()).collect()),
37
- value::Value::Node(n) => Ok(n.properties.keys().map(|x| x.to_owned().into()).collect()),
38
- value::Value::Edge(e) => Ok(e.properties.keys().map(|x| x.to_owned().into()).collect()),
39
- _ =>
40
- {
41
- return Err(
42
- RunTimeError::InvalidArgument {
43
- function_name: "keys",
44
- index: 0,
45
- expected_type: "map, node or relationship",
46
- value: format!("{:?}", container),
47
- }
48
- .into(),
49
- )
50
- }
38
+ value::Value::Node(n) => Ok(n.properties().keys().map(|x| x.to_owned().into()).collect()),
39
+ value::Value::Edge(e) => Ok(e.properties().keys().map(|x| x.to_owned().into()).collect()),
40
+ _ => Err(
41
+ RunTimeError::InvalidArgument {
42
+ function_name: "keys",
43
+ index: 0,
44
+ expected_type: "map, node or relationship",
45
+ value: format!("{:?}", container),
46
+ }
47
+ .into(),
48
+ ),
51
49
  }
52
50
  }
53
51
  }
@@ -88,18 +86,15 @@ impl super::FunctionTrait for Size
88
86
  value::Value::Array(arr) => Ok((arr.len() as i64).into()),
89
87
  value::Value::Map(obj) => Ok((obj.len() as i64).into()),
90
88
  value::Value::Path(..) => Ok(1.into()),
91
- _ =>
92
- {
93
- return Err(
94
- RunTimeError::InvalidArgument {
95
- function_name: "size",
96
- index: 0,
97
- expected_type: "array or map",
98
- value: format!("{:?}", container),
99
- }
100
- .into(),
101
- )
102
- }
89
+ _ => Err(
90
+ RunTimeError::InvalidArgument {
91
+ function_name: "size",
92
+ index: 0,
93
+ expected_type: "array or map",
94
+ value: format!("{:?}", container),
95
+ }
96
+ .into(),
97
+ ),
103
98
  }
104
99
  }
105
100
  fn validate_arguments(&self, _: Vec<ExpressionType>) -> Result<ExpressionType>
@@ -10,9 +10,9 @@ impl Type
10
10
  fn call_impl(edge: &graph::Edge) -> FResult<String>
11
11
  {
12
12
  edge
13
- .labels
13
+ .labels()
14
14
  .first()
15
- .ok_or_else(|| RunTimeError::MissingEdgeLabel)
15
+ .ok_or(RunTimeError::MissingEdgeLabel)
16
16
  .map(|v| v.to_owned())
17
17
  }
18
18
  }
@@ -24,7 +24,7 @@ impl Ceil
24
24
  {
25
25
  fn call_impl(value: &f64) -> FResult<f64>
26
26
  {
27
- Ok(value.ceil() as f64)
27
+ Ok(value.ceil())
28
28
  }
29
29
  }
30
30
 
@@ -37,7 +37,7 @@ impl Floor
37
37
  {
38
38
  fn call_impl(value: &f64) -> FResult<f64>
39
39
  {
40
- Ok(value.floor() as f64)
40
+ Ok(value.floor())
41
41
  }
42
42
  }
43
43
 
@@ -9,7 +9,7 @@ impl Labels
9
9
  {
10
10
  fn call_impl(node: &graph::Node) -> FResult<Vec<String>>
11
11
  {
12
- Ok(node.labels.to_owned())
12
+ Ok(node.labels().to_owned())
13
13
  }
14
14
  }
15
15
 
@@ -21,18 +21,15 @@ impl super::FunctionTrait for Length
21
21
  value::Value::Array(arr) => Ok((arr.len() as i64).into()),
22
22
  value::Value::Map(obj) => Ok((obj.len() as i64).into()),
23
23
  value::Value::Path(..) => Ok(1.into()),
24
- _ =>
25
- {
26
- return Err(
27
- RunTimeError::InvalidArgument {
28
- function_name: "length",
29
- index: 0,
30
- expected_type: "array or map",
31
- value: format!("{:?}", container),
32
- }
33
- .into(),
34
- )
35
- }
24
+ _ => Err(
25
+ RunTimeError::InvalidArgument {
26
+ function_name: "length",
27
+ index: 0,
28
+ expected_type: "array or map",
29
+ value: format!("{:?}", container),
30
+ }
31
+ .into(),
32
+ ),
36
33
  }
37
34
  }
38
35
  fn validate_arguments(&self, _: Vec<ExpressionType>) -> crate::Result<ExpressionType>
@@ -54,7 +51,7 @@ impl Nodes
54
51
  {
55
52
  fn call_impl(path: &graph::Path) -> FResult<Vec<graph::Node>>
56
53
  {
57
- Ok(vec![path.source.clone(), path.destination.clone()])
54
+ Ok(vec![path.source().clone(), path.destination().clone()])
58
55
  }
59
56
  }
60
57
 
@@ -67,13 +64,11 @@ impl Edges
67
64
  {
68
65
  fn call_impl(path: &graph::Path) -> FResult<Vec<graph::Edge>>
69
66
  {
70
- Ok(vec![graph::Edge {
71
- key: path.key.clone(),
72
- source: path.source.clone(),
73
- destination: path.destination.clone(),
74
- properties: path.properties.clone(),
75
- labels: path.labels.clone(),
76
- }])
67
+ Ok(vec![graph::Edge::new(
68
+ path.key(),
69
+ path.labels().clone(),
70
+ path.properties().clone(),
71
+ )])
77
72
  }
78
73
  }
79
74
 
@@ -70,8 +70,8 @@ impl Properties
70
70
  {
71
71
  match value
72
72
  {
73
- value::Value::Node(n) => Ok(n.properties.to_owned()),
74
- value::Value::Edge(e) => Ok(e.properties.to_owned()),
73
+ value::Value::Node(n) => Ok(n.properties().to_owned()),
74
+ value::Value::Edge(e) => Ok(e.properties().to_owned()),
75
75
  value::Value::Map(m) => Ok(m.to_owned()),
76
76
  _ => Err(RunTimeError::InvalidArgument {
77
77
  function_name: "properties",