quasardb 3.14.2.dev3__cp311-cp311-macosx_11_0_arm64.whl → 3.14.2.dev5__cp311-cp311-macosx_11_0_arm64.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 (105) hide show
  1. quasardb/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  2. quasardb/Makefile +20 -20
  3. quasardb/__init__.py +21 -7
  4. quasardb/cmake_install.cmake +10 -4
  5. quasardb/date/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  6. quasardb/date/CMakeFiles/Export/a52b05f964b070ee926bcad51d3288af/dateTargets.cmake +2 -2
  7. quasardb/date/Makefile +20 -20
  8. quasardb/date/cmake_install.cmake +10 -4
  9. quasardb/date/dateConfigVersion.cmake +0 -0
  10. quasardb/date/dateTargets.cmake +2 -2
  11. quasardb/extensions/writer.py +59 -61
  12. quasardb/firehose.py +24 -22
  13. quasardb/libqdb_api.dylib +0 -0
  14. quasardb/numpy/__init__.py +181 -120
  15. quasardb/pandas/__init__.py +145 -95
  16. quasardb/pool.py +13 -2
  17. quasardb/pybind11/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  18. quasardb/pybind11/Makefile +20 -20
  19. quasardb/pybind11/cmake_install.cmake +7 -1
  20. quasardb/quasardb.cpython-311-darwin.so +0 -0
  21. quasardb/range-v3/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  22. quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +2 -2
  23. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/build.make +18 -15
  24. quasardb/range-v3/Makefile +25 -25
  25. quasardb/range-v3/cmake_install.cmake +13 -7
  26. quasardb/range-v3/range-v3-config-version.cmake +0 -0
  27. quasardb/range-v3/range-v3-config.cmake +2 -2
  28. quasardb/stats.py +92 -80
  29. quasardb/table_cache.py +5 -1
  30. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/METADATA +13 -8
  31. quasardb-3.14.2.dev5.dist-info/RECORD +45 -0
  32. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/WHEEL +1 -1
  33. quasardb/CMakeLists.txt +0 -517
  34. quasardb/batch_column.hpp +0 -80
  35. quasardb/batch_inserter.hpp +0 -248
  36. quasardb/blob.hpp +0 -150
  37. quasardb/cluster.cpp +0 -102
  38. quasardb/cluster.hpp +0 -593
  39. quasardb/concepts.hpp +0 -322
  40. quasardb/continuous.cpp +0 -199
  41. quasardb/continuous.hpp +0 -109
  42. quasardb/convert/array.hpp +0 -299
  43. quasardb/convert/point.hpp +0 -330
  44. quasardb/convert/range.hpp +0 -282
  45. quasardb/convert/unicode.hpp +0 -598
  46. quasardb/convert/util.hpp +0 -22
  47. quasardb/convert/value.hpp +0 -782
  48. quasardb/convert.hpp +0 -38
  49. quasardb/detail/invoke.hpp +0 -0
  50. quasardb/detail/qdb_resource.hpp +0 -129
  51. quasardb/detail/retry.cpp +0 -30
  52. quasardb/detail/retry.hpp +0 -147
  53. quasardb/detail/sleep.hpp +0 -53
  54. quasardb/detail/ts_column.hpp +0 -224
  55. quasardb/detail/writer.cpp +0 -440
  56. quasardb/detail/writer.hpp +0 -550
  57. quasardb/direct_blob.hpp +0 -108
  58. quasardb/direct_handle.hpp +0 -83
  59. quasardb/direct_integer.hpp +0 -94
  60. quasardb/dispatch.hpp +0 -157
  61. quasardb/double.hpp +0 -87
  62. quasardb/entry.hpp +0 -273
  63. quasardb/error.hpp +0 -393
  64. quasardb/handle.cpp +0 -29
  65. quasardb/handle.hpp +0 -98
  66. quasardb/integer.hpp +0 -88
  67. quasardb/logger.cpp +0 -106
  68. quasardb/logger.hpp +0 -228
  69. quasardb/masked_array.hpp +0 -658
  70. quasardb/metrics.cpp +0 -103
  71. quasardb/metrics.hpp +0 -112
  72. quasardb/module.cpp +0 -92
  73. quasardb/module.hpp +0 -24
  74. quasardb/node.hpp +0 -132
  75. quasardb/numpy.cpp +0 -6
  76. quasardb/numpy.hpp +0 -489
  77. quasardb/object_tracker.hpp +0 -282
  78. quasardb/options.hpp +0 -273
  79. quasardb/perf.hpp +0 -336
  80. quasardb/properties.cpp +0 -41
  81. quasardb/properties.hpp +0 -85
  82. quasardb/pytypes.hpp +0 -221
  83. quasardb/query.cpp +0 -420
  84. quasardb/query.hpp +0 -92
  85. quasardb/reader.cpp +0 -282
  86. quasardb/reader.hpp +0 -256
  87. quasardb/remove_cvref.hpp +0 -31
  88. quasardb/string.hpp +0 -160
  89. quasardb/table.cpp +0 -257
  90. quasardb/table.hpp +0 -366
  91. quasardb/tag.hpp +0 -77
  92. quasardb/timestamp.hpp +0 -97
  93. quasardb/traits.hpp +0 -642
  94. quasardb/ts_iterator.hpp +0 -193
  95. quasardb/utils/blob_deque.hpp +0 -96
  96. quasardb/utils/ostream.hpp +0 -17
  97. quasardb/utils/permutation.hpp +0 -50
  98. quasardb/utils/stable_sort.hpp +0 -25
  99. quasardb/utils/unzip_view.hpp +0 -89
  100. quasardb/utils.cpp +0 -28
  101. quasardb/utils.hpp +0 -174
  102. quasardb/writer.hpp +0 -354
  103. quasardb-3.14.2.dev3.dist-info/RECORD +0 -115
  104. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/LICENSE.md +0 -0
  105. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/top_level.txt +0 -0
quasardb/concepts.hpp DELETED
@@ -1,322 +0,0 @@
1
- #pragma once
2
-
3
- #include "traits.hpp" // We include traits.hpp only for static_asserts below
4
- #include <pybind11/numpy.h>
5
- #include <range/v3/range/concepts.hpp>
6
- #include <range/v3/range/traits.hpp>
7
- #include <chrono>
8
- #include <iterator>
9
- #include <type_traits>
10
-
11
- namespace qdb::concepts
12
- {
13
-
14
- template <typename R, typename T>
15
- concept range_t =
16
- // Ensure we are a range
17
- ranges::range<R> &&
18
-
19
- std::is_same_v<ranges::range_value_t<R>, T>;
20
-
21
- template <typename R, typename T>
22
- concept input_range_t =
23
- // Ensure we are an input range
24
- ranges::input_range<R>
25
-
26
- // Ensure the range carries the correct type.
27
- && range_t<R, T>;
28
-
29
- template <typename R, typename T>
30
- concept forward_range_t =
31
- // Ensure we are a forward range
32
- ranges::forward_range<R>
33
-
34
- // And delegate the rest of the checks
35
- && input_range_t<R, T>;
36
-
37
- template <typename R, typename T>
38
- concept sized_range_t =
39
- // Ensure we are a sized range
40
- ranges::sized_range<R>
41
-
42
- // And delegate the rest of the checks
43
- && range_t<R, T>;
44
-
45
- namespace py = pybind11;
46
-
47
- ////////////////////////////////////////////////////////////////////////////////
48
- //
49
- // QuasarDB value types
50
- //
51
- // Verifies a "type" of QuasarDB value we're dealing with.
52
- //
53
- ///////////////////
54
-
55
- template <typename T>
56
- concept qdb_point =
57
- // Check for the boolean flag
58
- traits::qdb_value<T>::is_qdb_point &&
59
-
60
- // Every point should have a "primitive" counterpart, for which we do a
61
- // basic 'is_qdb_primitive' assessment.
62
- traits::qdb_value<typename traits::qdb_value<T>::primitive_type>::is_qdb_primitive
63
-
64
- ;
65
-
66
- template <typename T>
67
- concept qdb_primitive =
68
-
69
- // Check for the boolean flag
70
- traits::qdb_value<T>::is_qdb_primitive &&
71
-
72
- // Every primitive has a null representation
73
- std::is_same_v<decltype(traits::null_value<T>()), T> &&
74
-
75
- // Every primitive should be able to check for null validity
76
- std::is_same_v<decltype(traits::is_null<T>(T{})), bool> &&
77
-
78
- // And every primitive should have its "point" counterpart, which must
79
- // be a valid qdb_point.
80
- qdb_point<typename traits::qdb_value<T>::point_type>;
81
-
82
- // XXX(leon): could be enabled for debug-only, but we don't build Debug in CI,
83
- // and these checks are cheap.
84
-
85
- static_assert(qdb_primitive<qdb_int_t>);
86
- static_assert(qdb_primitive<double>);
87
- static_assert(qdb_primitive<qdb_timespec_t>);
88
- static_assert(qdb_primitive<qdb_string_t>);
89
- static_assert(qdb_primitive<qdb_blob_t>);
90
-
91
- static_assert(not qdb_point<qdb_int_t>);
92
- static_assert(not qdb_point<double>);
93
- static_assert(not qdb_point<qdb_timespec_t>);
94
- static_assert(not qdb_point<qdb_string_t>);
95
- static_assert(not qdb_point<qdb_blob_t>);
96
-
97
- static_assert(qdb_point<qdb_ts_double_point>);
98
- static_assert(qdb_point<qdb_ts_int64_point>);
99
- static_assert(qdb_point<qdb_ts_timestamp_point>);
100
- static_assert(qdb_point<qdb_ts_blob_point>);
101
- static_assert(qdb_point<qdb_ts_string_point>);
102
-
103
- static_assert(not qdb_primitive<qdb_ts_double_point>);
104
- static_assert(not qdb_primitive<qdb_ts_int64_point>);
105
- static_assert(not qdb_primitive<qdb_ts_timestamp_point>);
106
- static_assert(not qdb_primitive<qdb_ts_blob_point>);
107
- static_assert(not qdb_primitive<qdb_ts_string_point>);
108
-
109
- ////////////////////////////////////////////////////////////////////////////////
110
- //
111
- // Numpy / DType concepts
112
- //
113
- ///////////////////
114
-
115
- template <typename Dtype>
116
- concept dtype = std::is_base_of_v<traits::dtype<Dtype::kind>, Dtype>
117
-
118
- && std::is_enum_v<decltype(Dtype::kind)>
119
-
120
- ;
121
-
122
- template <typename Dtype>
123
- concept fixed_width_dtype =
124
- dtype<Dtype>
125
-
126
- // Check base class
127
- && std::is_base_of_v<traits::fixed_width_dtype<Dtype::kind, Dtype::size>, Dtype>;
128
-
129
- // Test dtypes against their size
130
- template <typename Dtype, py::ssize_t Size>
131
- concept dtype_of_width = fixed_width_dtype<Dtype> && Dtype::size == Size;
132
-
133
- // 64bit dtype
134
- template <typename Dtype>
135
- concept dtype64 = dtype_of_width<Dtype, 8>;
136
-
137
- // 32bit dtype
138
- template <typename Dtype>
139
- concept dtype32 = dtype_of_width<Dtype, 4>;
140
-
141
- // 16bit dtype
142
- template <typename Dtype>
143
- concept dtype16 = dtype_of_width<Dtype, 2>;
144
-
145
- // 8bit dtype
146
- template <typename Dtype>
147
- concept dtype8 = dtype_of_width<Dtype, 1>;
148
-
149
- template <typename Dtype>
150
- concept datetime64_dtype = fixed_width_dtype<Dtype>
151
-
152
- // Verify base class is datetime64_dtype
153
- && std::is_base_of_v<traits::datetime64_dtype<Dtype::precision>, Dtype>
154
-
155
- // datetime64 is always a 64bit object
156
- && dtype64<Dtype>
157
-
158
- // It needs to have a precision
159
- && std::is_enum_v<decltype(Dtype::precision)>;
160
-
161
- template <typename Dtype>
162
- concept variable_width_dtype =
163
- dtype<Dtype>
164
-
165
- // Verify base class
166
- && std::is_base_of_v<
167
- traits::variable_width_dtype<Dtype::kind, typename Dtype::stride_type, Dtype::code_point_size>,
168
- Dtype>
169
-
170
- // Verify we have a "stride_type", which is the type used to represent a single stride.
171
- && Dtype::code_point_size == sizeof(typename Dtype::stride_type::value_type)
172
-
173
- ;
174
-
175
- template <typename Dtype>
176
- concept object_dtype = dtype<Dtype>
177
-
178
- // Objects are always fixed width (64-bit pointers, effectively)
179
- && fixed_width_dtype<Dtype>
180
-
181
- // Verify base class
182
- && std::is_base_of_v<traits::object_dtype<typename Dtype::value_type>, Dtype>;
183
-
184
- // Trivial dtypes are useful for deciding whether you can use fast memcpy-based
185
- // conversions, e.g. when numpy's int64 has the exact same representation as
186
- // qdb_int_t.
187
- template <typename Dtype>
188
- concept trivial_dtype =
189
- // Trivial dtypes are *always* fixed width
190
- fixed_width_dtype<Dtype>
191
-
192
- // The low-level numpy representation needs to be trivial; e.g. numpy represents
193
- // something as int32.
194
- && std::is_trivial<typename Dtype::value_type>::value
195
-
196
- // Needs to have a quasardb representation of this type as well (e.g.
197
- // dtype('int64') mapping to qdb_int_t
198
- && std::is_trivial<typename Dtype::qdb_value>::value
199
-
200
- // Sanity check: the trivial qdb_value needs to be a qdb_primitive -- if this fails,
201
- // it hints at a misconfigured dtype specification.
202
- && qdb_primitive<typename Dtype::qdb_value>
203
-
204
- // Last but not least (and most important one): both the dtype's low level
205
- // representation and quasardb's representation need to be equivalent.
206
- && std::is_same_v<typename Dtype::value_type, typename Dtype::qdb_value>
207
-
208
- ;
209
-
210
- template <typename Dtype>
211
- using delegate_from_type_t = typename Dtype::value_type;
212
-
213
- template <typename Dtype>
214
- using delegate_to_type_t = typename Dtype::delegate_type::value_type;
215
-
216
- template <typename Dtype>
217
- concept delegate_dtype =
218
- // Delegates are always dtypes
219
- dtype<Dtype>
220
-
221
- // And delegates have a delegate that is also a proper dtype
222
- && dtype<typename Dtype::delegate_type>
223
-
224
- // And conversion between these types should be possible (nothrow could be
225
- // left away, but that comes with certain performance disadvantages).
226
- //
227
- // Note that this only checks for <From, To>, e.g. if int32_t is a delegate
228
- // to int64_t, it only checks whether int32_t is convertible to int64_t, not the
229
- // other way around. This is intentional, because the other way around leads to
230
- // loss of precision, and as such can be argued is *not* convertible, at the
231
- // very least nothrow_convertible.
232
- && std::is_nothrow_convertible_v<delegate_from_type_t<Dtype>, delegate_to_type_t<Dtype>>;
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
-
275
- // Assertions
276
- static_assert(dtype<traits::unicode_dtype>);
277
-
278
- static_assert(variable_width_dtype<traits::unicode_dtype>);
279
- static_assert(fixed_width_dtype<traits::pyobject_dtype>);
280
- static_assert(datetime64_dtype<traits::datetime64_ns_dtype>);
281
- static_assert(not fixed_width_dtype<traits::unicode_dtype>);
282
- static_assert(not variable_width_dtype<traits::pyobject_dtype>);
283
-
284
- static_assert(not trivial_dtype<traits::datetime64_ns_dtype>);
285
- static_assert(not trivial_dtype<traits::pyobject_dtype>);
286
- static_assert(not trivial_dtype<traits::unicode_dtype>);
287
- static_assert(not trivial_dtype<traits::bytestring_dtype>);
288
- static_assert(trivial_dtype<traits::float64_dtype>);
289
-
290
- static_assert(dtype_of_width<traits::int64_dtype, 8>);
291
- static_assert(dtype_of_width<traits::int32_dtype, 4>);
292
- static_assert(dtype_of_width<traits::int16_dtype, 2>);
293
-
294
- static_assert(dtype64<traits::int64_dtype>);
295
- static_assert(dtype32<traits::int32_dtype>);
296
- static_assert(dtype16<traits::int16_dtype>);
297
-
298
- static_assert(fixed_width_dtype<traits::int64_dtype>);
299
- static_assert(fixed_width_dtype<traits::int32_dtype>);
300
- static_assert(fixed_width_dtype<traits::int16_dtype>);
301
-
302
- static_assert(trivial_dtype<traits::int64_dtype>);
303
- // Not trivial because they don't have a qdb-native representation, so
304
- // they're not trivial in the sense of how we should handle them.
305
- static_assert(not trivial_dtype<traits::int32_dtype>);
306
- static_assert(not trivial_dtype<traits::int16_dtype>);
307
-
308
- static_assert(not delegate_dtype<traits::int64_dtype>);
309
- static_assert(delegate_dtype<traits::int32_dtype>);
310
-
311
- static_assert(dtype_of_width<traits::float64_dtype, 8>);
312
- static_assert(dtype_of_width<traits::float32_dtype, 4>);
313
-
314
- static_assert(trivial_dtype<traits::float64_dtype>);
315
- // Not trivial because they don't have a qdb-native representation, so
316
- // they're not trivial in the sense of how we should handle them.
317
- static_assert(not trivial_dtype<traits::float32_dtype>);
318
-
319
- static_assert(fixed_width_dtype<traits::float64_dtype>);
320
- static_assert(fixed_width_dtype<traits::float32_dtype>);
321
-
322
- }; // namespace qdb::concepts
quasardb/continuous.cpp DELETED
@@ -1,199 +0,0 @@
1
- #include "continuous.hpp"
2
- #include <iostream>
3
-
4
- namespace qdb
5
- {
6
-
7
- query_continuous::query_continuous(qdb::handle_ptr h, const py::object & bools)
8
- : _logger("quasardb.query_continuous")
9
- , _handle{h}
10
- , _callback{&query_continuous::continuous_callback}
11
- , _cont_handle{nullptr}
12
- , _parse_bools{bools}
13
- , _previous_watermark{0}
14
- , _watermark{0}
15
- , _last_error{qdb_e_uninitialized}
16
- {}
17
-
18
- query_continuous::~query_continuous()
19
- {
20
- stop();
21
- release_results();
22
- }
23
-
24
- void query_continuous::run(qdb_query_continuous_mode_type_t mode,
25
- std::chrono::milliseconds pace,
26
- const std::string & query_string)
27
- {
28
- qdb::qdb_throw_if_error(
29
- *_handle, qdb_query_continuous(*_handle, query_string.c_str(), mode,
30
- static_cast<unsigned>(pace.count()), _callback, this, &_cont_handle));
31
- }
32
-
33
- void query_continuous::release_results()
34
- {
35
- if (_results)
36
- {
37
- qdb_release(*_handle, _results);
38
- _results = nullptr;
39
- }
40
- }
41
-
42
- qdb_error_t query_continuous::copy_results(const qdb_query_result_t * res)
43
- {
44
- // release whatever results we may be holding before, if we don't have any it does nothing
45
- release_results();
46
- if (!res) return qdb_e_ok;
47
- return qdb_query_copy_results(*_handle, res, &_results);
48
- }
49
-
50
- int query_continuous::continuous_callback(void * p, qdb_error_t err, const qdb_query_result_t * res)
51
- {
52
- auto pthis = static_cast<query_continuous *>(p);
53
-
54
- try
55
- {
56
- std::unique_lock<std::mutex> lock{pthis->_results_mutex};
57
-
58
- ++pthis->_watermark;
59
-
60
- pthis->_last_error = err;
61
- if (QDB_FAILURE(pthis->_last_error))
62
- {
63
- // signal the error, if processing end, we will get a qdb_e_interrupted which is handled
64
- // in the results function
65
- lock.unlock();
66
- pthis->_results_cond.notify_all();
67
- return 0;
68
- }
69
-
70
- // copy the results using the API convenience function
71
- // there are two traps to avoid
72
- // 1. we are within the context of a thread owned by the quasardb C API, calling Python
73
- // functions could results in deadlocks
74
- // 2. the results are valid only in the context of the callback, if we want to work on them
75
- // outside we need to copy them
76
- pthis->_last_error = pthis->copy_results(res);
77
- if (QDB_FAILURE(pthis->_last_error))
78
- {
79
- pthis->release_results();
80
- }
81
- }
82
- catch (std::system_error const & e)
83
- {
84
- // Nothing we can do really, this is most likely a "deadlock avoided" issue.
85
- std::cerr << "Internal error: unexpected exception caught in continuous query callback: "
86
- "system_error: "
87
- << e.what() << std::endl;
88
- }
89
- catch (std::exception const & e)
90
- {
91
- // Nothing we can do really, this is most likely a "deadlock avoided" issue.
92
- std::cerr << "Internal error: unexpected exception caught in continuous query callback: "
93
- << e.what() << std::endl;
94
- }
95
-
96
- pthis->_results_cond.notify_all();
97
-
98
- return 0;
99
- }
100
-
101
- dict_query_result_t query_continuous::unsafe_results()
102
- {
103
- // when we return from the condition variable we own the mutex
104
- _previous_watermark.store(_watermark.load());
105
-
106
- if (_last_error == qdb_e_interrupted) throw py::stop_iteration{};
107
-
108
- // throw an error, user may decide to resume iteration
109
- qdb::qdb_throw_if_error(*_handle, _last_error);
110
-
111
- // safe and quick to call if _results is nullptr
112
- auto res = convert_query_results(_results, _parse_bools);
113
-
114
- release_results();
115
-
116
- return res;
117
- }
118
-
119
- dict_query_result_t query_continuous::results()
120
- {
121
- try
122
- {
123
- std::unique_lock<std::mutex> lock{_results_mutex};
124
-
125
- // you need an additional mechanism to check if you need to do something with the results
126
- // because condition variables can have spurious calls
127
- while (_watermark == _previous_watermark)
128
- {
129
- // entering the condition variables releases the mutex
130
- // the callback can update the values when needed
131
- // every second we are going to check if the user didn't do CTRL-C
132
- if (_results_cond.wait_for(lock, std::chrono::seconds{1}) == std::cv_status::timeout)
133
- {
134
- // if we don't do this, it will be impossible to interrupt the Python program while
135
- // we wait for results
136
- if (PyErr_CheckSignals() != 0)
137
- {
138
- throw py::error_already_set();
139
- }
140
- }
141
- }
142
-
143
- return unsafe_results();
144
- }
145
- catch (std::system_error const & e)
146
- {
147
- _logger.warn("continuous query caught system error, e.what(): %s", e.what());
148
- _logger.warn("continuous query caught system error, e.code(): %d", e.code());
149
- return dict_query_result_t{};
150
- }
151
- catch (std::exception const & e)
152
- {
153
- _logger.warn(
154
- "Internal error: unexpected exception caught while gathering results: %s", e.what());
155
- return dict_query_result_t{};
156
- }
157
- }
158
-
159
- // the difference with the call above is that we're returning immediately if there's no change
160
- dict_query_result_t query_continuous::probe_results()
161
- {
162
- try
163
- {
164
- std::unique_lock<std::mutex> lock{_results_mutex};
165
-
166
- // check if there's a new value
167
- if (_watermark == _previous_watermark)
168
- {
169
- // nope return empty, don't wait, don't acquire the condition variable
170
- return dict_query_result_t{};
171
- }
172
-
173
- // yes, return the value
174
- return unsafe_results();
175
- }
176
- catch (std::system_error const & e)
177
- {
178
- _logger.warn("continuous query caught system error, e.what(): %s", e.what());
179
- _logger.warn("continuous query caught system error, e.code(): %d", e.code());
180
- return dict_query_result_t{};
181
- }
182
- catch (std::exception const & e)
183
- {
184
- _logger.warn(
185
- "Internal error: unexpected exception caught while gathering results: %s", e.what());
186
- return dict_query_result_t{};
187
- }
188
- }
189
-
190
- void query_continuous::stop()
191
- {
192
- if (_handle && _cont_handle)
193
- {
194
- qdb_release(*_handle, _cont_handle);
195
- _cont_handle = nullptr;
196
- }
197
- }
198
-
199
- } // namespace qdb
quasardb/continuous.hpp DELETED
@@ -1,109 +0,0 @@
1
- /*
2
- *
3
- * Official Python API
4
- *
5
- * Copyright (c) 2009-2024, quasardb SAS. All rights reserved.
6
- * All rights reserved.
7
- *
8
- * Redistribution and use in source and binary forms, with or without
9
- * modification, are permitted provided that the following conditions are met:
10
- *
11
- * * Redistributions of source code must retain the above copyright
12
- * notice, this list of conditions and the following disclaimer.
13
- * * Redistributions in binary form must reproduce the above copyright
14
- * notice, this list of conditions and the following disclaimer in the
15
- * documentation and/or other materials provided with the distribution.
16
- * * Neither the name of quasardb nor the names of its contributors may
17
- * be used to endorse or promote products derived from this software
18
- * without specific prior written permission.
19
- *
20
- * THIS SOFTWARE IS PROVIDED BY QUASARDB AND CONTRIBUTORS ``AS IS'' AND ANY
21
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
24
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
- */
31
- #pragma once
32
-
33
- #include "logger.hpp"
34
- #include "query.hpp"
35
- #include <atomic>
36
- #include <condition_variable>
37
- #include <memory>
38
-
39
- namespace py = pybind11;
40
-
41
- namespace qdb
42
- {
43
-
44
- class query_continuous : public std::enable_shared_from_this<query_continuous>
45
- {
46
- public:
47
- query_continuous(qdb::handle_ptr h, const py::object & bools);
48
- query_continuous(const qdb::query_continuous & /*other*/) = delete;
49
- ~query_continuous();
50
-
51
- void run(qdb_query_continuous_mode_type_t mode,
52
- std::chrono::milliseconds pace,
53
- const std::string & query_string);
54
-
55
- private:
56
- void release_results();
57
- qdb_error_t copy_results(const qdb_query_result_t * res);
58
- static int continuous_callback(void * p, qdb_error_t err, const qdb_query_result_t * res);
59
-
60
- private:
61
- dict_query_result_t unsafe_results();
62
-
63
- public:
64
- // returns the results (blocking)
65
- dict_query_result_t results();
66
- // returns the results (non-blocking), empty if no results available yet
67
- // needed to be able to interface with other framework that can't wait for results to be available
68
- // in that case you would poll probe_results(), the cost is low because it doesn't result in a
69
- // remote call just acquiring the mutex and see if results have been updated
70
- dict_query_result_t probe_results();
71
- void stop();
72
-
73
- private:
74
- qdb::logger _logger;
75
-
76
- qdb::handle_ptr _handle;
77
- qdb_query_cont_callback_t _callback;
78
- qdb_query_cont_handle_t _cont_handle;
79
-
80
- py::object _parse_bools;
81
-
82
- mutable std::condition_variable _results_cond;
83
- mutable std::mutex _results_mutex;
84
- std::atomic<size_t> _previous_watermark;
85
- std::atomic<size_t> _watermark;
86
- qdb_error_t _last_error;
87
-
88
- qdb_query_result_t * _results;
89
- };
90
-
91
- template <typename Module>
92
- static inline void register_continuous(Module & m)
93
- {
94
- namespace py = pybind11;
95
-
96
- py::class_<qdb::query_continuous, std::shared_ptr<qdb::query_continuous>>{m, "QueryContinuous"} //
97
- .def(py::init<qdb::handle_ptr,
98
- const py::object &>()) //
99
- .def("run", &qdb::query_continuous::run) //
100
- .def("results", &qdb::query_continuous::results) //
101
- .def("probe_results", &qdb::query_continuous::probe_results) //
102
- .def("stop", &qdb::query_continuous::stop) //
103
-
104
- // required interface to use query_continuous as an iterator
105
- .def("__iter__", [](const std::shared_ptr<qdb::query_continuous> & cont) { return cont; }) //
106
- .def("__next__", &qdb::query_continuous::results); //
107
- }
108
-
109
- } // namespace qdb