couchbase 3.4.1 → 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 +2 -2
- data/ext/couchbase/CMakeLists.txt +59 -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/ThirdPartyDependencies.cmake +4 -0
- 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 -7
- data/ext/couchbase/core/{config_profile.cxx → cluster_options_fwd.hxx} +7 -6
- data/ext/couchbase/core/config_profile.hxx +2 -65
- 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 +237 -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 -1
- 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/dns_srv_tracker.cxx +5 -3
- 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.cxx +5 -5
- 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/dns_client.cxx +225 -0
- data/ext/couchbase/core/io/dns_client.hxx +19 -188
- 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/active_transaction_record.hxx +2 -2
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +3 -0
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +1 -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/transactions/internal/transaction_context.hxx +12 -12
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +7 -1
- data/ext/couchbase/core/transactions/transaction_context.cxx +1 -0
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +144 -155
- data/ext/couchbase/core/utils/connection_string.cxx +27 -3
- data/ext/couchbase/core/utils/connection_string.hxx +3 -3
- data/ext/couchbase/core/utils/json.cxx +4 -1
- data/ext/couchbase/couchbase/analytics_error_context.hxx +143 -0
- data/ext/couchbase/couchbase/analytics_meta_data.hxx +155 -0
- data/ext/couchbase/couchbase/analytics_metrics.hxx +163 -0
- data/ext/couchbase/couchbase/analytics_options.hxx +359 -0
- data/ext/couchbase/couchbase/analytics_result.hxx +102 -0
- data/ext/couchbase/couchbase/analytics_scan_consistency.hxx +46 -0
- data/ext/couchbase/couchbase/analytics_status.hxx +41 -0
- data/ext/couchbase/couchbase/analytics_warning.hxx +85 -0
- 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 +75 -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/analytics_status.hxx +76 -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_options.hxx +0 -1
- 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 +73 -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 +68 -1
- 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 +8 -7
- data/ext/couchbase/test/benchmark_helper_integration.hxx +2 -2
- data/ext/couchbase/test/test_helper.hxx +6 -6
- data/ext/couchbase/test/test_integration_analytics.cxx +314 -16
- 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 +19 -2
- 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 +324 -11
- data/ext/couchbase/test/test_integration_management.cxx +162 -94
- 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 +621 -0
- 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} +90 -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 +13 -13
- data/ext/couchbase/test/test_unit_connection_string.cxx +35 -0
- 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/third_party/snappy/CMakeLists.txt +150 -27
- data/ext/couchbase/third_party/snappy/cmake/config.h.in +28 -24
- data/ext/couchbase/third_party/snappy/snappy-internal.h +189 -25
- data/ext/couchbase/third_party/snappy/snappy-sinksource.cc +26 -9
- data/ext/couchbase/third_party/snappy/snappy-sinksource.h +11 -11
- data/ext/couchbase/third_party/snappy/snappy-stubs-internal.cc +1 -1
- data/ext/couchbase/third_party/snappy/snappy-stubs-internal.h +227 -308
- data/ext/couchbase/third_party/snappy/snappy-stubs-public.h.in +0 -11
- data/ext/couchbase/third_party/snappy/snappy.cc +1176 -410
- data/ext/couchbase/third_party/snappy/snappy.h +19 -4
- data/ext/couchbase.cxx +85 -22
- data/ext/revisions.rb +3 -3
- data/lib/couchbase/authenticator.rb +0 -1
- data/lib/couchbase/cluster.rb +13 -13
- data/lib/couchbase/cluster_registry.rb +7 -2
- data/lib/couchbase/config_profiles.rb +1 -1
- data/lib/couchbase/configuration.rb +3 -4
- 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/options.rb +85 -2
- 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 +163 -240
- data/lib/couchbase/transcoder_flags.rb +62 -0
- data/lib/couchbase/version.rb +1 -1
- metadata +151 -12
- data/ext/couchbase/core/CMakeLists.txt +0 -0
- /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
|
@@ -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 },
|
|
@@ -896,4 +908,77 @@ TEST_CASE("transactions: atr and client_record are binary documents", "[transact
|
|
|
896
908
|
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
897
909
|
REQUIRE(resp.value == binary_null);
|
|
898
910
|
}
|
|
899
|
-
}
|
|
911
|
+
}
|
|
912
|
+
TEST_CASE("transactions: get non-existent doc fails txn", "[transactions]")
|
|
913
|
+
{
|
|
914
|
+
test::utils::integration_test_guard integration;
|
|
915
|
+
auto cluster = integration.cluster;
|
|
916
|
+
transactions txn(cluster, get_conf());
|
|
917
|
+
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
918
|
+
REQUIRE_THROWS_AS(txn.run([id](attempt_context& ctx) { ctx.get(id); }), transaction_exception);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
TEST_CASE("transactions: get_optional on non-existent doc doesn't fail txn", "[transactions]")
|
|
922
|
+
{
|
|
923
|
+
test::utils::integration_test_guard integration;
|
|
924
|
+
auto cluster = integration.cluster;
|
|
925
|
+
transactions txn(cluster, get_conf());
|
|
926
|
+
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
927
|
+
REQUIRE_NOTHROW(txn.run([id](attempt_context& ctx) { ctx.get_optional(id); }));
|
|
928
|
+
}
|
|
929
|
+
TEST_CASE("transactions: get after query behaves same as before a query", "[transactions]")
|
|
930
|
+
{
|
|
931
|
+
test::utils::integration_test_guard integration;
|
|
932
|
+
auto cluster = integration.cluster;
|
|
933
|
+
transactions txn(cluster, get_conf());
|
|
934
|
+
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
935
|
+
REQUIRE_THROWS_AS(txn.run([id](attempt_context& ctx) {
|
|
936
|
+
ctx.query("select * from `default` limit 1");
|
|
937
|
+
ctx.get(id);
|
|
938
|
+
}),
|
|
939
|
+
transaction_exception);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
TEST_CASE("transactions: get_optional after query behaves same as before a query", "[transactions]")
|
|
943
|
+
{
|
|
944
|
+
test::utils::integration_test_guard integration;
|
|
945
|
+
auto cluster = integration.cluster;
|
|
946
|
+
transactions txn(cluster, get_conf());
|
|
947
|
+
couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
948
|
+
REQUIRE_NOTHROW(txn.run([id](attempt_context& ctx) {
|
|
949
|
+
ctx.query("select * from `default` limit 1");
|
|
950
|
+
ctx.get_optional(id);
|
|
951
|
+
}));
|
|
952
|
+
}
|
|
953
|
+
TEST_CASE("transactions: sergey example", "[transactions]")
|
|
954
|
+
{
|
|
955
|
+
test::utils::integration_test_guard integration;
|
|
956
|
+
auto cluster = integration.cluster;
|
|
957
|
+
transactions txn(cluster, get_conf());
|
|
958
|
+
couchbase::core::document_id id_to_remove{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
959
|
+
couchbase::core::document_id id_to_replace{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
960
|
+
couchbase::core::document_id id_to_insert{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("txn") };
|
|
961
|
+
{
|
|
962
|
+
couchbase::core::operations::upsert_request req{ id_to_remove, content_json };
|
|
963
|
+
auto resp = test::utils::execute(integration.cluster, req);
|
|
964
|
+
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
965
|
+
}
|
|
966
|
+
{
|
|
967
|
+
couchbase::core::operations::upsert_request req{ id_to_replace, content_json };
|
|
968
|
+
auto resp = test::utils::execute(integration.cluster, req);
|
|
969
|
+
REQUIRE_SUCCESS(resp.ctx.ec());
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
REQUIRE_NOTHROW(txn.run([&](attempt_context& ctx) {
|
|
973
|
+
ctx.query(fmt::format(
|
|
974
|
+
"INSERT INTO `default` (KEY, VALUE) VALUES ('{}', {})", id_to_insert.key(), couchbase::core::utils::json::generate(content)));
|
|
975
|
+
ctx.query(fmt::format("UPDATE `default` USE KEYS '{}' SET `some_number` = 10 ", id_to_replace.key()));
|
|
976
|
+
ctx.query(fmt::format("DELETE FROM `default` WHERE META().id = '{}'", id_to_remove.key()));
|
|
977
|
+
auto insert_res = ctx.get(id_to_insert);
|
|
978
|
+
CHECK(insert_res.content<tao::json::value>() == content);
|
|
979
|
+
auto replace_res = ctx.get(id_to_replace);
|
|
980
|
+
CHECK(replace_res.content<tao::json::value>()["some_number"] == 10);
|
|
981
|
+
auto remove_res = ctx.get_optional(id_to_remove);
|
|
982
|
+
CHECK_FALSE(remove_res.has_value());
|
|
983
|
+
}));
|
|
984
|
+
}
|
|
@@ -596,16 +596,15 @@ TEST_CASE("transactions: async KV get", "[transactions]")
|
|
|
596
596
|
[get_called, &id](async_attempt_context& ctx) {
|
|
597
597
|
ctx.get(id, [get_called, &id, &ctx](std::exception_ptr, std::optional<transaction_get_result>) {
|
|
598
598
|
auto query = fmt::format("UPDATE `{}` USE KEYS '{}' SET `some` = 'thing else'", id.bucket(), id.key());
|
|
599
|
-
ctx.query(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
});
|
|
599
|
+
ctx.query(query, [get_called, &id, &ctx](std::exception_ptr err, std::optional<couchbase::core::operations::query_response>) {
|
|
600
|
+
if (!err) {
|
|
601
|
+
ctx.get(id, [get_called](std::exception_ptr err, std::optional<transaction_get_result>) {
|
|
602
|
+
if (!err) {
|
|
603
|
+
get_called->store(true);
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
});
|
|
609
608
|
});
|
|
610
609
|
},
|
|
611
610
|
[get_called, barrier](std::optional<transaction_exception> err, std::optional<couchbase::transactions::transaction_result> result) {
|
|
@@ -643,17 +642,16 @@ TEST_CASE("transactions: rollback async KV get", "[transactions]")
|
|
|
643
642
|
[get_called, &id](async_attempt_context& ctx) {
|
|
644
643
|
ctx.get(id, [&ctx, get_called, &id](std::exception_ptr, std::optional<transaction_get_result>) {
|
|
645
644
|
auto query = fmt::format("UPDATE `{}` USE KEYS '{}' SET `some` = 'thing else'", id.bucket(), id.key());
|
|
646
|
-
ctx.query(
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
});
|
|
645
|
+
ctx.query(query, [&ctx, get_called, &id](std::exception_ptr err, std::optional<couchbase::core::operations::query_response>) {
|
|
646
|
+
if (!err) {
|
|
647
|
+
ctx.get(id, [get_called](std::exception_ptr err, std::optional<transaction_get_result>) {
|
|
648
|
+
if (!err) {
|
|
649
|
+
get_called->store(true);
|
|
650
|
+
throw 3;
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
});
|
|
657
655
|
});
|
|
658
656
|
},
|
|
659
657
|
[&get_called, barrier](std::optional<transaction_exception> err, std::optional<couchbase::transactions::transaction_result> result) {
|