From b10218a6248aa8ead9880455db29161fb76327b1 Mon Sep 17 00:00:00 2001 From: Ezra Chung Date: Wed, 3 Dec 2025 14:09:44 -0600 Subject: [PATCH 1/3] v1: delete_many_options and delete_one_options (CXX-3237, CXX-3238) --- .../mongocxx/v1/delete_many_options.hpp | 2 + .../mongocxx/v1/delete_one_options.hpp | 4 +- .../v_noabi/mongocxx/options/delete-fwd.hpp | 9 +- .../v_noabi/mongocxx/options/delete.hpp | 179 ++++++++++++++++-- .../lib/mongocxx/v1/delete_many_options.cpp | 144 +++++++++++++- .../lib/mongocxx/v1/delete_many_options.hh | 42 ++++ .../lib/mongocxx/v1/delete_one_options.cpp | 141 +++++++++++++- .../lib/mongocxx/v1/delete_one_options.hh | 42 ++++ .../v_noabi/mongocxx/options/delete.cpp | 85 ++++----- src/mongocxx/test/CMakeLists.txt | 2 + src/mongocxx/test/v1/delete_many_options.cpp | 139 ++++++++++++++ src/mongocxx/test/v1/delete_one_options.cpp | 139 ++++++++++++++ 12 files changed, 861 insertions(+), 67 deletions(-) create mode 100644 src/mongocxx/lib/mongocxx/v1/delete_many_options.hh create mode 100644 src/mongocxx/lib/mongocxx/v1/delete_one_options.hh create mode 100644 src/mongocxx/test/v1/delete_many_options.cpp create mode 100644 src/mongocxx/test/v1/delete_one_options.cpp diff --git a/src/mongocxx/include/mongocxx/v1/delete_many_options.hpp b/src/mongocxx/include/mongocxx/v1/delete_many_options.hpp index b4ef9a0f4b..e5e0208eaa 100644 --- a/src/mongocxx/include/mongocxx/v1/delete_many_options.hpp +++ b/src/mongocxx/include/mongocxx/v1/delete_many_options.hpp @@ -146,6 +146,8 @@ class delete_many_options { /// Return the current "comment" field. /// MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v1::stdx::optional const) comment() const; + + class internal; }; } // namespace v1 diff --git a/src/mongocxx/include/mongocxx/v1/delete_one_options.hpp b/src/mongocxx/include/mongocxx/v1/delete_one_options.hpp index 88dbac7cee..e668ce24d0 100644 --- a/src/mongocxx/include/mongocxx/v1/delete_one_options.hpp +++ b/src/mongocxx/include/mongocxx/v1/delete_one_options.hpp @@ -110,7 +110,7 @@ class delete_one_options { /// /// Set the "writeConcern" field. /// - MONGOCXX_ABI_EXPORT_CDECL(delete_one_options&) write_concern(write_concern wc); + MONGOCXX_ABI_EXPORT_CDECL(delete_one_options&) write_concern(v1::write_concern wc); /// /// Return the current "writeConcern" field. @@ -146,6 +146,8 @@ class delete_one_options { /// Return the current "comment" field. /// MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v1::stdx::optional const) comment() const; + + class internal; }; } // namespace v1 diff --git a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete-fwd.hpp b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete-fwd.hpp index a443afd4e6..db97551d09 100644 --- a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete-fwd.hpp +++ b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete-fwd.hpp @@ -14,6 +14,9 @@ #pragma once +#include // IWYU pragma: export +#include // IWYU pragma: export + #include namespace mongocxx { @@ -29,7 +32,7 @@ class delete_options; namespace mongocxx { namespace options { -using ::mongocxx::v_noabi::options::delete_options; +using v_noabi::options::delete_options; } // namespace options } // namespace mongocxx @@ -40,3 +43,7 @@ using ::mongocxx::v_noabi::options::delete_options; /// @file /// Declares @ref mongocxx::v_noabi::options::delete_options. /// +/// @par Includes +/// - @ref mongocxx/v1/delete_many_options-fwd.hpp +/// - @ref mongocxx/v1/delete_one_options-fwd.hpp +/// diff --git a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp index aeafa2c9d8..2949facfb8 100644 --- a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp +++ b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp @@ -16,8 +16,20 @@ #include // IWYU pragma: export +// + +#include +#include + +#include // IWYU pragma: export +#include // IWYU pragma: export + +#include + +#include #include #include +#include #include #include @@ -34,6 +46,85 @@ namespace options { /// class delete_options { public: + /// + /// Default initialization. + /// + delete_options() = default; + + /// + /// Construct with the @ref mongocxx::v1 equivalent. + /// + /* explicit(false) */ MONGOCXX_ABI_EXPORT_CDECL() delete_options(v1::delete_many_options opts); + + /// + /// Construct with the @ref mongocxx::v1 equivalent. + /// + /* explicit(false) */ MONGOCXX_ABI_EXPORT_CDECL() delete_options(v1::delete_one_options opts); + + /// + /// Convert to the @ref mongocxx::v1 equivalent. + /// + explicit operator v1::delete_many_options() const { + using bsoncxx::v_noabi::to_v1; + using mongocxx::v_noabi::to_v1; + + v1::delete_many_options ret; + + if (_collation) { + ret.collation(bsoncxx::v1::document::value{to_v1(_collation->view())}); + } + + if (_write_concern) { + ret.write_concern(to_v1(*_write_concern)); + } + + if (_hint) { + ret.hint(to_v1(*_hint)); + } + + if (_let) { + ret.let(bsoncxx::v1::document::value{to_v1(_let->view())}); + } + + if (_comment) { + ret.comment(bsoncxx::v1::types::value{to_v1(_comment->view())}); + } + + return ret; + } + + /// + /// Convert to the @ref mongocxx::v1 equivalent. + /// + explicit operator v1::delete_one_options() const { + using bsoncxx::v_noabi::to_v1; + using mongocxx::v_noabi::to_v1; + + v1::delete_one_options ret; + + if (_collation) { + ret.collation(bsoncxx::v1::document::value{to_v1(_collation->view())}); + } + + if (_write_concern) { + ret.write_concern(to_v1(*_write_concern)); + } + + if (_hint) { + ret.hint(to_v1(*_hint)); + } + + if (_let) { + ret.let(bsoncxx::v1::document::value{to_v1(_let->view())}); + } + + if (_comment) { + ret.comment(bsoncxx::v1::types::value{to_v1(_comment->view())}); + } + + return ret; + } + /// /// Sets the collation for this operation. /// @@ -47,8 +138,10 @@ class delete_options { /// @see /// - https://www.mongodb.com/docs/manual/reference/collation/ /// - MONGOCXX_ABI_EXPORT_CDECL(delete_options&) - collation(bsoncxx::v_noabi::document::view_or_value collation); + delete_options& collation(bsoncxx::v_noabi::document::view_or_value collation) { + _collation = std::move(collation); + return *this; + } /// /// Retrieves the current collation for this operation. @@ -59,8 +152,9 @@ class delete_options { /// @see /// - https://www.mongodb.com/docs/manual/reference/collation/ /// - MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional const&) - collation() const; + bsoncxx::v_noabi::stdx::optional const& collation() const { + return _collation; + } /// /// Sets the write_concern for this operation. @@ -75,7 +169,10 @@ class delete_options { /// @see /// - https://www.mongodb.com/docs/manual/core/write-concern/ /// - MONGOCXX_ABI_EXPORT_CDECL(delete_options&) write_concern(write_concern wc); + delete_options& write_concern(write_concern wc) { + _write_concern = std::move(wc); + return *this; + } /// /// The current write_concern for this operation. @@ -86,8 +183,9 @@ class delete_options { /// @see /// - https://www.mongodb.com/docs/manual/core/write-concern/ /// - MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional const&) - write_concern() const; + bsoncxx::v_noabi::stdx::optional const& write_concern() const { + return _write_concern; + } /// /// Sets the index to use for this operation. @@ -102,15 +200,19 @@ class delete_options { /// A reference to the object on which this member function is being called. This facilitates /// method chaining. /// - MONGOCXX_ABI_EXPORT_CDECL(delete_options&) hint(mongocxx::v_noabi::hint index_hint); + delete_options& hint(v_noabi::hint index_hint) { + _hint = std::move(index_hint); + return *this; + } /// /// Gets the current hint. /// /// @return The current hint, if one is set. /// - MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional const&) - hint() const; + bsoncxx::v_noabi::stdx::optional const& hint() const { + return _hint; + } /// /// Set the value of the let option. @@ -122,7 +224,10 @@ class delete_options { /// A reference to the object on which this member function is being called. This facilitates /// method chaining. /// - MONGOCXX_ABI_EXPORT_CDECL(delete_options&) let(bsoncxx::v_noabi::document::view_or_value let); + delete_options& let(bsoncxx::v_noabi::document::view_or_value let) { + _let = std::move(let); + return *this; + } /// /// Gets the current value of the let option. @@ -130,8 +235,9 @@ class delete_options { /// @return /// The current let option. /// - MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional const) - let() const; + bsoncxx::v_noabi::stdx::optional const let() const { + return _let; + } /// /// Set the value of the comment option. @@ -143,8 +249,10 @@ class delete_options { /// A reference to the object on which this member function is being called. This facilitates /// method chaining. /// - MONGOCXX_ABI_EXPORT_CDECL(delete_options&) - comment(bsoncxx::v_noabi::types::bson_value::view_or_value comment); + delete_options& comment(bsoncxx::v_noabi::types::bson_value::view_or_value comment) { + _comment = std::move(comment); + return *this; + } /// /// Gets the current value of the comment option. @@ -152,13 +260,14 @@ class delete_options { /// @return /// The current comment option. /// - MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional const) - comment() const; + bsoncxx::v_noabi::stdx::optional const comment() const { + return _comment; + } private: bsoncxx::v_noabi::stdx::optional _collation; - bsoncxx::v_noabi::stdx::optional _write_concern; - bsoncxx::v_noabi::stdx::optional _hint; + bsoncxx::v_noabi::stdx::optional _write_concern; + bsoncxx::v_noabi::stdx::optional _hint; bsoncxx::v_noabi::stdx::optional _let; bsoncxx::v_noabi::stdx::optional _comment; }; @@ -167,9 +276,41 @@ class delete_options { } // namespace v_noabi } // namespace mongocxx +namespace mongocxx { +namespace v_noabi { + +/// +/// Convert to the @ref mongocxx::v_noabi equivalent of `v`. +/// +inline v_noabi::options::delete_options from_v1(v1::delete_many_options v) { + return {std::move(v)}; +} + +/// +/// Convert to the @ref mongocxx::v_noabi equivalent of `v`. +/// +/// @note The `ordered` field is initialized as unset. +/// +inline v_noabi::options::delete_options from_v1(v1::delete_one_options v) { + return {std::move(v)}; +} + +// Ambiguous whether `v_noabi::options::delete` should be converted to `v1::delete_many_options` or +// `v1::delete_one_options`. Require users to explicitly cast to the expected type instead. +// +// v1::delete_many_options to_v1(v_noabi::options::delete const& v); +// v1::delete_one_options to_v1(v_noabi::options::delete const& v); + +} // namespace v_noabi +} // namespace mongocxx + #include /// /// @file /// Provides @ref mongocxx::v_noabi::options::delete_options. /// +/// @par Includes +/// - @ref mongocxx/v1/delete_many_options.hpp +/// - @ref mongocxx/v1/delete_one_options.hpp +/// diff --git a/src/mongocxx/lib/mongocxx/v1/delete_many_options.cpp b/src/mongocxx/lib/mongocxx/v1/delete_many_options.cpp index 33f29efb25..f95b5635ac 100644 --- a/src/mongocxx/lib/mongocxx/v1/delete_many_options.cpp +++ b/src/mongocxx/lib/mongocxx/v1/delete_many_options.cpp @@ -12,4 +12,146 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include + +// + +#include +#include +#include + +#include +#include + +#include + +namespace mongocxx { +namespace v1 { + +class delete_many_options::impl { + public: + bsoncxx::v1::stdx::optional _collation; + bsoncxx::v1::stdx::optional _write_concern; + bsoncxx::v1::stdx::optional _hint; + bsoncxx::v1::stdx::optional _let; + bsoncxx::v1::stdx::optional _comment; + + static impl const& with(delete_many_options const& self) { + return *static_cast(self._impl); + } + + static impl const* with(delete_many_options const* self) { + return static_cast(self->_impl); + } + + static impl& with(delete_many_options& self) { + return *static_cast(self._impl); + } + + static impl* with(delete_many_options* self) { + return static_cast(self->_impl); + } + + static impl* with(void* ptr) { + return static_cast(ptr); + } +}; + +delete_many_options::~delete_many_options() { + delete impl::with(this); +} + +delete_many_options::delete_many_options(delete_many_options&& other) noexcept + : _impl{exchange(other._impl, nullptr)} {} + +delete_many_options& delete_many_options::operator=(delete_many_options&& other) noexcept { + if (this != &other) { + delete impl::with(exchange(_impl, exchange(other._impl, nullptr))); + } + + return *this; +} + +delete_many_options::delete_many_options(delete_many_options const& other) : _impl{new impl{impl::with(other)}} {} + +delete_many_options& delete_many_options::operator=(delete_many_options const& other) { + if (this != &other) { + delete impl::with(exchange(_impl, new impl{impl::with(other)})); + } + + return *this; +} + +delete_many_options::delete_many_options() : _impl{new impl{}} {} + +delete_many_options& delete_many_options::collation(bsoncxx::v1::document::value collation) { + impl::with(this)->_collation = std::move(collation); + return *this; +} + +bsoncxx::v1::stdx::optional delete_many_options::collation() const { + return impl::with(this)->_collation; +} + +delete_many_options& delete_many_options::write_concern(v1::write_concern wc) { + impl::with(this)->_write_concern = std::move(wc); + return *this; +} + +bsoncxx::v1::stdx::optional delete_many_options::write_concern() const { + return impl::with(this)->_write_concern; +} + +delete_many_options& delete_many_options::hint(v1::hint index_hint) { + impl::with(this)->_hint = std::move(index_hint); + return *this; +} + +bsoncxx::v1::stdx::optional delete_many_options::hint() const { + return impl::with(this)->_hint; +} + +delete_many_options& delete_many_options::let(bsoncxx::v1::document::value let) { + impl::with(this)->_let = std::move(let); + return *this; +} + +bsoncxx::v1::stdx::optional const delete_many_options::let() const { + return impl::with(this)->_let; +} + +delete_many_options& delete_many_options::comment(bsoncxx::v1::types::value comment) { + impl::with(this)->_comment = std::move(comment); + return *this; +} + +bsoncxx::v1::stdx::optional const delete_many_options::comment() const { + return impl::with(this)->_comment; +} + +bsoncxx::v1::stdx::optional& delete_many_options::internal::collation( + delete_many_options& self) { + return impl::with(self)._collation; +} + +bsoncxx::v1::stdx::optional& delete_many_options::internal::write_concern( + delete_many_options& self) { + return impl::with(self)._write_concern; +} + +bsoncxx::v1::stdx::optional& delete_many_options::internal::hint(delete_many_options& self) { + return impl::with(self)._hint; +} + +bsoncxx::v1::stdx::optional& delete_many_options::internal::let( + delete_many_options& self) { + return impl::with(self)._let; +} + +bsoncxx::v1::stdx::optional& delete_many_options::internal::comment( + delete_many_options& self) { + return impl::with(self)._comment; +} + +} // namespace v1 +} // namespace mongocxx diff --git a/src/mongocxx/lib/mongocxx/v1/delete_many_options.hh b/src/mongocxx/lib/mongocxx/v1/delete_many_options.hh new file mode 100644 index 0000000000..ed2abb4371 --- /dev/null +++ b/src/mongocxx/lib/mongocxx/v1/delete_many_options.hh @@ -0,0 +1,42 @@ +// Copyright 2009-present MongoDB, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include // IWYU pragma: export + +// + +#include +#include + +#include +#include + +#include + +namespace mongocxx { +namespace v1 { + +class delete_many_options::internal { + public: + static bsoncxx::v1::stdx::optional& collation(delete_many_options& self); + static bsoncxx::v1::stdx::optional& write_concern(delete_many_options& self); + static bsoncxx::v1::stdx::optional& hint(delete_many_options& self); + static bsoncxx::v1::stdx::optional& let(delete_many_options& self); + static bsoncxx::v1::stdx::optional& comment(delete_many_options& self); +}; + +} // namespace v1 +} // namespace mongocxx diff --git a/src/mongocxx/lib/mongocxx/v1/delete_one_options.cpp b/src/mongocxx/lib/mongocxx/v1/delete_one_options.cpp index a2ed7fd572..8fce6ff003 100644 --- a/src/mongocxx/lib/mongocxx/v1/delete_one_options.cpp +++ b/src/mongocxx/lib/mongocxx/v1/delete_one_options.cpp @@ -12,4 +12,143 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include + +// + +#include +#include +#include + +#include +#include + +#include + +namespace mongocxx { +namespace v1 { + +class delete_one_options::impl { + public: + bsoncxx::v1::stdx::optional _collation; + bsoncxx::v1::stdx::optional _write_concern; + bsoncxx::v1::stdx::optional _hint; + bsoncxx::v1::stdx::optional _let; + bsoncxx::v1::stdx::optional _comment; + + static impl const& with(delete_one_options const& self) { + return *static_cast(self._impl); + } + + static impl const* with(delete_one_options const* self) { + return static_cast(self->_impl); + } + + static impl& with(delete_one_options& self) { + return *static_cast(self._impl); + } + + static impl* with(delete_one_options* self) { + return static_cast(self->_impl); + } + + static impl* with(void* ptr) { + return static_cast(ptr); + } +}; + +delete_one_options::~delete_one_options() { + delete impl::with(this); +} + +delete_one_options::delete_one_options(delete_one_options&& other) noexcept : _impl{exchange(other._impl, nullptr)} {} + +delete_one_options& delete_one_options::operator=(delete_one_options&& other) noexcept { + if (this != &other) { + delete impl::with(exchange(_impl, exchange(other._impl, nullptr))); + } + + return *this; +} + +delete_one_options::delete_one_options(delete_one_options const& other) : _impl{new impl{impl::with(other)}} {} + +delete_one_options& delete_one_options::operator=(delete_one_options const& other) { + if (this != &other) { + delete impl::with(exchange(_impl, new impl{impl::with(other)})); + } + + return *this; +} + +delete_one_options::delete_one_options() : _impl{new impl{}} {} + +delete_one_options& delete_one_options::collation(bsoncxx::v1::document::value collation) { + impl::with(this)->_collation = std::move(collation); + return *this; +} + +bsoncxx::v1::stdx::optional delete_one_options::collation() const { + return impl::with(this)->_collation; +} + +delete_one_options& delete_one_options::write_concern(v1::write_concern wc) { + impl::with(this)->_write_concern = std::move(wc); + return *this; +} + +bsoncxx::v1::stdx::optional delete_one_options::write_concern() const { + return impl::with(this)->_write_concern; +} + +delete_one_options& delete_one_options::hint(v1::hint index_hint) { + impl::with(this)->_hint = std::move(index_hint); + return *this; +} + +bsoncxx::v1::stdx::optional delete_one_options::hint() const { + return impl::with(this)->_hint; +} + +delete_one_options& delete_one_options::let(bsoncxx::v1::document::value let) { + impl::with(this)->_let = std::move(let); + return *this; +} + +bsoncxx::v1::stdx::optional const delete_one_options::let() const { + return impl::with(this)->_let; +} + +delete_one_options& delete_one_options::comment(bsoncxx::v1::types::value comment) { + impl::with(this)->_comment = std::move(comment); + return *this; +} + +bsoncxx::v1::stdx::optional const delete_one_options::comment() const { + return impl::with(this)->_comment; +} + +bsoncxx::v1::stdx::optional& delete_one_options::internal::collation( + delete_one_options& self) { + return impl::with(self)._collation; +} + +bsoncxx::v1::stdx::optional& delete_one_options::internal::write_concern(delete_one_options& self) { + return impl::with(self)._write_concern; +} + +bsoncxx::v1::stdx::optional& delete_one_options::internal::hint(delete_one_options& self) { + return impl::with(self)._hint; +} + +bsoncxx::v1::stdx::optional& delete_one_options::internal::let(delete_one_options& self) { + return impl::with(self)._let; +} + +bsoncxx::v1::stdx::optional& delete_one_options::internal::comment( + delete_one_options& self) { + return impl::with(self)._comment; +} + +} // namespace v1 +} // namespace mongocxx diff --git a/src/mongocxx/lib/mongocxx/v1/delete_one_options.hh b/src/mongocxx/lib/mongocxx/v1/delete_one_options.hh new file mode 100644 index 0000000000..6e96eeb9c9 --- /dev/null +++ b/src/mongocxx/lib/mongocxx/v1/delete_one_options.hh @@ -0,0 +1,42 @@ +// Copyright 2009-present MongoDB, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include // IWYU pragma: export + +// + +#include +#include + +#include +#include + +#include + +namespace mongocxx { +namespace v1 { + +class delete_one_options::internal { + public: + static bsoncxx::v1::stdx::optional& collation(delete_one_options& self); + static bsoncxx::v1::stdx::optional& write_concern(delete_one_options& self); + static bsoncxx::v1::stdx::optional& hint(delete_one_options& self); + static bsoncxx::v1::stdx::optional& let(delete_one_options& self); + static bsoncxx::v1::stdx::optional& comment(delete_one_options& self); +}; + +} // namespace v1 +} // namespace mongocxx diff --git a/src/mongocxx/lib/mongocxx/v_noabi/mongocxx/options/delete.cpp b/src/mongocxx/lib/mongocxx/v_noabi/mongocxx/options/delete.cpp index 4f91f62af6..d4e1ff5b61 100644 --- a/src/mongocxx/lib/mongocxx/v_noabi/mongocxx/options/delete.cpp +++ b/src/mongocxx/lib/mongocxx/v_noabi/mongocxx/options/delete.cpp @@ -12,58 +12,55 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include -namespace mongocxx { -namespace v_noabi { -namespace options { - -delete_options& delete_options::collation(bsoncxx::v_noabi::document::view_or_value collation) { - _collation = std::move(collation); - return *this; -} - -delete_options& delete_options::write_concern(mongocxx::v_noabi::write_concern wc) { - _write_concern = std::move(wc); - return *this; -} - -delete_options& delete_options::hint(mongocxx::v_noabi::hint index_hint) { - _hint = std::move(index_hint); - return *this; -} - -bsoncxx::v_noabi::stdx::optional const& delete_options::collation() const { - return _collation; -} +// -bsoncxx::v_noabi::stdx::optional const& delete_options::write_concern() const { - return _write_concern; -} +#include +#include -bsoncxx::v_noabi::stdx::optional const& delete_options::hint() const { - return _hint; -} +#include -delete_options& delete_options::let(bsoncxx::v_noabi::document::view_or_value let) { - _let = let; - return *this; -} +#include +#include -bsoncxx::v_noabi::stdx::optional const delete_options::let() const { - return _let; -} +namespace mongocxx { +namespace v_noabi { +namespace options { -delete_options& delete_options::comment(bsoncxx::v_noabi::types::bson_value::view_or_value comment) { - _comment = std::move(comment); - return *this; -} +delete_options::delete_options(v1::delete_many_options opts) + : _collation{[&]() -> decltype(_collation) { + if (auto& opt = v1::delete_many_options::internal::collation(opts)) { + return bsoncxx::v_noabi::from_v1(std::move(*opt)); + } + return {}; + }()}, + _write_concern{std::move(v1::delete_many_options::internal::write_concern(opts))}, + _hint{std::move(v1::delete_many_options::internal::hint(opts))}, + _let{[&]() -> decltype(_let) { + if (auto& opt = v1::delete_many_options::internal::let(opts)) { + return bsoncxx::v_noabi::from_v1(std::move(*opt)); + } + return {}; + }()}, + _comment{std::move(v1::delete_many_options::internal::comment(opts))} {} -bsoncxx::v_noabi::stdx::optional const delete_options::comment() - const { - return _comment; -} +delete_options::delete_options(v1::delete_one_options opts) + : _collation{[&]() -> decltype(_collation) { + if (auto& opt = v1::delete_one_options::internal::collation(opts)) { + return bsoncxx::v_noabi::from_v1(std::move(*opt)); + } + return {}; + }()}, + _write_concern{std::move(v1::delete_one_options::internal::write_concern(opts))}, + _hint{std::move(v1::delete_one_options::internal::hint(opts))}, + _let{[&]() -> decltype(_let) { + if (auto& opt = v1::delete_one_options::internal::let(opts)) { + return bsoncxx::v_noabi::from_v1(std::move(*opt)); + } + return {}; + }()}, + _comment{std::move(v1::delete_one_options::internal::comment(opts))} {} } // namespace options } // namespace v_noabi diff --git a/src/mongocxx/test/CMakeLists.txt b/src/mongocxx/test/CMakeLists.txt index 6d0940c5d6..2fc62e6d10 100644 --- a/src/mongocxx/test/CMakeLists.txt +++ b/src/mongocxx/test/CMakeLists.txt @@ -104,6 +104,8 @@ set(mongocxx_test_sources_v1 v1/bsoncxx.cpp v1/count_options.cpp v1/data_key_options.cpp + v1/delete_many_options.cpp + v1/delete_one_options.cpp v1/distinct_options.cpp v1/estimated_document_count_options.cpp v1/events.cpp diff --git a/src/mongocxx/test/v1/delete_many_options.cpp b/src/mongocxx/test/v1/delete_many_options.cpp new file mode 100644 index 0000000000..0dafa998ce --- /dev/null +++ b/src/mongocxx/test/v1/delete_many_options.cpp @@ -0,0 +1,139 @@ +// Copyright 2009-present MongoDB, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +// + +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +namespace mongocxx { +namespace v1 { + +TEST_CASE("ownership", "[mongocxx][v1][delete_many_options]") { + delete_many_options source; + delete_many_options target; + + source.comment(bsoncxx::v1::types::value{"source"}); + target.comment(bsoncxx::v1::types::value{"target"}); + + REQUIRE(source.comment() == bsoncxx::v1::types::b_string{"source"}); + REQUIRE(target.comment() == bsoncxx::v1::types::b_string{"target"}); + + auto const source_value = source.comment(); + + SECTION("move") { + auto move = std::move(source); + + // source is in an assign-or-move-only state. + + CHECK(move.comment() == source_value); + + target = std::move(move); + + // source is in an assign-or-move-only state. + + CHECK(target.comment() == source_value); + } + + SECTION("copy") { + auto copy = source; + + CHECK(source.comment() == source_value); + CHECK(copy.comment() == source_value); + + target = copy; + + CHECK(copy.comment() == source_value); + CHECK(target.comment() == source_value); + } +} + +TEST_CASE("default", "[mongocxx][v1][delete_many_options]") { + delete_many_options const opts; + + CHECK_FALSE(opts.collation().has_value()); + CHECK_FALSE(opts.write_concern().has_value()); + CHECK_FALSE(opts.hint().has_value()); + CHECK_FALSE(opts.let().has_value()); + CHECK_FALSE(opts.comment().has_value()); +} + +TEST_CASE("collation", "[mongocxx][v1][delete_many_options]") { + auto const v = GENERATE(values({ + scoped_bson{}, + scoped_bson{R"({"x": 1})"}, + })); + + CHECK(delete_many_options{}.collation(v.value()).collation() == v.view()); +} + +TEST_CASE("write_concern", "[mongocxx][v1][delete_many_options]") { + using T = v1::write_concern; + + auto const v = GENERATE(values({ + T{}, + T{}.acknowledge_level(T::level::k_majority), + T{}.tag("abc"), + })); + + CHECK(delete_many_options{}.write_concern(v).write_concern() == v); +} + +TEST_CASE("hint", "[mongocxx][v1][delete_many_options]") { + auto const v = GENERATE(values({ + v1::hint{"abc"}, + v1::hint{scoped_bson{R"({"x": 1})"}.value()}, + })); + + CHECK(delete_many_options{}.hint(v).hint() == v); +} + +TEST_CASE("let", "[mongocxx][v1][delete_many_options]") { + auto const v = GENERATE(values({ + scoped_bson{}, + scoped_bson{R"({"x": 1})"}, + })); + + CHECK(delete_many_options{}.let(v.value()).let() == v.view()); +} + +TEST_CASE("comment", "[mongocxx][v1][delete_many_options]") { + using T = bsoncxx::v1::types::value; + + auto const v = GENERATE(values({ + T{}, + T{std::int32_t{123}}, + T{std::int64_t{456}}, + T{123.456}, + T{"abc"}, + })); + + CHECK(delete_many_options{}.comment(v).comment() == v); +} + +} // namespace v1 +} // namespace mongocxx diff --git a/src/mongocxx/test/v1/delete_one_options.cpp b/src/mongocxx/test/v1/delete_one_options.cpp new file mode 100644 index 0000000000..ecb348f6fe --- /dev/null +++ b/src/mongocxx/test/v1/delete_one_options.cpp @@ -0,0 +1,139 @@ +// Copyright 2009-present MongoDB, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +// + +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +namespace mongocxx { +namespace v1 { + +TEST_CASE("ownership", "[mongocxx][v1][delete_one_options]") { + delete_one_options source; + delete_one_options target; + + source.comment(bsoncxx::v1::types::value{"source"}); + target.comment(bsoncxx::v1::types::value{"target"}); + + REQUIRE(source.comment() == bsoncxx::v1::types::b_string{"source"}); + REQUIRE(target.comment() == bsoncxx::v1::types::b_string{"target"}); + + auto const source_value = source.comment(); + + SECTION("move") { + auto move = std::move(source); + + // source is in an assign-or-move-only state. + + CHECK(move.comment() == source_value); + + target = std::move(move); + + // source is in an assign-or-move-only state. + + CHECK(target.comment() == source_value); + } + + SECTION("copy") { + auto copy = source; + + CHECK(source.comment() == source_value); + CHECK(copy.comment() == source_value); + + target = copy; + + CHECK(copy.comment() == source_value); + CHECK(target.comment() == source_value); + } +} + +TEST_CASE("default", "[mongocxx][v1][delete_one_options]") { + delete_one_options const opts; + + CHECK_FALSE(opts.collation().has_value()); + CHECK_FALSE(opts.write_concern().has_value()); + CHECK_FALSE(opts.hint().has_value()); + CHECK_FALSE(opts.let().has_value()); + CHECK_FALSE(opts.comment().has_value()); +} + +TEST_CASE("collation", "[mongocxx][v1][delete_one_options]") { + auto const v = GENERATE(values({ + scoped_bson{}, + scoped_bson{R"({"x": 1})"}, + })); + + CHECK(delete_one_options{}.collation(v.value()).collation() == v.view()); +} + +TEST_CASE("write_concern", "[mongocxx][v1][delete_one_options]") { + using T = v1::write_concern; + + auto const v = GENERATE(values({ + T{}, + T{}.acknowledge_level(T::level::k_majority), + T{}.tag("abc"), + })); + + CHECK(delete_one_options{}.write_concern(v).write_concern() == v); +} + +TEST_CASE("hint", "[mongocxx][v1][delete_one_options]") { + auto const v = GENERATE(values({ + v1::hint{"abc"}, + v1::hint{scoped_bson{R"({"x": 1})"}.value()}, + })); + + CHECK(delete_one_options{}.hint(v).hint() == v); +} + +TEST_CASE("let", "[mongocxx][v1][delete_one_options]") { + auto const v = GENERATE(values({ + scoped_bson{}, + scoped_bson{R"({"x": 1})"}, + })); + + CHECK(delete_one_options{}.let(v.value()).let() == v.view()); +} + +TEST_CASE("comment", "[mongocxx][v1][delete_one_options]") { + using T = bsoncxx::v1::types::value; + + auto const v = GENERATE(values({ + T{}, + T{std::int32_t{123}}, + T{std::int64_t{456}}, + T{123.456}, + T{"abc"}, + })); + + CHECK(delete_one_options{}.comment(v).comment() == v); +} + +} // namespace v1 +} // namespace mongocxx From 4ea736894e01e129f70fc0e51aa255c001bfabdf Mon Sep 17 00:00:00 2001 From: Ezra Chung Date: Thu, 4 Dec 2025 14:48:42 -0600 Subject: [PATCH 2/3] Remove copy-paste error from v_noabi::options::insert --- .../include/mongocxx/v_noabi/mongocxx/options/delete.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp index 2949facfb8..4f53cac472 100644 --- a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp +++ b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp @@ -289,8 +289,6 @@ inline v_noabi::options::delete_options from_v1(v1::delete_many_options v) { /// /// Convert to the @ref mongocxx::v_noabi equivalent of `v`. /// -/// @note The `ordered` field is initialized as unset. -/// inline v_noabi::options::delete_options from_v1(v1::delete_one_options v) { return {std::move(v)}; } From 7136fdf1e74d6a968038baf18803db7c8bb761d7 Mon Sep 17 00:00:00 2001 From: Ezra Chung Date: Thu, 4 Dec 2025 14:48:42 -0600 Subject: [PATCH 3/3] Fix typos --- .../include/mongocxx/v_noabi/mongocxx/options/delete.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp index 4f53cac472..766a93ff3a 100644 --- a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp +++ b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/delete.hpp @@ -293,11 +293,11 @@ inline v_noabi::options::delete_options from_v1(v1::delete_one_options v) { return {std::move(v)}; } -// Ambiguous whether `v_noabi::options::delete` should be converted to `v1::delete_many_options` or +// Ambiguous whether `v_noabi::options::delete_options` should be converted to `v1::delete_many_options` or // `v1::delete_one_options`. Require users to explicitly cast to the expected type instead. // -// v1::delete_many_options to_v1(v_noabi::options::delete const& v); -// v1::delete_one_options to_v1(v_noabi::options::delete const& v); +// v1::delete_many_options to_v1(v_noabi::options::delete_options const& v); +// v1::delete_one_options to_v1(v_noabi::options::delete_options const& v); } // namespace v_noabi } // namespace mongocxx