quasardb 3.14.2.dev1__cp310-cp310-win32.whl → 3.14.2.dev2__cp310-cp310-win32.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.

Files changed (58) hide show
  1. quasardb/CMakeLists.txt +19 -12
  2. quasardb/INSTALL.vcxproj +4 -0
  3. quasardb/__init__.py +33 -4
  4. quasardb/cluster.cpp +7 -1
  5. quasardb/cluster.hpp +111 -72
  6. quasardb/concepts.hpp +56 -12
  7. quasardb/continuous.cpp +84 -34
  8. quasardb/continuous.hpp +10 -7
  9. quasardb/convert/array.hpp +23 -6
  10. quasardb/convert/value.hpp +78 -7
  11. quasardb/date/ALL_BUILD.vcxproj +4 -4
  12. quasardb/date/CMakeFiles/Export/df49adab93b9e0c10c64f72458b31971/dateTargets.cmake +12 -12
  13. quasardb/date/CMakeFiles/generate.stamp.depend +4 -4
  14. quasardb/date/INSTALL.vcxproj +4 -0
  15. quasardb/date/dateConfigVersion.cmake +0 -5
  16. quasardb/date/dateTargets.cmake +3 -7
  17. quasardb/detail/invoke.hpp +0 -0
  18. quasardb/detail/retry.cpp +30 -0
  19. quasardb/detail/retry.hpp +147 -0
  20. quasardb/detail/sleep.hpp +53 -0
  21. quasardb/{writer.cpp → detail/writer.cpp} +68 -162
  22. quasardb/detail/writer.hpp +550 -0
  23. quasardb/error.hpp +76 -1
  24. quasardb/masked_array.hpp +9 -2
  25. quasardb/module.cpp +20 -4
  26. quasardb/numpy/__init__.py +58 -10
  27. quasardb/object_tracker.hpp +2 -3
  28. quasardb/options.hpp +32 -3
  29. quasardb/pandas/__init__.py +59 -102
  30. quasardb/properties.cpp +41 -0
  31. quasardb/properties.hpp +85 -0
  32. quasardb/pybind11/ALL_BUILD.vcxproj +4 -4
  33. quasardb/pybind11/CMakeFiles/generate.stamp.depend +14 -14
  34. quasardb/pybind11/INSTALL.vcxproj +4 -0
  35. quasardb/qdb_api.dll +0 -0
  36. quasardb/quasardb.cp310-win32.pyd +0 -0
  37. quasardb/range-v3/ALL_BUILD.vcxproj +4 -4
  38. quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +12 -12
  39. quasardb/range-v3/CMakeFiles/generate.stamp.depend +11 -11
  40. quasardb/range-v3/INSTALL.vcxproj +4 -0
  41. quasardb/range-v3/cmake_install.cmake +36 -0
  42. quasardb/range-v3/range-v3-config-version.cmake +0 -5
  43. quasardb/range-v3/range-v3-config.cmake +3 -7
  44. quasardb/range-v3/range.v3.headers.vcxproj +4 -4
  45. quasardb/reader.cpp +282 -0
  46. quasardb/reader.hpp +256 -0
  47. quasardb/table.cpp +4 -36
  48. quasardb/table.hpp +69 -28
  49. quasardb/traits.hpp +23 -0
  50. quasardb/writer.hpp +245 -287
  51. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev2.dist-info}/METADATA +7 -7
  52. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev2.dist-info}/RECORD +55 -49
  53. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev2.dist-info}/WHEEL +1 -1
  54. quasardb/reader/ts_row.hpp +0 -281
  55. quasardb/reader/ts_value.hpp +0 -245
  56. quasardb/table_reader.hpp +0 -220
  57. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev2.dist-info}/LICENSE.md +0 -0
  58. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev2.dist-info}/top_level.txt +0 -0
quasardb/CMakeLists.txt CHANGED
@@ -223,12 +223,6 @@ elseif (MSVC)
223
223
 
224
224
 
225
225
  )
226
- if(QDB_CPU_IS_X86)
227
- add_compile_options(
228
- # Enable AVX as we target Core2 and later
229
- /arch:AVX
230
- )
231
- endif()
232
226
  endif()
