bsoncxx::document::value collection::create_index(view_or_value keys, const options::index& options) { scoped_bson_t bson_keys{keys}; bson_error_t error; ::mongoc_index_opt_geo_t geo_opt{}; ::mongoc_index_opt_t opt{}; ::mongoc_index_opt_wt_t wt_opt{}; libmongoc::index_opt_init(&opt); // keep our safe copies alive bsoncxx::string::view_or_value name_copy{}; bsoncxx::string::view_or_value wt_config_copy{}; bsoncxx::string::view_or_value default_language_copy{}; bsoncxx::string::view_or_value language_override_copy{}; if (options.background()) { opt.background = *options.background(); } if (options.unique()) { opt.unique = *options.unique(); } if (options.name()) { name_copy = options.name()->terminated(); opt.name = name_copy.data(); } if (options.sparse()) { opt.sparse = *options.sparse(); } if (options.storage_options()) { const options::index::wiredtiger_storage_options* wt_options; libmongoc::index_opt_wt_init(&wt_opt); if (options.storage_options()->type() == ::mongoc_index_storage_opt_type_t::MONGOC_INDEX_STORAGE_OPT_WIREDTIGER) { wt_options = static_cast<const options::index::wiredtiger_storage_options*>( options.storage_options().get()); if (wt_options->config_string()) { wt_config_copy = wt_options->config_string()->terminated(); wt_opt.config_str = wt_config_copy.data(); } opt.storage_options = reinterpret_cast<mongoc_index_opt_storage_t*>(&wt_opt); } } if (options.expire_after()) { const auto count = options.expire_after()->count(); if ((count < 0) || (count > std::numeric_limits<int32_t>::max())) { throw logic_error{error_code::k_invalid_parameter}; } opt.expire_after_seconds = static_cast<std::int32_t>(count); } if (options.version()) { opt.v = *options.version(); } if (options.weights()) { scoped_bson_t weights{*options.weights()}; opt.weights = weights.bson(); } if (options.default_language()) { default_language_copy = options.default_language()->terminated(); opt.default_language = default_language_copy.data(); } if (options.language_override()) { language_override_copy = options.language_override()->terminated(); opt.language_override = language_override_copy.data(); } if (options.collation()) { scoped_bson_t collation{*options.collation()}; opt.collation = collation.bson(); } if (options.partial_filter_expression()) { scoped_bson_t partial_filter_expression{*options.partial_filter_expression()}; opt.partial_filter_expression = partial_filter_expression.bson(); } if (options.twod_sphere_version() || options.twod_bits_precision() || options.twod_location_min() || options.twod_location_max() || options.haystack_bucket_size()) { libmongoc::index_opt_geo_init(&geo_opt); if (options.twod_sphere_version()) { geo_opt.twod_sphere_version = *options.twod_sphere_version(); } if (options.twod_bits_precision()) { geo_opt.twod_bits_precision = *options.twod_bits_precision(); } if (options.twod_location_min()) { geo_opt.twod_location_min = *options.twod_location_min(); } if (options.twod_location_max()) { geo_opt.twod_location_max = *options.twod_location_max(); } if (options.haystack_bucket_size()) { geo_opt.haystack_bucket_size = *options.haystack_bucket_size(); } opt.geo_options = &geo_opt; } auto result = libmongoc::collection_create_index( _get_impl().collection_t, bson_keys.bson(), &opt, &error); if (!result) { throw_exception<operation_exception>(error); } if (options.name()) { return make_document(kvp("name", *options.name())); } else { const auto keys = libmongoc::collection_keys_to_index_string(bson_keys.bson()); const auto clean_keys = make_guard([&] { bson_free(keys); }); return make_document(kvp("name", keys)); } }
#include "helpers.hpp" #include <bsoncxx/builder/stream/document.hpp> #include <bsoncxx/stdx/make_unique.hpp> #include <bsoncxx/test_util/catch.hh> #include <mongocxx/instance.hpp> #include <mongocxx/options/index.hpp> #include <mongocxx/stdx.hpp> using namespace bsoncxx::builder::stream; using namespace mongocxx; TEST_CASE("index", "[index][option]") { instance::current(); options::index idx; std::unique_ptr<options::index::wiredtiger_storage_options> storage = stdx::make_unique<options::index::wiredtiger_storage_options>(); auto collation = document{} << "locale" << "en_US" << finalize; auto partial_filter_expression = document{} << "x" << true << finalize; auto weights = document{} << "a" << 100 << finalize; CHECK_OPTIONAL_ARGUMENT(idx, background, true); CHECK_OPTIONAL_ARGUMENT(idx, unique, true); CHECK_OPTIONAL_ARGUMENT(idx, name, "name"); CHECK_OPTIONAL_ARGUMENT(idx, collation, collation.view()); CHECK_OPTIONAL_ARGUMENT(idx, sparse, true); CHECK_OPTIONAL_ARGUMENT(idx, expire_after, std::chrono::seconds(3600)); CHECK_OPTIONAL_ARGUMENT(idx, version, 540);
bsoncxx::document::value collection::create_index(view_or_value keys, const options::index& options) { scoped_bson_t bson_keys{keys}; bson_error_t error; ::mongoc_index_opt_geo_t geo_opt{}; ::mongoc_index_opt_t opt{}; ::mongoc_index_opt_wt_t wt_opt{}; libmongoc::index_opt_init(&opt); // keep our safe copies alive bsoncxx::string::view_or_value name_copy{}; bsoncxx::string::view_or_value wt_config_copy{}; bsoncxx::string::view_or_value default_language_copy{}; bsoncxx::string::view_or_value language_override_copy{}; if (options.background()) { opt.background = *options.background(); } if (options.unique()) { opt.unique = *options.unique(); } if (options.name()) { name_copy = options.name()->terminated(); opt.name = name_copy.data(); } if (options.sparse()) { opt.sparse = *options.sparse(); } if (options.storage_options()) { const options::index::wiredtiger_storage_options* wt_options; libmongoc::index_opt_wt_init(&wt_opt); if (options.storage_options()->type() == ::mongoc_index_storage_opt_type_t::MONGOC_INDEX_STORAGE_OPT_WIREDTIGER) { wt_options = static_cast<const options::index::wiredtiger_storage_options*>( options.storage_options().get()); if (wt_options->config_string()) { wt_config_copy = wt_options->config_string()->terminated(); wt_opt.config_str = wt_config_copy.data(); } opt.storage_options = reinterpret_cast<mongoc_index_opt_storage_t*>(&wt_opt); } } if (options.expire_after_seconds()) { opt.expire_after_seconds = *options.expire_after_seconds(); } if (options.version()) { opt.v = *options.version(); } if (options.weights()) { scoped_bson_t weights{*options.weights()}; opt.weights = weights.bson(); } if (options.default_language()) { default_language_copy = options.default_language()->terminated(); opt.default_language = default_language_copy.data(); } if (options.language_override()) { language_override_copy = options.language_override()->terminated(); opt.language_override = language_override_copy.data(); } if (options.partial_filter_expression()) { scoped_bson_t partial_filter_expression{*options.partial_filter_expression()}; opt.partial_filter_expression = partial_filter_expression.bson(); } if (options.twod_sphere_version() || options.twod_bits_precision() || options.twod_location_min() || options.twod_location_max() || options.haystack_bucket_size()) { libmongoc::index_opt_geo_init(&geo_opt); if (options.twod_sphere_version()) { geo_opt.twod_sphere_version = *options.twod_sphere_version(); } if (options.twod_bits_precision()) { geo_opt.twod_bits_precision = *options.twod_bits_precision(); } if (options.twod_location_min()) { geo_opt.twod_location_min = *options.twod_location_min(); } if (options.twod_location_max()) { geo_opt.twod_location_max = *options.twod_location_max(); } if (options.haystack_bucket_size()) { geo_opt.haystack_bucket_size = *options.haystack_bucket_size(); } opt.geo_options = &geo_opt; } auto result = libmongoc::collection_create_index(_get_impl().collection_t, bson_keys.bson(), &opt, &error); if (!result) { throw_exception<operation_exception>(error); } if (options.name()) { return bsoncxx::builder::stream::document{} << "name" << *options.name() << bsoncxx::builder::stream::finalize; } else { return bsoncxx::builder::stream::document{} << "name" << std::string{libmongoc::collection_keys_to_index_string(bson_keys.bson())} << bsoncxx::builder::stream::finalize; } }