gqlite 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,90 @@
1
+ #pragma once
2
+
3
+ #include <stdbool.h>
4
+
5
+ #ifdef __cplusplus
6
+ extern "C" {
7
+ #endif
8
+
9
+ /**
10
+ * The context is needed for most call to the API, it currently is mainly used to handle error reporting.
11
+ * It also manage the memory for any string value returned by the API.
12
+ */
13
+ typedef struct gqlite_api_context* gqlite_api_context_t;
14
+
15
+ /**
16
+ * Connection to the database.
17
+ */
18
+ typedef struct gqlite_connection* gqlite_connection_t;
19
+
20
+ /**
21
+ * Represent a value (integer, double, string, map, array).
22
+ */
23
+ typedef struct gqlite_value* gqlite_value_t;
24
+
25
+ /**
26
+ * Create a new context.
27
+ */
28
+ gqlite_api_context_t gqlite_api_context_create();
29
+ /**
30
+ * Free context memory.
31
+ */
32
+ void gqlite_api_context_destroy(gqlite_api_context_t);
33
+ /**
34
+ * Return the error message. The memory is owned by the context,
35
+ * it will be cleared when the context is freed or after the next function call.
36
+ */
37
+ const char* gqlite_api_context_get_message(gqlite_api_context_t);
38
+ /**
39
+ * Return true if an error has occured in the last call.
40
+ */
41
+ bool gqlite_api_context_has_error(gqlite_api_context_t);
42
+ /**
43
+ * Clear the error message.
44
+ */
45
+ void gqlite_api_context_clear_error(gqlite_api_context_t);
46
+
47
+ /**
48
+ * Create a connection, using the sqlite backend. Expect as argument an handle to a sqlite connection.
49
+ */
50
+ gqlite_connection_t gqlite_connection_create_from_sqlite(gqlite_api_context_t, void* _handle, gqlite_value_t _options);
51
+
52
+ /**
53
+ * Create a connection, using the sqlite backend. Using the database specified by the filename.
54
+ */
55
+ gqlite_connection_t gqlite_connection_create_from_sqlite_file(gqlite_api_context_t, const char* _filename, gqlite_value_t _options);
56
+
57
+ /**
58
+ * Destroy the connection. Does not delete any connection handle passed as an argument.
59
+ */
60
+ void gqlite_connection_destroy(gqlite_api_context_t, gqlite_connection_t);
61
+
62
+ /**
63
+ * Execute an OpenCypher query on the connection.
64
+ * Return a null value if an error has occured during execution.
65
+ */
66
+ gqlite_value_t gqlite_connection_oc_query(gqlite_api_context_t, gqlite_connection_t, const char*, gqlite_value_t);
67
+
68
+ /**
69
+ * Create a value object to use in a query.
70
+ */
71
+ gqlite_value_t gqlite_value_create(gqlite_api_context_t);
72
+
73
+ /**
74
+ * Destroy a value.
75
+ */
76
+ void gqlite_value_destroy(gqlite_api_context_t, gqlite_value_t);
77
+
78
+ /**
79
+ * Convert value to json. The returned string is only valid until the next API call with the given context.
80
+ */
81
+ const char* gqlite_value_to_json(gqlite_api_context_t, gqlite_value_t);
82
+
83
+ /**
84
+ * Check if the value is valid.
85
+ */
86
+ bool gqlite_value_is_valid(gqlite_api_context_t, gqlite_value_t);
87
+
88
+ #ifdef __cplusplus
89
+ }
90
+ #endif
@@ -0,0 +1,152 @@
1
+ #pragma once
2
+
3
+ #include <exception>
4
+ #include <memory>
5
+ #include <string>
6
+ #include <unordered_map>
7
+ #include <vector>
8
+
9
+ namespace gqlite
10
+ {
11
+ class backend;
12
+ struct debug_stats;
13
+ /**
14
+ * Represents an error that occurs during the execution of a query.
15
+ */
16
+ class exception : public std::exception
17
+ {
18
+ public:
19
+ exception(const std::string& _error) : m_error(_error), m_c_error(m_error.c_str()) {}
20
+ exception(const char* _error) : m_c_error(_error) {}
21
+ template<typename _T_, typename... _TOther_>
22
+ inline exception(const char* _format, const _T_& _value, const _TOther_&... _other);
23
+ template<typename _T_, typename... _TOther_>
24
+ inline exception(const std::string& _format, const _T_& _value, const _TOther_&... _other);
25
+ exception(const exception& _rhs);
26
+ exception& operator=(const exception& _rhs);
27
+ /**
28
+ * @return the error message
29
+ */
30
+ const char* what() const throw() override
31
+ {
32
+ return m_c_error;
33
+ }
34
+ private:
35
+ std::string m_error;
36
+ const char* m_c_error;
37
+ };
38
+ /**
39
+ * Represent the value type.
40
+ */
41
+ enum class value_type
42
+ {
43
+ invalid,
44
+ boolean,
45
+ integer,
46
+ number, ///< aka float
47
+ string,
48
+ map,
49
+ vector
50
+ };
51
+ class value;
52
+ using value_map = std::unordered_map<std::string, value>;
53
+ using value_vector = std::vector<value>;
54
+ /**
55
+ * Represent a value (boolean, integer, number, string, map or vector)
56
+ */
57
+ class value
58
+ {
59
+ public:
60
+ value();
61
+ value(const value& _rhs);
62
+ value& operator=(const value& _rhs);
63
+ ~value();
64
+ public:
65
+ value(int _v);
66
+ value(double _v);
67
+ value(const std::string& _v);
68
+ value(const value_map& _v);
69
+ /// not part of the public API
70
+ template<typename _T_>
71
+ value(const std::initializer_list<typename std::unordered_map<std::string, _T_>::value_type>& _v);
72
+ value(const value_vector& _v);
73
+ /// not part of the public API
74
+ template<typename _T_>
75
+ value(const std::vector<_T_>& _v);
76
+ bool operator==(const value& _rhs) const;
77
+ public:
78
+ /**
79
+ * @return the type hold by this value
80
+ */
81
+ value_type get_type() const;
82
+ /**
83
+ * Attempt to return a bool. Throw an exception if not possible.
84
+ */
85
+ bool to_bool() const;
86
+ /**
87
+ * Attempt to return an integer. Throw an exception if not possible.
88
+ */
89
+ int to_integer() const;
90
+ /**
91
+ * Attempt to return a double. Throw an exception if not possible.
92
+ */
93
+ double to_double() const;
94
+ /**
95
+ * Attempt to return a string. Throw an exception if not possible.
96
+ */
97
+ std::string to_string() const;
98
+ /**
99
+ * Attempt to return a map. Throw an exception if not possible.
100
+ */
101
+ value_map to_map() const;
102
+ /**
103
+ * Attempt to return a vector. Throw an exception if not possible.
104
+ */
105
+ value_vector to_vector() const;
106
+ public:
107
+ /**
108
+ * Attempt to return a json string to represent a value.
109
+ */
110
+ std::string to_json() const;
111
+ /**
112
+ * Construct a value from a json string. Throw an exception if not possible.
113
+ */
114
+ static value from_json(const std::string& _json);
115
+ private:
116
+ struct data;
117
+ std::shared_ptr<data> d;
118
+ };
119
+ /**
120
+ * Main class for connecting to a gqlite database.
121
+ */
122
+ class connection
123
+ {
124
+ connection(backend* _backend);
125
+ public:
126
+ connection();
127
+ connection(const connection& _rhs);
128
+ connection& operator=(const connection& _rhs);
129
+ ~connection();
130
+ /**
131
+ * Create a sqlite connection from a \p _pointer to a valid sqlite handle.
132
+ */
133
+ static connection create_from_sqlite(void* _pointer, const value& _options = value());
134
+ /**
135
+ * Create a sqlite connection from a file.
136
+ */
137
+ static connection create_from_sqlite_file(const std::string& _filename, const value& _options = value());
138
+ /**
139
+ * @internal
140
+ * Part of the private API, what is returned by this function may change at any time.
141
+ */
142
+ gqlite::value get_debug_stats() const;
143
+ public:
144
+ /**
145
+ * Execute a query.
146
+ */
147
+ value execute_oc_query(const std::string& _string, const value_map& _variant = {});
148
+ private:
149
+ struct data;
150
+ std::shared_ptr<data> d;
151
+ };
152
+ }
data/lib/gqlite.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'ffi'
2
+ require 'objspace'
3
+ require 'json'
4
+
5
+ module Gqlite
6
+ class Error < StandardError
7
+ end
8
+ module CApi
9
+ extend FFI::Library
10
+ ffi_lib 'gqlite'
11
+ attach_function :gqlite_api_context_create, [], :pointer
12
+ attach_function :gqlite_api_context_destroy, [:pointer], :void
13
+ attach_function :gqlite_api_context_clear_error, [:pointer], :void
14
+ attach_function :gqlite_api_context_has_error, [:pointer], :bool
15
+ attach_function :gqlite_api_context_get_message, [:pointer], :string
16
+ attach_function :gqlite_connection_create_from_sqlite_file, [:pointer, :string, :pointer], :pointer
17
+ attach_function :gqlite_connection_destroy, [:pointer, :pointer], :void
18
+ attach_function :gqlite_connection_oc_query, [:pointer, :pointer, :string, :pointer], :pointer
19
+ attach_function :gqlite_value_create, [:pointer], :pointer
20
+ attach_function :gqlite_value_destroy, [:pointer, :pointer], :void
21
+ attach_function :gqlite_value_to_json, [:pointer, :pointer], :string
22
+ attach_function :gqlite_value_is_valid, [:pointer, :pointer], :bool
23
+ ApiError = CApi.gqlite_api_context_create()
24
+ def CApi.call_function(fname, *args)
25
+ r = CApi.send fname, ApiError, *args
26
+ if CApi.gqlite_api_context_has_error(ApiError)
27
+ err = CApi.gqlite_api_context_get_message ApiError
28
+ CApi.gqlite_api_context_clear_error ApiError
29
+ raise Error.new err
30
+ end
31
+ return r
32
+ end
33
+ end
34
+ class Connection
35
+ attr_reader :dbhandle
36
+ def initialize(sqlite_filename: nil)
37
+ if sqlite_filename != nil
38
+ @dbhandle = CApi.call_function :gqlite_connection_create_from_sqlite_file, sqlite_filename, nil
39
+ else
40
+ raise Error.new "No connection backend was selected."
41
+ end
42
+ ObjectSpace.define_finalizer @dbhandle, proc {|id|
43
+ CApi.call_function :gqlite_connection_destroy, @dbhandle
44
+ }
45
+ end
46
+ def execute_oc_query(query, bindings: nil)
47
+ ret = CApi.call_function :gqlite_connection_oc_query, @dbhandle, query, nil
48
+ if CApi.call_function(:gqlite_value_is_valid, ret)
49
+ val = JSON.parse CApi.call_function :gqlite_value_to_json, ret
50
+ else
51
+ ret = nil
52
+ end
53
+ CApi.call_function :gqlite_value_destroy, ret
54
+ return val
55
+ end
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gqlite
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.9'
5
+ platform: ruby
6
+ authors:
7
+ - Cyrille Berger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-09-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ description: |2
28
+ GQLite aims to be the equivalent to SQLite for graph database: an easy to embedd query engine, with the data stored in a single file. To achieve that, GQLite uses SQLite to store data, and come as a library implementing a translation between graph query languages and SQL.
29
+
30
+ This is an experimental release.
31
+ email:
32
+ executables: []
33
+ extensions:
34
+ - ext/gqlite/extconf.rb
35
+ extra_rdoc_files: []
36
+ files:
37
+ - ext/gqlite/extconf.rb
38
+ - ext/gqlite/gqlite-amalgamate.cpp
39
+ - ext/gqlite/gqlite-c.h
40
+ - ext/gqlite/gqlite.h
41
+ - lib/gqlite.rb
42
+ homepage: https://gitlab.com/cyloncore/gqlite
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.3.5
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Ruby bindings for GQLite, a Graph Query library.
65
+ test_files: []