233
227
 
234
228
  ###
@@ -357,23 +351,29 @@ set(QDB_FILES
357
351
  numpy.cpp
358
352
  object_tracker.hpp
359
353
  options.hpp
354
+ properties.cpp
355
+ properties.hpp
360
356
  query.hpp
361
357
  query.cpp
358
+ reader.cpp
359
+ reader.hpp
362
360
  string.hpp
363
361
  table.cpp
364
362
  table.hpp
365
- table_reader.hpp
366
363
  tag.hpp
367
364
  timestamp.hpp
368
365
  traits.hpp
369
366
  utils.cpp
370
367
  utils.hpp
371
- writer.cpp
372
368
  writer.hpp
369
+ detail/invoke.hpp
370
+ detail/retry.hpp
371
+ detail/retry.cpp
372
+ detail/sleep.hpp
373
373
  detail/qdb_resource.hpp
374
374
  detail/ts_column.hpp
375
- reader/ts_row.hpp
376
- reader/ts_value.hpp
375
+ detail/writer.cpp
376
+ detail/writer.hpp
377
377
  utils/blob_deque.hpp
378
378
  utils/ostream.hpp
379
379
  utils/permutation.hpp
@@ -387,11 +387,18 @@ if(QDB_TESTS_ENABLED)
387
387
  ------------------------------------------------------------------ \
388
388
  [qdb-api-python] Tests enabled -- do not enable for release builds \
389
389
  ------------------------------------------------------------------ \ ")
390
- set(QDB_TEST_FILES
391
390
 
391
+ add_compile_definitions(QDB_TESTS_ENABLED)
392
+
393
+ set(QDB_TEST_FILES
392
394
  ../tests/conftest.cpp
393
395
  ../tests/conftest.hpp
394
- ../tests/test_convert.cpp)
396
+ ../tests/test_convert.cpp
397
+
398
+ ../tests/detail/mock_failure.hpp
399
+ ../tests/detail/mock_failure.cpp
400
+ ../tests/detail/sleep.hpp
401
+ )
395
402
  endif()
396
403
 
397
404
  # step 3: build
quasardb/INSTALL.vcxproj CHANGED
@@ -126,6 +126,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
126
126
  </ItemDefinitionGroup>
127
127
  <ItemGroup>
128
128
  <CustomBuild Include="C:\TeamCity\work\938b0bdf6727d1ad\build\temp.win32-cpython-310\Release\CMakeFiles\2f5138c6189df16b6f2b038f022b1220\INSTALL_force.rule">
129
+ <BuildInParallel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BuildInParallel>
129
130
  <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> </Message>
130
131
  <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">setlocal
131
132
  cd .
@@ -140,6 +141,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
140
141
  <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\TeamCity\work\938b0bdf6727d1ad\build\lib.win32-cpython-310\quasardb\CMakeFiles\INSTALL_force</Outputs>
141
142
  <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
142
143
  <VerifyInputsAndOutputsExist Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</VerifyInputsAndOutputsExist>
144
+ <BuildInParallel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BuildInParallel>
143
145
  <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> </Message>
144
146
  <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">setlocal
145
147
  cd .
@@ -154,6 +156,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
154
156
  <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\TeamCity\work\938b0bdf6727d1ad\build\lib.win32-cpython-310\quasardb\CMakeFiles\INSTALL_force</Outputs>
155
157
  <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
156
158
  <VerifyInputsAndOutputsExist Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</VerifyInputsAndOutputsExist>
159
+ <BuildInParallel Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">true</BuildInParallel>
157
160
  <Message Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'"> </Message>
158
161
  <Command Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">setlocal
159
162
  cd .
@@ -168,6 +171,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
168
171
  <Outputs Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">C:\TeamCity\work\938b0bdf6727d1ad\build\lib.win32-cpython-310\quasardb\CMakeFiles\INSTALL_force</Outputs>
169
172
  <LinkObjects Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">false</LinkObjects>
170
173
  <VerifyInputsAndOutputsExist Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">false</VerifyInputsAndOutputsExist>
174
+ <BuildInParallel Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">true</BuildInParallel>
171
175
  <Message Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'"> </Message>
172
176
  <Command Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">setlocal
173
177
  cd .
quasardb/__init__.py CHANGED
@@ -35,9 +35,19 @@
35
35
  .. moduleauthor: quasardb SAS. All rights reserved
36
36
  """
37
37
 
38
- def generic_error_msg(msg, e):
38
+ def generic_error_msg(msg, e = None):
39
39
  msg_str = "\n".join(msg)
40
- return """
40
+
41
+ if e is None:
42
+ return """
43
+ **************************************************************************
44
+
45
+ {}
46
+
47
+ **************************************************************************
48
+ """.format(msg_str, type(e), str(e))
49
+ else:
50
+ return """
41
51
  **************************************************************************
42
52
 
43
53
  {}
@@ -46,8 +56,8 @@ def generic_error_msg(msg, e):
46
56
 
47
57
  Original exception:
48
58
 
49
- Type: {}
50
- Message: {}
59
+ Type: {}
60
+ Message: {}
51
61
 
52
62
  **************************************************************************
53
63
  """.format(msg_str, type(e), str(e))
@@ -79,9 +89,23 @@ def glibc_error_msg(e):
79
89
 
80
90
  return generic_error_msg(msg, e)
81
91
 
92
+ def unknown_error_msg():
93
+ msg = [
94
+ "Unable to import quasardb module: unknown error. ",
95
+ "",
96
+ "This may have several causes, including, but not limited to: ",
97
+ " - a link error, ",
98
+ " - architecture mismatch, ",
99
+ " - the current working directory already contains a 'quasardb' subdirectory.",
100
+ "",
101
+ "If you believe this to be a bug, please reach out to QuasarDB at",
102
+ "support@quasar.ai"]
103
+
104
+ return generic_error_msg(msg)
82
105
  try:
83
106
  from quasardb.quasardb import *
84
107
  except BaseException as e:
108
+ print(e)
85
109
  if "undefined symbol" in str(e):
86
110
  print(link_error_msg(e))
87
111
  raise e
@@ -90,5 +114,10 @@ except BaseException as e:
90
114
  else:
91
115
  from quasardb import *
92
116
 
117
+ if not 'quasardb' in locals():
118
+ print(unknown_error_msg())
119
+ raise ImportError()
120
+
121
+
93
122
  from .extensions import extend_module
94
123
  extend_module(quasardb)
quasardb/cluster.cpp CHANGED
@@ -13,7 +13,8 @@ cluster::cluster(const std::string & uri,
13
13
  const std::string & user_security_file,
14
14
  const std::string & cluster_public_key_file,
15
15
  std::chrono::milliseconds timeout,
16
- bool do_version_check)
16
+ bool do_version_check,
17
+ std::size_t client_max_parallelism)
17
18
  : _uri{uri}
