quasardb 3.14.1.dev4__cp39-cp39-macosx_10_14_x86_64.whl → 3.14.1.dev6__cp39-cp39-macosx_10_14_x86_64.whl
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.
Potentially problematic release.
This version of quasardb might be problematic. Click here for more details.
- quasardb/CMakeLists.txt +4 -0
- quasardb/cluster.cpp +89 -0
- quasardb/cluster.hpp +113 -33
- quasardb/cmake_install.cmake +1 -1
- quasardb/date/cmake_install.cmake +1 -1
- quasardb/error.hpp +25 -1
- quasardb/handle.cpp +29 -0
- quasardb/handle.hpp +28 -11
- quasardb/libqdb_api.dylib +0 -0
- quasardb/logger.cpp +3 -0
- quasardb/metrics.cpp +103 -0
- quasardb/metrics.hpp +112 -0
- quasardb/module.cpp +2 -0
- quasardb/options.hpp +15 -0
- quasardb/pybind11/cmake_install.cmake +1 -1
- quasardb/quasardb.cpython-39-darwin.so +0 -0
- quasardb/query.cpp +13 -2
- quasardb/range-v3/cmake_install.cmake +1 -1
- quasardb/table.cpp +42 -0
- quasardb/table.hpp +7 -19
- quasardb/table_reader.hpp +5 -1
- quasardb/writer.cpp +6 -0
- {quasardb-3.14.1.dev4.dist-info → quasardb-3.14.1.dev6.dist-info}/METADATA +1 -1
- {quasardb-3.14.1.dev4.dist-info → quasardb-3.14.1.dev6.dist-info}/RECORD +27 -24
- quasardb/add_boost_test.cmake +0 -43
- {quasardb-3.14.1.dev4.dist-info → quasardb-3.14.1.dev6.dist-info}/LICENSE.md +0 -0
- {quasardb-3.14.1.dev4.dist-info → quasardb-3.14.1.dev6.dist-info}/WHEEL +0 -0
- {quasardb-3.14.1.dev4.dist-info → quasardb-3.14.1.dev6.dist-info}/top_level.txt +0 -0
quasardb/CMakeLists.txt
CHANGED
|
@@ -325,6 +325,7 @@ set(QDB_FILES
|
|
|
325
325
|
batch_inserter.hpp
|
|
326
326
|
blob.hpp
|
|
327
327
|
cluster.hpp
|
|
328
|
+
cluster.cpp
|
|
328
329
|
concepts.hpp
|
|
329
330
|
continuous.cpp
|
|
330
331
|
continuous.hpp
|
|
@@ -333,9 +334,12 @@ set(QDB_FILES
|
|
|
333
334
|
error.hpp
|
|
334
335
|
entry.hpp
|
|
335
336
|
handle.hpp
|
|
337
|
+
handle.cpp
|
|
336
338
|
logger.hpp
|
|
337
339
|
logger.cpp
|
|
338
340
|
masked_array.hpp
|
|
341
|
+
metrics.hpp
|
|
342
|
+
metrics.cpp
|
|
339
343
|
module.hpp
|
|
340
344
|
module.cpp
|
|
341
345
|
node.hpp
|
quasardb/cluster.cpp
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#include "cluster.hpp"
|
|
2
|
+
#include "metrics.hpp"
|
|
3
|
+
#include <chrono>
|
|
4
|
+
#include <thread>
|
|
5
|
+
|
|
6
|
+
namespace qdb
|
|
7
|
+
{
|
|
8
|
+
|
|
9
|
+
cluster::cluster(const std::string & uri,
|
|
10
|
+
const std::string & user_name,
|
|
11
|
+
const std::string & user_private_key,
|
|
12
|
+
const std::string & cluster_public_key,
|
|
13
|
+
const std::string & user_security_file,
|
|
14
|
+
const std::string & cluster_public_key_file,
|
|
15
|
+
std::chrono::milliseconds timeout,
|
|
16
|
+
bool do_version_check)
|
|
17
|
+
: _uri{uri}
|
|
18
|
+
, _handle{make_handle_ptr()}
|
|
19
|
+
, _json_loads{pybind11::module::import("json").attr("loads")}
|
|
20
|
+
, _logger("quasardb.cluster")
|
|
21
|
+
{
|
|
22
|
+
if (do_version_check == true)
|
|
23
|
+
{
|
|
24
|
+
_logger.warn(
|
|
25
|
+
"do_version_check parameter has been deprecated and a no-op. It will be removed from a "
|
|
26
|
+
"future release");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
options().apply_credentials(user_name, user_private_key, cluster_public_key, //
|
|
30
|
+
user_security_file, cluster_public_key_file);
|
|
31
|
+
|
|
32
|
+
options().set_timeout(timeout);
|
|
33
|
+
|
|
34
|
+
// HACKS(leon): we need to ensure there is always one callback active
|
|
35
|
+
// for qdb. Callbacks can be lost when the last active session
|
|
36
|
+
// gets closed. As such, the most pragmatic place to 'check'
|
|
37
|
+
// for this callback is when establishing a new connection.
|
|
38
|
+
qdb::native::swap_callback();
|
|
39
|
+
|
|
40
|
+
_logger.info("Connecting to cluster %s", _uri);
|
|
41
|
+
_handle->connect(_uri);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void cluster::close()
|
|
45
|
+
{
|
|
46
|
+
_logger.info("Closing connection to cluster");
|
|
47
|
+
|
|
48
|
+
try
|
|
49
|
+
{
|
|
50
|
+
if (is_open() == true) [[likely]]
|
|
51
|
+
{
|
|
52
|
+
_handle->close();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (qdb::invalid_handle_exception const & e)
|
|
56
|
+
{
|
|
57
|
+
// This can happen if, for example, we call close() after an error occured; in those
|
|
58
|
+
// circumstances, we fully expect the connection to already be invalid, and we should
|
|
59
|
+
// not care if this specific exception is raised.
|
|
60
|
+
_logger.warn("Connection already closed");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_handle.reset();
|
|
64
|
+
|
|
65
|
+
assert(is_open() == false);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void cluster::wait_for_compaction()
|
|
69
|
+
{
|
|
70
|
+
|
|
71
|
+
// We define this function in the .cpp file so we can avoid including chrono and thread
|
|
72
|
+
// in the header file.
|
|
73
|
+
|
|
74
|
+
using namespace std::chrono_literals;
|
|
75
|
+
|
|
76
|
+
for (;;)
|
|
77
|
+
{
|
|
78
|
+
std::uint64_t progress = compact_progress();
|
|
79
|
+
|
|
80
|
+
if (progress == 0) [[unlikely]]
|
|
81
|
+
{
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::this_thread::sleep_for(100ms);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}; // namespace qdb
|
quasardb/cluster.hpp
CHANGED
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
#include <pybind11/operators.h>
|
|
58
58
|
#include <pybind11/stl.h>
|
|
59
59
|
#include <chrono>
|
|
60
|
+
#include <iostream>
|
|
60
61
|
|
|
61
62
|
namespace qdb
|
|
62
63
|
{
|
|
@@ -71,39 +72,30 @@ public:
|
|
|
71
72
|
const std::string & user_security_file = {},
|
|
72
73
|
const std::string & cluster_public_key_file = {},
|
|
73
74
|
std::chrono::milliseconds timeout = std::chrono::minutes{1},
|
|
74
|
-
bool do_version_check = false)
|
|
75
|
-
: _uri{uri}
|
|
76
|
-
, _handle{make_handle_ptr()}
|
|
77
|
-
, _json_loads{pybind11::module::import("json").attr("loads")}
|
|
78
|
-
, _logger("quasardb.cluster")
|
|
79
|
-
{
|
|
80
|
-
if (do_version_check == true)
|
|
81
|
-
{
|
|
82
|
-
_logger.warn(
|
|
83
|
-
"do_version_check parameter has been deprecated and a no-op. It will be removed from a "
|
|
84
|
-
"future release");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
options().apply_credentials(user_name, user_private_key, cluster_public_key, //
|
|
88
|
-
user_security_file, cluster_public_key_file);
|
|
75
|
+
bool do_version_check = false);
|
|
89
76
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// HACKS(leon): we need to ensure there is always one callback active
|
|
93
|
-
// for qdb. Callbacks can be lost when the last active session
|
|
94
|
-
// gets closed. As such, the most pragmatic place to 'check'
|
|
95
|
-
// for this callback is when establishing a new connection.
|
|
96
|
-
qdb::native::swap_callback();
|
|
77
|
+
public:
|
|
78
|
+
void close();
|
|
97
79
|
|
|
98
|
-
|
|
99
|
-
|
|
80
|
+
bool is_open() const
|
|
81
|
+
{
|
|
82
|
+
return _handle.get() != nullptr && _handle->is_open();
|
|
100
83
|
}
|
|
101
84
|
|
|
102
|
-
|
|
103
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Throws exception if the connection is not open. Should be invoked before any operation
|
|
87
|
+
* is done on the handle, as the QuasarDB C API only checks for a canary presence in the
|
|
88
|
+
* handle's memory arena. If a compiler is optimizing enough, the handle can be closed but
|
|
89
|
+
* the canary still present in memory, so it's UB.
|
|
90
|
+
*
|
|
91
|
+
* As such, we should check on a higher level.
|
|
92
|
+
*/
|
|
93
|
+
void check_open() const
|
|
104
94
|
{
|
|
105
|
-
|
|
106
|
-
|
|
95
|
+
if (is_open() == false) [[unlikely]]
|
|
96
|
+
{
|
|
97
|
+
throw qdb::invalid_handle_exception{};
|
|
98
|
+
}
|
|
107
99
|
}
|
|
108
100
|
|
|
109
101
|
void tidy_memory()
|
|
@@ -153,11 +145,6 @@ public:
|
|
|
153
145
|
return *this;
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
bool is_open() const
|
|
157
|
-
{
|
|
158
|
-
return _handle.get() != nullptr;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
148
|
void exit(pybind11::object type, pybind11::object value, pybind11::object traceback)
|
|
162
149
|
{
|
|
163
150
|
return close();
|
|
@@ -165,6 +152,8 @@ public:
|
|
|
165
152
|
|
|
166
153
|
pybind11::object node_config(const std::string & uri)
|
|
167
154
|
{
|
|
155
|
+
check_open();
|
|
156
|
+
|
|
168
157
|
const char * content = nullptr;
|
|
169
158
|
qdb_size_t content_length = 0;
|
|
170
159
|
|
|
@@ -176,6 +165,8 @@ public:
|
|
|
176
165
|
|
|
177
166
|
pybind11::object node_status(const std::string & uri)
|
|
178
167
|
{
|
|
168
|
+
check_open();
|
|
169
|
+
|
|
179
170
|
const char * content = nullptr;
|
|
180
171
|
qdb_size_t content_length = 0;
|
|
181
172
|
|
|
@@ -187,6 +178,8 @@ public:
|
|
|
187
178
|
|
|
188
179
|
pybind11::object node_topology(const std::string & uri)
|
|
189
180
|
{
|
|
181
|
+
check_open();
|
|
182
|
+
|
|
190
183
|
const char * content = nullptr;
|
|
191
184
|
qdb_size_t content_length = 0;
|
|
192
185
|
|
|
@@ -199,64 +192,88 @@ public:
|
|
|
199
192
|
public:
|
|
200
193
|
qdb::tag tag(const std::string & alias)
|
|
201
194
|
{
|
|
195
|
+
check_open();
|
|
196
|
+
|
|
202
197
|
return qdb::tag{_handle, alias};
|
|
203
198
|
}
|
|
204
199
|
|
|
205
200
|
qdb::blob_entry blob(const std::string & alias)
|
|
206
201
|
{
|
|
202
|
+
check_open();
|
|
203
|
+
|
|
207
204
|
return qdb::blob_entry{_handle, alias};
|
|
208
205
|
}
|
|
209
206
|
|
|
210
207
|
qdb::string_entry string(const std::string & alias)
|
|
211
208
|
{
|
|
209
|
+
check_open();
|
|
210
|
+
|
|
212
211
|
return qdb::string_entry{_handle, alias};
|
|
213
212
|
}
|
|
214
213
|
|
|
215
214
|
qdb::integer_entry integer(const std::string & alias)
|
|
216
215
|
{
|
|
216
|
+
check_open();
|
|
217
|
+
|
|
217
218
|
return qdb::integer_entry{_handle, alias};
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
qdb::double_entry double_(const std::string & alias)
|
|
221
222
|
{
|
|
223
|
+
check_open();
|
|
224
|
+
|
|
222
225
|
return qdb::double_entry{_handle, alias};
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
qdb::timestamp_entry timestamp(const std::string & alias)
|
|
226
229
|
{
|
|
230
|
+
check_open();
|
|
231
|
+
|
|
227
232
|
return qdb::timestamp_entry{_handle, alias};
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
qdb::table table(const std::string & alias)
|
|
231
236
|
{
|
|
237
|
+
check_open();
|
|
238
|
+
|
|
232
239
|
return qdb::table{_handle, alias};
|
|
233
240
|
}
|
|
234
241
|
|
|
235
242
|
// the batch_inserter_ptr is non-copyable
|
|
236
243
|
qdb::batch_inserter_ptr inserter(const std::vector<batch_column_info> & ci)
|
|
237
244
|
{
|
|
245
|
+
check_open();
|
|
246
|
+
|
|
238
247
|
return std::make_unique<qdb::batch_inserter>(_handle, ci);
|
|
239
248
|
}
|
|
240
249
|
|
|
241
250
|
// the batch_inserter_ptr is non-copyable
|
|
242
251
|
qdb::writer_ptr writer()
|
|
243
252
|
{
|
|
253
|
+
check_open();
|
|
254
|
+
|
|
244
255
|
return std::make_unique<qdb::writer>(_handle);
|
|
245
256
|
}
|
|
246
257
|
|
|
247
258
|
// the batch_inserter_ptr is non-copyable
|
|
248
259
|
qdb::writer_ptr pinned_writer()
|
|
249
260
|
{
|
|
261
|
+
check_open();
|
|
262
|
+
|
|
250
263
|
return writer();
|
|
251
264
|
}
|
|
252
265
|
|
|
253
266
|
qdb::options options()
|
|
254
267
|
{
|
|
268
|
+
check_open();
|
|
269
|
+
|
|
255
270
|
return qdb::options{_handle};
|
|
256
271
|
}
|
|
257
272
|
|
|
258
273
|
qdb::perf perf()
|
|
259
274
|
{
|
|
275
|
+
check_open();
|
|
276
|
+
|
|
260
277
|
return qdb::perf{_handle};
|
|
261
278
|
}
|
|
262
279
|
|
|
@@ -268,6 +285,8 @@ public:
|
|
|
268
285
|
public:
|
|
269
286
|
std::vector<std::string> prefix_get(const std::string & prefix, qdb_int_t max_count)
|
|
270
287
|
{
|
|
288
|
+
check_open();
|
|
289
|
+
|
|
271
290
|
const char ** result = nullptr;
|
|
272
291
|
size_t count = 0;
|
|
273
292
|
|
|
@@ -283,6 +302,8 @@ public:
|
|
|
283
302
|
|
|
284
303
|
qdb_uint_t prefix_count(const std::string & prefix)
|
|
285
304
|
{
|
|
305
|
+
check_open();
|
|
306
|
+
|
|
286
307
|
qdb_uint_t count = 0;
|
|
287
308
|
|
|
288
309
|
const qdb_error_t err = qdb_prefix_count(*_handle, prefix.c_str(), &count);
|
|
@@ -294,22 +315,30 @@ public:
|
|
|
294
315
|
public:
|
|
295
316
|
qdb::find_query find(const std::string & query_string)
|
|
296
317
|
{
|
|
318
|
+
check_open();
|
|
319
|
+
|
|
297
320
|
return qdb::find_query{_handle, query_string};
|
|
298
321
|
}
|
|
299
322
|
|
|
300
323
|
py::object query(const std::string & query_string, const py::object & blobs)
|
|
301
324
|
{
|
|
325
|
+
check_open();
|
|
326
|
+
|
|
302
327
|
return py::cast(qdb::dict_query(_handle, query_string, blobs));
|
|
303
328
|
}
|
|
304
329
|
|
|
305
330
|
py::object query_numpy(const std::string & query_string)
|
|
306
331
|
{
|
|
332
|
+
check_open();
|
|
333
|
+
|
|
307
334
|
return py::cast(qdb::numpy_query(_handle, query_string));
|
|
308
335
|
}
|
|
309
336
|
|
|
310
337
|
std::shared_ptr<qdb::query_continuous> query_continuous_full(
|
|
311
338
|
const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
|
|
312
339
|
{
|
|
340
|
+
check_open();
|
|
341
|
+
|
|
313
342
|
return std::make_shared<qdb::query_continuous>(
|
|
314
343
|
_handle, qdb_query_continuous_full, pace, query_string, blobs);
|
|
315
344
|
}
|
|
@@ -317,6 +346,8 @@ public:
|
|
|
317
346
|
std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
|
|
318
347
|
const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
|
|
319
348
|
{
|
|
349
|
+
check_open();
|
|
350
|
+
|
|
320
351
|
return std::make_shared<qdb::query_continuous>(
|
|
321
352
|
_handle, qdb_query_continuous_new_values_only, pace, query_string, blobs);
|
|
322
353
|
}
|
|
@@ -324,6 +355,8 @@ public:
|
|
|
324
355
|
public:
|
|
325
356
|
std::vector<std::string> suffix_get(const std::string & suffix, qdb_int_t max_count)
|
|
326
357
|
{
|
|
358
|
+
check_open();
|
|
359
|
+
|
|
327
360
|
const char ** result = nullptr;
|
|
328
361
|
size_t count = 0;
|
|
329
362
|
|
|
@@ -339,6 +372,8 @@ public:
|
|
|
339
372
|
|
|
340
373
|
qdb_uint_t suffix_count(const std::string & suffix)
|
|
341
374
|
{
|
|
375
|
+
check_open();
|
|
376
|
+
|
|
342
377
|
qdb_uint_t count = 0;
|
|
343
378
|
|
|
344
379
|
const qdb_error_t err = qdb_suffix_count(*_handle, suffix.c_str(), &count);
|
|
@@ -350,31 +385,72 @@ public:
|
|
|
350
385
|
public:
|
|
351
386
|
void purge_all(std::chrono::milliseconds timeout_ms)
|
|
352
387
|
{
|
|
388
|
+
check_open();
|
|
389
|
+
|
|
353
390
|
qdb::qdb_throw_if_error(
|
|
354
391
|
*_handle, qdb_purge_all(*_handle, static_cast<int>(timeout_ms.count())));
|
|
355
392
|
}
|
|
356
393
|
|
|
357
394
|
void purge_cache(std::chrono::milliseconds timeout_ms)
|
|
358
395
|
{
|
|
396
|
+
check_open();
|
|
397
|
+
|
|
359
398
|
qdb::qdb_throw_if_error(
|
|
360
399
|
*_handle, qdb_purge_cache(*_handle, static_cast<int>(timeout_ms.count())));
|
|
361
400
|
}
|
|
362
401
|
|
|
363
402
|
void wait_for_stabilization(std::chrono::milliseconds timeout_ms)
|
|
364
403
|
{
|
|
404
|
+
check_open();
|
|
405
|
+
|
|
365
406
|
qdb::qdb_throw_if_error(
|
|
366
407
|
*_handle, qdb_wait_for_stabilization(*_handle, static_cast<int>(timeout_ms.count())));
|
|
367
408
|
}
|
|
368
409
|
|
|
369
410
|
void trim_all(std::chrono::milliseconds pause_ms, std::chrono::milliseconds timeout_ms)
|
|
370
411
|
{
|
|
412
|
+
check_open();
|
|
413
|
+
|
|
371
414
|
qdb::qdb_throw_if_error(*_handle, qdb_trim_all(*_handle, static_cast<int>(pause_ms.count()),
|
|
372
415
|
static_cast<int>(timeout_ms.count())));
|
|
373
416
|
}
|
|
374
417
|
|
|
418
|
+
void compact_full()
|
|
419
|
+
{
|
|
420
|
+
check_open();
|
|
421
|
+
|
|
422
|
+
qdb_compact_params_t params{};
|
|
423
|
+
params.options = qdb_compact_full;
|
|
424
|
+
|
|
425
|
+
qdb::qdb_throw_if_error(*_handle, qdb_cluster_compact(*_handle, ¶ms));
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Returns 0 when finished / no compaction running
|
|
429
|
+
std::uint64_t compact_progress()
|
|
430
|
+
{
|
|
431
|
+
check_open();
|
|
432
|
+
|
|
433
|
+
std::uint64_t progress;
|
|
434
|
+
|
|
435
|
+
qdb::qdb_throw_if_error(*_handle, qdb_cluster_get_compact_progress(*_handle, &progress));
|
|
436
|
+
|
|
437
|
+
return progress;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
void compact_abort()
|
|
441
|
+
{
|
|
442
|
+
check_open();
|
|
443
|
+
|
|
444
|
+
qdb::qdb_throw_if_error(*_handle, qdb_cluster_abort_compact(*_handle));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
void wait_for_compaction();
|
|
448
|
+
|
|
375
449
|
public:
|
|
376
450
|
std::vector<std::string> endpoints()
|
|
377
451
|
{
|
|
452
|
+
check_open();
|
|
453
|
+
|
|
378
454
|
qdb_remote_node_t * endpoints = nullptr;
|
|
379
455
|
qdb_size_t count = 0;
|
|
380
456
|
|
|
@@ -465,6 +541,10 @@ static inline void register_cluster(Module & m)
|
|
|
465
541
|
.def("purge_all", &qdb::cluster::purge_all) //
|
|
466
542
|
.def("trim_all", &qdb::cluster::trim_all) //
|
|
467
543
|
.def("purge_cache", &qdb::cluster::purge_cache) //
|
|
544
|
+
.def("compact_full", &qdb::cluster::compact_full) //
|
|
545
|
+
.def("compact_progress", &qdb::cluster::compact_progress) //
|
|
546
|
+
.def("compact_abort", &qdb::cluster::compact_abort) //
|
|
547
|
+
.def("wait_for_compaction", &qdb::cluster::wait_for_compaction) //
|
|
468
548
|
.def("endpoints", &qdb::cluster::endpoints); //
|
|
469
549
|
}
|
|
470
550
|
|
quasardb/cmake_install.cmake
CHANGED
|
@@ -34,7 +34,7 @@ endif()
|
|
|
34
34
|
|
|
35
35
|
# Set default install directory permissions.
|
|
36
36
|
if(NOT DEFINED CMAKE_OBJDUMP)
|
|
37
|
-
set(CMAKE_OBJDUMP "/
|
|
37
|
+
set(CMAKE_OBJDUMP "/usr/local/clang16/bin/llvm-objdump")
|
|
38
38
|
endif()
|
|
39
39
|
|
|
40
40
|
if(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
|
@@ -34,7 +34,7 @@ endif()
|
|
|
34
34
|
|
|
35
35
|
# Set default install directory permissions.
|
|
36
36
|
if(NOT DEFINED CMAKE_OBJDUMP)
|
|
37
|
-
set(CMAKE_OBJDUMP "/
|
|
37
|
+
set(CMAKE_OBJDUMP "/usr/local/clang16/bin/llvm-objdump")
|
|
38
38
|
endif()
|
|
39
39
|
|
|
40
40
|
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
|
quasardb/error.hpp
CHANGED
|
@@ -78,6 +78,17 @@ public:
|
|
|
78
78
|
{}
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
+
class invalid_handle_exception : public exception
|
|
82
|
+
{
|
|
83
|
+
public:
|
|
84
|
+
invalid_handle_exception() noexcept
|
|
85
|
+
: exception(qdb_e_invalid_handle,
|
|
86
|
+
std::string("Invalid handle: the connection to the cluster has been closed. Please "
|
|
87
|
+
"re-establish a new connection"
|
|
88
|
+
"with the QuasarDB cluster."))
|
|
89
|
+
{}
|
|
90
|
+
};
|
|
91
|
+
|
|
81
92
|
class incompatible_type_exception : public exception
|
|
82
93
|
{
|
|
83
94
|
public:
|
|
@@ -218,7 +229,15 @@ inline void qdb_throw_if_error(
|
|
|
218
229
|
{
|
|
219
230
|
// Error context returned is not the same, which means this thread already made
|
|
220
231
|
// another call to the QDB API, or the QDB API itself
|
|
221
|
-
|
|
232
|
+
|
|
233
|
+
switch (err)
|
|
234
|
+
{
|
|
235
|
+
case qdb_e_not_connected:
|
|
236
|
+
case qdb_e_invalid_handle:
|
|
237
|
+
throw qdb::invalid_handle_exception{};
|
|
238
|
+
default:
|
|
239
|
+
throw qdb::exception{err, qdb_error(err)};
|
|
240
|
+
}
|
|
222
241
|
}
|
|
223
242
|
assert(err_ == err);
|
|
224
243
|
assert(msg_ != nullptr);
|
|
@@ -233,6 +252,10 @@ inline void qdb_throw_if_error(
|
|
|
233
252
|
case qdb_e_invalid_query:
|
|
234
253
|
throw qdb::invalid_query_exception{msg_data_};
|
|
235
254
|
|
|
255
|
+
case qdb_e_not_connected:
|
|
256
|
+
case qdb_e_invalid_handle:
|
|
257
|
+
throw qdb::invalid_handle_exception{};
|
|
258
|
+
|
|
236
259
|
case qdb_e_alias_already_exists:
|
|
237
260
|
throw qdb::alias_already_exists_exception{msg_data_};
|
|
238
261
|
|
|
@@ -289,6 +312,7 @@ static inline void register_errors(Module & m)
|
|
|
289
312
|
py::register_exception<qdb::internal_local_exception>(m, "InternalLocalError", base_class);
|
|
290
313
|
py::register_exception<qdb::invalid_argument_exception>(m, "InvalidArgumentError", base_class);
|
|
291
314
|
py::register_exception<qdb::invalid_query_exception>(m, "InvalidQueryError", base_class);
|
|
315
|
+
py::register_exception<qdb::invalid_handle_exception>(m, "InvalidHandleError", base_class);
|
|
292
316
|
}
|
|
293
317
|
|
|
294
318
|
} // namespace qdb
|
quasardb/handle.cpp
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#include "handle.hpp"
|
|
2
|
+
#include "metrics.hpp"
|
|
3
|
+
|
|
4
|
+
namespace qdb
|
|
5
|
+
{
|
|
6
|
+
|
|
7
|
+
void handle::connect(const std::string & uri)
|
|
8
|
+
{
|
|
9
|
+
qdb_error_t err;
|
|
10
|
+
{
|
|
11
|
+
metrics::scoped_capture{"qdb_connect"};
|
|
12
|
+
err = qdb_connect(handle_, uri.c_str());
|
|
13
|
+
}
|
|
14
|
+
qdb::qdb_throw_if_error(handle_, err);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void handle::close()
|
|
18
|
+
{
|
|
19
|
+
if (handle_ != nullptr)
|
|
20
|
+
{
|
|
21
|
+
metrics::scoped_capture{"qdb_close"};
|
|
22
|
+
qdb_close(handle_);
|
|
23
|
+
handle_ = nullptr;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
assert(handle_ == nullptr);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}; // namespace qdb
|
quasardb/handle.hpp
CHANGED
|
@@ -42,33 +42,50 @@ class handle
|
|
|
42
42
|
{
|
|
43
43
|
public:
|
|
44
44
|
handle() noexcept
|
|
45
|
+
: handle_{nullptr}
|
|
45
46
|
{}
|
|
46
47
|
|
|
47
48
|
explicit handle(qdb_handle_t h) noexcept
|
|
48
|
-
:
|
|
49
|
+
: handle_{h}
|
|
49
50
|
{}
|
|
50
51
|
|
|
51
52
|
~handle()
|
|
52
53
|
{
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
qdb_close(_handle);
|
|
56
|
-
_handle = nullptr;
|
|
57
|
-
}
|
|
54
|
+
close();
|
|
58
55
|
}
|
|
59
56
|
|
|
60
|
-
void connect(const std::string & uri)
|
|
57
|
+
void connect(const std::string & uri);
|
|
58
|
+
|
|
59
|
+
operator qdb_handle_t() const noexcept
|
|
61
60
|
{
|
|
62
|
-
|
|
61
|
+
return handle_;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
void close();
|
|
65
|
+
|
|
66
|
+
constexpr inline bool is_open() const
|
|
66
67
|
{
|
|
67
|
-
return
|
|
68
|
+
return handle_ != nullptr;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Throws exception if the connection is not open. Should be invoked before any operation
|
|
73
|
+
* is done on the handle, as the QuasarDB C API only checks for a canary presence in the
|
|
74
|
+
* handle's memory arena. If a compiler is optimizing enough, the handle can be closed but
|
|
75
|
+
* the canary still present in memory, so it's UB.
|
|
76
|
+
*
|
|
77
|
+
* As such, we should check on a higher level.
|
|
78
|
+
*/
|
|
79
|
+
inline void check_open() const
|
|
80
|
+
{
|
|
81
|
+
if (is_open() == false) [[unlikely]]
|
|
82
|
+
{
|
|
83
|
+
throw qdb::invalid_handle_exception{};
|
|
84
|
+
}
|
|
68
85
|
}
|
|
69
86
|
|
|
70
87
|
private:
|
|
71
|
-
qdb_handle_t
|
|
88
|
+
qdb_handle_t handle_{nullptr};
|
|
72
89
|
};
|
|
73
90
|
|
|
74
91
|
using handle_ptr = std::shared_ptr<handle>;
|
quasardb/libqdb_api.dylib
CHANGED
|
Binary file
|
quasardb/logger.cpp
CHANGED
|
@@ -11,6 +11,8 @@ void qdb::native::swap_callback()
|
|
|
11
11
|
{
|
|
12
12
|
// Potential race condition avoidance!
|
|
13
13
|
std::lock_guard<std::mutex> guard(_buffer_lock);
|
|
14
|
+
|
|
15
|
+
#ifndef NDEBUG
|
|
14
16
|
qdb_error_t error;
|
|
15
17
|
|
|
16
18
|
error = qdb_log_remove_callback(local_callback_id);
|
|
@@ -26,6 +28,7 @@ void qdb::native::swap_callback()
|
|
|
26
28
|
// fprintf(stderr, "unable to add new callback: %s (%#x)\n", qdb_error(error), error);
|
|
27
29
|
// fflush(stderr);
|
|
28
30
|
}
|
|
31
|
+
#endif
|
|
29
32
|
|
|
30
33
|
_logger = qdb::logger("quasardb.native");
|
|
31
34
|
}
|