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.
Files changed (104) 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}/release.toml +2 -2
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +34 -10
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
  16. data/ext/gqlitedb/src/connection.rs +300 -0
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
  22. data/ext/gqlitedb/src/functions/path.rs +75 -0
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
  25. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
  27. data/ext/gqlitedb/src/graph.rs +11 -0
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
  31. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
  32. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
  33. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
  34. data/ext/gqlitedb/src/parser.rs +4 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  36. data/ext/gqlitedb/src/query_result.rs +88 -0
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +260 -170
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
  44. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  46. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  47. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  48. data/ext/gqlitedb/src/value.rs +225 -0
  49. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +22 -18
  50. data/ext/gqliterb/Cargo.toml +12 -34
  51. data/ext/gqliterb/src/lib.rs +67 -39
  52. data/ext/graphcore/Cargo.toml +19 -0
  53. data/ext/graphcore/README.MD +4 -0
  54. data/ext/graphcore/release.toml +1 -0
  55. data/ext/graphcore/src/error.rs +28 -0
  56. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +146 -35
  57. data/ext/graphcore/src/lib.rs +16 -0
  58. data/ext/graphcore/src/prelude.rs +4 -0
  59. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  60. data/ext/graphcore/src/table.rs +272 -0
  61. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  62. data/ext/graphcore/src/value.rs +413 -0
  63. metadata +94 -83
  64. data/ext/gqliterb/.cargo/config.toml +0 -2
  65. data/ext/gqliterb/Cargo.lock +0 -1109
  66. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
  67. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
  68. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
  69. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
  70. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  71. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  103. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  104. /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
+ &parameters,
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::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
@@ -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
- fn assert_send_sync<T: Send + Sync>() {}
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::parser::Rule>> for Error
502
+ impl From<pest::error::Error<crate::parser::parser_impl::Rule>> for Error
463
503
  {
464
- fn from(value: pest::error::Error<crate::parser::parser::Rule>) -> Self
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::error_as_internal! {redb::Error}
494
- macro_rules! redb_error_as_internal {
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::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();
502
571
  err.into()
503
572
  }
504
573
  }
505
574
  };
506
575
  }
507
- redb_error_as_internal! {redb::StorageError}
508
- redb_error_as_internal! {redb::DatabaseError}
509
- redb_error_as_internal! {redb::TransactionError}
510
- redb_error_as_internal! {redb::TableError}
511
- 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}
512
583
  }
513
584
  #[cfg(feature = "sqlite")]
514
585
  mod _trait_impl_sqlite
515
586
  {
516
- error_as_internal! {rusqlite::Error}
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<E: std::fmt::Display>(errs: &Vec<ErrorType>) -> String
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<'a>(
528
- text: &'a str,
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 (error, meta) = $err.split_error();
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