quasardb 3.14.2.dev1__cp312-cp312-macosx_10_14_x86_64.whl → 3.14.2.dev3__cp312-cp312-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.

Files changed (58) hide show
  1. quasardb/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  2. quasardb/CMakeLists.txt +19 -12
  3. quasardb/Makefile +10 -10
  4. quasardb/__init__.py +33 -4
  5. quasardb/cluster.cpp +14 -1
  6. quasardb/cluster.hpp +114 -72
  7. quasardb/concepts.hpp +56 -12
  8. quasardb/continuous.cpp +84 -34
  9. quasardb/continuous.hpp +10 -7
  10. quasardb/convert/array.hpp +23 -6
  11. quasardb/convert/value.hpp +78 -7
  12. quasardb/date/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  13. quasardb/date/CMakeFiles/Export/a52b05f964b070ee926bcad51d3288af/dateTargets.cmake +12 -12
  14. quasardb/date/Makefile +10 -10
  15. quasardb/date/dateConfigVersion.cmake +9 -2
  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/libqdb_api.dylib +0 -0
  25. quasardb/masked_array.hpp +9 -2
  26. quasardb/module.cpp +20 -4
  27. quasardb/node.hpp +17 -8
  28. quasardb/numpy/__init__.py +58 -10
  29. quasardb/object_tracker.hpp +2 -3
  30. quasardb/options.hpp +32 -3
  31. quasardb/pandas/__init__.py +59 -102
  32. quasardb/properties.cpp +41 -0
  33. quasardb/properties.hpp +85 -0
  34. quasardb/pybind11/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  35. quasardb/pybind11/Makefile +10 -10
  36. quasardb/quasardb.cpython-312-darwin.so +0 -0
  37. quasardb/range-v3/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  38. quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +12 -12
  39. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/DependInfo.cmake +6 -2
  40. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/build.make +2 -2
  41. quasardb/range-v3/Makefile +10 -10
  42. quasardb/range-v3/cmake_install.cmake +12 -0
  43. quasardb/range-v3/range-v3-config-version.cmake +9 -2
  44. quasardb/range-v3/range-v3-config.cmake +3 -7
  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.dev3.dist-info}/METADATA +7 -7
  52. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev3.dist-info}/RECORD +55 -49
  53. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev3.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.dev3.dist-info}/LICENSE.md +0 -0
  58. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev3.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # CMAKE generated file: DO NOT EDIT!
2
- # Generated by "Unix Makefiles" Generator, CMake Version 3.24
2
+ # Generated by "Unix Makefiles" Generator, CMake Version 3.29
3
3
 
4
4
  # Relative path conversion top directories.
5
5
  set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/Users/teamcity/buildAgent/work/938b0bdf6727d1ad/thirdparty")
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/Makefile CHANGED
@@ -1,5 +1,5 @@
1
1
  # CMAKE generated file: DO NOT EDIT!
2
- # Generated by "Unix Makefiles" Generator, CMake Version 3.24
2
+ # Generated by "Unix Makefiles" Generator, CMake Version 3.29
3
3
 
4
4
  # Default target executed when no arguments are given to make.
5
5
  default_target: all
@@ -67,7 +67,7 @@ CMAKE_BINARY_DIR = /Users/teamcity/buildAgent/work/938b0bdf6727d1ad/build/temp.m
67
67
 
68
68
  # Special rule for the target edit_cache
69
69
  edit_cache:
70
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
70
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake cache editor..."
71
71
  /opt/local/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
72
72
  .PHONY : edit_cache
73
73
 
@@ -77,7 +77,7 @@ edit_cache/fast: edit_cache
77
77
 
78
78
  # Special rule for the target rebuild_cache
79
79
  rebuild_cache:
80
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
80
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..."
81
81
  /opt/local/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
82
82
  .PHONY : rebuild_cache
83
83
 
@@ -87,7 +87,7 @@ rebuild_cache/fast: rebuild_cache
87
87
 
88
88
  # Special rule for the target list_install_components
89
89
  list_install_components:
90
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
90
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Available install components are: \"Unspecified\""
91
91
  .PHONY : list_install_components
92
92
 
93
93
  # Special rule for the target list_install_components
@@ -96,37 +96,37 @@ list_install_components/fast: list_install_components
96
96
 
97
97
  # Special rule for the target install
98
98
  install: preinstall
99
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
99
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Install the project..."
100
100
  /opt/local/bin/cmake -P cmake_install.cmake
101
101
  .PHONY : install
102
102
 
103
103
  # Special rule for the target install
104
104
  install/fast: preinstall/fast
105
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
105
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Install the project..."
106
106
  /opt/local/bin/cmake -P cmake_install.cmake
