Пример #1
0
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));
    }
}
Пример #2
0
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);
    CHECK_OPTIONAL_ARGUMENT(idx, default_language, "en");
    CHECK_OPTIONAL_ARGUMENT(idx, language_override, "lang");
    CHECK_OPTIONAL_ARGUMENT(idx, twod_sphere_version, 4);
    CHECK_OPTIONAL_ARGUMENT(idx, twod_bits_precision, 4);
    CHECK_OPTIONAL_ARGUMENT(idx, twod_location_min, 90.0);
    CHECK_OPTIONAL_ARGUMENT(idx, twod_location_max, 90.0);
    CHECK_OPTIONAL_ARGUMENT(idx, haystack_bucket_size, 90.0);
    CHECK_OPTIONAL_ARGUMENT(idx, weights, weights.view());
    CHECK_OPTIONAL_ARGUMENT(idx, partial_filter_expression, partial_filter_expression.view());
    REQUIRE_NOTHROW(idx.storage_options(std::move(storage)));
}
Пример #3
0
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;
    }
}