18
19
  , _handle{make_handle_ptr()}
19
20
  , _json_loads{pybind11::module::import("json").attr("loads")}
@@ -31,6 +32,11 @@ cluster::cluster(const std::string & uri,
31
32
 
32
33
  options().set_timeout(timeout);
33
34
 
35
+ if (client_max_parallelism != 0)
36
+ {
37
+ options().set_client_max_parallelism(client_max_parallelism);
38
+ }
39
+
34
40
  // HACKS(leon): we need to ensure there is always one callback active
35
41
  // for qdb. Callbacks can be lost when the last active session
36
42
  // gets closed. As such, the most pragmatic place to 'check'
quasardb/cluster.hpp CHANGED
@@ -41,10 +41,11 @@
41
41
  #include "node.hpp"
42
42
  #include "options.hpp"
43
43
  #include "perf.hpp"
44
+ #include "properties.hpp"
44
45
  #include "query.hpp"
46
+ #include "reader.hpp"
45
47
  #include "string.hpp"
46
48
  #include "table.hpp"
47
- #include "table_reader.hpp"
48
49
  #include "tag.hpp"
49
50
  #include "timestamp.hpp"
50
51
  #include "utils.hpp"
@@ -72,7 +73,8 @@ public:
72
73
  const std::string & user_security_file = {},
73
74
  const std::string & cluster_public_key_file = {},
74
75
  std::chrono::milliseconds timeout = std::chrono::minutes{1},
75
- bool do_version_check = false);
76
+ bool do_version_check = false,
77
+ std::size_t client_max_parallelism = 0);
76
78
 
