couchbase 3.4.2 → 3.4.3
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/couchbase/CMakeLists.txt +57 -7
- data/ext/couchbase/cmake/Documentation.cmake +0 -1
- data/ext/couchbase/cmake/OpenSSL.cmake +98 -3
- data/ext/couchbase/cmake/Testing.cmake +12 -4
- data/ext/couchbase/cmake/build_config.hxx.in +3 -0
- data/ext/couchbase/core/bucket.cxx +3 -2
- data/ext/couchbase/core/bucket.hxx +9 -0
- data/ext/couchbase/core/cluster.hxx +17 -0
- data/ext/couchbase/core/cluster_options.cxx +2 -2
- data/ext/couchbase/core/cluster_options.hxx +4 -6
- data/ext/couchbase/core/cluster_options_fwd.hxx +26 -0
- data/ext/couchbase/core/config_profile.hxx +1 -54
- data/ext/couchbase/core/config_profiles.cxx +79 -0
- data/ext/couchbase/core/config_profiles.hxx +56 -0
- data/ext/couchbase/core/error_context/search.hxx +1 -1
- data/ext/couchbase/core/impl/analytics.cxx +1 -0
- data/ext/couchbase/core/impl/boolean_field_query.cxx +40 -0
- data/ext/couchbase/core/impl/boolean_query.cxx +62 -0
- data/ext/couchbase/core/impl/cluster.cxx +2 -0
- data/ext/couchbase/core/impl/conjunction_query.cxx +51 -0
- data/ext/couchbase/core/impl/date_range.cxx +89 -0
- data/ext/couchbase/core/impl/date_range_facet.cxx +54 -0
- data/ext/couchbase/core/impl/date_range_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/date_range_query.cxx +125 -0
- data/ext/couchbase/core/impl/disjunction_query.cxx +51 -0
- data/ext/couchbase/core/impl/encoded_search_facet.hxx +29 -0
- data/ext/couchbase/core/impl/encoded_search_query.hxx +29 -0
- data/ext/couchbase/core/impl/encoded_search_sort.hxx +29 -0
- data/ext/couchbase/core/impl/geo_bounding_box_query.cxx +46 -0
- data/ext/couchbase/core/impl/geo_distance_query.cxx +43 -0
- data/ext/couchbase/core/impl/geo_polygon_query.cxx +46 -0
- data/ext/couchbase/core/impl/internal_date_range_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_date_range_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/internal_numeric_range_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_numeric_range_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/internal_search_error_context.cxx +141 -0
- data/ext/couchbase/core/impl/internal_search_error_context.hxx +61 -0
- data/ext/couchbase/core/impl/internal_search_meta_data.cxx +60 -0
- data/ext/couchbase/core/impl/internal_search_meta_data.hxx +41 -0
- data/ext/couchbase/core/impl/internal_search_result.cxx +84 -0
- data/ext/couchbase/core/impl/internal_search_result.hxx +43 -0
- data/ext/couchbase/core/impl/internal_search_row.cxx +82 -0
- data/ext/couchbase/core/impl/internal_search_row.hxx +56 -0
- data/ext/couchbase/core/impl/internal_search_row_location.hxx +32 -0
- data/ext/couchbase/core/impl/internal_search_row_locations.cxx +137 -0
- data/ext/couchbase/core/impl/internal_search_row_locations.hxx +45 -0
- data/ext/couchbase/core/impl/internal_term_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_term_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/match_all_query.cxx +35 -0
- data/ext/couchbase/core/impl/match_none_query.cxx +35 -0
- data/ext/couchbase/core/impl/match_phrase_query.cxx +43 -0
- data/ext/couchbase/core/impl/match_query.cxx +59 -0
- data/ext/couchbase/core/impl/numeric_range.cxx +49 -0
- data/ext/couchbase/core/impl/numeric_range_facet.cxx +54 -0
- data/ext/couchbase/core/impl/numeric_range_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/numeric_range_query.cxx +56 -0
- data/ext/couchbase/core/impl/phrase_query.cxx +42 -0
- data/ext/couchbase/core/impl/prefix_query.cxx +40 -0
- data/ext/couchbase/core/impl/query_string_query.cxx +37 -0
- data/ext/couchbase/core/impl/regexp_query.cxx +40 -0
- data/ext/couchbase/core/impl/search.cxx +191 -0
- data/ext/couchbase/core/impl/search_error_context.cxx +147 -0
- data/ext/couchbase/core/impl/search_meta_data.cxx +46 -0
- data/ext/couchbase/core/impl/search_result.cxx +66 -0
- data/ext/couchbase/core/impl/search_row.cxx +74 -0
- data/ext/couchbase/core/impl/search_row_location.cxx +64 -0
- data/ext/couchbase/core/impl/search_row_locations.cxx +66 -0
- data/ext/couchbase/core/impl/search_sort_field.cxx +104 -0
- data/ext/couchbase/core/impl/search_sort_id.cxx +43 -0
- data/ext/couchbase/core/impl/search_sort_score.cxx +43 -0
- data/ext/couchbase/core/impl/term_facet.cxx +36 -0
- data/ext/couchbase/core/impl/term_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/term_query.cxx +56 -0
- data/ext/couchbase/core/impl/term_range_query.cxx +57 -0
- data/ext/couchbase/core/impl/wildcard_query.cxx +40 -0
- data/ext/couchbase/core/io/http_context.hxx +1 -1
- data/ext/couchbase/core/io/http_session.hxx +10 -0
- data/ext/couchbase/core/io/http_session_manager.hxx +5 -3
- data/ext/couchbase/core/io/mcbp_session.cxx +28 -1
- data/ext/couchbase/core/io/retry_orchestrator.hxx +3 -2
- data/ext/couchbase/core/json_string.hxx +5 -0
- data/ext/couchbase/core/meta/version.cxx +18 -4
- data/ext/couchbase/core/mozilla_ca_bundle.hxx +39 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +1 -0
- data/ext/couchbase/core/operations/document_analytics.hxx +1 -0
- data/ext/couchbase/core/operations/document_append.hxx +1 -1
- data/ext/couchbase/core/operations/document_decrement.hxx +1 -1
- data/ext/couchbase/core/operations/document_exists.hxx +1 -1
- data/ext/couchbase/core/operations/document_get.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_and_lock.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_and_touch.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_projected.hxx +1 -1
- data/ext/couchbase/core/operations/document_increment.hxx +1 -1
- data/ext/couchbase/core/operations/document_insert.hxx +1 -1
- data/ext/couchbase/core/operations/document_lookup_in.hxx +1 -1
- data/ext/couchbase/core/operations/document_mutate_in.hxx +1 -1
- data/ext/couchbase/core/operations/document_prepend.hxx +1 -1
- data/ext/couchbase/core/operations/document_query.cxx +2 -0
- data/ext/couchbase/core/operations/document_query.hxx +6 -0
- data/ext/couchbase/core/operations/document_remove.hxx +1 -1
- data/ext/couchbase/core/operations/document_replace.hxx +1 -1
- data/ext/couchbase/core/operations/document_search.cxx +4 -1
- data/ext/couchbase/core/operations/document_search.hxx +2 -1
- data/ext/couchbase/core/operations/document_touch.hxx +1 -1
- data/ext/couchbase/core/operations/document_unlock.hxx +1 -1
- data/ext/couchbase/core/operations/document_upsert.hxx +1 -1
- data/ext/couchbase/core/operations/document_view.hxx +1 -0
- data/ext/couchbase/core/protocol/client_request.hxx +11 -2
- data/ext/couchbase/core/public_fwd.hxx +21 -0
- data/ext/couchbase/core/tls_verify_mode.hxx +26 -0
- data/ext/couchbase/core/topology/configuration.cxx +15 -2
- data/ext/couchbase/core/topology/configuration.hxx +5 -1
- data/ext/couchbase/core/transactions/attempt_context_testing_hooks.cxx +93 -0
- data/ext/couchbase/core/transactions/attempt_context_testing_hooks.hxx +48 -75
- data/ext/couchbase/core/transactions/cleanup_testing_hooks.cxx +52 -0
- data/ext/couchbase/core/transactions/cleanup_testing_hooks.hxx +17 -31
- data/ext/couchbase/core/transactions/exceptions.hxx +12 -9
- data/ext/couchbase/core/utils/connection_string.cxx +17 -0
- data/ext/couchbase/core/utils/json.cxx +4 -1
- data/ext/couchbase/couchbase/behavior_options.hxx +10 -1
- data/ext/couchbase/couchbase/boolean_field_query.hxx +77 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +223 -0
- data/ext/couchbase/couchbase/cluster.hxx +42 -1
- data/ext/couchbase/couchbase/conjunction_query.hxx +88 -0
- data/ext/couchbase/couchbase/date_range.hxx +69 -0
- data/ext/couchbase/couchbase/date_range_facet.hxx +56 -0
- data/ext/couchbase/couchbase/date_range_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/date_range_query.hxx +265 -0
- data/ext/couchbase/couchbase/disjunction_query.hxx +109 -0
- data/ext/couchbase/couchbase/doc_id_query.hxx +111 -0
- data/ext/couchbase/couchbase/error_context.hxx +7 -6
- data/ext/couchbase/couchbase/fmt/analytics_scan_consistency.hxx +52 -0
- data/ext/couchbase/couchbase/fmt/search_scan_consistency.hxx +49 -0
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +107 -0
- data/ext/couchbase/couchbase/geo_distance_query.hxx +109 -0
- data/ext/couchbase/couchbase/geo_point.hxx +32 -0
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +85 -0
- data/ext/couchbase/couchbase/highlight_style.hxx +45 -0
- data/ext/couchbase/couchbase/match_all_query.hxx +43 -0
- data/ext/couchbase/couchbase/match_none_query.hxx +43 -0
- data/ext/couchbase/couchbase/match_operator.hxx +45 -0
- data/ext/couchbase/couchbase/match_phrase_query.hxx +108 -0
- data/ext/couchbase/couchbase/match_query.hxx +163 -0
- data/ext/couchbase/couchbase/numeric_range.hxx +58 -0
- data/ext/couchbase/couchbase/numeric_range_facet.hxx +56 -0
- data/ext/couchbase/couchbase/numeric_range_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/numeric_range_query.hxx +143 -0
- data/ext/couchbase/couchbase/phrase_query.hxx +93 -0
- data/ext/couchbase/couchbase/prefix_query.hxx +82 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +72 -0
- data/ext/couchbase/couchbase/regexp_query.hxx +82 -0
- data/ext/couchbase/couchbase/scope.hxx +40 -0
- data/ext/couchbase/couchbase/search_date_range.hxx +68 -0
- data/ext/couchbase/couchbase/search_error_context.hxx +138 -0
- data/ext/couchbase/couchbase/search_facet.hxx +60 -0
- data/ext/couchbase/couchbase/search_facet_result.hxx +50 -0
- data/ext/couchbase/couchbase/search_meta_data.hxx +85 -0
- data/ext/couchbase/couchbase/search_metrics.hxx +127 -0
- data/ext/couchbase/couchbase/search_numeric_range.hxx +69 -0
- data/ext/couchbase/couchbase/search_options.hxx +509 -0
- data/ext/couchbase/couchbase/search_query.hxx +69 -0
- data/ext/couchbase/couchbase/search_result.hxx +77 -0
- data/ext/couchbase/couchbase/search_row.hxx +104 -0
- data/ext/couchbase/couchbase/search_row_location.hxx +55 -0
- data/ext/couchbase/couchbase/search_row_locations.hxx +86 -0
- data/ext/couchbase/couchbase/search_scan_consistency.hxx +34 -0
- data/ext/couchbase/couchbase/search_sort.hxx +58 -0
- data/ext/couchbase/couchbase/search_sort_field.hxx +117 -0
- data/ext/couchbase/couchbase/search_sort_field_missing.hxx +26 -0
- data/ext/couchbase/couchbase/search_sort_field_mode.hxx +27 -0
- data/ext/couchbase/couchbase/search_sort_field_type.hxx +28 -0
- data/ext/couchbase/couchbase/search_sort_id.hxx +60 -0
- data/ext/couchbase/couchbase/search_sort_score.hxx +60 -0
- data/ext/couchbase/couchbase/search_term_range.hxx +51 -0
- data/ext/couchbase/couchbase/security_options.hxx +3 -0
- data/ext/couchbase/couchbase/term_facet.hxx +48 -0
- data/ext/couchbase/couchbase/term_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/term_query.hxx +151 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +142 -0
- data/ext/couchbase/couchbase/tracing/request_span.hxx +63 -0
- data/ext/couchbase/couchbase/tracing/request_tracer.hxx +2 -40
- data/ext/couchbase/couchbase/transactions/async_attempt_context.hxx +83 -4
- data/ext/couchbase/couchbase/transactions/attempt_context.hxx +67 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +2 -0
- data/ext/couchbase/couchbase/transactions/transaction_keyspace.hxx +11 -1
- data/ext/couchbase/couchbase/transactions/transaction_options.hxx +79 -8
- data/ext/couchbase/couchbase/transactions/transaction_query_options.hxx +128 -15
- data/ext/couchbase/couchbase/transactions/transaction_query_result.hxx +4 -0
- data/ext/couchbase/couchbase/transactions/transaction_result.hxx +1 -1
- data/ext/couchbase/couchbase/transactions/transactions_cleanup_config.hxx +5 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +9 -5
- data/ext/couchbase/couchbase/transactions/transactions_query_config.hxx +6 -3
- data/ext/couchbase/couchbase/transactions.hxx +34 -1
- data/ext/couchbase/couchbase/wildcard_query.hxx +83 -0
- data/ext/couchbase/test/CMakeLists.txt +7 -5
- data/ext/couchbase/test/benchmark_helper_integration.hxx +2 -2
- data/ext/couchbase/test/test_helper.hxx +5 -5
- data/ext/couchbase/test/test_integration_analytics.cxx +28 -6
- data/ext/couchbase/test/test_integration_collections.cxx +7 -3
- data/ext/couchbase/test/test_integration_connect.cxx +7 -3
- data/ext/couchbase/test/test_integration_crud.cxx +13 -3
- data/ext/couchbase/test/test_integration_diagnostics.cxx +11 -5
- data/ext/couchbase/test/test_integration_durability.cxx +12 -7
- data/ext/couchbase/test/test_integration_examples.cxx +283 -11
- data/ext/couchbase/test/test_integration_management.cxx +147 -91
- data/ext/couchbase/test/test_integration_query.cxx +68 -10
- data/ext/couchbase/test/test_integration_range_scan.cxx +12 -12
- data/ext/couchbase/test/test_integration_read_replica.cxx +48 -11
- data/ext/couchbase/test/test_integration_search.cxx +22 -2
- data/ext/couchbase/test/test_integration_subdoc.cxx +62 -11
- data/ext/couchbase/test/test_integration_tracer.cxx +5 -0
- data/ext/couchbase/test/test_integration_transcoders.cxx +13 -5
- data/ext/couchbase/test/{test_transaction_transaction_context.cxx → test_transaction_context.cxx} +1 -1
- data/ext/couchbase/test/test_transaction_examples.cxx +195 -0
- data/ext/couchbase/test/{test_transaction_transaction_simple.cxx → test_transaction_simple.cxx} +17 -5
- data/ext/couchbase/test/{test_transaction_transaction_simple_async.cxx → test_transaction_simple_async.cxx} +19 -21
- data/ext/couchbase/test/test_unit_config_profiles.cxx +1 -1
- data/ext/couchbase/test/test_unit_json_transcoder.cxx +4 -0
- data/ext/couchbase/test/test_unit_search.cxx +427 -0
- data/ext/couchbase/test/test_unit_transaction_utils.cxx +10 -1
- data/ext/couchbase/test/test_unit_utils.cxx +8 -4
- data/ext/couchbase.cxx +58 -16
- data/ext/revisions.rb +3 -3
- data/lib/couchbase/authenticator.rb +0 -1
- data/lib/couchbase/cluster.rb +0 -4
- data/lib/couchbase/config_profiles.rb +1 -1
- data/lib/couchbase/json_transcoder.rb +12 -5
- data/lib/couchbase/management/collection_query_index_manager.rb +54 -15
- data/lib/couchbase/management/query_index_manager.rb +70 -5
- data/lib/couchbase/raw_binary_transcoder.rb +37 -0
- data/lib/couchbase/raw_json_transcoder.rb +38 -0
- data/lib/couchbase/raw_string_transcoder.rb +40 -0
- data/lib/couchbase/search_options.rb +5 -0
- data/lib/couchbase/transcoder_flags.rb +62 -0
- data/lib/couchbase/version.rb +1 -1
- metadata +139 -11
- data/ext/couchbase/core/config_profile.cxx +0 -47
- /data/ext/couchbase/test/{test_transaction_transaction_public_async_api.cxx → test_transaction_public_async_api.cxx} +0 -0
- /data/ext/couchbase/test/{test_transaction_transaction_public_blocking_api.cxx → test_transaction_public_blocking_api.cxx} +0 -0
|
@@ -63,8 +63,13 @@ TEST_CASE("integration: get any replica", "[integration]")
|
|
|
63
63
|
{
|
|
64
64
|
test::utils::integration_test_guard integration;
|
|
65
65
|
|
|
66
|
-
if (integration.number_of_replicas() == 0
|
|
67
|
-
|
|
66
|
+
if (integration.number_of_replicas() == 0) {
|
|
67
|
+
SKIP("bucket has zero replicas");
|
|
68
|
+
}
|
|
69
|
+
if (integration.number_of_nodes() <= integration.number_of_replicas()) {
|
|
70
|
+
SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
|
|
71
|
+
integration.number_of_nodes(),
|
|
72
|
+
integration.number_of_replicas()));
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -95,8 +100,12 @@ TEST_CASE("integration: get all replicas", "[integration]")
|
|
|
95
100
|
test::utils::integration_test_guard integration;
|
|
96
101
|
|
|
97
102
|
auto number_of_replicas = integration.number_of_replicas();
|
|
98
|
-
if (number_of_replicas == 0
|
|
99
|
-
|
|
103
|
+
if (number_of_replicas == 0) {
|
|
104
|
+
SKIP("bucket has zero replicas");
|
|
105
|
+
}
|
|
106
|
+
if (integration.number_of_nodes() <= number_of_replicas) {
|
|
107
|
+
SKIP(fmt::format(
|
|
108
|
+
"number of nodes ({}) is less or equal to number of replicas ({})", integration.number_of_nodes(), number_of_replicas));
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -109,10 +118,16 @@ TEST_CASE("integration: get all replicas", "[integration]")
|
|
|
109
118
|
couchbase::core::document_id id{ integration.ctx.bucket, scope_name, collection_name, key };
|
|
110
119
|
|
|
111
120
|
couchbase::core::operations::insert_request req{ id, basic_doc_json };
|
|
121
|
+
req.durability_level = couchbase::durability_level::majority_and_persist_to_active;
|
|
112
122
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
113
123
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
114
124
|
}
|
|
115
125
|
|
|
126
|
+
if (integration.cluster_version().is_mock()) {
|
|
127
|
+
// GOCAVES does not implement syncDurability. See https://github.com/couchbaselabs/gocaves/issues/109
|
|
128
|
+
std::this_thread::sleep_for(std::chrono::seconds{ 1 });
|
|
129
|
+
}
|
|
130
|
+
|
|
116
131
|
{
|
|
117
132
|
auto collection =
|
|
118
133
|
couchbase::cluster(integration.cluster).bucket(integration.ctx.bucket).scope(scope_name).collection(collection_name);
|
|
@@ -128,8 +143,13 @@ TEST_CASE("integration: get all replicas with missing key", "[integration]")
|
|
|
128
143
|
{
|
|
129
144
|
test::utils::integration_test_guard integration;
|
|
130
145
|
|
|
131
|
-
if (integration.number_of_replicas() == 0
|
|
132
|
-
|
|
146
|
+
if (integration.number_of_replicas() == 0) {
|
|
147
|
+
SKIP("bucket has zero replicas");
|
|
148
|
+
}
|
|
149
|
+
if (integration.number_of_nodes() <= integration.number_of_replicas()) {
|
|
150
|
+
SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
|
|
151
|
+
integration.number_of_nodes(),
|
|
152
|
+
integration.number_of_replicas()));
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -152,7 +172,9 @@ TEST_CASE("integration: get any replica with missing key", "[integration]")
|
|
|
152
172
|
test::utils::integration_test_guard integration;
|
|
153
173
|
|
|
154
174
|
if (integration.number_of_nodes() <= integration.number_of_replicas()) {
|
|
155
|
-
|
|
175
|
+
SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
|
|
176
|
+
integration.number_of_nodes(),
|
|
177
|
+
integration.number_of_replicas()));
|
|
156
178
|
}
|
|
157
179
|
|
|
158
180
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -173,8 +195,13 @@ TEST_CASE("integration: get any replica low-level version", "[integration]")
|
|
|
173
195
|
{
|
|
174
196
|
test::utils::integration_test_guard integration;
|
|
175
197
|
|
|
176
|
-
if (integration.number_of_replicas() == 0
|
|
177
|
-
|
|
198
|
+
if (integration.number_of_replicas() == 0) {
|
|
199
|
+
SKIP("bucket has zero replicas");
|
|
200
|
+
}
|
|
201
|
+
if (integration.number_of_nodes() <= integration.number_of_replicas()) {
|
|
202
|
+
SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
|
|
203
|
+
integration.number_of_nodes(),
|
|
204
|
+
integration.number_of_replicas()));
|
|
178
205
|
}
|
|
179
206
|
|
|
180
207
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -204,8 +231,12 @@ TEST_CASE("integration: get all replicas low-level version", "[integration]")
|
|
|
204
231
|
test::utils::integration_test_guard integration;
|
|
205
232
|
|
|
206
233
|
auto number_of_replicas = integration.number_of_replicas();
|
|
207
|
-
if (number_of_replicas == 0
|
|
208
|
-
|
|
234
|
+
if (number_of_replicas == 0) {
|
|
235
|
+
SKIP("bucket has zero replicas");
|
|
236
|
+
}
|
|
237
|
+
if (integration.number_of_nodes() <= number_of_replicas) {
|
|
238
|
+
SKIP(fmt::format(
|
|
239
|
+
"number of nodes ({}) is less or equal to number of replicas ({})", integration.number_of_nodes(), number_of_replicas));
|
|
209
240
|
}
|
|
210
241
|
|
|
211
242
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -217,10 +248,16 @@ TEST_CASE("integration: get all replicas low-level version", "[integration]")
|
|
|
217
248
|
{ "b", 2.0 },
|
|
218
249
|
};
|
|
219
250
|
couchbase::core::operations::upsert_request req{ id, couchbase::core::utils::json::generate_binary(value) };
|
|
251
|
+
req.durability_level = couchbase::durability_level::majority_and_persist_to_active;
|
|
220
252
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
221
253
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
222
254
|
}
|
|
223
255
|
|
|
256
|
+
if (integration.cluster_version().is_mock()) {
|
|
257
|
+
// GOCAVES does not implement syncDurability. See https://github.com/couchbaselabs/gocaves/issues/109
|
|
258
|
+
std::this_thread::sleep_for(std::chrono::seconds{ 1 });
|
|
259
|
+
}
|
|
260
|
+
|
|
224
261
|
{
|
|
225
262
|
couchbase::core::operations::get_all_replicas_request req{ id };
|
|
226
263
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
@@ -17,16 +17,24 @@
|
|
|
17
17
|
|
|
18
18
|
#include "test_helper_integration.hxx"
|
|
19
19
|
|
|
20
|
+
#include <catch2/matchers/catch_matchers_string.hpp>
|
|
21
|
+
|
|
20
22
|
#include "core/operations/management/collection_create.hxx"
|
|
21
23
|
#include "core/operations/management/search_index_drop.hxx"
|
|
22
24
|
#include "core/operations/management/search_index_upsert.hxx"
|
|
23
25
|
|
|
26
|
+
#include <couchbase/query_string_query.hxx>
|
|
27
|
+
|
|
24
28
|
using Catch::Matchers::StartsWith;
|
|
25
29
|
|
|
26
30
|
TEST_CASE("integration: search query")
|
|
27
31
|
{
|
|
28
32
|
test::utils::integration_test_guard integration;
|
|
29
33
|
|
|
34
|
+
if (!integration.cluster_version().supports_search()) {
|
|
35
|
+
SKIP("cluster does not support search");
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
31
39
|
|
|
32
40
|
{
|
|
@@ -348,6 +356,14 @@ TEST_CASE("integration: search query consistency", "[integration]")
|
|
|
348
356
|
{
|
|
349
357
|
test::utils::integration_test_guard integration;
|
|
350
358
|
|
|
359
|
+
if (integration.ctx.deployment == test::utils::deployment_type::elixir) {
|
|
360
|
+
SKIP("elixir deployment is incompatible with parts of this test");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (!integration.cluster_version().supports_search()) {
|
|
364
|
+
SKIP("cluster does not support search");
|
|
365
|
+
}
|
|
366
|
+
|
|
351
367
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
352
368
|
|
|
353
369
|
const std::string params =
|
|
@@ -441,7 +457,7 @@ TEST_CASE("integration: search query consistency", "[integration]")
|
|
|
441
457
|
CB_LOG_INFO("ignore consistency_mismatch: {}", resp.ctx.http_body);
|
|
442
458
|
continue;
|
|
443
459
|
}
|
|
444
|
-
INFO(resp.ctx.http_body)
|
|
460
|
+
INFO(resp.ctx.http_body);
|
|
445
461
|
REQUIRE_SUCCESS(resp.ctx.ec);
|
|
446
462
|
switch (resp.rows.size()) {
|
|
447
463
|
case 1:
|
|
@@ -474,8 +490,12 @@ TEST_CASE("integration: search query collections")
|
|
|
474
490
|
{
|
|
475
491
|
test::utils::integration_test_guard integration;
|
|
476
492
|
|
|
493
|
+
if (!integration.cluster_version().supports_search()) {
|
|
494
|
+
SKIP("cluster does not support search");
|
|
495
|
+
}
|
|
496
|
+
|
|
477
497
|
if (!integration.cluster_version().supports_collections()) {
|
|
478
|
-
|
|
498
|
+
SKIP("cluster does not support collections");
|
|
479
499
|
}
|
|
480
500
|
|
|
481
501
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
@@ -30,7 +30,7 @@ assert_single_lookup_success(test::utils::integration_test_guard& integration,
|
|
|
30
30
|
couchbase::core::operations::lookup_in_request req{ id };
|
|
31
31
|
req.specs = couchbase::lookup_in_specs{ spec }.specs();
|
|
32
32
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
33
|
-
INFO(fmt::format("assert_single_lookup_success(\"{}\", \"{}\")", id, req.specs[0].path_))
|
|
33
|
+
INFO(fmt::format("assert_single_lookup_success(\"{}\", \"{}\")", id, req.specs[0].path_));
|
|
34
34
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
35
35
|
REQUIRE_FALSE(resp.cas.empty());
|
|
36
36
|
REQUIRE(resp.fields.size() == 1);
|
|
@@ -54,7 +54,7 @@ assert_single_lookup_error(test::utils::integration_test_guard& integration,
|
|
|
54
54
|
couchbase::core::operations::lookup_in_request req{ id };
|
|
55
55
|
req.specs = couchbase::lookup_in_specs{ spec }.specs();
|
|
56
56
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
57
|
-
INFO(fmt::format("assert_single_lookup_error(\"{}\", \"{}\")", id, req.specs[0].path_))
|
|
57
|
+
INFO(fmt::format("assert_single_lookup_error(\"{}\", \"{}\")", id, req.specs[0].path_));
|
|
58
58
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
59
59
|
REQUIRE_FALSE(resp.cas.empty());
|
|
60
60
|
REQUIRE(resp.fields.size() == 1);
|
|
@@ -197,6 +197,10 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
|
|
|
197
197
|
|
|
198
198
|
SECTION("non json get")
|
|
199
199
|
{
|
|
200
|
+
if (integration.cluster_version().is_mock()) {
|
|
201
|
+
SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
|
|
202
|
+
"https://github.com/couchbaselabs/gocaves/issues/103");
|
|
203
|
+
}
|
|
200
204
|
assert_single_lookup_error(integration,
|
|
201
205
|
non_json_id,
|
|
202
206
|
couchbase::lookup_in_specs::get("non-exist"),
|
|
@@ -206,6 +210,10 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
|
|
|
206
210
|
|
|
207
211
|
SECTION("non json exists")
|
|
208
212
|
{
|
|
213
|
+
if (integration.cluster_version().is_mock()) {
|
|
214
|
+
SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
|
|
215
|
+
"https://github.com/couchbaselabs/gocaves/issues/103");
|
|
216
|
+
}
|
|
209
217
|
assert_single_lookup_error(integration,
|
|
210
218
|
non_json_id,
|
|
211
219
|
couchbase::lookup_in_specs::exists("non-exist"),
|
|
@@ -218,11 +226,19 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
|
|
|
218
226
|
{
|
|
219
227
|
std::vector<std::string> invalid_paths = { "invalid..path", "invalid[-2]" };
|
|
220
228
|
for (const auto& path : invalid_paths) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
if (integration.cluster_version().is_mock()) {
|
|
230
|
+
assert_single_lookup_error(integration,
|
|
231
|
+
id,
|
|
232
|
+
couchbase::lookup_in_specs::get(path),
|
|
233
|
+
couchbase::key_value_status_code::subdoc_path_not_found,
|
|
234
|
+
couchbase::errc::key_value::path_not_found);
|
|
235
|
+
} else {
|
|
236
|
+
assert_single_lookup_error(integration,
|
|
237
|
+
id,
|
|
238
|
+
couchbase::lookup_in_specs::get(path),
|
|
239
|
+
couchbase::key_value_status_code::subdoc_path_invalid,
|
|
240
|
+
couchbase::errc::key_value::path_invalid);
|
|
241
|
+
}
|
|
226
242
|
}
|
|
227
243
|
}
|
|
228
244
|
|
|
@@ -317,6 +333,10 @@ TEST_CASE("integration: subdoc store", "[integration]")
|
|
|
317
333
|
|
|
318
334
|
SECTION("non json")
|
|
319
335
|
{
|
|
336
|
+
if (integration.cluster_version().is_mock()) {
|
|
337
|
+
SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
|
|
338
|
+
"https://github.com/couchbaselabs/gocaves/issues/103");
|
|
339
|
+
}
|
|
320
340
|
std::string path{ "dict" };
|
|
321
341
|
auto value = couchbase::core::utils::to_binary("non-json");
|
|
322
342
|
couchbase::core::operations::mutate_in_request req{ id };
|
|
@@ -411,6 +431,11 @@ TEST_CASE("integration: subdoc mutate in store semantics", "[integration]")
|
|
|
411
431
|
TEST_CASE("integration: subdoc unique", "[integration]")
|
|
412
432
|
{
|
|
413
433
|
test::utils::integration_test_guard integration;
|
|
434
|
+
|
|
435
|
+
if (integration.cluster_version().is_mock()) {
|
|
436
|
+
SKIP("GOCAVES does not support subdocument create_path feature. See https://github.com/couchbaselabs/gocaves/issues/17");
|
|
437
|
+
}
|
|
438
|
+
|
|
414
439
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
415
440
|
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
|
|
416
441
|
|
|
@@ -453,7 +478,6 @@ TEST_CASE("integration: subdoc unique", "[integration]")
|
|
|
453
478
|
couchbase::mutate_in_specs{ couchbase::mutate_in_specs::array_append("a", tao::json::empty_object).create_path() }.specs();
|
|
454
479
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
455
480
|
assert_single_mutate_success(resp, "a");
|
|
456
|
-
assert_single_lookup_success(integration, id, couchbase::lookup_in_specs::get("a[-1]"), "{}");
|
|
457
481
|
}
|
|
458
482
|
|
|
459
483
|
{
|
|
@@ -472,7 +496,10 @@ TEST_CASE("integration: subdoc counter", "[integration]")
|
|
|
472
496
|
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
|
|
473
497
|
|
|
474
498
|
{
|
|
475
|
-
auto value_json =
|
|
499
|
+
auto value_json =
|
|
500
|
+
integration.cluster_version().is_mock() // kv_engine creates counters automatically
|
|
501
|
+
? couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]],"counter":0})")
|
|
502
|
+
: couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
|
|
476
503
|
couchbase::core::operations::insert_request req{ id, value_json };
|
|
477
504
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
478
505
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
@@ -497,6 +524,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
|
|
|
497
524
|
|
|
498
525
|
SECTION("max value")
|
|
499
526
|
{
|
|
527
|
+
if (integration.cluster_version().is_mock()) {
|
|
528
|
+
SKIP("GOCAVES incorrectly handles limits for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/104");
|
|
529
|
+
}
|
|
500
530
|
{
|
|
501
531
|
int64_t max_value = std::numeric_limits<int64_t>::max();
|
|
502
532
|
couchbase::core::operations::mutate_in_request req{ id };
|
|
@@ -516,6 +546,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
|
|
|
516
546
|
|
|
517
547
|
SECTION("invalid delta")
|
|
518
548
|
{
|
|
549
|
+
if (integration.cluster_version().is_mock()) {
|
|
550
|
+
SKIP("GOCAVES incorrectly handles zero delta for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/105");
|
|
551
|
+
}
|
|
519
552
|
couchbase::core::operations::mutate_in_request req{ id };
|
|
520
553
|
req.specs = couchbase::mutate_in_specs{ couchbase::mutate_in_specs::increment("counter", 0) }.specs();
|
|
521
554
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
@@ -525,6 +558,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
|
|
|
525
558
|
|
|
526
559
|
SECTION("increase number already too big")
|
|
527
560
|
{
|
|
561
|
+
if (integration.cluster_version().is_mock()) {
|
|
562
|
+
SKIP("GOCAVES incorrectly handles big values for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/106");
|
|
563
|
+
}
|
|
528
564
|
{
|
|
529
565
|
auto big_value = R"({"counter":)" + std::to_string(std::numeric_limits<int64_t>::max()) + "999999999999999999999999999999}";
|
|
530
566
|
auto value_json = couchbase::core::utils::to_binary(big_value);
|
|
@@ -621,7 +657,11 @@ TEST_CASE("integration: subdoc multi lookup", "[integration]")
|
|
|
621
657
|
}
|
|
622
658
|
.specs();
|
|
623
659
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
624
|
-
|
|
660
|
+
if (integration.cluster_version().is_mock()) {
|
|
661
|
+
REQUIRE(resp.ctx.ec() == couchbase::errc::common::unsupported_operation);
|
|
662
|
+
} else {
|
|
663
|
+
REQUIRE(resp.ctx.ec() == couchbase::errc::common::invalid_argument);
|
|
664
|
+
}
|
|
625
665
|
}
|
|
626
666
|
|
|
627
667
|
SECTION("missing key")
|
|
@@ -647,7 +687,10 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
|
|
|
647
687
|
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
|
|
648
688
|
|
|
649
689
|
{
|
|
650
|
-
auto value_json =
|
|
690
|
+
auto value_json =
|
|
691
|
+
integration.cluster_version().is_mock() // kv_engine creates counters automatically
|
|
692
|
+
? couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]],"counter":0})")
|
|
693
|
+
: couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
|
|
651
694
|
couchbase::core::operations::insert_request req{ id, value_json };
|
|
652
695
|
auto resp = test::utils::execute(integration.cluster, req);
|
|
653
696
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
@@ -676,6 +719,9 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
|
|
|
676
719
|
|
|
677
720
|
SECTION("replace with errors")
|
|
678
721
|
{
|
|
722
|
+
if (integration.cluster_version().is_mock()) {
|
|
723
|
+
SKIP("GOCAVES incorrectly uses error indexes for subdoc mutations. See https://github.com/couchbaselabs/gocaves/issues/107");
|
|
724
|
+
}
|
|
679
725
|
couchbase::core::operations::mutate_in_request req{ id };
|
|
680
726
|
req.specs =
|
|
681
727
|
couchbase::mutate_in_specs{
|
|
@@ -695,6 +741,11 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
|
|
|
695
741
|
TEST_CASE("integration: subdoc expiry")
|
|
696
742
|
{
|
|
697
743
|
test::utils::integration_test_guard integration;
|
|
744
|
+
|
|
745
|
+
if (integration.cluster_version().is_mock()) {
|
|
746
|
+
SKIP("GOCAVES does not support subdoc mutations with expiry. See https://github.com/couchbaselabs/gocaves/issues/85");
|
|
747
|
+
}
|
|
748
|
+
|
|
698
749
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
699
750
|
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
|
|
700
751
|
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
#include "test_helper_integration.hxx"
|
|
19
19
|
|
|
20
|
+
#include <catch2/generators/catch_generators.hpp>
|
|
21
|
+
|
|
20
22
|
#include "core/platform/uuid.h"
|
|
21
23
|
|
|
22
24
|
#include <couchbase/lookup_in_specs.hxx>
|
|
@@ -247,6 +249,9 @@ TEST_CASE("integration: enable external tracer", "[integration]")
|
|
|
247
249
|
{
|
|
248
250
|
SECTION("query")
|
|
249
251
|
{
|
|
252
|
+
if (!guard.cluster_version().supports_query()) {
|
|
253
|
+
SKIP("cluster does not support query");
|
|
254
|
+
}
|
|
250
255
|
tracer->reset();
|
|
251
256
|
couchbase::core::operations::query_request req{ R"(SELECT "ruby rules" AS greeting)" };
|
|
252
257
|
req.parent_span = parent_span;
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
#include "test_helper_integration.hxx"
|
|
19
19
|
|
|
20
|
+
#include <catch2/matchers/catch_matchers.hpp>
|
|
21
|
+
#include <catch2/matchers/catch_matchers_exception.hpp>
|
|
22
|
+
#include <catch2/matchers/catch_matchers_string.hpp>
|
|
23
|
+
|
|
20
24
|
#include <couchbase/cluster.hxx>
|
|
21
25
|
#include <couchbase/codec/raw_binary_transcoder.hxx>
|
|
22
26
|
|
|
@@ -24,7 +28,7 @@
|
|
|
24
28
|
|
|
25
29
|
#include "profile.hxx"
|
|
26
30
|
|
|
27
|
-
using Catch::
|
|
31
|
+
using Catch::Matchers::ContainsSubstring;
|
|
28
32
|
|
|
29
33
|
TEST_CASE("integration: upsert/get with json transcoder", "[integration]")
|
|
30
34
|
{
|
|
@@ -427,6 +431,10 @@ TEST_CASE("integration: subdoc with public API", "[integration]")
|
|
|
427
431
|
{
|
|
428
432
|
test::utils::integration_test_guard integration;
|
|
429
433
|
|
|
434
|
+
if (integration.cluster_version().is_mock()) {
|
|
435
|
+
SKIP("GOCAVES incorrectly uses error indexes for subdoc mutations. See https://github.com/couchbaselabs/gocaves/issues/107");
|
|
436
|
+
}
|
|
437
|
+
|
|
430
438
|
test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
|
|
431
439
|
|
|
432
440
|
auto collection = couchbase::cluster(integration.cluster)
|
|
@@ -497,10 +505,10 @@ TEST_CASE("integration: subdoc with public API", "[integration]")
|
|
|
497
505
|
REQUIRE(ctx.first_error_path().has_value());
|
|
498
506
|
REQUIRE(ctx.first_error_path() == "missing_field");
|
|
499
507
|
REQUIRE(resp.cas().empty());
|
|
500
|
-
REQUIRE_THROWS_WITH(resp.has_value(0),
|
|
501
|
-
REQUIRE_THROWS_WITH(resp.has_value("views"),
|
|
502
|
-
REQUIRE_THROWS_WITH(resp.content_as<std::uint32_t>(0),
|
|
503
|
-
REQUIRE_THROWS_WITH(resp.content_as<std::uint32_t>("views"),
|
|
508
|
+
REQUIRE_THROWS_WITH(resp.has_value(0), ContainsSubstring("path_invalid"));
|
|
509
|
+
REQUIRE_THROWS_WITH(resp.has_value("views"), ContainsSubstring("path_invalid"));
|
|
510
|
+
REQUIRE_THROWS_WITH(resp.content_as<std::uint32_t>(0), ContainsSubstring("path_invalid"));
|
|
511
|
+
REQUIRE_THROWS_WITH(resp.content_as<std::uint32_t>("views"), ContainsSubstring("path_invalid"));
|
|
504
512
|
}
|
|
505
513
|
|
|
506
514
|
{
|
data/ext/couchbase/test/{test_transaction_transaction_context.cxx → test_transaction_context.cxx}
RENAMED
|
@@ -504,7 +504,7 @@ TEST_CASE("transactions: can see some query errors but no transactions failed",
|
|
|
504
504
|
// eat the expected op_exception
|
|
505
505
|
} catch (...) {
|
|
506
506
|
auto e = std::current_exception();
|
|
507
|
-
|
|
507
|
+
INFO(fmt::format("got {}", typeid(e).name()));
|
|
508
508
|
FAIL("expected op_exception to be thrown from the future");
|
|
509
509
|
}
|
|
510
510
|
REQUIRE_NOTHROW(tx.existing_error());
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2023-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 "test_helper_integration.hxx"
|
|
19
|
+
|
|
20
|
+
#include <couchbase/cluster.hxx>
|
|
21
|
+
#include <couchbase/fmt/cas.hxx>
|
|
22
|
+
#include <couchbase/transactions/attempt_context.hxx>
|
|
23
|
+
|
|
24
|
+
#include <tao/json.hpp>
|
|
25
|
+
|
|
26
|
+
namespace blocking_txn
|
|
27
|
+
{
|
|
28
|
+
//! [blocking-txn]
|
|
29
|
+
#include <couchbase/cluster.hxx>
|
|
30
|
+
#include <couchbase/fmt/cas.hxx>
|
|
31
|
+
#include <couchbase/transactions/attempt_context.hxx>
|
|
32
|
+
|
|
33
|
+
#include <tao/json.hpp>
|
|
34
|
+
|
|
35
|
+
int
|
|
36
|
+
main(int argc, const char* argv[])
|
|
37
|
+
{
|
|
38
|
+
if (argc != 4) {
|
|
39
|
+
fmt::print("USAGE: ./blocking-txn couchbase://127.0.0.1 Administrator password\n");
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
int retval = 0;
|
|
44
|
+
|
|
45
|
+
const std::string connection_string{ argv[1] };
|
|
46
|
+
const std::string username{ argv[2] };
|
|
47
|
+
const std::string password{ argv[3] };
|
|
48
|
+
|
|
49
|
+
// run IO context on separate thread
|
|
50
|
+
asio::io_context io;
|
|
51
|
+
auto guard = asio::make_work_guard(io);
|
|
52
|
+
std::thread io_thread([&io]() { io.run(); });
|
|
53
|
+
|
|
54
|
+
auto options = couchbase::cluster_options(username, password);
|
|
55
|
+
// customize through the 'options'.
|
|
56
|
+
// For example, optimize timeouts for WAN
|
|
57
|
+
options.apply_profile("wan_development");
|
|
58
|
+
|
|
59
|
+
// [1] connect to cluster using the given connection string and the options
|
|
60
|
+
auto [cluster, ec] = couchbase::cluster::connect(io, connection_string, options).get();
|
|
61
|
+
if (ec) {
|
|
62
|
+
fmt::print("unable to connect to the cluster: {}\n", ec.message());
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// [2] persist three documents to the default collection of bucket "default"
|
|
67
|
+
auto collection = cluster.bucket("default").default_collection();
|
|
68
|
+
constexpr auto id_1 = "my-doc_1";
|
|
69
|
+
constexpr auto id_2 = "my_doc_2";
|
|
70
|
+
constexpr auto id_3 = "my_doc_3";
|
|
71
|
+
const tao::json::value content = { { "some", "content" } };
|
|
72
|
+
|
|
73
|
+
for (const auto& id : { id_1, id_2, id_3 }) {
|
|
74
|
+
if (auto [ctx, res] = collection.upsert(id, content).get(); ctx.ec()) {
|
|
75
|
+
fmt::print(stderr, "upsert \"{}\" failed before starting transaction: {}\n", id, ctx.ec().message());
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
{ // [3] blocking transaction
|
|
81
|
+
//! [simple-blocking-txn]
|
|
82
|
+
auto [tx_err, tx_res] = cluster.transactions()->run(
|
|
83
|
+
// [3.1] closure argument to run() method encapsulates logic, that has to be run in transaction
|
|
84
|
+
[&](couchbase::transactions::attempt_context& ctx) {
|
|
85
|
+
// [3.2] get document
|
|
86
|
+
auto [err_ctx, doc] = ctx.get(collection, id_1);
|
|
87
|
+
if (err_ctx.ec()) {
|
|
88
|
+
fmt::print(stderr, "failed to get document \"{}\": {}\n", id_1, err_ctx.ec().message());
|
|
89
|
+
// [3.3] don't continue the transaction logic
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// [3.4] replace document's content
|
|
93
|
+
ctx.replace(doc, ::tao::json::value{ { "some", "other content" } });
|
|
94
|
+
});
|
|
95
|
+
// [3.5] check the overall status of the transaction
|
|
96
|
+
if (tx_err.ec()) {
|
|
97
|
+
fmt::print(stderr, "error in transaction {}, cause: {}\n", tx_err.ec().message(), tx_err.cause().message());
|
|
98
|
+
retval = 1;
|
|
99
|
+
} else {
|
|
100
|
+
fmt::print("transaction {} completed successfully", tx_res.transaction_id);
|
|
101
|
+
}
|
|
102
|
+
//! [simple-blocking-txn]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
{ // [4] asynchronous transaction
|
|
106
|
+
//! [simple-async-txn]
|
|
107
|
+
// [4.1] create promise to retrieve result from the transaction
|
|
108
|
+
auto barrier = std::make_shared<std::promise<std::error_code>>();
|
|
109
|
+
auto f = barrier->get_future();
|
|
110
|
+
cluster.transactions()->run(
|
|
111
|
+
// [4.2] closure argument to run() method encapsulates logic, that has to be run in transaction
|
|
112
|
+
[&](couchbase::transactions::async_attempt_context& ctx) {
|
|
113
|
+
// [4.3] get document
|
|
114
|
+
ctx.get(collection, id_1, [&](auto err_ctx_1, auto doc) {
|
|
115
|
+
if (err_ctx_1.ec()) {
|
|
116
|
+
fmt::print(stderr, "failed to get document \"{}\": {}\n", id_1, err_ctx_1.ec().message());
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// [4.4] replace document's content
|
|
120
|
+
ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
|
|
121
|
+
if (err_ctx_2.ec()) {
|
|
122
|
+
fmt::print(stderr, "error replacing content in doc {}: {}\n", id_1, err_ctx_2.ec().message());
|
|
123
|
+
} else {
|
|
124
|
+
fmt::print("successfully replaced: {}, cas={}\n", id_1, res.cas());
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
ctx.get(collection, id_2, [&](auto err_ctx_1, auto doc) {
|
|
129
|
+
if (err_ctx_1.ec()) {
|
|
130
|
+
fmt::print("error getting doc {}: {}", id_2, err_ctx_1.ec().message());
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
|
|
134
|
+
if (err_ctx_2.ec()) {
|
|
135
|
+
fmt::print(stderr, "error replacing content in doc {}: {}\n", id_2, err_ctx_2.ec().message());
|
|
136
|
+
} else {
|
|
137
|
+
fmt::print("successfully replaced: {}, cas={}\n", id_2, res.cas());
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
ctx.get(collection, id_3, [&](auto err_ctx_1, auto doc) {
|
|
142
|
+
if (err_ctx_1.ec()) {
|
|
143
|
+
fmt::print("error getting doc {}: {}", id_3, err_ctx_1.ec().message());
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
|
|
147
|
+
if (err_ctx_2.ec()) {
|
|
148
|
+
fmt::print(stderr, "error replacing content in doc {}: {}\n", id_3, err_ctx_2.ec().message());
|
|
149
|
+
} else {
|
|
150
|
+
fmt::print("successfully replaced: {}, cas={}\n", id_3, res.cas());
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
// [4.5], second closure represents transaction completion logic
|
|
156
|
+
[barrier](auto tx_err, auto tx_res) {
|
|
157
|
+
if (tx_err.ec()) {
|
|
158
|
+
fmt::print(stderr, "error in async transaction {}, {}\n", tx_res.transaction_id, tx_err.ec().message());
|
|
159
|
+
}
|
|
160
|
+
barrier->set_value(tx_err.ec());
|
|
161
|
+
});
|
|
162
|
+
if (auto async_err = f.get()) {
|
|
163
|
+
retval = 1;
|
|
164
|
+
}
|
|
165
|
+
//! [simple-async-txn]
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// [5], close cluster connection
|
|
169
|
+
cluster.close();
|
|
170
|
+
guard.reset();
|
|
171
|
+
|
|
172
|
+
io_thread.join();
|
|
173
|
+
return retval;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//! [blocking-txn]
|
|
177
|
+
} // namespace blocking_txn
|
|
178
|
+
|
|
179
|
+
TEST_CASE("example: basic transaction", "[integration]")
|
|
180
|
+
{
|
|
181
|
+
test::utils::integration_test_guard integration;
|
|
182
|
+
if (!integration.cluster_version().supports_collections()) {
|
|
183
|
+
SKIP("cluster does not support collections");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const auto env = test::utils::test_context::load_from_environment();
|
|
187
|
+
const char* argv[] = {
|
|
188
|
+
"blocking-txn", // name of the "executable"
|
|
189
|
+
env.connection_string.c_str(),
|
|
190
|
+
env.username.c_str(),
|
|
191
|
+
env.password.c_str(),
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
REQUIRE(blocking_txn::main(4, argv) == 0);
|
|
195
|
+
}
|
data/ext/couchbase/test/{test_transaction_transaction_simple.cxx → test_transaction_simple.cxx}
RENAMED
|
@@ -14,15 +14,27 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
#include "../core/transactions/atr_ids.hxx"
|
|
18
|
-
#include "simple_object.hxx"
|
|
19
17
|
#include "test_helper_integration.hxx"
|
|
20
|
-
|
|
21
|
-
#include
|
|
18
|
+
|
|
19
|
+
#include "simple_object.hxx"
|
|
20
|
+
|
|
21
|
+
#include "core/transactions.hxx"
|
|
22
|
+
#include "core/transactions/atr_ids.hxx"
|
|
22
23
|
|
|
23
24
|
#include <spdlog/spdlog.h>
|
|
25
|
+
#include <tao/json.hpp>
|
|
26
|
+
|
|
24
27
|
#include <stdexcept>
|
|
25
28
|
|
|
29
|
+
#if defined(__GNUC__)
|
|
30
|
+
#if __GNUC__ <= 10
|
|
31
|
+
#pragma GCC diagnostic ignored "-Wparentheses"
|
|
32
|
+
#endif
|
|
33
|
+
#if __GNUC__ < 9
|
|
34
|
+
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
|
35
|
+
#endif
|
|
36
|
+
#endif
|
|
37
|
+
|
|
26
38
|
using namespace couchbase::core::transactions;
|
|
27
39
|
static const tao::json::value content{
|
|
28
40
|
{ "some_number", 0 },
|
|
@@ -969,4 +981,4 @@ TEST_CASE("transactions: sergey example", "[transactions]")
|
|
|
969
981
|
auto remove_res = ctx.get_optional(id_to_remove);
|
|
970
982
|
CHECK_FALSE(remove_res.has_value());
|
|
971
983
|
}));
|
|
972
|
-
}
|
|
984
|
+
}
|