couchbase 4.2.1 → 4.2.2
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.
- package/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/.gitmodules +3 -0
- package/deps/couchbase-cxx-client/.idea/misc.xml +1 -0
- package/deps/couchbase-cxx-client/.idea/vcs.xml +1 -0
- package/deps/couchbase-cxx-client/CMakeLists.txt +11 -1
- package/deps/couchbase-cxx-client/README.md +3 -3
- package/deps/couchbase-cxx-client/cmake/CompilerWarnings.cmake +4 -1
- package/deps/couchbase-cxx-client/cmake/VersionInfo.cmake +13 -1
- package/deps/couchbase-cxx-client/cmake/build_version.hxx.in +1 -0
- package/deps/couchbase-cxx-client/core/cluster.hxx +15 -5
- package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +17 -6
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +93 -0
- package/deps/couchbase-cxx-client/core/impl/configuration_profiles_registry.cxx +11 -0
- package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +119 -0
- package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +108 -0
- package/deps/couchbase-cxx-client/core/impl/get.cxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +76 -0
- package/deps/couchbase-cxx-client/core/impl/query.cxx +5 -7
- package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +168 -0
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +15 -1
- package/deps/couchbase-cxx-client/core/logger/configuration.hxx +3 -0
- package/deps/couchbase-cxx-client/core/logger/level.hxx +21 -0
- package/deps/couchbase-cxx-client/core/logger/logger.hxx +4 -6
- package/deps/couchbase-cxx-client/core/meta/CMakeLists.txt +4 -2
- package/deps/couchbase-cxx-client/core/meta/features.hxx +31 -0
- package/deps/couchbase-cxx-client/core/meta/version.cxx +67 -5
- package/deps/couchbase-cxx-client/core/meta/version.hxx +12 -1
- package/deps/couchbase-cxx-client/core/metrics/CMakeLists.txt +4 -1
- package/deps/couchbase-cxx-client/core/metrics/logging_meter.cxx +46 -5
- package/deps/couchbase-cxx-client/core/metrics/logging_meter.hxx +10 -26
- package/deps/couchbase-cxx-client/core/operations/document_get_projected.cxx +3 -2
- package/deps/couchbase-cxx-client/core/operations/document_query.cxx +10 -12
- package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -3
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build.cxx +8 -14
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build.hxx +2 -1
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build_deferred.hxx +15 -8
- package/deps/couchbase-cxx-client/core/operations/management/query_index_create.cxx +7 -14
- package/deps/couchbase-cxx-client/core/operations/management/query_index_create.hxx +2 -0
- package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.cxx +11 -16
- package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.hxx +2 -0
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.cxx +8 -12
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.hxx +4 -3
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.cxx +21 -12
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.hxx +3 -2
- package/deps/couchbase-cxx-client/core/origin.hxx +1 -1
- package/deps/couchbase-cxx-client/core/platform/uuid.cc +1 -2
- package/deps/couchbase-cxx-client/core/protocol/cmd_hello.hxx +5 -1
- package/deps/couchbase-cxx-client/core/query_context.hxx +79 -0
- package/deps/couchbase-cxx-client/core/tracing/CMakeLists.txt +3 -1
- package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.cxx +19 -4
- package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.hxx +2 -2
- package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +10 -4
- package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +52 -63
- package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +8 -3
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +163 -126
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +24 -37
- package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +4 -4
- package/deps/couchbase-cxx-client/core/transactions/internal/atr_cleanup_entry.hxx +51 -13
- package/deps/couchbase-cxx-client/core/transactions/internal/client_record.hxx +26 -1
- package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +21 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/logging.hxx +40 -18
- package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +5 -0
- package/deps/couchbase-cxx-client/core/transactions/result.hxx +26 -0
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +48 -47
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +6 -6
- package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +33 -19
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_result.hxx +18 -2
- package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +25 -2
- package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +4 -4
- package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +49 -56
- package/deps/couchbase-cxx-client/core/transactions/waitable_op_list.hxx +7 -7
- package/deps/couchbase-cxx-client/core/transactions.hxx +0 -12
- package/deps/couchbase-cxx-client/core/utils/binary.hxx +1 -1
- package/deps/couchbase-cxx-client/core/utils/keyspace.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +12 -45
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +6 -7
- package/deps/couchbase-cxx-client/couchbase/collection.hxx +8 -0
- package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +218 -0
- package/deps/couchbase-cxx-client/couchbase/configuration_profiles_registry.hxx +3 -0
- package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +166 -0
- package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +172 -0
- package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +129 -0
- package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +116 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/cas.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/fmt/query_scan_consistency.hxx +46 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/query_status.hxx +70 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/tls_verify_mode.hxx +46 -0
- package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +100 -0
- package/deps/couchbase-cxx-client/{core → couchbase}/management/query_index.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/metrics/meter.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +178 -6
- package/deps/couchbase-cxx-client/couchbase/query_options.hxx +1 -18
- package/deps/couchbase-cxx-client/couchbase/scope.hxx +5 -2
- package/deps/couchbase-cxx-client/couchbase/tracing/request_tracer.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +11 -4
- package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +5 -3
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_keyspace.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +0 -6
- package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +115 -0
- package/deps/couchbase-cxx-client/examples/minimal.cxx +3 -1
- package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +72 -0
- package/deps/couchbase-cxx-client/test/test_integration_management.cxx +727 -310
- package/deps/couchbase-cxx-client/test/test_integration_query.cxx +4 -8
- package/deps/couchbase-cxx-client/test/test_integration_transcoders.cxx +14 -0
- package/deps/couchbase-cxx-client/test/test_transaction_transaction_public_blocking_api.cxx +34 -19
- package/deps/couchbase-cxx-client/test/test_unit_transaction_logging.cxx +66 -22
- package/deps/couchbase-cxx-client/test/test_unit_utils.cxx +51 -0
- package/deps/couchbase-cxx-client/test/tools/tool_kv_loader.cxx +2 -2
- package/deps/couchbase-cxx-client/test/utils/integration_test_guard.cxx +2 -0
- package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +4 -4
- package/deps/couchbase-cxx-client/third_party/docopt/.travis.yml +103 -0
- package/deps/couchbase-cxx-client/third_party/docopt/CMakeLists.txt +129 -0
- package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-Boost-1.0 +23 -0
- package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-MIT +23 -0
- package/deps/couchbase-cxx-client/third_party/docopt/README.rst +479 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt-config.cmake +1 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.cpp +687 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.h +98 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.pc.in +9 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_private.h +676 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_util.h +122 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_value.h +341 -0
- package/deps/couchbase-cxx-client/third_party/docopt/examples/naval_fate.cpp +36 -0
- package/deps/couchbase-cxx-client/third_party/docopt/main.cpp +16 -0
- package/deps/couchbase-cxx-client/third_party/docopt/run_testcase.cpp +40 -0
- package/deps/couchbase-cxx-client/third_party/docopt/run_tests.py +72 -0
- package/deps/couchbase-cxx-client/third_party/docopt/testcases.docopt +957 -0
- package/deps/couchbase-cxx-client/tools/CMakeLists.txt +14 -0
- package/deps/couchbase-cxx-client/tools/cbc.cxx +65 -0
- package/deps/couchbase-cxx-client/tools/command.hxx +31 -0
- package/deps/couchbase-cxx-client/tools/command_registry.cxx +43 -0
- package/deps/couchbase-cxx-client/tools/command_registry.hxx +39 -0
- package/deps/couchbase-cxx-client/tools/get.cxx +267 -0
- package/deps/couchbase-cxx-client/tools/get.hxx +26 -0
- package/deps/couchbase-cxx-client/tools/query.cxx +441 -0
- package/deps/couchbase-cxx-client/tools/query.hxx +26 -0
- package/deps/couchbase-cxx-client/tools/utils.cxx +418 -0
- package/deps/couchbase-cxx-client/tools/utils.hxx +150 -0
- package/deps/couchbase-cxx-client/tools/version.cxx +82 -0
- package/deps/couchbase-cxx-client/tools/version.hxx +26 -0
- package/dist/authenticators.d.ts +2 -2
- package/dist/authenticators.js +1 -2
- package/dist/binding.d.ts +32 -16
- package/dist/cluster.js +14 -7
- package/dist/collection.d.ts +6 -0
- package/dist/collection.js +8 -0
- package/dist/queryexecutor.js +1 -1
- package/dist/queryindexmanager.d.ts +100 -4
- package/dist/queryindexmanager.js +344 -118
- package/dist/transactions.js +0 -2
- package/package.json +1 -1
- package/src/connection.cpp +2 -0
- package/src/connection.hpp +1 -0
- package/src/connection_autogen.cpp +16 -0
- package/src/jstocbpp_autogen.hpp +93 -23
- package/src/jstocbpp_basic.hpp +24 -0
- package/src/jstocbpp_transactions.hpp +0 -8
- package/tools/gen-bindings-js.js +1 -0
- package/tools/gen-bindings-json.py +4 -2
- package/deps/couchbase-cxx-client/core/transactions/logging.cxx +0 -107
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <couchbase/manager_error_context.hxx>
|
|
19
|
+
#include <couchbase/query_index_manager.hxx>
|
|
20
|
+
|
|
21
|
+
#include "core/cluster.hxx"
|
|
22
|
+
#include "core/operations/management/query_index_build.hxx"
|
|
23
|
+
#include "core/operations/management/query_index_get_all.hxx"
|
|
24
|
+
|
|
25
|
+
namespace couchbase::core::impl
|
|
26
|
+
{
|
|
27
|
+
template<typename Response>
|
|
28
|
+
static manager_error_context
|
|
29
|
+
build_context(Response& resp)
|
|
30
|
+
{
|
|
31
|
+
return { resp.ctx.ec,
|
|
32
|
+
resp.ctx.last_dispatched_to,
|
|
33
|
+
resp.ctx.last_dispatched_from,
|
|
34
|
+
resp.ctx.retry_attempts,
|
|
35
|
+
std::move(resp.ctx.retry_reasons),
|
|
36
|
+
std::move(resp.ctx.client_context_id),
|
|
37
|
+
resp.ctx.http_status,
|
|
38
|
+
std::move(resp.ctx.http_body),
|
|
39
|
+
std::move(resp.ctx.path) };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void
|
|
43
|
+
initiate_get_all_query_indexes(std::shared_ptr<couchbase::core::cluster> core,
|
|
44
|
+
std::string bucket_name,
|
|
45
|
+
couchbase::get_all_query_indexes_options::built options,
|
|
46
|
+
query_context query_ctx,
|
|
47
|
+
std::string collection_name,
|
|
48
|
+
get_all_indexes_handler&& handler)
|
|
49
|
+
{
|
|
50
|
+
core->execute(
|
|
51
|
+
operations::management::query_index_get_all_request{
|
|
52
|
+
bucket_name,
|
|
53
|
+
"",
|
|
54
|
+
collection_name,
|
|
55
|
+
query_ctx,
|
|
56
|
+
{},
|
|
57
|
+
options.timeout,
|
|
58
|
+
},
|
|
59
|
+
[handler = std::move(handler)](operations::management::query_index_get_all_response resp) {
|
|
60
|
+
if (resp.ctx.ec) {
|
|
61
|
+
return handler(build_context(resp), {});
|
|
62
|
+
}
|
|
63
|
+
handler(build_context(resp), resp.indexes);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void
|
|
68
|
+
initiate_get_all_query_indexes(std::shared_ptr<couchbase::core::cluster> core,
|
|
69
|
+
std::string bucket_name,
|
|
70
|
+
couchbase::get_all_query_indexes_options::built options,
|
|
71
|
+
get_all_indexes_handler&& handler)
|
|
72
|
+
{
|
|
73
|
+
initiate_get_all_query_indexes(core, std::move(bucket_name), options, {}, "", std::move(handler));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
} // namespace couchbase::core::impl
|
|
@@ -168,10 +168,8 @@ build_query_request(query_options::built options)
|
|
|
168
168
|
options.pipeline_cap,
|
|
169
169
|
options.scan_consistency,
|
|
170
170
|
std::move(options.mutation_state),
|
|
171
|
-
{},
|
|
172
|
-
{},
|
|
173
|
-
std::move(options.scope_qualifier),
|
|
174
171
|
std::move(options.client_context_id),
|
|
172
|
+
{}, // we put the query_context in later, if one was specified.
|
|
175
173
|
options.timeout,
|
|
176
174
|
options.profile,
|
|
177
175
|
};
|
|
@@ -227,15 +225,15 @@ build_transaction_query_request(query_options::built opts)
|
|
|
227
225
|
void
|
|
228
226
|
initiate_query_operation(std::shared_ptr<couchbase::core::cluster> core,
|
|
229
227
|
std::string statement,
|
|
230
|
-
std::optional<std::string>
|
|
231
|
-
std::optional<std::string> scope_name,
|
|
228
|
+
std::optional<std::string> query_context,
|
|
232
229
|
query_options::built options,
|
|
233
230
|
query_handler&& handler)
|
|
234
231
|
{
|
|
235
232
|
auto request = build_query_request(options);
|
|
236
233
|
request.statement = std::move(statement);
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
if (query_context) {
|
|
235
|
+
request.query_context = std::move(query_context);
|
|
236
|
+
}
|
|
239
237
|
|
|
240
238
|
core->execute(std::move(request), [core, handler = std::move(handler)](operations::query_response resp) mutable {
|
|
241
239
|
auto r = std::move(resp);
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <couchbase/error_codes.hxx>
|
|
19
|
+
#include <couchbase/management/query_index.hxx>
|
|
20
|
+
#include <couchbase/query_index_manager.hxx>
|
|
21
|
+
|
|
22
|
+
#include "core/cluster.hxx"
|
|
23
|
+
#include "core/operations/management/query_index_get_all.hxx"
|
|
24
|
+
|
|
25
|
+
namespace couchbase::core::impl
|
|
26
|
+
{
|
|
27
|
+
|
|
28
|
+
template<typename Response>
|
|
29
|
+
static manager_error_context
|
|
30
|
+
build_context(Response& resp, std::optional<std::error_code> ec = {})
|
|
31
|
+
{
|
|
32
|
+
return { ec ? ec.value() : resp.ctx.ec, resp.ctx.last_dispatched_to, resp.ctx.last_dispatched_from,
|
|
33
|
+
resp.ctx.retry_attempts, std::move(resp.ctx.retry_reasons), std::move(resp.ctx.client_context_id),
|
|
34
|
+
resp.ctx.http_status, std::move(resp.ctx.http_body), std::move(resp.ctx.path) };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class watch_context : public std::enable_shared_from_this<watch_context>
|
|
38
|
+
{
|
|
39
|
+
|
|
40
|
+
private:
|
|
41
|
+
std::shared_ptr<couchbase::core::cluster> core_;
|
|
42
|
+
std::string bucket_name_;
|
|
43
|
+
std::vector<std::string> index_names_;
|
|
44
|
+
couchbase::watch_query_indexes_options::built options_;
|
|
45
|
+
query_context query_ctx_;
|
|
46
|
+
std::string collection_name_;
|
|
47
|
+
watch_query_indexes_handler handler_;
|
|
48
|
+
asio::steady_timer timer_{ core_->io_context() };
|
|
49
|
+
std::chrono::steady_clock::time_point start_time_{ std::chrono::steady_clock::now() };
|
|
50
|
+
std::chrono::milliseconds timeout_{ options_.timeout.value_or(core_->origin().second.options().query_timeout) };
|
|
51
|
+
std::atomic<size_t> attempts_{ 0 };
|
|
52
|
+
|
|
53
|
+
void finish(manager_error_context error_ctx)
|
|
54
|
+
{
|
|
55
|
+
handler_(error_ctx);
|
|
56
|
+
timer_.cancel();
|
|
57
|
+
}
|
|
58
|
+
std::chrono::milliseconds remaining()
|
|
59
|
+
{
|
|
60
|
+
return timeout_ - std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time_);
|
|
61
|
+
}
|
|
62
|
+
operations::management::query_index_get_all_request make_request()
|
|
63
|
+
{
|
|
64
|
+
return { bucket_name_, "", collection_name_, query_ctx_, {}, remaining() };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
bool check(couchbase::core::operations::management::query_index_get_all_response resp)
|
|
68
|
+
{
|
|
69
|
+
bool complete = true;
|
|
70
|
+
for (auto name : index_names_) {
|
|
71
|
+
auto it = std::find_if(resp.indexes.begin(), resp.indexes.end(), [&](const couchbase::management::query::index& index) {
|
|
72
|
+
return index.name == name;
|
|
73
|
+
});
|
|
74
|
+
complete &= (it != resp.indexes.end() && it->state == "online");
|
|
75
|
+
}
|
|
76
|
+
if (options_.watch_primary) {
|
|
77
|
+
auto it = std::find_if(
|
|
78
|
+
resp.indexes.begin(), resp.indexes.end(), [&](const couchbase::management::query::index& index) { return index.is_primary; });
|
|
79
|
+
complete &= it != resp.indexes.end() && it->state == "online";
|
|
80
|
+
}
|
|
81
|
+
if (complete || resp.ctx.ec == couchbase::errc::common::ambiguous_timeout) {
|
|
82
|
+
finish(build_context(resp));
|
|
83
|
+
} else if (remaining().count() <= 0) {
|
|
84
|
+
finish(build_context(resp, couchbase::errc::common::ambiguous_timeout));
|
|
85
|
+
complete = true;
|
|
86
|
+
}
|
|
87
|
+
return complete;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void poll()
|
|
91
|
+
{
|
|
92
|
+
timer_.expires_after(options_.polling_interval);
|
|
93
|
+
auto timer_f = [ctx = shared_from_this()](asio::error_code) { ctx->execute(); };
|
|
94
|
+
timer_.async_wait(timer_f);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public:
|
|
98
|
+
watch_context(std::shared_ptr<couchbase::core::cluster> core,
|
|
99
|
+
std::string bucket_name,
|
|
100
|
+
std::vector<std::string> index_names,
|
|
101
|
+
couchbase::watch_query_indexes_options::built options,
|
|
102
|
+
query_context query_ctx,
|
|
103
|
+
std::string collection_name,
|
|
104
|
+
watch_query_indexes_handler&& handler)
|
|
105
|
+
: core_(core)
|
|
106
|
+
, bucket_name_(bucket_name)
|
|
107
|
+
, index_names_(index_names)
|
|
108
|
+
, options_(options)
|
|
109
|
+
, query_ctx_(query_ctx)
|
|
110
|
+
, collection_name_(collection_name)
|
|
111
|
+
, handler_(std::move(handler))
|
|
112
|
+
, attempts_(0)
|
|
113
|
+
{
|
|
114
|
+
}
|
|
115
|
+
watch_context(watch_context&& other)
|
|
116
|
+
: core_(std::move(other.core_))
|
|
117
|
+
, bucket_name_(std::move(other.bucket_name_))
|
|
118
|
+
, index_names_(std::move(other.index_names_))
|
|
119
|
+
, options_(std::move(other.options_))
|
|
120
|
+
, query_ctx_(std::move(other.query_ctx_))
|
|
121
|
+
, collection_name_(std::move(other.collection_name_))
|
|
122
|
+
, handler_(std::move(other.handler_))
|
|
123
|
+
, timer_(std::move(other.timer_))
|
|
124
|
+
, start_time_(std::move(other.start_time_))
|
|
125
|
+
, timeout_(std::move(other.timeout_))
|
|
126
|
+
, attempts_(other.attempts_.load())
|
|
127
|
+
{
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void execute()
|
|
131
|
+
{
|
|
132
|
+
auto req = make_request();
|
|
133
|
+
CB_LOG_TRACE("watch indexes executing request");
|
|
134
|
+
auto resp_fn = [ctx = shared_from_this()](operations::management::query_index_get_all_response resp) {
|
|
135
|
+
CB_LOG_TRACE("watch indexes got {}", resp.ctx.ec.message());
|
|
136
|
+
if (!ctx->check(resp)) {
|
|
137
|
+
// now we try again
|
|
138
|
+
ctx->poll();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
core_->execute(req, resp_fn);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
void
|
|
146
|
+
initiate_watch_query_indexes(std::shared_ptr<couchbase::core::cluster> core,
|
|
147
|
+
std::string bucket_name,
|
|
148
|
+
std::vector<std::string> index_names,
|
|
149
|
+
couchbase::watch_query_indexes_options::built options,
|
|
150
|
+
query_context query_ctx,
|
|
151
|
+
std::string collection_name,
|
|
152
|
+
watch_query_indexes_handler&& handler)
|
|
153
|
+
{
|
|
154
|
+
auto ctx = std::make_shared<watch_context>(core, bucket_name, index_names, options, query_ctx, collection_name, std::move(handler));
|
|
155
|
+
ctx->execute();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
void
|
|
159
|
+
initiate_watch_query_indexes(std::shared_ptr<couchbase::core::cluster> core,
|
|
160
|
+
std::string bucket_name,
|
|
161
|
+
std::vector<std::string> index_names,
|
|
162
|
+
couchbase::watch_query_indexes_options::built options,
|
|
163
|
+
watch_query_indexes_handler&& handler)
|
|
164
|
+
{
|
|
165
|
+
initiate_watch_query_indexes(core, std::move(bucket_name), std::move(index_names), options, {}, "", std::move(handler));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
} // namespace couchbase::core::impl
|
|
@@ -111,11 +111,22 @@ class mcbp_session_impl
|
|
|
111
111
|
stopped_.compare_exchange_strong(expected_state, true);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
static auto sasl_mechanisms(const std::shared_ptr<mcbp_session_impl>& session) -> std::vector<std::string>
|
|
115
|
+
{
|
|
116
|
+
if (const auto user_mechanisms = session->origin_.credentials().allowed_sasl_mechanisms; user_mechanisms.has_value()) {
|
|
117
|
+
return user_mechanisms.value();
|
|
118
|
+
}
|
|
119
|
+
if (session->is_tls_) {
|
|
120
|
+
return { "PLAIN" };
|
|
121
|
+
}
|
|
122
|
+
return { "SCRAM-SHA512", "SCRAM-SHA256", "SCRAM-SHA1" };
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
explicit bootstrap_handler(std::shared_ptr<mcbp_session_impl> session)
|
|
115
126
|
: session_(std::move(session))
|
|
116
127
|
, sasl_([origin = session_->origin_]() { return origin.username(); },
|
|
117
128
|
[origin = session_->origin_]() { return origin.password(); },
|
|
118
|
-
session_
|
|
129
|
+
sasl_mechanisms(session_))
|
|
119
130
|
{
|
|
120
131
|
protocol::client_request<protocol::hello_request_body> hello_req;
|
|
121
132
|
if (session_->origin_.options().enable_unordered_execution) {
|
|
@@ -127,6 +138,9 @@ class mcbp_session_impl
|
|
|
127
138
|
if (session_->origin_.options().enable_compression) {
|
|
128
139
|
hello_req.body().enable_compression();
|
|
129
140
|
}
|
|
141
|
+
if (session_->origin_.options().enable_mutation_tokens) {
|
|
142
|
+
hello_req.body().enable_mutation_tokens();
|
|
143
|
+
}
|
|
130
144
|
hello_req.opaque(session_->next_opaque());
|
|
131
145
|
auto user_agent =
|
|
132
146
|
meta::user_agent_for_mcbp(session_->client_id_, session_->id_, session_->origin_.options().user_agent_extra, 250);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2018-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Use of this software is governed by the Business Source License included
|
|
6
|
+
* in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
|
|
7
|
+
* in that file, in accordance with the Business Source License, use of this
|
|
8
|
+
* software will be governed by the Apache License, Version 2.0, included in
|
|
9
|
+
* the file licenses/APL2.txt.
|
|
10
|
+
*/
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
namespace couchbase::core::logger
|
|
14
|
+
{
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* the various severity levels we can log at
|
|
18
|
+
*/
|
|
19
|
+
enum class level { trace, debug, info, warn, err, critical, off };
|
|
20
|
+
|
|
21
|
+
} // namespace couchbase::core::logger
|
|
@@ -25,21 +25,19 @@
|
|
|
25
25
|
|
|
26
26
|
#pragma once
|
|
27
27
|
|
|
28
|
+
#include "level.hxx"
|
|
29
|
+
|
|
28
30
|
#include <fmt/core.h>
|
|
31
|
+
#include <spdlog/fwd.h>
|
|
32
|
+
|
|
29
33
|
#include <memory>
|
|
30
34
|
#include <optional>
|
|
31
|
-
#include <spdlog/fwd.h>
|
|
32
35
|
#include <string>
|
|
33
36
|
|
|
34
37
|
namespace couchbase::core::logger
|
|
35
38
|
{
|
|
36
39
|
struct configuration;
|
|
37
40
|
|
|
38
|
-
/**
|
|
39
|
-
* the various severity levels we can log at
|
|
40
|
-
*/
|
|
41
|
-
enum class level { trace, debug, info, warn, err, critical, off };
|
|
42
|
-
|
|
43
41
|
level
|
|
44
42
|
level_from_str(const std::string& str);
|
|
45
43
|
|
|
@@ -7,8 +7,10 @@ target_link_libraries(
|
|
|
7
7
|
snappy
|
|
8
8
|
fmt::fmt
|
|
9
9
|
spdlog::spdlog)
|
|
10
|
-
target_include_directories(couchbase_meta PRIVATE
|
|
11
|
-
|
|
10
|
+
target_include_directories(couchbase_meta PRIVATE
|
|
11
|
+
${PROJECT_BINARY_DIR}/generated
|
|
12
|
+
${PROJECT_SOURCE_DIR}
|
|
13
|
+
${PROJECT_SOURCE_DIR}/third_party/http_parser)
|
|
12
14
|
|
|
13
15
|
if(NOT COUCHBASE_CXX_CLIENT_POST_LINKED_OPENSSL)
|
|
14
16
|
target_link_libraries(couchbase_meta PUBLIC OpenSSL::SSL OpenSSL::Crypto)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2022-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#pragma once
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* This header defines macros for the various features to help
|
|
22
|
+
* users adopt early features or use conditional compilation to avoid
|
|
23
|
+
* unnecessary or untested code.
|
|
24
|
+
*
|
|
25
|
+
* Feel free to update this header with more macros.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* couchbase::core::meta::sdk_version() function is available
|
|
30
|
+
*/
|
|
31
|
+
#define COUCHBASE_CXX_CLIENT_HAS_SDK_SEMVER 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
2
|
/*
|
|
3
|
-
* Copyright 2020-
|
|
3
|
+
* Copyright 2020-Present Couchbase, Inc.
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
#include <snappy-stubs-public.h>
|
|
33
33
|
#include <spdlog/version.h>
|
|
34
34
|
|
|
35
|
+
#include <regex>
|
|
36
|
+
|
|
35
37
|
namespace couchbase::core::meta
|
|
36
38
|
{
|
|
37
39
|
std::map<std::string, std::string>
|
|
@@ -52,6 +54,7 @@ sdk_build_info()
|
|
|
52
54
|
#else
|
|
53
55
|
info["snapshot"] = "false";
|
|
54
56
|
#endif
|
|
57
|
+
info["semver"] = sdk_semver();
|
|
55
58
|
auto txns_forward_compat = core::transactions::forward_compat_supported{};
|
|
56
59
|
info["txns_forward_compat_protocol_version"] =
|
|
57
60
|
fmt::format("{}.{}", txns_forward_compat.protocol_major, txns_forward_compat.protocol_minor);
|
|
@@ -140,14 +143,73 @@ sdk_build_info_short()
|
|
|
140
143
|
const std::string&
|
|
141
144
|
sdk_id()
|
|
142
145
|
{
|
|
143
|
-
static const std::string identifier{
|
|
144
|
-
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_MINOR) + "." +
|
|
145
|
-
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_PATCH) + "/" +
|
|
146
|
-
COUCHBASE_CXX_CLIENT_GIT_REVISION_SHORT + ";" + COUCHBASE_CXX_CLIENT_SYSTEM_NAME + "/" +
|
|
146
|
+
static const std::string identifier{ sdk_version() + ";" + COUCHBASE_CXX_CLIENT_SYSTEM_NAME + "/" +
|
|
147
147
|
COUCHBASE_CXX_CLIENT_SYSTEM_PROCESSOR };
|
|
148
148
|
return identifier;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
std::string
|
|
152
|
+
parse_git_describe_output(const std::string& git_describe_output)
|
|
153
|
+
{
|
|
154
|
+
if (git_describe_output.empty() || git_describe_output == "unknown") {
|
|
155
|
+
return "";
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static const std::regex version_regex(R"(^(\d+(?:\.\d+){2})(?:-(\w+(?:\.\w+)*))?(-(\d+)-g(\w+))?$)");
|
|
159
|
+
std::smatch match;
|
|
160
|
+
if (std::regex_match(git_describe_output, match, version_regex)) {
|
|
161
|
+
auto version_core = match[1].str();
|
|
162
|
+
auto pre_release = match[2].str();
|
|
163
|
+
auto number_of_commits{ 0 };
|
|
164
|
+
if (match[4].matched) {
|
|
165
|
+
number_of_commits = std::stoi(match[4].str());
|
|
166
|
+
}
|
|
167
|
+
if (auto build = match[5].str(); !build.empty() && number_of_commits > 0) {
|
|
168
|
+
if (pre_release.empty()) {
|
|
169
|
+
return fmt::format("{}+{}.{}", version_core, number_of_commits, build);
|
|
170
|
+
}
|
|
171
|
+
return fmt::format("{}-{}+{}.{}", version_core, pre_release, number_of_commits, build);
|
|
172
|
+
}
|
|
173
|
+
if (pre_release.empty()) {
|
|
174
|
+
return fmt::format("{}", version_core);
|
|
175
|
+
}
|
|
176
|
+
return fmt::format("{}-{}", version_core, pre_release);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return "";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const std::string&
|
|
183
|
+
sdk_semver()
|
|
184
|
+
{
|
|
185
|
+
static const std::string simple_version{ std::to_string(COUCHBASE_CXX_CLIENT_VERSION_MAJOR) + "." +
|
|
186
|
+
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_MINOR) + "." +
|
|
187
|
+
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_PATCH) + "+" +
|
|
188
|
+
std::string(COUCHBASE_CXX_CLIENT_GIT_REVISION_SHORT) };
|
|
189
|
+
static const std::string git_describe_output{ COUCHBASE_CXX_CLIENT_GIT_DESCRIBE };
|
|
190
|
+
static const std::string semantic_version = parse_git_describe_output(git_describe_output);
|
|
191
|
+
if (semantic_version.empty()) {
|
|
192
|
+
return simple_version;
|
|
193
|
+
}
|
|
194
|
+
return semantic_version;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const std::string&
|
|
198
|
+
sdk_version()
|
|
199
|
+
{
|
|
200
|
+
static const std::string version{ sdk_version_short() + "/" + COUCHBASE_CXX_CLIENT_GIT_REVISION_SHORT };
|
|
201
|
+
return version;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const std::string&
|
|
205
|
+
sdk_version_short()
|
|
206
|
+
{
|
|
207
|
+
static const std::string version{ std::string("cxx/") + std::to_string(COUCHBASE_CXX_CLIENT_VERSION_MAJOR) + "." +
|
|
208
|
+
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_MINOR) + "." +
|
|
209
|
+
std::to_string(COUCHBASE_CXX_CLIENT_VERSION_PATCH) };
|
|
210
|
+
return version;
|
|
211
|
+
}
|
|
212
|
+
|
|
151
213
|
const std::string&
|
|
152
214
|
os()
|
|
153
215
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
2
|
/*
|
|
3
|
-
* Copyright 2020-
|
|
3
|
+
* Copyright 2020-Present Couchbase, Inc.
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -20,11 +20,22 @@
|
|
|
20
20
|
#include <map>
|
|
21
21
|
#include <string>
|
|
22
22
|
|
|
23
|
+
#include "features.hxx"
|
|
24
|
+
|
|
23
25
|
namespace couchbase::core::meta
|
|
24
26
|
{
|
|
25
27
|
const std::string&
|
|
26
28
|
sdk_id();
|
|
27
29
|
|
|
30
|
+
const std::string&
|
|
31
|
+
sdk_semver();
|
|
32
|
+
|
|
33
|
+
const std::string&
|
|
34
|
+
sdk_version();
|
|
35
|
+
|
|
36
|
+
const std::string&
|
|
37
|
+
sdk_version_short();
|
|
38
|
+
|
|
28
39
|
std::map<std::string, std::string>
|
|
29
40
|
sdk_build_info();
|
|
30
41
|
|
|
@@ -7,4 +7,7 @@ target_link_libraries(
|
|
|
7
7
|
hdr_histogram_static
|
|
8
8
|
fmt::fmt
|
|
9
9
|
spdlog::spdlog)
|
|
10
|
-
target_include_directories(couchbase_metrics PRIVATE
|
|
10
|
+
target_include_directories(couchbase_metrics PRIVATE
|
|
11
|
+
${PROJECT_BINARY_DIR}/generated
|
|
12
|
+
${PROJECT_SOURCE_DIR}
|
|
13
|
+
${PROJECT_SOURCE_DIR}/third_party/hdr_histogram_c/src)
|
|
@@ -17,12 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
#include "logging_meter.hxx"
|
|
19
19
|
|
|
20
|
+
#include "couchbase/build_info.hxx"
|
|
21
|
+
|
|
20
22
|
#include "core/logger/logger.hxx"
|
|
21
23
|
#include "core/utils/json.hxx"
|
|
22
24
|
#include "noop_meter.hxx"
|
|
23
25
|
|
|
24
|
-
#include
|
|
26
|
+
#include <hdr_histogram.h>
|
|
27
|
+
|
|
25
28
|
#include <gsl/assert>
|
|
29
|
+
|
|
26
30
|
#include <memory>
|
|
27
31
|
#include <utility>
|
|
28
32
|
|
|
@@ -142,7 +146,7 @@ logging_meter::log_report() const
|
|
|
142
146
|
{
|
|
143
147
|
|
|
144
148
|
{ "emit_interval_s", std::chrono::duration_cast<std::chrono::seconds>(options_.emit_interval).count() },
|
|
145
|
-
#if
|
|
149
|
+
#if COUCHBASE_CXX_CLIENT_DEBUG_BUILD
|
|
146
150
|
{ "emit_interval_ms", options_.emit_interval.count() },
|
|
147
151
|
#endif
|
|
148
152
|
},
|
|
@@ -158,22 +162,59 @@ logging_meter::log_report() const
|
|
|
158
162
|
}
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
logging_meter::logging_meter(asio::io_context& ctx, logging_meter_options options)
|
|
166
|
+
: emit_report_(ctx)
|
|
167
|
+
, options_(options)
|
|
168
|
+
{
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
logging_meter::~logging_meter()
|
|
172
|
+
{
|
|
173
|
+
emit_report_.cancel();
|
|
174
|
+
log_report();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
void
|
|
178
|
+
logging_meter::rearm_reporter()
|
|
179
|
+
{
|
|
180
|
+
emit_report_.expires_after(options_.emit_interval);
|
|
181
|
+
emit_report_.async_wait([self = shared_from_this()](std::error_code ec) {
|
|
182
|
+
if (ec == asio::error::operation_aborted) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
self->log_report();
|
|
186
|
+
self->rearm_reporter();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
void
|
|
191
|
+
logging_meter::start()
|
|
192
|
+
{
|
|
193
|
+
rearm_reporter();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
void
|
|
197
|
+
logging_meter::stop()
|
|
198
|
+
{
|
|
199
|
+
emit_report_.cancel();
|
|
200
|
+
}
|
|
201
|
+
|
|
161
202
|
std::shared_ptr<couchbase::metrics::value_recorder>
|
|
162
203
|
logging_meter::get_value_recorder(const std::string& name, const std::map<std::string, std::string>& tags)
|
|
163
204
|
{
|
|
164
205
|
static std::shared_ptr<noop_value_recorder> noop_recorder{ std::make_shared<noop_value_recorder>() };
|
|
165
206
|
|
|
166
|
-
if (static std::string meter_name = "db.couchbase.operations"; name != meter_name) {
|
|
207
|
+
if (static const std::string meter_name = "db.couchbase.operations"; name != meter_name) {
|
|
167
208
|
return noop_recorder;
|
|
168
209
|
}
|
|
169
210
|
|
|
170
|
-
static std::string service_tag = "db.couchbase.service";
|
|
211
|
+
static const std::string service_tag = "db.couchbase.service";
|
|
171
212
|
auto service = tags.find(service_tag);
|
|
172
213
|
if (service == tags.end()) {
|
|
173
214
|
return noop_recorder;
|
|
174
215
|
}
|
|
175
216
|
|
|
176
|
-
static std::string operation_tag = "db.operation";
|
|
217
|
+
static const std::string operation_tag = "db.operation";
|
|
177
218
|
auto operation = tags.find(operation_tag);
|
|
178
219
|
if (operation == tags.end()) {
|
|
179
220
|
return noop_recorder;
|