77
79
  public:
78
80
  void close();
@@ -239,6 +241,18 @@ public:
239
241
  return qdb::table{_handle, alias};
240
242
  }
241
243
 
244
+ // the reader_ptr is non-copyable
245
+ qdb::reader_ptr reader( //
246
+ std::vector<std::string> const & table_names, //
247
+ std::vector<std::string> const & column_names, //
248
+ std::size_t batch_size, //
249
+ std::vector<py::tuple> const & ranges) //
250
+ {
251
+ check_open();
252
+
253
+ return std::make_unique<qdb::reader>(_handle, table_names, column_names, batch_size, ranges);
254
+ }
255
+
242
256
  // the batch_inserter_ptr is non-copyable
243
257
  qdb::batch_inserter_ptr inserter(const std::vector<batch_column_info> & ci)
244
258
  {
@@ -270,6 +284,13 @@ public:
270
284
  return qdb::options{_handle};
271
285
  }
272
286
 
287
+ qdb::properties properties()
288
+ {
289
+ check_open();
290
+
291
+ return qdb::properties{_handle};
292
+ }
293
+
273
294
  qdb::perf perf()
274
295
  {
275
296
  check_open();
@@ -334,22 +355,30 @@ public:
334
355
  return py::cast(qdb::numpy_query(_handle, query_string));
335
356
  }
336
357
 
