couchbase 3.4.3 → 3.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/couchbase/CMakeLists.txt +15 -1
- data/ext/couchbase/core/bucket.cxx +183 -152
- data/ext/couchbase/core/bucket.hxx +17 -4
- data/ext/couchbase/core/cluster.hxx +34 -13
- data/ext/couchbase/core/cluster_options.hxx +3 -0
- data/ext/couchbase/core/crud_component.cxx +51 -22
- data/ext/couchbase/core/error_context/key_value.cxx +2 -1
- data/ext/couchbase/core/error_context/key_value.hxx +10 -12
- data/ext/couchbase/core/impl/build_deferred_query_indexes.cxx +115 -50
- data/ext/couchbase/core/impl/cluster.cxx +6 -0
- data/ext/couchbase/core/impl/create_bucket.cxx +155 -0
- data/ext/couchbase/core/impl/create_query_index.cxx +172 -59
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +2 -1
- data/ext/couchbase/core/impl/drop_bucket.cxx +66 -0
- data/ext/couchbase/core/impl/drop_query_index.cxx +138 -59
- data/ext/couchbase/core/impl/flush_bucket.cxx +66 -0
- data/ext/couchbase/core/impl/get_all_buckets.cxx +163 -0
- data/ext/couchbase/core/impl/get_all_query_indexes.cxx +67 -37
- data/ext/couchbase/core/impl/get_bucket.cxx +153 -0
- data/ext/couchbase/core/impl/internal_manager_error_context.cxx +113 -0
- data/ext/couchbase/core/impl/internal_manager_error_context.hxx +60 -0
- data/ext/couchbase/core/impl/key_value_error_category.cxx +2 -4
- data/ext/couchbase/core/impl/key_value_error_context.cxx +98 -0
- data/ext/couchbase/core/impl/lookup_in.cxx +1 -0
- data/ext/couchbase/core/impl/lookup_in_all_replicas.cxx +176 -0
- data/ext/couchbase/core/impl/lookup_in_all_replicas.hxx +80 -0
- data/ext/couchbase/core/impl/lookup_in_any_replica.cxx +167 -0
- data/ext/couchbase/core/impl/lookup_in_any_replica.hxx +75 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +97 -0
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +67 -0
- data/ext/couchbase/core/impl/manager_error_context.cxx +100 -0
- data/ext/couchbase/core/impl/query.cxx +1 -0
- data/ext/couchbase/core/impl/query_error_context.cxx +75 -0
- data/ext/couchbase/core/impl/update_bucket.cxx +130 -0
- data/ext/couchbase/core/impl/watch_query_indexes.cxx +53 -29
- data/ext/couchbase/core/io/dns_client.cxx +111 -40
- data/ext/couchbase/core/io/dns_config.cxx +5 -4
- data/ext/couchbase/core/io/http_session.hxx +24 -1
- data/ext/couchbase/core/io/mcbp_command.hxx +9 -2
- data/ext/couchbase/core/io/mcbp_session.cxx +80 -43
- data/ext/couchbase/core/io/mcbp_session.hxx +4 -3
- data/ext/couchbase/core/logger/custom_rotating_file_sink.cxx +1 -1
- data/ext/couchbase/core/logger/logger.cxx +80 -20
- data/ext/couchbase/core/logger/logger.hxx +31 -0
- data/ext/couchbase/core/meta/features.hxx +25 -0
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +192 -0
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +188 -0
- data/ext/couchbase/core/operations/document_query.cxx +11 -0
- data/ext/couchbase/core/operations/document_query.hxx +1 -0
- data/ext/couchbase/core/operations.hxx +2 -0
- data/ext/couchbase/core/origin.cxx +270 -0
- data/ext/couchbase/core/origin.hxx +2 -0
- data/ext/couchbase/core/protocol/client_response.hxx +1 -0
- data/ext/couchbase/core/protocol/cmd_hello.hxx +1 -0
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +107 -0
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.hxx +137 -0
- data/ext/couchbase/core/protocol/hello_feature.hxx +6 -0
- data/ext/couchbase/core/protocol/hello_feature_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/status.cxx +2 -2
- data/ext/couchbase/core/range_scan_options.cxx +3 -27
- data/ext/couchbase/core/range_scan_options.hxx +13 -17
- data/ext/couchbase/core/range_scan_orchestrator.cxx +388 -170
- data/ext/couchbase/core/range_scan_orchestrator.hxx +13 -2
- data/ext/couchbase/core/range_scan_orchestrator_options.hxx +5 -3
- data/ext/couchbase/core/scan_options.hxx +0 -19
- data/ext/couchbase/core/scan_result.cxx +19 -5
- data/ext/couchbase/core/scan_result.hxx +5 -2
- data/ext/couchbase/core/timeout_defaults.hxx +2 -3
- data/ext/couchbase/core/topology/capabilities.hxx +3 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +8 -0
- data/ext/couchbase/core/topology/collections_manifest_fmt.hxx +1 -1
- data/ext/couchbase/core/topology/configuration.hxx +15 -0
- data/ext/couchbase/core/topology/configuration_json.hxx +6 -1
- data/ext/couchbase/core/utils/connection_string.cxx +62 -47
- data/ext/couchbase/core/utils/connection_string.hxx +1 -0
- data/ext/couchbase/couchbase/analytics_error_context.hxx +1 -1
- data/ext/couchbase/couchbase/behavior_options.hxx +19 -2
- data/ext/couchbase/couchbase/bucket_manager.hxx +135 -0
- data/ext/couchbase/couchbase/build_query_index_options.hxx +0 -30
- data/ext/couchbase/couchbase/cluster.hxx +14 -0
- data/ext/couchbase/couchbase/collection.hxx +111 -0
- data/ext/couchbase/couchbase/collection_query_index_manager.hxx +7 -48
- data/ext/couchbase/couchbase/create_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/create_primary_query_index_options.hxx +0 -29
- data/ext/couchbase/couchbase/create_query_index_options.hxx +0 -33
- data/ext/couchbase/couchbase/drop_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/drop_primary_query_index_options.hxx +0 -30
- data/ext/couchbase/couchbase/drop_query_index_options.hxx +0 -31
- data/ext/couchbase/couchbase/error_codes.hxx +1 -2
- data/ext/couchbase/couchbase/error_context.hxx +10 -2
- data/ext/couchbase/couchbase/flush_bucket_options.hxx +41 -0
- data/ext/couchbase/{core/topology/error_map_fmt.hxx → couchbase/fmt/key_value_error_map_attribute.hxx} +21 -21
- data/ext/couchbase/couchbase/get_all_buckets_options.hxx +44 -0
- data/ext/couchbase/couchbase/get_all_query_indexes_options.hxx +0 -30
- data/ext/couchbase/couchbase/get_and_lock_options.hxx +2 -2
- data/ext/couchbase/couchbase/get_and_touch_options.hxx +2 -2
- data/ext/couchbase/couchbase/get_bucket_options.hxx +43 -0
- data/ext/couchbase/couchbase/get_options.hxx +2 -2
- data/ext/couchbase/couchbase/insert_options.hxx +3 -3
- data/ext/couchbase/couchbase/key_value_error_context.hxx +7 -2
- data/ext/couchbase/couchbase/lookup_in_all_replicas_options.hxx +109 -0
- data/ext/couchbase/couchbase/lookup_in_any_replica_options.hxx +101 -0
- data/ext/couchbase/couchbase/lookup_in_options.hxx +2 -2
- data/ext/couchbase/couchbase/lookup_in_replica_result.hxx +74 -0
- data/ext/couchbase/couchbase/lookup_in_result.hxx +26 -0
- data/ext/couchbase/couchbase/management/bucket_settings.hxx +116 -0
- data/ext/couchbase/couchbase/manager_error_context.hxx +29 -53
- data/ext/couchbase/couchbase/mutate_in_options.hxx +2 -2
- data/ext/couchbase/couchbase/query_error_context.hxx +3 -1
- data/ext/couchbase/couchbase/query_index_manager.hxx +16 -83
- data/ext/couchbase/couchbase/query_options.hxx +18 -0
- data/ext/couchbase/couchbase/remove_options.hxx +2 -2
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/security_options.hxx +15 -0
- data/ext/couchbase/couchbase/subdocument_error_context.hxx +4 -2
- data/ext/couchbase/couchbase/touch_options.hxx +2 -2
- data/ext/couchbase/couchbase/unlock_options.hxx +2 -2
- data/ext/couchbase/couchbase/update_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/watch_query_indexes_options.hxx +0 -31
- data/ext/couchbase/test/CMakeLists.txt +1 -0
- data/ext/couchbase/test/test_integration_collections.cxx +6 -0
- data/ext/couchbase/test/test_integration_crud.cxx +5 -0
- data/ext/couchbase/test/test_integration_examples.cxx +137 -1
- data/ext/couchbase/test/test_integration_management.cxx +709 -266
- data/ext/couchbase/test/test_integration_query.cxx +19 -7
- data/ext/couchbase/test/test_integration_range_scan.cxx +351 -112
- data/ext/couchbase/test/test_integration_search.cxx +10 -1
- data/ext/couchbase/test/test_integration_subdoc.cxx +655 -0
- data/ext/couchbase/test/test_transaction_public_async_api.cxx +13 -12
- data/ext/couchbase/test/test_transaction_public_blocking_api.cxx +27 -21
- data/ext/couchbase/test/test_unit_connection_string.cxx +29 -0
- data/ext/couchbase/test/test_unit_query.cxx +75 -0
- data/ext/couchbase.cxx +583 -29
- data/ext/revisions.rb +3 -3
- data/lib/couchbase/cluster.rb +1 -1
- data/lib/couchbase/collection.rb +108 -0
- data/lib/couchbase/collection_options.rb +100 -0
- data/lib/couchbase/errors.rb +5 -0
- data/lib/couchbase/key_value_scan.rb +125 -0
- data/lib/couchbase/options.rb +151 -0
- data/lib/couchbase/scope.rb +1 -1
- data/lib/couchbase/utils/time.rb +14 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +41 -7
- data/ext/couchbase/core/impl/collection_query_index_manager.cxx +0 -93
@@ -40,12 +40,12 @@ populate_documents_for_range_scan(const couchbase::collection& collection,
|
|
40
40
|
options.expiry(expiry.value());
|
41
41
|
}
|
42
42
|
|
43
|
-
std::map<std::
|
43
|
+
std::map<std::string, couchbase::mutation_token> mutations;
|
44
44
|
for (const auto& id : ids) {
|
45
45
|
auto [ctx, resp] = collection.upsert<couchbase::codec::raw_binary_transcoder>(id, value, options).get();
|
46
46
|
REQUIRE_SUCCESS(ctx.ec());
|
47
47
|
REQUIRE(resp.mutation_token().has_value());
|
48
|
-
mutations[
|
48
|
+
mutations[id] = resp.mutation_token().value();
|
49
49
|
}
|
50
50
|
return mutations;
|
51
51
|
}
|
@@ -76,7 +76,6 @@ do_range_scan(couchbase::core::agent agent,
|
|
76
76
|
std::vector<couchbase::core::range_scan_item> data;
|
77
77
|
|
78
78
|
auto options = continue_options;
|
79
|
-
options.ids_only = create_options.ids_only; // support servers before MB-54267. TODO: remove after server GA
|
80
79
|
|
81
80
|
do {
|
82
81
|
auto barrier = std::make_shared<std::promise<std::pair<couchbase::core::range_scan_continue_result, std::error_code>>>();
|
@@ -115,6 +114,26 @@ make_binary_value(std::size_t number_of_bytes)
|
|
115
114
|
return value;
|
116
115
|
}
|
117
116
|
|
117
|
+
static couchbase::core::topology::configuration::vbucket_map
|
118
|
+
get_vbucket_map(test::utils::integration_test_guard& integration)
|
119
|
+
{
|
120
|
+
auto barrier = std::make_shared<std::promise<tl::expected<couchbase::core::topology::configuration::vbucket_map, std::error_code>>>();
|
121
|
+
auto f = barrier->get_future();
|
122
|
+
integration.cluster->with_bucket_configuration(
|
123
|
+
integration.ctx.bucket, [barrier](std::error_code ec, const couchbase::core::topology::configuration& config) mutable {
|
124
|
+
if (ec) {
|
125
|
+
return barrier->set_value(tl::unexpected(ec));
|
126
|
+
}
|
127
|
+
if (!config.vbmap || config.vbmap->empty()) {
|
128
|
+
return barrier->set_value(tl::unexpected(couchbase::errc::common::feature_not_available));
|
129
|
+
}
|
130
|
+
barrier->set_value(config.vbmap.value());
|
131
|
+
});
|
132
|
+
auto vbucket_map = f.get();
|
133
|
+
EXPECT_SUCCESS(vbucket_map);
|
134
|
+
return vbucket_map.value();
|
135
|
+
}
|
136
|
+
|
118
137
|
TEST_CASE("integration: range scan large values", "[integration]")
|
119
138
|
{
|
120
139
|
test::utils::integration_test_guard integration;
|
@@ -148,8 +167,8 @@ TEST_CASE("integration: range scan large values", "[integration]")
|
|
148
167
|
couchbase::scope::default_name,
|
149
168
|
couchbase::collection::default_name,
|
150
169
|
couchbase::core::range_scan{
|
151
|
-
|
152
|
-
|
170
|
+
couchbase::core::scan_term{ "largevalues" },
|
171
|
+
couchbase::core::scan_term{ "largevalues\xff" },
|
153
172
|
},
|
154
173
|
};
|
155
174
|
create_options.snapshot_requirements = couchbase::core::range_snapshot_requirements{
|
@@ -208,8 +227,8 @@ TEST_CASE("integration: range scan small values", "[integration]")
|
|
208
227
|
couchbase::scope::default_name,
|
209
228
|
couchbase::collection::default_name,
|
210
229
|
couchbase::core::range_scan{
|
211
|
-
|
212
|
-
|
230
|
+
couchbase::core::scan_term{ "rangesmallvalues" },
|
231
|
+
couchbase::core::scan_term{ "rangesmallvalues\xff" },
|
213
232
|
},
|
214
233
|
};
|
215
234
|
create_options.snapshot_requirements = couchbase::core::range_snapshot_requirements{
|
@@ -312,8 +331,8 @@ TEST_CASE("integration: range scan collection retry", "[integration]")
|
|
312
331
|
couchbase::scope::default_name,
|
313
332
|
new_collection.name(),
|
314
333
|
couchbase::core::range_scan{
|
315
|
-
|
316
|
-
|
334
|
+
couchbase::core::scan_term{ "rangecollectionretry" },
|
335
|
+
couchbase::core::scan_term{ "rangecollectionretry\xff" },
|
317
336
|
},
|
318
337
|
};
|
319
338
|
create_options.snapshot_requirements = couchbase::core::range_snapshot_requirements{
|
@@ -372,8 +391,8 @@ TEST_CASE("integration: range scan only keys", "[integration]")
|
|
372
391
|
couchbase::scope::default_name,
|
373
392
|
couchbase::collection::default_name,
|
374
393
|
couchbase::core::range_scan{
|
375
|
-
|
376
|
-
|
394
|
+
couchbase::core::scan_term{ "rangekeysonly" },
|
395
|
+
couchbase::core::scan_term{ "rangekeysonly\xff" },
|
377
396
|
},
|
378
397
|
};
|
379
398
|
create_options.ids_only = true;
|
@@ -435,8 +454,8 @@ TEST_CASE("integration: range scan cancellation before continue", "[integration]
|
|
435
454
|
couchbase::scope::default_name,
|
436
455
|
couchbase::collection::default_name,
|
437
456
|
couchbase::core::range_scan{
|
438
|
-
|
439
|
-
|
457
|
+
couchbase::core::scan_term{ "rangescancancel" },
|
458
|
+
couchbase::core::scan_term{ "rangescancancel\xff" },
|
440
459
|
},
|
441
460
|
};
|
442
461
|
options.ids_only = true;
|
@@ -474,7 +493,6 @@ TEST_CASE("integration: range scan cancellation before continue", "[integration]
|
|
474
493
|
|
475
494
|
couchbase::core::range_scan_continue_options options{};
|
476
495
|
options.batch_time_limit = std::chrono::seconds{ 10 };
|
477
|
-
options.ids_only = true; // support servers before MB-54267. TODO: remove after server GA
|
478
496
|
|
479
497
|
bool items_callback_invoked{ false };
|
480
498
|
{
|
@@ -539,8 +557,8 @@ TEST_CASE("integration: range scan cancel during streaming using protocol cancel
|
|
539
557
|
couchbase::scope::default_name,
|
540
558
|
couchbase::collection::default_name,
|
541
559
|
couchbase::core::range_scan{
|
542
|
-
|
543
|
-
|
560
|
+
couchbase::core::scan_term{ "rangescancancel" },
|
561
|
+
couchbase::core::scan_term{ "rangescancancel\xff" },
|
544
562
|
},
|
545
563
|
};
|
546
564
|
options.ids_only = true;
|
@@ -577,7 +595,6 @@ TEST_CASE("integration: range scan cancel during streaming using protocol cancel
|
|
577
595
|
couchbase::core::range_scan_continue_options options{};
|
578
596
|
options.batch_time_limit = std::chrono::seconds{ 10 };
|
579
597
|
options.batch_item_limit = 3; // limit batch to 3 items, while range expected to be larger
|
580
|
-
options.ids_only = true; // support servers before MB-54267. TODO: remove after server GA
|
581
598
|
|
582
599
|
auto barrier = std::make_shared<std::promise<std::pair<couchbase::core::range_scan_continue_result, std::error_code>>>();
|
583
600
|
auto f = barrier->get_future();
|
@@ -651,8 +668,8 @@ TEST_CASE("integration: range scan cancel during streaming using pending_operati
|
|
651
668
|
couchbase::scope::default_name,
|
652
669
|
couchbase::collection::default_name,
|
653
670
|
couchbase::core::range_scan{
|
654
|
-
|
655
|
-
|
671
|
+
couchbase::core::scan_term{ "rangescancancel" },
|
672
|
+
couchbase::core::scan_term{ "rangescancancel\xff" },
|
656
673
|
},
|
657
674
|
};
|
658
675
|
options.ids_only = true;
|
@@ -685,7 +702,6 @@ TEST_CASE("integration: range scan cancel during streaming using pending_operati
|
|
685
702
|
couchbase::core::range_scan_continue_options options{};
|
686
703
|
options.batch_time_limit = std::chrono::seconds{ 10 };
|
687
704
|
options.batch_item_limit = 3; // limit batch to 3 items, while range expected to be larger
|
688
|
-
options.ids_only = true; // support servers before MB-54267. TODO: remove after server GA
|
689
705
|
|
690
706
|
auto barrier = std::make_shared<std::promise<std::pair<couchbase::core::range_scan_continue_result, std::error_code>>>();
|
691
707
|
auto f = barrier->get_future();
|
@@ -774,7 +790,7 @@ make_doc_ids(std::size_t number_of_keys, const std::string& prefix)
|
|
774
790
|
}
|
775
791
|
|
776
792
|
static auto
|
777
|
-
mutations_to_mutation_state(std::map<std::
|
793
|
+
mutations_to_mutation_state(std::map<std::string, couchbase::mutation_token> mutations)
|
778
794
|
{
|
779
795
|
couchbase::core::mutation_state state;
|
780
796
|
for (const auto& [key, token] : mutations) {
|
@@ -800,42 +816,27 @@ TEST_CASE("integration: manager scan range without content", "[integration]")
|
|
800
816
|
auto value = make_binary_value(1);
|
801
817
|
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
802
818
|
|
803
|
-
auto
|
804
|
-
auto f = barrier->get_future();
|
805
|
-
integration.cluster->with_bucket_configuration(
|
806
|
-
integration.ctx.bucket, [barrier](std::error_code ec, const couchbase::core::topology::configuration& config) mutable {
|
807
|
-
if (ec) {
|
808
|
-
return barrier->set_value(tl::unexpected(ec));
|
809
|
-
}
|
810
|
-
if (!config.vbmap || config.vbmap->empty()) {
|
811
|
-
return barrier->set_value(tl::unexpected(couchbase::errc::common::feature_not_available));
|
812
|
-
}
|
813
|
-
barrier->set_value(config.vbmap->size());
|
814
|
-
});
|
815
|
-
auto number_of_vbuckets = f.get();
|
816
|
-
EXPECT_SUCCESS(number_of_vbuckets);
|
819
|
+
auto vbucket_map = get_vbucket_map(integration);
|
817
820
|
|
818
821
|
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
819
822
|
ag.open_bucket(integration.ctx.bucket);
|
820
823
|
auto agent = ag.get_agent(integration.ctx.bucket);
|
821
824
|
REQUIRE(agent.has_value());
|
822
825
|
|
823
|
-
couchbase::core::range_scan scan{
|
826
|
+
couchbase::core::range_scan scan{
|
827
|
+
couchbase::core::scan_term{ "rangescanwithoutcontent" },
|
828
|
+
couchbase::core::scan_term{ "rangescanwithoutcontent\xff" },
|
829
|
+
};
|
824
830
|
couchbase::core::range_scan_orchestrator_options options{};
|
825
831
|
options.consistent_with = mutations_to_mutation_state(mutations);
|
826
832
|
options.ids_only = true;
|
827
|
-
couchbase::core::range_scan_orchestrator orchestrator(
|
828
|
-
|
829
|
-
number_of_vbuckets.value(),
|
830
|
-
couchbase::scope::default_name,
|
831
|
-
couchbase::collection::default_name,
|
832
|
-
scan,
|
833
|
-
options);
|
833
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
834
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
834
835
|
|
835
836
|
auto result = orchestrator.scan();
|
836
837
|
EXPECT_SUCCESS(result);
|
837
838
|
|
838
|
-
std::set<std::
|
839
|
+
std::set<std::string> entry_ids{};
|
839
840
|
|
840
841
|
do {
|
841
842
|
auto entry = result->next();
|
@@ -848,10 +849,11 @@ TEST_CASE("integration: manager scan range without content", "[integration]")
|
|
848
849
|
REQUIRE_FALSE(entry->body.has_value());
|
849
850
|
} while (true);
|
850
851
|
|
852
|
+
REQUIRE(ids.size() == entry_ids.size());
|
853
|
+
|
851
854
|
for (const auto& id : ids) {
|
852
|
-
REQUIRE(entry_ids.count(
|
855
|
+
REQUIRE(entry_ids.count(id) == 1);
|
853
856
|
}
|
854
|
-
REQUIRE(ids.size() == entry_ids.size());
|
855
857
|
}
|
856
858
|
|
857
859
|
TEST_CASE("integration: manager scan range with content", "[integration]")
|
@@ -871,41 +873,26 @@ TEST_CASE("integration: manager scan range with content", "[integration]")
|
|
871
873
|
auto value = make_binary_value(100);
|
872
874
|
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
873
875
|
|
874
|
-
auto
|
875
|
-
auto f = barrier->get_future();
|
876
|
-
integration.cluster->with_bucket_configuration(
|
877
|
-
integration.ctx.bucket, [barrier](std::error_code ec, const couchbase::core::topology::configuration& config) mutable {
|
878
|
-
if (ec) {
|
879
|
-
return barrier->set_value(tl::unexpected(ec));
|
880
|
-
}
|
881
|
-
if (!config.vbmap || config.vbmap->empty()) {
|
882
|
-
return barrier->set_value(tl::unexpected(couchbase::errc::common::feature_not_available));
|
883
|
-
}
|
884
|
-
barrier->set_value(config.vbmap->size());
|
885
|
-
});
|
886
|
-
auto number_of_vbuckets = f.get();
|
887
|
-
EXPECT_SUCCESS(number_of_vbuckets);
|
876
|
+
auto vbucket_map = get_vbucket_map(integration);
|
888
877
|
|
889
878
|
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
890
879
|
ag.open_bucket(integration.ctx.bucket);
|
891
880
|
auto agent = ag.get_agent(integration.ctx.bucket);
|
892
881
|
REQUIRE(agent.has_value());
|
893
882
|
|
894
|
-
couchbase::core::range_scan scan{
|
883
|
+
couchbase::core::range_scan scan{
|
884
|
+
couchbase::core::scan_term{ "rangescanwithcontent" },
|
885
|
+
couchbase::core::scan_term{ "rangescanwithcontent\xff" },
|
886
|
+
};
|
895
887
|
couchbase::core::range_scan_orchestrator_options options{};
|
896
888
|
options.consistent_with = mutations_to_mutation_state(mutations);
|
897
|
-
couchbase::core::range_scan_orchestrator orchestrator(
|
898
|
-
|
899
|
-
number_of_vbuckets.value(),
|
900
|
-
couchbase::scope::default_name,
|
901
|
-
couchbase::collection::default_name,
|
902
|
-
scan,
|
903
|
-
options);
|
889
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
890
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
904
891
|
|
905
892
|
auto result = orchestrator.scan();
|
906
893
|
EXPECT_SUCCESS(result);
|
907
894
|
|
908
|
-
std::set<std::
|
895
|
+
std::set<std::string> entry_ids{};
|
909
896
|
|
910
897
|
do {
|
911
898
|
auto entry = result->next();
|
@@ -918,11 +905,12 @@ TEST_CASE("integration: manager scan range with content", "[integration]")
|
|
918
905
|
REQUIRE(entry->body.has_value());
|
919
906
|
} while (true);
|
920
907
|
|
908
|
+
REQUIRE(ids.size() == entry_ids.size());
|
909
|
+
|
921
910
|
for (const auto& id : ids) {
|
922
911
|
INFO(id);
|
923
|
-
REQUIRE(entry_ids.count(
|
912
|
+
REQUIRE(entry_ids.count(id) == 1);
|
924
913
|
}
|
925
|
-
REQUIRE(ids.size() == entry_ids.size());
|
926
914
|
}
|
927
915
|
|
928
916
|
TEST_CASE("integration: manager sampling scan with custom collection", "[integration]")
|
@@ -944,20 +932,7 @@ TEST_CASE("integration: manager sampling scan with custom collection", "[integra
|
|
944
932
|
auto value = make_binary_value(100);
|
945
933
|
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 300 });
|
946
934
|
|
947
|
-
auto
|
948
|
-
auto f = barrier->get_future();
|
949
|
-
integration.cluster->with_bucket_configuration(
|
950
|
-
integration.ctx.bucket, [barrier](std::error_code ec, const couchbase::core::topology::configuration& config) mutable {
|
951
|
-
if (ec) {
|
952
|
-
return barrier->set_value(tl::unexpected(ec));
|
953
|
-
}
|
954
|
-
if (!config.vbmap || config.vbmap->empty()) {
|
955
|
-
return barrier->set_value(tl::unexpected(couchbase::errc::common::feature_not_available));
|
956
|
-
}
|
957
|
-
barrier->set_value(config.vbmap->size());
|
958
|
-
});
|
959
|
-
auto number_of_vbuckets = f.get();
|
960
|
-
EXPECT_SUCCESS(number_of_vbuckets);
|
935
|
+
auto vbucket_map = get_vbucket_map(integration);
|
961
936
|
|
962
937
|
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
963
938
|
ag.open_bucket(integration.ctx.bucket);
|
@@ -968,12 +943,12 @@ TEST_CASE("integration: manager sampling scan with custom collection", "[integra
|
|
968
943
|
couchbase::core::range_scan_orchestrator_options options{};
|
969
944
|
options.consistent_with = mutations_to_mutation_state(mutations);
|
970
945
|
couchbase::core::range_scan_orchestrator orchestrator(
|
971
|
-
integration.io, agent.value(),
|
946
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, new_collection.name(), scan, options);
|
972
947
|
|
973
948
|
auto result = orchestrator.scan();
|
974
949
|
EXPECT_SUCCESS(result);
|
975
950
|
|
976
|
-
std::set<std::
|
951
|
+
std::set<std::string> entry_ids{};
|
977
952
|
|
978
953
|
auto now = std::chrono::system_clock::now();
|
979
954
|
do {
|
@@ -994,11 +969,65 @@ TEST_CASE("integration: manager sampling scan with custom collection", "[integra
|
|
994
969
|
REQUIRE(ids.size() >= 10);
|
995
970
|
|
996
971
|
for (const auto& id : entry_ids) {
|
997
|
-
REQUIRE(std::find(ids.begin(), ids.end(),
|
972
|
+
REQUIRE(std::find(ids.begin(), ids.end(), id) != ids.end());
|
998
973
|
}
|
999
974
|
}
|
1000
975
|
|
1001
|
-
TEST_CASE("integration: manager
|
976
|
+
TEST_CASE("integration: manager prefix scan without content", "[integration]")
|
977
|
+
{
|
978
|
+
test::utils::integration_test_guard integration;
|
979
|
+
|
980
|
+
if (!integration.has_bucket_capability("range_scan")) {
|
981
|
+
SKIP("cluster does not support range_scan");
|
982
|
+
}
|
983
|
+
|
984
|
+
auto collection = couchbase::cluster(integration.cluster)
|
985
|
+
.bucket(integration.ctx.bucket)
|
986
|
+
.scope(couchbase::scope::default_name)
|
987
|
+
.collection(couchbase::collection::default_name);
|
988
|
+
|
989
|
+
auto ids = make_doc_ids(100, "prefixscanwithoutcontent-");
|
990
|
+
auto value = make_binary_value(1);
|
991
|
+
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
992
|
+
|
993
|
+
auto vbucket_map = get_vbucket_map(integration);
|
994
|
+
|
995
|
+
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
996
|
+
ag.open_bucket(integration.ctx.bucket);
|
997
|
+
auto agent = ag.get_agent(integration.ctx.bucket);
|
998
|
+
REQUIRE(agent.has_value());
|
999
|
+
|
1000
|
+
couchbase::core::prefix_scan scan{ "prefixscanwithoutcontent" };
|
1001
|
+
couchbase::core::range_scan_orchestrator_options options{};
|
1002
|
+
options.consistent_with = mutations_to_mutation_state(mutations);
|
1003
|
+
options.ids_only = true;
|
1004
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
1005
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
1006
|
+
|
1007
|
+
auto result = orchestrator.scan();
|
1008
|
+
EXPECT_SUCCESS(result);
|
1009
|
+
|
1010
|
+
std::set<std::string> entry_ids{};
|
1011
|
+
|
1012
|
+
do {
|
1013
|
+
auto entry = result->next();
|
1014
|
+
if (!entry) {
|
1015
|
+
break;
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
auto [_, inserted] = entry_ids.insert(entry->key);
|
1019
|
+
REQUIRE(inserted);
|
1020
|
+
REQUIRE_FALSE(entry->body.has_value());
|
1021
|
+
} while (true);
|
1022
|
+
|
1023
|
+
REQUIRE(ids.size() == entry_ids.size());
|
1024
|
+
|
1025
|
+
for (const auto& id : ids) {
|
1026
|
+
REQUIRE(entry_ids.count(id) == 1);
|
1027
|
+
}
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
TEST_CASE("integration: manager sampling scan with custom collection and up to 10 concurrent streams", "[integration]")
|
1002
1031
|
{
|
1003
1032
|
test::utils::integration_test_guard integration;
|
1004
1033
|
|
@@ -1013,43 +1042,151 @@ TEST_CASE("integration: manager range scan with sort", "[integration]")
|
|
1013
1042
|
.scope(couchbase::scope::default_name)
|
1014
1043
|
.collection(new_collection.name());
|
1015
1044
|
|
1016
|
-
auto ids = make_doc_ids(100, "
|
1045
|
+
auto ids = make_doc_ids(100, "samplingscan-");
|
1017
1046
|
auto value = make_binary_value(100);
|
1018
1047
|
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 300 });
|
1019
1048
|
|
1020
|
-
auto
|
1021
|
-
|
1022
|
-
integration.cluster
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1049
|
+
auto vbucket_map = get_vbucket_map(integration);
|
1050
|
+
|
1051
|
+
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
1052
|
+
ag.open_bucket(integration.ctx.bucket);
|
1053
|
+
auto agent = ag.get_agent(integration.ctx.bucket);
|
1054
|
+
REQUIRE(agent.has_value());
|
1055
|
+
|
1056
|
+
couchbase::core::sampling_scan scan{ 10, 50 };
|
1057
|
+
couchbase::core::range_scan_orchestrator_options options{};
|
1058
|
+
options.consistent_with = mutations_to_mutation_state(mutations);
|
1059
|
+
options.concurrency = 10;
|
1060
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
1061
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, new_collection.name(), scan, options);
|
1062
|
+
|
1063
|
+
auto result = orchestrator.scan();
|
1064
|
+
EXPECT_SUCCESS(result);
|
1065
|
+
|
1066
|
+
std::set<std::string> entry_ids{};
|
1067
|
+
|
1068
|
+
auto now = std::chrono::system_clock::now();
|
1069
|
+
do {
|
1070
|
+
auto entry = result->next();
|
1071
|
+
if (!entry) {
|
1072
|
+
break;
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
REQUIRE(entry->body);
|
1076
|
+
REQUIRE_FALSE(entry->body->cas.empty());
|
1077
|
+
REQUIRE(entry->body->value == value);
|
1078
|
+
REQUIRE(entry->body->expiry_time() > now);
|
1079
|
+
|
1080
|
+
auto [_, inserted] = entry_ids.insert(entry->key);
|
1081
|
+
REQUIRE(inserted);
|
1082
|
+
} while (true);
|
1083
|
+
|
1084
|
+
REQUIRE(ids.size() >= 10);
|
1085
|
+
|
1086
|
+
for (const auto& id : entry_ids) {
|
1087
|
+
REQUIRE(std::find(ids.begin(), ids.end(), id) != ids.end());
|
1088
|
+
}
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
TEST_CASE("integration: manager sampling scan with custom collection and up to 128 concurrent streams and batch item limit 0",
|
1092
|
+
"[integration]")
|
1093
|
+
{
|
1094
|
+
test::utils::integration_test_guard integration;
|
1095
|
+
|
1096
|
+
if (!integration.has_bucket_capability("range_scan")) {
|
1097
|
+
SKIP("cluster does not support range_scan");
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
collection_guard new_collection(integration);
|
1101
|
+
|
1102
|
+
auto collection = couchbase::cluster(integration.cluster)
|
1103
|
+
.bucket(integration.ctx.bucket)
|
1104
|
+
.scope(couchbase::scope::default_name)
|
1105
|
+
.collection(new_collection.name());
|
1106
|
+
|
1107
|
+
auto ids = make_doc_ids(100, "samplingscan-");
|
1108
|
+
auto value = make_binary_value(100);
|
1109
|
+
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 300 });
|
1110
|
+
|
1111
|
+
auto vbucket_map = get_vbucket_map(integration);
|
1034
1112
|
|
1035
1113
|
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
1036
1114
|
ag.open_bucket(integration.ctx.bucket);
|
1037
1115
|
auto agent = ag.get_agent(integration.ctx.bucket);
|
1038
1116
|
REQUIRE(agent.has_value());
|
1039
1117
|
|
1040
|
-
couchbase::core::
|
1118
|
+
couchbase::core::sampling_scan scan{ 10, 50 };
|
1119
|
+
couchbase::core::range_scan_orchestrator_options options{};
|
1120
|
+
options.consistent_with = mutations_to_mutation_state(mutations);
|
1121
|
+
options.concurrency = 128;
|
1122
|
+
options.batch_item_limit = 0;
|
1123
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
1124
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, new_collection.name(), scan, options);
|
1125
|
+
|
1126
|
+
auto result = orchestrator.scan();
|
1127
|
+
EXPECT_SUCCESS(result);
|
1128
|
+
|
1129
|
+
std::set<std::string> entry_ids{};
|
1130
|
+
|
1131
|
+
auto now = std::chrono::system_clock::now();
|
1132
|
+
do {
|
1133
|
+
auto entry = result->next();
|
1134
|
+
if (!entry) {
|
1135
|
+
break;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
REQUIRE(entry->body);
|
1139
|
+
REQUIRE_FALSE(entry->body->cas.empty());
|
1140
|
+
REQUIRE(entry->body->value == value);
|
1141
|
+
REQUIRE(entry->body->expiry_time() > now);
|
1142
|
+
|
1143
|
+
auto [_, inserted] = entry_ids.insert(entry->key);
|
1144
|
+
REQUIRE(inserted);
|
1145
|
+
} while (true);
|
1146
|
+
|
1147
|
+
REQUIRE(ids.size() >= 10);
|
1148
|
+
|
1149
|
+
for (const auto& id : entry_ids) {
|
1150
|
+
REQUIRE(std::find(ids.begin(), ids.end(), id) != ids.end());
|
1151
|
+
}
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
TEST_CASE("integration: manager prefix scan without content and up to 5 concurrent streams", "[integration]")
|
1155
|
+
{
|
1156
|
+
test::utils::integration_test_guard integration;
|
1157
|
+
|
1158
|
+
if (!integration.has_bucket_capability("range_scan")) {
|
1159
|
+
SKIP("cluster does not support range_scan");
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
auto collection = couchbase::cluster(integration.cluster)
|
1163
|
+
.bucket(integration.ctx.bucket)
|
1164
|
+
.scope(couchbase::scope::default_name)
|
1165
|
+
.collection(couchbase::collection::default_name);
|
1166
|
+
|
1167
|
+
auto ids = make_doc_ids(100, "prefixscanwithoutcontent-");
|
1168
|
+
auto value = make_binary_value(1);
|
1169
|
+
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
1170
|
+
|
1171
|
+
auto vbucket_map = get_vbucket_map(integration);
|
1172
|
+
|
1173
|
+
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
1174
|
+
ag.open_bucket(integration.ctx.bucket);
|
1175
|
+
auto agent = ag.get_agent(integration.ctx.bucket);
|
1176
|
+
REQUIRE(agent.has_value());
|
1177
|
+
|
1178
|
+
couchbase::core::prefix_scan scan{ "prefixscanwithoutcontent" };
|
1041
1179
|
couchbase::core::range_scan_orchestrator_options options{};
|
1042
1180
|
options.consistent_with = mutations_to_mutation_state(mutations);
|
1043
1181
|
options.ids_only = true;
|
1044
|
-
options.
|
1182
|
+
options.concurrency = 5;
|
1045
1183
|
couchbase::core::range_scan_orchestrator orchestrator(
|
1046
|
-
integration.io, agent.value(),
|
1184
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
1047
1185
|
|
1048
1186
|
auto result = orchestrator.scan();
|
1049
1187
|
EXPECT_SUCCESS(result);
|
1050
1188
|
|
1051
|
-
std::
|
1052
|
-
entry_ids.reserve(ids.size());
|
1189
|
+
std::set<std::string> entry_ids{};
|
1053
1190
|
|
1054
1191
|
do {
|
1055
1192
|
auto entry = result->next();
|
@@ -1057,11 +1194,113 @@ TEST_CASE("integration: manager range scan with sort", "[integration]")
|
|
1057
1194
|
break;
|
1058
1195
|
}
|
1059
1196
|
|
1060
|
-
entry_ids.
|
1197
|
+
auto [_, inserted] = entry_ids.insert(entry->key);
|
1198
|
+
REQUIRE(inserted);
|
1061
1199
|
REQUIRE_FALSE(entry->body.has_value());
|
1062
1200
|
} while (true);
|
1063
1201
|
|
1064
1202
|
REQUIRE(ids.size() == entry_ids.size());
|
1065
|
-
|
1066
|
-
|
1203
|
+
|
1204
|
+
for (const auto& id : ids) {
|
1205
|
+
REQUIRE(entry_ids.count(id) == 1);
|
1206
|
+
}
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
TEST_CASE("integration: manager prefix scan, get 10 items and cancel", "[integration]")
|
1210
|
+
{
|
1211
|
+
test::utils::integration_test_guard integration;
|
1212
|
+
|
1213
|
+
if (!integration.has_bucket_capability("range_scan")) {
|
1214
|
+
SKIP("cluster does not support range_scan");
|
1215
|
+
}
|
1216
|
+
|
1217
|
+
auto collection = couchbase::cluster(integration.cluster)
|
1218
|
+
.bucket(integration.ctx.bucket)
|
1219
|
+
.scope(couchbase::scope::default_name)
|
1220
|
+
.collection(couchbase::collection::default_name);
|
1221
|
+
|
1222
|
+
auto ids = make_doc_ids(15, "rangescancancel-");
|
1223
|
+
auto value = make_binary_value(1);
|
1224
|
+
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
1225
|
+
|
1226
|
+
auto vbucket_map = get_vbucket_map(integration);
|
1227
|
+
|
1228
|
+
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
1229
|
+
ag.open_bucket(integration.ctx.bucket);
|
1230
|
+
auto agent = ag.get_agent(integration.ctx.bucket);
|
1231
|
+
REQUIRE(agent.has_value());
|
1232
|
+
|
1233
|
+
couchbase::core::prefix_scan scan{ "rangescancancel" };
|
1234
|
+
couchbase::core::range_scan_orchestrator_options options{};
|
1235
|
+
options.consistent_with = mutations_to_mutation_state(mutations);
|
1236
|
+
options.ids_only = true;
|
1237
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
1238
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
1239
|
+
|
1240
|
+
auto result = orchestrator.scan();
|
1241
|
+
EXPECT_SUCCESS(result);
|
1242
|
+
|
1243
|
+
std::set<std::string> entry_ids{};
|
1244
|
+
std::size_t const expected_id_count = 10;
|
1245
|
+
|
1246
|
+
for (std::size_t i = 0; i < expected_id_count; i++) {
|
1247
|
+
auto entry = result->next();
|
1248
|
+
if (!entry) {
|
1249
|
+
break;
|
1250
|
+
}
|
1251
|
+
|
1252
|
+
auto [_, inserted] = entry_ids.insert(entry->key);
|
1253
|
+
REQUIRE(inserted);
|
1254
|
+
REQUIRE_FALSE(entry->body.has_value());
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
result->cancel();
|
1258
|
+
|
1259
|
+
REQUIRE(expected_id_count == entry_ids.size());
|
1260
|
+
|
1261
|
+
for (const auto& entry_id : entry_ids) {
|
1262
|
+
REQUIRE(std::count(ids.begin(), ids.end(), entry_id) == 0);
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
auto next_item = result->next();
|
1266
|
+
REQUIRE(!next_item.has_value());
|
1267
|
+
REQUIRE(next_item.error() == couchbase::errc::key_value::range_scan_completed);
|
1268
|
+
REQUIRE(result->is_cancelled());
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
TEST_CASE("integration: manager prefix scan with concurrency 0 (invalid argument)", "[integration]")
|
1272
|
+
{
|
1273
|
+
test::utils::integration_test_guard integration;
|
1274
|
+
|
1275
|
+
if (!integration.has_bucket_capability("range_scan")) {
|
1276
|
+
SKIP("cluster does not support range_scan");
|
1277
|
+
}
|
1278
|
+
|
1279
|
+
auto collection = couchbase::cluster(integration.cluster)
|
1280
|
+
.bucket(integration.ctx.bucket)
|
1281
|
+
.scope(couchbase::scope::default_name)
|
1282
|
+
.collection(couchbase::collection::default_name);
|
1283
|
+
|
1284
|
+
auto ids = make_doc_ids(100, "prefixscaninvalidconcurrency-");
|
1285
|
+
auto value = make_binary_value(1);
|
1286
|
+
auto mutations = populate_documents_for_range_scan(collection, ids, value, std::chrono::seconds{ 30 });
|
1287
|
+
|
1288
|
+
auto vbucket_map = get_vbucket_map(integration);
|
1289
|
+
|
1290
|
+
auto ag = couchbase::core::agent_group(integration.io, { { integration.cluster } });
|
1291
|
+
ag.open_bucket(integration.ctx.bucket);
|
1292
|
+
auto agent = ag.get_agent(integration.ctx.bucket);
|
1293
|
+
REQUIRE(agent.has_value());
|
1294
|
+
|
1295
|
+
couchbase::core::prefix_scan scan{ "prefixscaninvalidconcurrency" };
|
1296
|
+
couchbase::core::range_scan_orchestrator_options options{};
|
1297
|
+
options.consistent_with = mutations_to_mutation_state(mutations);
|
1298
|
+
options.ids_only = true;
|
1299
|
+
options.concurrency = 0;
|
1300
|
+
couchbase::core::range_scan_orchestrator orchestrator(
|
1301
|
+
integration.io, agent.value(), vbucket_map, couchbase::scope::default_name, couchbase::collection::default_name, scan, options);
|
1302
|
+
|
1303
|
+
auto result = orchestrator.scan();
|
1304
|
+
REQUIRE(!result.has_value());
|
1305
|
+
REQUIRE(result.error() == couchbase::errc::common::invalid_argument);
|
1067
1306
|
}
|