107
107
  .PHONY : install/fast
108
108
 
109
109
  # Special rule for the target install/local
110
110
  install/local: preinstall
111
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
111
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing only the local directory..."
112
112
  /opt/local/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
113
113
  .PHONY : install/local
114
114
 
115
115
  # Special rule for the target install/local
116
116
  install/local/fast: preinstall/fast
117
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
117
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing only the local directory..."
118
118
  /opt/local/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
119
119
  .PHONY : install/local/fast
120
120
 
121
121
  # Special rule for the target install/strip
122
122
  install/strip: preinstall
123
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
123
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing the project stripped..."
124
124
  /opt/local/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
125
125
  .PHONY : install/strip
126
126
 
127
127
  # Special rule for the target install/strip
128
128
  install/strip/fast: preinstall/fast
129
- @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
129
+ @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing the project stripped..."
130
130
  /opt/local/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
131
131
  .PHONY : install/strip/fast
132
132
 
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,9 @@ 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
+ bool enable_encryption,
18
+ std::size_t client_max_parallelism)
17
19
  : _uri{uri}
18
20
  , _handle{make_handle_ptr()}
19
21
  , _json_loads{pybind11::module::import("json").attr("loads")}
@@ -31,6 +33,17 @@ cluster::cluster(const std::string & uri,
31
33
 
32
34
  options().set_timeout(timeout);
33
35
 
36
+ if (client_max_parallelism != 0)
37
+ {
38
+ options().set_client_max_parallelism(client_max_parallelism);
39
+ }
40
+
41
+ if (enable_encryption == true)
42
+ {
43
+ options().set_encryption(qdb_crypt_aes_gcm_256);
44
+ }
45
+
46
+
34
47
  // HACKS(leon): we need to ensure there is always one callback active
35
48
  // for qdb. Callbacks can be lost when the last active session
36
49
  // 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,9 @@ 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
+ bool enable_encryption = false,
78
+ std::size_t client_max_parallelism = 0);
76
79
 
77
80
  public:
78
81
  void close();
@@ -239,6 +242,18 @@ public:
239
242
  return qdb::table{_handle, alias};
240
243
  }
241
244
 
245
+ // the reader_ptr is non-copyable
246
+ qdb::reader_ptr reader( //
247
+ std::vector<std::string> const & table_names, //
248
+ std::vector<std::string> const & column_names, //
249
+ std::size_t batch_size, //
250
+ std::vector<py::tuple> const & ranges) //
251
+ {
252
+ check_open();
253
+
254
+ return std::make_unique<qdb::reader>(_handle, table_names, column_names, batch_size, ranges);
255
+ }
256
+
242
257
  // the batch_inserter_ptr is non-copyable
243
258
  qdb::batch_inserter_ptr inserter(const std::vector<batch_column_info> & ci)
244
259
  {
@@ -270,6 +285,13 @@ public:
270
285
  return qdb::options{_handle};
271
286
  }
272
287
 
288
+ qdb::properties properties()
289
+ {
290
+ check_open();
291
+
292
+ return qdb::properties{_handle};
293
+ }
294
+
273
295
  qdb::perf perf()
274
296
  {
275
297
  check_open();
@@ -334,22 +356,30 @@ public:
334
356
  return py::cast(qdb::numpy_query(_handle, query_string));
335
357
  }
336
358
 