337
- std::shared_ptr<qdb::query_continuous> query_continuous_full(
338
- const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
358
+ std::shared_ptr<qdb::query_continuous> query_continuous(qdb_query_continuous_mode_type_t mode,
359
+ const std::string & query_string,
360
+ std::chrono::milliseconds pace,
361
+ const py::object & blobs)
339
362
  {
340
363
  check_open();
341
364
 
342
- return std::make_shared<qdb::query_continuous>(
343
- _handle, qdb_query_continuous_full, pace, query_string, blobs);
365
+ auto o = std::make_shared<qdb::query_continuous>(_handle, blobs);
366
+
367
+ o->run(mode, pace, query_string);
368
+
369
+ return o;
344
370
  }
345
371
 
346
- std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
372
+ std::shared_ptr<qdb::query_continuous> query_continuous_full(
347
373
  const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
348
374
  {
349
- check_open();
375
+ return query_continuous(qdb_query_continuous_full, query_string, pace, blobs);
376
+ }
350
377
 
351
- return std::make_shared<qdb::query_continuous>(
352
- _handle, qdb_query_continuous_new_values_only, pace, query_string, blobs);
378
+ std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
379
+ const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
380
+ {
381
+ return query_continuous(qdb_query_continuous_new_values_only, query_string, pace, blobs);
353
382
  }
354
383
 
355
384
  public:
@@ -484,68 +513,78 @@ static inline void register_cluster(Module & m)
484
513
 
485
514
  py::class_<qdb::cluster>(m, "Cluster",
486
515
  "Represents a connection to the QuasarDB cluster. ") //
487
- .def(
488
- py::init<const std::string &, const std::string &, const std::string &, const std::string &,
489
- const std::string &, const std::string &, std::chrono::milliseconds, bool>(), //
490
- py::arg("uri"), //
491
- py::arg("user_name") = std::string{}, //
492
- py::arg("user_private_key") = std::string{}, //
493
- py::arg("cluster_public_key") = std::string{}, //
494
- py::arg("user_security_file") = std::string{}, //
495
- py::arg("cluster_public_key_file") = std::string{}, //
496
- py::arg("timeout") = std::chrono::minutes{1}, //
497
- py::arg("do_version_check") = false) //
498
- .def("__enter__", &qdb::cluster::enter) //
499
- .def("__exit__", &qdb::cluster::exit) //
500
- .def("tidy_memory", &qdb::cluster::tidy_memory) //
501
- .def("get_memory_info", &qdb::cluster::get_memory_info) //
502
- .def("is_open", &qdb::cluster::is_open) //
503
- .def("uri", &qdb::cluster::uri) //
504
- .def("node", &qdb::cluster::node) //
505
- .def("options", &qdb::cluster::options) //
506
- .def("perf", &qdb::cluster::perf) //
507
- .def("node_status", &qdb::cluster::node_status) //
508
- .def("node_config", &qdb::cluster::node_config) //
509
- .def("node_topology", &qdb::cluster::node_topology) //
510
- .def("tag", &qdb::cluster::tag) //
511
- .def("blob", &qdb::cluster::blob) //
512
- .def("string", &qdb::cluster::string) //
513
- .def("integer", &qdb::cluster::integer) //
514
- .def("double", &qdb::cluster::double_) //
515
- .def("timestamp", &qdb::cluster::timestamp) //
516
- .def("ts", &qdb::cluster::table) //
517
- .def("table", &qdb::cluster::table) //
518
- .def("ts_batch", &qdb::cluster::inserter) //
519
- .def("inserter", &qdb::cluster::inserter) //
520
- .def("pinned_writer", &qdb::cluster::pinned_writer) //
521
- .def("writer", &qdb::cluster::writer) //
522
- .def("find", &qdb::cluster::find) //
523
- .def("query", &qdb::cluster::query, //
524
- py::arg("query"), //
525
- py::arg("blobs") = false) //
526
- .def("query_numpy", &qdb::cluster::query_numpy, //
527
- py::arg("query")) //
528
- .def("query_continuous_full", &qdb::cluster::query_continuous_full, //
529
- py::arg("query"), //
530
- py::arg("pace"), //
531
- py::arg("blobs") = false) //
532
- .def("query_continuous_new_values", &qdb::cluster::query_continuous_new_values, //
533
- py::arg("query"), //
534
- py::arg("pace"), //
535
- py::arg("blobs") = false) //
536
- .def("prefix_get", &qdb::cluster::prefix_get) //
537
- .def("prefix_count", &qdb::cluster::prefix_count) //
538
- .def("suffix_get", &qdb::cluster::suffix_get) //
539
- .def("suffix_count", &qdb::cluster::suffix_count) //
540
- .def("close", &qdb::cluster::close) //
541
- .def("purge_all", &qdb::cluster::purge_all) //
542
- .def("trim_all", &qdb::cluster::trim_all) //
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) //
548
- .def("endpoints", &qdb::cluster::endpoints); //
516
+ .def(py::init<const std::string &, const std::string &, const std::string &,
517
+ const std::string &, const std::string &, const std::string &,
518
+ std::chrono::milliseconds, bool, std::size_t>(), //
519
+ py::arg("uri"), //
520
+ py::arg("user_name") = std::string{}, //
521
+ py::arg("user_private_key") = std::string{}, //
522
+ py::arg("cluster_public_key") = std::string{}, //
523
+ py::arg("user_security_file") = std::string{}, //
524
+ py::arg("cluster_public_key_file") = std::string{}, //
525
+ py::arg("timeout") = std::chrono::minutes{1}, //
526
+ py::arg("do_version_check") = false, //
527
+ py::arg("client_max_parallelism") = std::size_t{0} //
528
+ ) //
529
+ .def("__enter__", &qdb::cluster::enter) //
530
+ .def("__exit__", &qdb::cluster::exit) //
531
+ .def("tidy_memory", &qdb::cluster::tidy_memory) //
532
+ .def("get_memory_info", &qdb::cluster::get_memory_info) //
533
+ .def("is_open", &qdb::cluster::is_open) //
534
+ .def("uri", &qdb::cluster::uri) //
535
+ .def("node", &qdb::cluster::node) //
536
+ .def("options", &qdb::cluster::options) //
537
+ .def("properties", &qdb::cluster::properties) //
538
+ .def("perf", &qdb::cluster::perf) //
539
+ .def("node_status", &qdb::cluster::node_status) //
540
+ .def("node_config", &qdb::cluster::node_config) //
541
+ .def("node_topology", &qdb::cluster::node_topology) //
542
+ .def("tag", &qdb::cluster::tag) //
543
+ .def("blob", &qdb::cluster::blob) //
544
+ .def("string", &qdb::cluster::string) //
545
+ .def("integer", &qdb::cluster::integer) //
546
+ .def("double", &qdb::cluster::double_) //
547
+ .def("timestamp", &qdb::cluster::timestamp) //
548
+ .def("ts", &qdb::cluster::table) //
549
+ .def("table", &qdb::cluster::table) //
550
+ .def("ts_batch", &qdb::cluster::inserter) //
551
+ .def("inserter", &qdb::cluster::inserter) //
552
+ .def("reader", &qdb::cluster::reader, //
553
+ py::arg("table_names"), //
554
+ py::kw_only(), //
555
+ py::arg("column_names") = std::vector<std::string>{}, //
556
+ py::arg("batch_size") = std::size_t{0}, //
557
+ py::arg("ranges") = std::vector<py::tuple>{} //
558
+ ) //
559
+ .def("pinned_writer", &qdb::cluster::pinned_writer) //
560
+ .def("writer", &qdb::cluster::writer) //
561
+ .def("find", &qdb::cluster::find) //
562
+ .def("query", &qdb::cluster::query, //
563
+ py::arg("query"), //
564
+ py::arg("blobs") = false) //
565
+ .def("query_numpy", &qdb::cluster::query_numpy, //
566
+ py::arg("query")) //
567
+ .def("query_continuous_full", &qdb::cluster::query_continuous_full, //
568
+ py::arg("query"), //
569
+ py::arg("pace"), //
570
+ py::arg("blobs") = false) //
571
+ .def("query_continuous_new_values", &qdb::cluster::query_continuous_new_values, //
572
+ py::arg("query"), //
573
+ py::arg("pace"), //
574
+ py::arg("blobs") = false) //
575
+ .def("prefix_get", &qdb::cluster::prefix_get) //
576
+ .def("prefix_count", &qdb::cluster::prefix_count) //
577
+ .def("suffix_get", &qdb::cluster::suffix_get) //
578
+ .def("suffix_count", &qdb::cluster::suffix_count) //
579
+ .def("close", &qdb::cluster::close) //
580
+ .def("purge_all", &qdb::cluster::purge_all) //
581
+ .def("trim_all", &qdb::cluster::trim_all) //
582
+ .def("purge_cache", &qdb::cluster::purge_cache) //
583
+ .def("compact_full", &qdb::cluster::compact_full) //
584
+ .def("compact_progress", &qdb::cluster::compact_progress) //
585
+ .def("compact_abort", &qdb::cluster::compact_abort) //
586
+ .def("wait_for_compaction", &qdb::cluster::wait_for_compaction) //
587
+ .def("endpoints", &qdb::cluster::endpoints); //
549
588
  }
