gqlite 0.9

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.
@@ -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: []