337
- std::shared_ptr<qdb::query_continuous> query_continuous_full(
338
- const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
359
+ std::shared_ptr<qdb::query_continuous> query_continuous(qdb_query_continuous_mode_type_t mode,
360
+ const std::string & query_string,
361
+ std::chrono::milliseconds pace,
362
+ const py::object & blobs)
339
363
  {
340
364
  check_open();
341
365
 
342
- return std::make_shared<qdb::query_continuous>(
343
- _handle, qdb_query_continuous_full, pace, query_string, blobs);
366
+ auto o = std::make_shared<qdb::query_continuous>(_handle, blobs);
367
+
368
+ o->run(mode, pace, query_string);
369
+
370
+ return o;
344
371
  }
345
372
 
346
- std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
373
+ std::shared_ptr<qdb::query_continuous> query_continuous_full(
347
374
  const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
348
375
  {
349
- check_open();
376
+ return query_continuous(qdb_query_continuous_full, query_string, pace, blobs);
377
+ }
350
378
 
351
- return std::make_shared<qdb::query_continuous>(
352
- _handle, qdb_query_continuous_new_values_only, pace, query_string, blobs);
379
+ std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
380
+ const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
381
+ {
382
+ return query_continuous(qdb_query_continuous_new_values_only, query_string, pace, blobs);
353
383
  }
354
384
 
355
385
  public:
@@ -484,68 +514,80 @@ static inline void register_cluster(Module & m)
484
514
 
485
515
  py::class_<qdb::cluster>(m, "Cluster",
486
516
  "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); //
517
+ .def(py::init<const std::string &, const std::string &, const std::string &,
518
+ const std::string &, const std::string &, const std::string &,
519
+ std::chrono::milliseconds, bool, bool, std::size_t>(), //
520
+ py::arg("uri"), //
521
+ py::arg("user_name") = std::string{}, //
522
+ py::arg("user_private_key") = std::string{}, //
523
+ py::arg("cluster_public_key") = std::string{}, //
524
+ py::kw_only(), //
525
+ py::arg("user_security_file") = std::string{}, //
526
+ py::arg("cluster_public_key_file") = std::string{}, //
527
+ py::arg("timeout") = std::chrono::minutes{1}, //
528
+ py::arg("do_version_check") = false, //
529
+ py::arg("enable_encryption") = false, //
530
+ py::arg("client_max_parallelism") = std::size_t{0} //
531
+ ) //
532
+ .def("__enter__", &qdb::cluster::enter) //
533
+ .def("__exit__", &qdb::cluster::exit) //
534
+ .def("tidy_memory", &qdb::cluster::tidy_memory) //
535
+ .def("get_memory_info", &qdb::cluster::get_memory_info) //
536
+ .def("is_open", &qdb::cluster::is_open) //
537
+ .def("uri", &qdb::cluster::uri) //
538
+ .def("node", &qdb::cluster::node) //
539
+ .def("options", &qdb::cluster::options) //
540
+ .def("properties", &qdb::cluster::properties) //
541
+ .def("perf", &qdb::cluster::perf) //
542
+ .def("node_status", &qdb::cluster::node_status) //
543
+ .def("node_config", &qdb::cluster::node_config) //
544
+ .def("node_topology", &qdb::cluster::node_topology) //
545
+ .def("tag", &qdb::cluster::tag) //
546
+ .def("blob", &qdb::cluster::blob) //
547
+ .def("string", &qdb::cluster::string) //
548
+ .def("integer", &qdb::cluster::integer) //
549
+ .def("double", &qdb::cluster::double_) //
550
+ .def("timestamp", &qdb::cluster::timestamp) //
551
+ .def("ts", &qdb::cluster::table) //
552
+ .def("table", &qdb::cluster::table) //
553
+ .def("ts_batch", &qdb::cluster::inserter) //
554
+ .def("inserter", &qdb::cluster::inserter) //
555
+ .def("reader", &qdb::cluster::reader, //
556
+ py::arg("table_names"), //
557
+ py::kw_only(), //
558
+ py::arg("column_names") = std::vector<std::string>{}, //
559
+ py::arg("batch_size") = std::size_t{0}, //
560
+ py::arg("ranges") = std::vector<py::tuple>{} //
561
+ ) //
562
+ .def("pinned_writer", &qdb::cluster::pinned_writer) //
563
+ .def("writer", &qdb::cluster::writer) //
564
+ .def("find", &qdb::cluster::find) //
565
+ .def("query", &qdb::cluster::query, //
566
+ py::arg("query"), //
567
+ py::arg("blobs") = false) //
568
+ .def("query_numpy", &qdb::cluster::query_numpy, //
569
+ py::arg("query")) //
570
+ .def("query_continuous_full", &qdb::cluster::query_continuous_full, //
571
+ py::arg("query"), //
572
+ py::arg("pace"), //
573
+ py::arg("blobs") = false) //
574
+ .def("query_continuous_new_values", &qdb::cluster::query_continuous_new_values, //
575
+ py::arg("query"), //
576
+ py::arg("pace"), //
577
+ py::arg("blobs") = false) //
578
+ .def("prefix_get", &qdb::cluster::prefix_get) //
579
+ .def("prefix_count", &qdb::cluster::prefix_count) //
580
+ .def("suffix_get", &qdb::cluster::suffix_get) //
581
+ .def("suffix_count", &qdb::cluster::suffix_count) //
582
+ .def("close", &qdb::cluster::close) //
583
+ .def("purge_all", &qdb::cluster::purge_all) //
584
+ .def("trim_all", &qdb::cluster::trim_all) //
585
+ .def("purge_cache", &qdb::cluster::purge_cache) //
586
+ .def("compact_full", &qdb::cluster::compact_full) //
587
+ .def("compact_progress", &qdb::cluster::compact_progress) //
588
+ .def("compact_abort", &qdb::cluster::compact_abort) //
589
+ .def("wait_for_compaction", &qdb::cluster::wait_for_compaction) //
590
+ .def("endpoints", &qdb::cluster::endpoints); //
549
591
  }
550
592
 
551
593
  } // 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