550
589
 
551
590
  } // namespace qdb
quasardb/concepts.hpp CHANGED
@@ -4,6 +4,7 @@
4
4
  #include <pybind11/numpy.h>
5
5
  #include <range/v3/range/concepts.hpp>
6
6
  #include <range/v3/range/traits.hpp>
7
+ #include <chrono>
7
8
  #include <iterator>
8
9
  #include <type_traits>
9
10
 
@@ -114,12 +115,13 @@ static_assert(not qdb_primitive<qdb_ts_string_point>);
114
115
  template <typename Dtype>
115
116
  concept dtype = std::is_base_of_v<traits::dtype<Dtype::kind>, Dtype>
116
117
 
117
- && std::is_enum_v<decltype(Dtype::kind)>
118
+ && std::is_enum_v<decltype(Dtype::kind)>
118
119
 
119
120
  ;
120
121
 
121
122
  template <typename Dtype>
122
- concept fixed_width_dtype = dtype<Dtype>
123
+ concept fixed_width_dtype =
124
+ dtype<Dtype>
123
125
 
124
126
  // Check base class
125
127
  && std::is_base_of_v<traits::fixed_width_dtype<Dtype::kind, Dtype::size>, Dtype>;
@@ -147,14 +149,14 @@ concept dtype8 = dtype_of_width<Dtype, 1>;
147
149
  template <typename Dtype>
