Skip to content

Conversation

@eramongodb
Copy link
Contributor

@eramongodb eramongodb commented Dec 12, 2025

Resolves CXX-3237 and CXX-3238 for the v1::uri component.

To continue to support implicit conversion from e.g. char const* -> string::view_or_value without ambiguity with the v1 ctor (because v1::uri also has a non-explicit string_view ctor), a constrained non-explicit constructor template is added to have higher priority for convertible-to-string::view_or_value arguments than the non-explicit v1 ctor.

This PR also adds /Zc:strictStrings (part of /permissive-, which we do not yet enable) to avoid non-conforming behavior with MSVC which interacts poorly with our void* ctor (even when private or explicit). This flag is applied to mongocxx library (and test) builds only and is not inherited by users. We can consider adding a char const* ctor instead, but I'd prefer depending on and encouraging standard conformance instead.

Additional notes:

  • Fix missing const qualifiers for getters overlooked by CXX-3236 add mongocxx v1 declarations #1482.
  • Try to use new mongoc URI API when able.
  • Try to use v1 bsoncxx API instead of bson when able; however, cannot use bsoncxx for URI field lookup due to backward compatibility with case (in)sensitivity lookups. Not all options may support canonicalization into lowercase form.
  • v_noabi::uri remains non-copyable for backward compatibility despite v1::uri being copyable.

@eramongodb eramongodb requested a review from kevinAlbs December 12, 2025 17:03
@eramongodb eramongodb self-assigned this Dec 12, 2025
@eramongodb eramongodb requested a review from a team as a code owner December 12, 2025 17:03
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor comments.

uri const opts;
auto const identity = uri::internal::as_mongoc(opts);

char const str = '\0';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: also test C function returning NULL causes C++ member function to return unset optional:

template <typename MemFn, typename Mock>
void test_string_opt(MemFn mem_fn, Mock& mock) {
    uri const opts;
    auto const identity = uri::internal::as_mongoc(opts);

    auto const v = GENERATE(bsoncxx::v1::stdx::optional<char const>{}, bsoncxx::v1::stdx::optional<char const>{'\0'});

    auto fn = mock.create_instance();
    fn->interpose([&](mongoc_uri_t const* ptr) -> char const* {
        CHECK(ptr == identity);
        if (v.has_value()) {
            return &(*v);
        }
        return nullptr;
    });

    auto const opt = (opts.*mem_fn)();
    if (v.has_value()) {
        REQUIRE(opt.has_value());
        CHECK(opt->data() == static_cast<void const*>(&(*v)));
    } else {
        CHECK(!opt.has_value());
    }
}

}

template <typename MemFn, typename Mock>
void test_doc_opt(MemFn mem_fn, Mock& mock) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: also test C function returning NULL causes C++ member function to return unset optional:

template <typename MemFn, typename Mock>
void test_doc_opt(MemFn mem_fn, Mock& mock) {
    uri const opts;
    auto const identity = uri::internal::as_mongoc(opts);

    auto const v =
        GENERATE(bsoncxx::v1::stdx::optional<scoped_bson>{}, bsoncxx::v1::stdx::optional<scoped_bson>{R"({"x": 1})"});

    auto fn = mock.create_instance();
    fn->interpose([&](mongoc_uri_t const* ptr) -> bson_t const* {
        CHECK(ptr == identity);
        if (v.has_value()) {
            return v->bson();
        }
        return nullptr;
    });

    auto const opt = (opts.*mem_fn)();
    if (v.has_value()) {
        REQUIRE(opt.has_value());
        CHECK(opt->data() == v->view().data());
    } else {
        CHECK(!opt.has_value());
    }
}

}
}

TEST_CASE("exceptions", "[bsoncxx][v1][uri]") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TEST_CASE("exceptions", "[bsoncxx][v1][uri]") {
TEST_CASE("exceptions", "[mongocxx][v1][uri]") {

CHECK_FALSE(opts.retry_reads().has_value());
CHECK_FALSE(opts.retry_writes().has_value());
CHECK_FALSE(opts.server_selection_timeout_ms().has_value());
CHECK_FALSE(opts.server_selection_try_once().has_value());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove duplicate check.

Suggested change
CHECK_FALSE(opts.server_selection_try_once().has_value());

Comment on lines +118 to +121
/// @par Postconditions:
/// - `other` is in an assign-or-destroy-only state.
///
/// @warning Invalidates all associated iterators and views.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove non-applicable docs.

Suggested change
/// @par Postconditions:
/// - `other` is in an assign-or-destroy-only state.
///
/// @warning Invalidates all associated iterators and views.

Comment on lines +95 to +99
template <typename T>
bsoncxx::v1::stdx::optional<T> get_credentials_field(mongoc_uri_t const* uri, char const* field);

template <>
bsoncxx::v1::stdx::optional<bsoncxx::v1::document::view> get_credentials_field(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unnecessary template? I expect it is not needed since there is only one specialization.

Suggested change
template <typename T>
bsoncxx::v1::stdx::optional<T> get_credentials_field(mongoc_uri_t const* uri, char const* field);
template <>
bsoncxx::v1::stdx::optional<bsoncxx::v1::document::view> get_credentials_field(
bsoncxx::v1::stdx::optional<bsoncxx::v1::document::view> get_credentials_field(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants