gqlite 1.1.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 +1109 -0
- data/ext/gqliterb/Cargo.toml +43 -0
- data/ext/gqliterb/extconf.rb +4 -0
- data/ext/gqliterb/src/lib.rs +260 -0
- 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
- data/lib/gqlite.rb +1 -75
- metadata +118 -25
- data/ext/gqlite/extconf.rb +0 -21
- data/ext/gqlite/gqlite-amalgamate.cpp +0 -9599
- data/ext/gqlite/gqlite-c.h +0 -95
- data/ext/gqlite/gqlite.h +0 -141
@@ -0,0 +1,33 @@
|
|
1
|
+
use super::AggregatorState;
|
2
|
+
|
3
|
+
use crate::{value::Value, Result};
|
4
|
+
|
5
|
+
#[derive(Debug)]
|
6
|
+
struct CollectState
|
7
|
+
{
|
8
|
+
value: Vec<Value>,
|
9
|
+
}
|
10
|
+
|
11
|
+
impl CollectState
|
12
|
+
{
|
13
|
+
fn new() -> Result<Self>
|
14
|
+
{
|
15
|
+
Ok(Self {
|
16
|
+
value: Default::default(),
|
17
|
+
})
|
18
|
+
}
|
19
|
+
}
|
20
|
+
impl AggregatorState for CollectState
|
21
|
+
{
|
22
|
+
fn next(&mut self, value: Value) -> crate::Result<()>
|
23
|
+
{
|
24
|
+
self.value.push(value);
|
25
|
+
Ok(())
|
26
|
+
}
|
27
|
+
fn finalise(self: Box<Self>) -> crate::Result<crate::value::Value>
|
28
|
+
{
|
29
|
+
Ok(self.value.into())
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
super::declare_aggregator!(collect, Collect, CollectState, () -> i64);
|
@@ -0,0 +1,35 @@
|
|
1
|
+
use super::AggregatorState;
|
2
|
+
|
3
|
+
use crate::Result;
|
4
|
+
|
5
|
+
#[derive(Debug)]
|
6
|
+
struct CountState
|
7
|
+
{
|
8
|
+
count: i64,
|
9
|
+
}
|
10
|
+
|
11
|
+
impl CountState
|
12
|
+
{
|
13
|
+
fn new() -> Result<Self>
|
14
|
+
{
|
15
|
+
Ok(Self { count: 0 })
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
impl AggregatorState for CountState
|
20
|
+
{
|
21
|
+
fn next(&mut self, value: crate::value::Value) -> crate::Result<()>
|
22
|
+
{
|
23
|
+
if !value.is_null()
|
24
|
+
{
|
25
|
+
self.count += 1;
|
26
|
+
}
|
27
|
+
Ok(())
|
28
|
+
}
|
29
|
+
fn finalise(self: Box<Self>) -> crate::Result<crate::value::Value>
|
30
|
+
{
|
31
|
+
Ok(self.count.into())
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
super::declare_aggregator!(count, Count, CountState, () -> i64);
|
@@ -0,0 +1,168 @@
|
|
1
|
+
use std::fmt::Debug;
|
2
|
+
|
3
|
+
use super::AggregatorState;
|
4
|
+
|
5
|
+
use crate::{
|
6
|
+
error::{InternalError, RunTimeError},
|
7
|
+
value::Value,
|
8
|
+
Result,
|
9
|
+
};
|
10
|
+
|
11
|
+
#[derive(Debug)]
|
12
|
+
struct AvgState
|
13
|
+
{
|
14
|
+
value: Value,
|
15
|
+
count: usize,
|
16
|
+
}
|
17
|
+
|
18
|
+
impl AvgState
|
19
|
+
{
|
20
|
+
fn new() -> Result<Self>
|
21
|
+
{
|
22
|
+
Ok(Self {
|
23
|
+
value: Value::Null,
|
24
|
+
count: 0,
|
25
|
+
})
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
impl AggregatorState for AvgState
|
30
|
+
{
|
31
|
+
fn next(&mut self, value: Value) -> crate::Result<()>
|
32
|
+
{
|
33
|
+
if self.value.is_null()
|
34
|
+
{
|
35
|
+
self.value = value;
|
36
|
+
}
|
37
|
+
else
|
38
|
+
{
|
39
|
+
match value
|
40
|
+
{
|
41
|
+
Value::Null =>
|
42
|
+
{}
|
43
|
+
Value::Integer(i) =>
|
44
|
+
{
|
45
|
+
self.count += 1;
|
46
|
+
match self.value
|
47
|
+
{
|
48
|
+
Value::Integer(vi) => self.value = (vi + i).into(),
|
49
|
+
Value::Float(vf) => self.value = (vf + i as f64).into(),
|
50
|
+
_ => Err(InternalError::InvalidAggregationState)?,
|
51
|
+
}
|
52
|
+
}
|
53
|
+
Value::Float(f) =>
|
54
|
+
{
|
55
|
+
self.count += 1;
|
56
|
+
match self.value
|
57
|
+
{
|
58
|
+
Value::Integer(vi) => self.value = (vi as f64 + f).into(),
|
59
|
+
Value::Float(vf) => self.value = (vf + f).into(),
|
60
|
+
_ => Err(InternalError::InvalidAggregationState)?,
|
61
|
+
}
|
62
|
+
}
|
63
|
+
_ => Err(RunTimeError::InvalidArgumentType)?,
|
64
|
+
}
|
65
|
+
}
|
66
|
+
Ok(())
|
67
|
+
}
|
68
|
+
fn finalise(self: Box<Self>) -> crate::Result<crate::value::Value>
|
69
|
+
{
|
70
|
+
match self.value
|
71
|
+
{
|
72
|
+
Value::Null => Ok(Value::Null),
|
73
|
+
Value::Integer(vi) => Ok((vi / self.count as i64).into()),
|
74
|
+
Value::Float(vf) => Ok((vf / self.count as f64).into()),
|
75
|
+
_ => Err(InternalError::InvalidAggregationState)?,
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
super::declare_aggregator!(avg, Avg, AvgState, () -> Value);
|
81
|
+
|
82
|
+
#[derive(Debug)]
|
83
|
+
struct MinState
|
84
|
+
{
|
85
|
+
value: Value,
|
86
|
+
}
|
87
|
+
|
88
|
+
impl MinState
|
89
|
+
{
|
90
|
+
fn new() -> Result<Self>
|
91
|
+
{
|
92
|
+
Ok(Self { value: Value::Null })
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
impl AggregatorState for MinState
|
97
|
+
{
|
98
|
+
fn next(&mut self, value: Value) -> crate::Result<()>
|
99
|
+
{
|
100
|
+
if self.value.is_null()
|
101
|
+
{
|
102
|
+
self.value = value;
|
103
|
+
}
|
104
|
+
else if !value.is_null()
|
105
|
+
{
|
106
|
+
match value.orderability(&self.value)
|
107
|
+
{
|
108
|
+
std::cmp::Ordering::Less =>
|
109
|
+
{
|
110
|
+
self.value = value;
|
111
|
+
}
|
112
|
+
_ =>
|
113
|
+
{}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
Ok(())
|
117
|
+
}
|
118
|
+
fn finalise(self: Box<Self>) -> crate::Result<crate::value::Value>
|
119
|
+
{
|
120
|
+
Ok(self.value)
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
super::declare_aggregator!(min, Min, MinState, () -> i64);
|
125
|
+
|
126
|
+
#[derive(Debug)]
|
127
|
+
struct MaxState
|
128
|
+
{
|
129
|
+
value: Value,
|
130
|
+
}
|
131
|
+
|
132
|
+
impl MaxState
|
133
|
+
{
|
134
|
+
fn new() -> Result<Self>
|
135
|
+
{
|
136
|
+
Ok(Self { value: Value::Null })
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
impl AggregatorState for MaxState
|
141
|
+
{
|
142
|
+
fn next(&mut self, value: Value) -> crate::Result<()>
|
143
|
+
{
|
144
|
+
if self.value.is_null()
|
145
|
+
{
|
146
|
+
self.value = value;
|
147
|
+
}
|
148
|
+
else if !value.is_null()
|
149
|
+
{
|
150
|
+
match value.orderability(&self.value)
|
151
|
+
{
|
152
|
+
std::cmp::Ordering::Greater =>
|
153
|
+
{
|
154
|
+
self.value = value;
|
155
|
+
}
|
156
|
+
_ =>
|
157
|
+
{}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
Ok(())
|
161
|
+
}
|
162
|
+
fn finalise(self: Box<Self>) -> crate::Result<crate::value::Value>
|
163
|
+
{
|
164
|
+
Ok(self.value)
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
super::declare_aggregator!(max, Max, MaxState, () -> i64);
|
@@ -0,0 +1,74 @@
|
|
1
|
+
mod arithmetic;
|
2
|
+
mod containers;
|
3
|
+
mod count;
|
4
|
+
mod stats;
|
5
|
+
|
6
|
+
use std::{fmt::Debug, sync::Arc};
|
7
|
+
|
8
|
+
use crate::prelude::*;
|
9
|
+
use compiler::expression_analyser::ExpressionType;
|
10
|
+
|
11
|
+
pub(crate) trait AggregatorState: Debug
|
12
|
+
{
|
13
|
+
fn next(&mut self, expression: value::Value) -> Result<()>;
|
14
|
+
fn finalise(self: Box<Self>) -> Result<value::Value>;
|
15
|
+
}
|
16
|
+
|
17
|
+
pub(crate) trait AggregatorTrait: Debug + Sync + Send
|
18
|
+
{
|
19
|
+
fn create(&self, arguments: Vec<value::Value>) -> Result<Box<dyn AggregatorState>>;
|
20
|
+
fn validate_arguments(&self, arguments: Vec<ExpressionType>) -> Result<ExpressionType>;
|
21
|
+
}
|
22
|
+
|
23
|
+
pub(crate) type Aggregator = Arc<Box<dyn AggregatorTrait>>;
|
24
|
+
|
25
|
+
macro_rules! declare_aggregator {
|
26
|
+
($function_name: ident, $type_name: ident, $state_type_name: tt, ( $( $arg_type: ty $(,)? )* ) -> $ret_type: ty) => {
|
27
|
+
#[derive(Debug)]
|
28
|
+
pub(super) struct $type_name {}
|
29
|
+
impl $type_name
|
30
|
+
{
|
31
|
+
pub(crate) fn new() -> (String, crate::aggregators::Aggregator)
|
32
|
+
{
|
33
|
+
(
|
34
|
+
stringify!($function_name).to_string(),
|
35
|
+
std::sync::Arc::new(Box::new(Self {})),
|
36
|
+
)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
impl crate::aggregators::AggregatorTrait for $type_name
|
40
|
+
{
|
41
|
+
#[allow(unused_variables)]
|
42
|
+
fn create(&self, arguments: Vec<crate::value::Value>) -> Result<Box<dyn AggregatorState>>
|
43
|
+
{
|
44
|
+
Ok(Box::new($crate::functions::make_function_call!($function_name, $state_type_name::new, arguments, $( $arg_type,)*)?))
|
45
|
+
}
|
46
|
+
#[allow(unused_variables)]
|
47
|
+
fn validate_arguments(
|
48
|
+
&self,
|
49
|
+
arguments: Vec<$crate::compiler::expression_analyser::ExpressionType>,
|
50
|
+
) -> Result<$crate::compiler::expression_analyser::ExpressionType>
|
51
|
+
{
|
52
|
+
use crate::functions::FunctionTypeTrait;
|
53
|
+
// TODO
|
54
|
+
Ok(<$ret_type>::result_type())
|
55
|
+
}
|
56
|
+
|
57
|
+
}
|
58
|
+
};
|
59
|
+
}
|
60
|
+
|
61
|
+
pub(crate) use declare_aggregator;
|
62
|
+
|
63
|
+
pub(crate) fn init_aggregators() -> std::collections::HashMap<String, Aggregator>
|
64
|
+
{
|
65
|
+
[
|
66
|
+
count::Count::new(),
|
67
|
+
arithmetic::Sum::new(),
|
68
|
+
containers::Collect::new(),
|
69
|
+
stats::Avg::new(),
|
70
|
+
stats::Min::new(),
|
71
|
+
stats::Max::new(),
|
72
|
+
]
|
73
|
+
.into()
|
74
|
+
}
|
@@ -0,0 +1,236 @@
|
|
1
|
+
use std::borrow::Borrow;
|
2
|
+
|
3
|
+
fn handle_error<T, E: std::borrow::Borrow<E> + ToString>(
|
4
|
+
context: *mut GqliteApiContextT,
|
5
|
+
result: Result<T, E>,
|
6
|
+
) -> Result<T, E>
|
7
|
+
{
|
8
|
+
match &result
|
9
|
+
{
|
10
|
+
Ok(_) =>
|
11
|
+
{}
|
12
|
+
Err(e) =>
|
13
|
+
{
|
14
|
+
let mut context = unsafe { Box::from_raw(context) };
|
15
|
+
context.string = std::ffi::CString::new(e.borrow().to_string()).unwrap();
|
16
|
+
context.has_error = true;
|
17
|
+
let _ = Box::into_raw(context);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
result
|
21
|
+
}
|
22
|
+
|
23
|
+
fn get_value(value: *mut GqliteValueT) -> crate::value::Value
|
24
|
+
{
|
25
|
+
if value.is_null()
|
26
|
+
{
|
27
|
+
crate::value::Value::default()
|
28
|
+
}
|
29
|
+
else
|
30
|
+
{
|
31
|
+
let value = unsafe { Box::from_raw(value) };
|
32
|
+
let v = value.value.clone();
|
33
|
+
let _ = Box::into_raw(value);
|
34
|
+
v
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
fn check_error(context: *mut GqliteApiContextT)
|
39
|
+
{
|
40
|
+
if unsafe { (*context).has_error }
|
41
|
+
{
|
42
|
+
let context = unsafe { Box::from_raw(context) };
|
43
|
+
let stri = context.string.to_str().unwrap();
|
44
|
+
println!("Error message '{stri:?}' was not cleared from context!");
|
45
|
+
let _ = Box::into_raw(context);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
#[repr(C)]
|
50
|
+
pub struct GqliteApiContextT
|
51
|
+
{
|
52
|
+
string: std::ffi::CString,
|
53
|
+
has_error: bool,
|
54
|
+
}
|
55
|
+
|
56
|
+
#[repr(C)]
|
57
|
+
pub struct GqliteConnectionT
|
58
|
+
{
|
59
|
+
connection: crate::Connection,
|
60
|
+
}
|
61
|
+
|
62
|
+
#[repr(C)]
|
63
|
+
pub struct GqliteValueT
|
64
|
+
{
|
65
|
+
value: crate::value::Value,
|
66
|
+
}
|
67
|
+
|
68
|
+
#[no_mangle]
|
69
|
+
pub extern "C" fn gqlite_api_context_create() -> *mut GqliteApiContextT
|
70
|
+
{
|
71
|
+
Box::into_raw(Box::new(GqliteApiContextT {
|
72
|
+
string: std::ffi::CString::new("").unwrap(),
|
73
|
+
has_error: false,
|
74
|
+
}))
|
75
|
+
}
|
76
|
+
|
77
|
+
#[no_mangle]
|
78
|
+
pub extern "C" fn gqlite_api_context_destroy(context: *mut GqliteApiContextT)
|
79
|
+
{
|
80
|
+
unsafe {
|
81
|
+
let _ = Box::from_raw(context);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
#[no_mangle]
|
86
|
+
pub extern "C" fn gqlite_api_context_get_message(
|
87
|
+
context: *mut GqliteApiContextT,
|
88
|
+
) -> *const std::ffi::c_char
|
89
|
+
{
|
90
|
+
unsafe { (*context).string.as_ptr() }
|
91
|
+
}
|
92
|
+
|
93
|
+
#[no_mangle]
|
94
|
+
pub extern "C" fn gqlite_api_context_has_error(context: *mut GqliteApiContextT) -> bool
|
95
|
+
{
|
96
|
+
unsafe { (*context).has_error }
|
97
|
+
}
|
98
|
+
|
99
|
+
#[no_mangle]
|
100
|
+
pub extern "C" fn gqlite_api_context_clear_error(context: *mut GqliteApiContextT)
|
101
|
+
{
|
102
|
+
let mut context = unsafe { Box::from_raw(context) };
|
103
|
+
context.has_error = false;
|
104
|
+
let _ = Box::into_raw(context);
|
105
|
+
}
|
106
|
+
|
107
|
+
#[no_mangle]
|
108
|
+
pub extern "C" fn gqlite_connection_create_from_file(
|
109
|
+
context: *mut GqliteApiContextT,
|
110
|
+
filename: *const std::ffi::c_char,
|
111
|
+
options: *mut GqliteValueT,
|
112
|
+
) -> *mut GqliteConnectionT
|
113
|
+
{
|
114
|
+
check_error(context);
|
115
|
+
let options = get_value(options);
|
116
|
+
let path = unsafe { std::ffi::CStr::from_ptr(filename) };
|
117
|
+
if let Ok(path) = handle_error(context, path.to_str())
|
118
|
+
{
|
119
|
+
if let Ok(c) = handle_error(context, crate::Connection::open(path, options.into_map()))
|
120
|
+
{
|
121
|
+
return Box::into_raw(Box::new(GqliteConnectionT { connection: c }));
|
122
|
+
}
|
123
|
+
}
|
124
|
+
std::ptr::null::<GqliteConnectionT>() as *mut GqliteConnectionT
|
125
|
+
}
|
126
|
+
|
127
|
+
#[no_mangle]
|
128
|
+
pub extern "C" fn gqlite_connection_destroy(
|
129
|
+
_context: *mut GqliteApiContextT,
|
130
|
+
connection: *mut GqliteConnectionT,
|
131
|
+
)
|
132
|
+
{
|
133
|
+
unsafe {
|
134
|
+
let _ = Box::from_raw(connection);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
#[no_mangle]
|
139
|
+
pub extern "C" fn gqlite_connection_query(
|
140
|
+
context: *mut GqliteApiContextT,
|
141
|
+
connection: *mut GqliteConnectionT,
|
142
|
+
query: *const std::ffi::c_char,
|
143
|
+
bindings: *mut GqliteValueT,
|
144
|
+
) -> *mut GqliteValueT
|
145
|
+
{
|
146
|
+
check_error(context);
|
147
|
+
let query = unsafe { std::ffi::CStr::from_ptr(query) };
|
148
|
+
if let Ok(query) = handle_error(context, query.to_str())
|
149
|
+
{
|
150
|
+
let conn = unsafe { Box::from_raw(connection) };
|
151
|
+
let result = conn
|
152
|
+
.connection
|
153
|
+
.execute_query(query, get_value(bindings).into_map());
|
154
|
+
let _ = Box::into_raw(conn);
|
155
|
+
if let Ok(v) = handle_error(context, result)
|
156
|
+
{
|
157
|
+
return Box::into_raw(Box::new(GqliteValueT { value: v }));
|
158
|
+
}
|
159
|
+
}
|
160
|
+
std::ptr::null::<GqliteValueT>() as *mut GqliteValueT
|
161
|
+
}
|
162
|
+
|
163
|
+
#[no_mangle]
|
164
|
+
pub extern "C" fn gqlite_value_create(context: *mut GqliteApiContextT) -> *mut GqliteValueT
|
165
|
+
{
|
166
|
+
check_error(context);
|
167
|
+
Box::into_raw(Box::new(GqliteValueT {
|
168
|
+
value: crate::value::Value::default(),
|
169
|
+
}))
|
170
|
+
}
|
171
|
+
|
172
|
+
#[no_mangle]
|
173
|
+
pub extern "C" fn gqlite_value_destroy(context: *mut GqliteApiContextT, value: *mut GqliteValueT)
|
174
|
+
{
|
175
|
+
check_error(context);
|
176
|
+
unsafe {
|
177
|
+
let _ = Box::from_raw(value);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
#[no_mangle]
|
182
|
+
pub extern "C" fn gqlite_value_to_json(
|
183
|
+
context: *mut GqliteApiContextT,
|
184
|
+
value: *mut GqliteValueT,
|
185
|
+
) -> *const std::ffi::c_char
|
186
|
+
{
|
187
|
+
check_error(context);
|
188
|
+
|
189
|
+
let value = unsafe { Box::from_raw(value) };
|
190
|
+
|
191
|
+
if let Ok(v) = handle_error(context, serde_json::to_string(value.value.borrow()))
|
192
|
+
{
|
193
|
+
let mut context = unsafe { Box::from_raw(context) };
|
194
|
+
context.string = std::ffi::CString::new(v).unwrap();
|
195
|
+
context.has_error = false;
|
196
|
+
let r = context.string.as_ptr();
|
197
|
+
let _ = Box::into_raw(context);
|
198
|
+
let _ = Box::into_raw(value);
|
199
|
+
return r;
|
200
|
+
}
|
201
|
+
let _ = Box::into_raw(value);
|
202
|
+
return std::ptr::null();
|
203
|
+
}
|
204
|
+
|
205
|
+
#[no_mangle]
|
206
|
+
pub extern "C" fn gqlite_value_from_json(
|
207
|
+
context: *mut GqliteApiContextT,
|
208
|
+
json: *const std::ffi::c_char,
|
209
|
+
) -> *mut GqliteValueT
|
210
|
+
{
|
211
|
+
check_error(context);
|
212
|
+
|
213
|
+
let json = unsafe { std::ffi::CStr::from_ptr(json) };
|
214
|
+
if let Ok(json) = handle_error(context, json.to_str())
|
215
|
+
{
|
216
|
+
if let Ok(v) = handle_error(context, serde_json::from_str::<crate::value::Value>(json))
|
217
|
+
{
|
218
|
+
return Box::into_raw(Box::new(GqliteValueT { value: v }));
|
219
|
+
}
|
220
|
+
}
|
221
|
+
return std::ptr::null::<GqliteValueT>() as *mut GqliteValueT;
|
222
|
+
}
|
223
|
+
|
224
|
+
#[no_mangle]
|
225
|
+
pub extern "C" fn gqlite_value_is_valid(
|
226
|
+
context: *mut GqliteApiContextT,
|
227
|
+
value: *mut GqliteValueT,
|
228
|
+
) -> bool
|
229
|
+
{
|
230
|
+
check_error(context);
|
231
|
+
match unsafe { (*value).value.borrow() }
|
232
|
+
{
|
233
|
+
crate::value::Value::Null => false,
|
234
|
+
_ => true,
|
235
|
+
}
|
236
|
+
}
|