148
150
  concept datetime64_dtype = fixed_width_dtype<Dtype>
149
151
 
150
- // Verify base class is datetime64_dtype
151
- && std::is_base_of_v<traits::datetime64_dtype<Dtype::precision>, Dtype>
152
+ // Verify base class is datetime64_dtype
153
+ && std::is_base_of_v<traits::datetime64_dtype<Dtype::precision>, Dtype>
152
154
 
153
- // datetime64 is always a 64bit object
154
- && dtype64<Dtype>
155
+ // datetime64 is always a 64bit object
156
+ && dtype64<Dtype>
155
157
 
156
- // It needs to have a precision
157
- && std::is_enum_v<decltype(Dtype::precision)>;
158
+ // It needs to have a precision
159
+ && std::is_enum_v<decltype(Dtype::precision)>;
158
160
 
159
161
  template <typename Dtype>
160
162
  concept variable_width_dtype =
@@ -173,11 +175,11 @@ concept variable_width_dtype =
173
175
  template <typename Dtype>
174
176
  concept object_dtype = dtype<Dtype>
175
177
 
176
- // Objects are always fixed width (64-bit pointers, effectively)
177
- && fixed_width_dtype<Dtype>
178
+ // Objects are always fixed width (64-bit pointers, effectively)
179
+ && fixed_width_dtype<Dtype>
178
180
 
179
- // Verify base class
180
- && std::is_base_of_v<traits::object_dtype<typename Dtype::value_type>, Dtype>;
181
+ // Verify base class
182
+ && std::is_base_of_v<traits::object_dtype<typename Dtype::value_type>, Dtype>;
181
183
 
182
184
  // Trivial dtypes are useful for deciding whether you can use fast memcpy-based
183
185
  // conversions, e.g. when numpy's int64 has the exact same representation as
@@ -229,6 +231,47 @@ concept delegate_dtype =
229
231
  // very least nothrow_convertible.
230
232
  && std::is_nothrow_convertible_v<delegate_from_type_t<Dtype>, delegate_to_type_t<Dtype>>;
231
233
 
234
+ ////////////////////////////////////////////////////////////////////////////////
235
+ //
236
+ // Python API useful concepts, for e.g. batch writer
237
+ //
238
+ ///////////////////
239
+
240
+ template <typename T>
241
+ concept duration = traits::is_chrono_duration<T>::value;
242
+
243
+ template <typename T, typename Duration = T::duration_t>
244
+ concept sleep_strategy =
245
+ // Should always be a valid chrono duration
246
+ duration<Duration>
247
+
248
+ // And have a sleep function that takes a duration, and returns void
249
+ && requires(T s, Duration duration_) {
250
+ {
251
+ s.sleep(duration_)
252
+ } -> std::same_as<void>;
253
+ };
254
+
255
+ template <typename T>
256
+ concept writer_push_strategy =
257
+ // Check that we can do a batch push invoke
258
+ requires( //
259
+ T t, //
260
+ qdb_handle_t handle, //
261
+ qdb_exp_batch_options_t const * options, //
262
+ qdb_exp_batch_push_table_t const * tables, //
263
+ qdb_exp_batch_push_table_schema_t const ** table_schemas, //
264
+ qdb_size_t table_count, //
265
+ py::kwargs const & kwargs //
266
+ ) {
267
+ {
268
+ t(handle, options, tables, table_schemas, table_count)
269
+ } -> std::same_as<qdb_error_t>;
270
+ {
271
+ T::from_kwargs(kwargs)
272
+ } -> std::same_as<T>;
273
+ };
274
+
232
275
  // Assertions
233
276
  static_assert(dtype<traits::unicode_dtype>);
234
277
 
@@ -275,4 +318,5 @@ static_assert(not trivial_dtype<traits::float32_dtype>);
275
318
 
276
319
  static_assert(fixed_width_dtype<traits::float64_dtype>);
277
320
  static_assert(fixed_width_dtype<traits::float32_dtype>);
321
+
278
322
  }; // namespace qdb::concepts