Skip to content

Commit 3fef6e6

Browse files
authored
v1: server_api (CXX-3237, CXX-3238) (#1539)
1 parent cadbc0a commit 3fef6e6

File tree

7 files changed

+489
-51
lines changed

7 files changed

+489
-51
lines changed

src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/server_api-fwd.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#pragma once
1616

17+
#include <mongocxx/v1/server_api-fwd.hpp>
18+
1719
#include <mongocxx/config/prelude.hpp>
1820

1921
namespace mongocxx {
@@ -29,7 +31,7 @@ class server_api;
2931
namespace mongocxx {
3032
namespace options {
3133

32-
using ::mongocxx::v_noabi::options::server_api;
34+
using v_noabi::options::server_api;
3335

3436
} // namespace options
3537
} // namespace mongocxx
@@ -40,3 +42,6 @@ using ::mongocxx::v_noabi::options::server_api;
4042
/// @file
4143
/// Declares @ref mongocxx::v_noabi::options::server_api.
4244
///
45+
/// @par Includes
46+
/// - @ref mongocxx/v1/server_api-fwd.hpp
47+
///

src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/server_api.hpp

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414

1515
#pragma once
1616

17+
#include <mongocxx/options/server_api-fwd.hpp> // IWYU pragma: export
18+
19+
//
20+
21+
#include <mongocxx/v1/server_api.hpp> // IWYU pragma: export
22+
1723
#include <string>
1824

19-
#include <mongocxx/client-fwd.hpp>
20-
#include <mongocxx/options/server_api-fwd.hpp> // IWYU pragma: export
21-
#include <mongocxx/pool-fwd.hpp>
25+
#include <mongocxx/client-fwd.hpp> // IWYU pragma: keep: backward compatibility, to be removed.
26+
#include <mongocxx/pool-fwd.hpp> // IWYU pragma: keep: backward compatibility, to be removed.
2227

2328
#include <bsoncxx/stdx/optional.hpp>
2429
#include <bsoncxx/stdx/string_view.hpp>
@@ -40,9 +45,7 @@ class server_api {
4045
///
4146
/// Enum representing the possible values for server API version.
4247
///
43-
enum class version {
44-
k_version_1, ///< Stable API Version 1.
45-
};
48+
using version = v1::server_api::version;
4649

4750
///
4851
/// Constructs a new server_api object.
@@ -55,7 +58,19 @@ class server_api {
5558
/// @param version
5659
/// The server api version to send to the server.
5760
///
58-
MONGOCXX_ABI_EXPORT_CDECL() server_api(version version);
61+
/* explicit(false) */ server_api(version version) : _version{version} {}
62+
63+
///
64+
/// Construct with the @ref mongocxx::v1 equivalent.
65+
///
66+
/* explicit(false) */ server_api(v1::server_api const& opts) : server_api{opts.get_version()} {}
67+
68+
///
69+
/// Convert to the @ref mongocxx::v1 equivalent.
70+
///
71+
explicit operator v1::server_api() const {
72+
return v1::server_api{_version};
73+
}
5974

6075
///
6176
/// Converts a version enum value to its string value.
@@ -93,15 +108,20 @@ class server_api {
93108
/// @return
94109
/// A reference to this object to facilitate method chaining.
95110
///
96-
MONGOCXX_ABI_EXPORT_CDECL(server_api&) strict(bool strict);
111+
server_api& strict(bool strict) {
112+
_strict = strict;
113+
return *this;
114+
}
97115

98116
///
99117
/// Gets the current value of the strict option.
100118
///
101119
/// @return
102120
/// The optional value of the strict option.
103121
///
104-
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional<bool> const&) strict() const;
122+
bsoncxx::v_noabi::stdx::optional<bool> const& strict() const {
123+
return _strict;
124+
}
105125

106126
///
107127
/// Sets the deprecation errors option, specifying whether the server should
@@ -113,29 +133,32 @@ class server_api {
113133
/// @return
114134
/// A reference to this object to facilitate method chaining.
115135
///
116-
MONGOCXX_ABI_EXPORT_CDECL(server_api&) deprecation_errors(bool deprecation_errors);
136+
server_api& deprecation_errors(bool deprecation_errors) {
137+
_deprecation_errors = deprecation_errors;
138+
return *this;
139+
}
117140

118141
///
119142
/// Gets the current value of the deprecation errors option.
120143
///
121144
/// @return
122145
/// The optional value of the deprecation errors option.
123146
///
124-
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional<bool> const&)
125-
deprecation_errors() const;
147+
bsoncxx::v_noabi::stdx::optional<bool> const& deprecation_errors() const {
148+
return _deprecation_errors;
149+
}
126150

127151
///
128152
/// Gets the declared server api version.
129153
///
130154
/// @return
131155
/// The version enum value specifying the declared server api version.
132156
///
133-
MONGOCXX_ABI_EXPORT_CDECL(version) get_version() const;
157+
version get_version() const {
158+
return _version;
159+
}
134160

135161
private:
136-
friend ::mongocxx::v_noabi::client;
137-
friend ::mongocxx::v_noabi::pool;
138-
139162
version _version;
140163
bsoncxx::v_noabi::stdx::optional<bool> _strict;
141164
bsoncxx::v_noabi::stdx::optional<bool> _deprecation_errors;
@@ -145,9 +168,32 @@ class server_api {
145168
} // namespace v_noabi
146169
} // namespace mongocxx
147170

171+
namespace mongocxx {
172+
namespace v_noabi {
173+
174+
///
175+
/// Convert to the @ref mongocxx::v_noabi equivalent of `v`.
176+
///
177+
inline v_noabi::options::server_api from_v1(v1::server_api const& v) {
178+
return {v};
179+
}
180+
181+
///
182+
/// Convert to the @ref mongocxx::v1 equivalent of `v`.
183+
///
184+
inline v1::server_api to_v1(v_noabi::options::server_api const& v) {
185+
return v1::server_api{v};
186+
}
187+
188+
} // namespace v_noabi
189+
} // namespace mongocxx
190+
148191
#include <mongocxx/config/postlude.hpp>
149192

150193
///
151194
/// @file
152195
/// Provides @ref mongocxx::v_noabi::options::server_api.
153196
///
197+
/// @par Includes
198+
/// - @ref mongocxx/v1/server_api.hpp
199+
///

src/mongocxx/lib/mongocxx/v1/server_api.cpp

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,196 @@
1313
// limitations under the License.
1414

1515
#include <mongocxx/v1/server_api.hpp>
16+
17+
//
18+
19+
#include <bsoncxx/v1/stdx/optional.hpp>
20+
#include <bsoncxx/v1/stdx/string_view.hpp>
21+
22+
#include <mongocxx/v1/exception.hh>
23+
24+
#include <string>
25+
#include <system_error>
26+
27+
#include <bsoncxx/private/immortal.hh>
28+
29+
#include <mongocxx/private/mongoc.hh>
30+
#include <mongocxx/private/utility.hh>
31+
32+
namespace mongocxx {
33+
namespace v1 {
34+
35+
using code = server_api::errc;
36+
37+
namespace {
38+
39+
static_assert(
40+
static_cast<int>(server_api::version::k_version_1) ==
41+
static_cast<int>(mongoc_server_api_version_t::MONGOC_SERVER_API_V1),
42+
"");
43+
44+
server_api::version from_mongoc(mongoc_server_api_version_t v) {
45+
return static_cast<server_api::version>(v);
46+
}
47+
48+
} // namespace
49+
50+
class server_api::impl {
51+
public:
52+
version _version;
53+
bsoncxx::v1::stdx::optional<bool> _strict;
54+
bsoncxx::v1::stdx::optional<bool> _deprecation_errors;
55+
56+
explicit impl(version v) : _version{v} {}
57+
58+
static impl const& with(server_api const& self) {
59+
return *static_cast<impl*>(self._impl);
60+
}
61+
62+
static impl const* with(server_api const* self) {
63+
return static_cast<impl*>(self->_impl);
64+
}
65+
66+
static impl& with(server_api& self) {
67+
return *static_cast<impl*>(self._impl);
68+
}
69+
70+
static impl* with(server_api* self) {
71+
return static_cast<impl*>(self->_impl);
72+
}
73+
74+
static impl* with(void* ptr) {
75+
return static_cast<impl*>(ptr);
76+
}
77+
};
78+
79+
// NOLINTBEGIN(cppcoreguidelines-owning-memory): owning void* for ABI stability.
80+
81+
server_api::~server_api() {
82+
delete impl::with(this);
83+
}
84+
85+
server_api::server_api(server_api&& other) noexcept : _impl{exchange(other._impl, nullptr)} {}
86+
87+
server_api& server_api::operator=(server_api&& other) noexcept {
88+
if (this != &other) {
89+
delete impl::with(exchange(_impl, exchange(other._impl, nullptr)));
90+
}
91+
92+
return *this;
93+
}
94+
95+
server_api::server_api(server_api const& other) : _impl{new impl{impl::with(other)}} {}
96+
97+
server_api& server_api::operator=(server_api const& other) {
98+
if (this != &other) {
99+
delete impl::with(exchange(_impl, new impl{impl::with(other)}));
100+
}
101+
102+
return *this;
103+
}
104+
105+
server_api::server_api(version v) : _impl{new impl{v}} {}
106+
107+
// NOLINTEND(cppcoreguidelines-owning-memory)
108+
109+
std::string server_api::version_to_string(version v) {
110+
switch (v) {
111+
case version::k_version_1:
112+
return "1";
113+
default:
114+
throw v1::exception::internal::make(code::invalid_version);
115+
}
116+
}
117+
118+
server_api::version server_api::version_from_string(bsoncxx::v1::stdx::string_view v) {
119+
mongoc_server_api_version_t ver = {};
120+
121+
if (libmongoc::server_api_version_from_string(std::string{v}.c_str(), &ver)) {
122+
return from_mongoc(ver);
123+
}
124+
125+
throw v1::exception::internal::make(code::invalid_version);
126+
}
127+
128+
server_api& server_api::strict(bool strict) {
129+
impl::with(this)->_strict = strict;
130+
return *this;
131+
}
132+
133+
bsoncxx::v1::stdx::optional<bool> server_api::strict() const {
134+
return impl::with(this)->_strict;
135+
}
136+
137+
server_api& server_api::deprecation_errors(bool v) {
138+
impl::with(this)->_deprecation_errors = v;
139+
return *this;
140+
}
141+
142+
bsoncxx::v1::stdx::optional<bool> server_api::deprecation_errors() const {
143+
return impl::with(this)->_deprecation_errors;
144+
}
145+
146+
server_api::version server_api::get_version() const {
147+
return impl::with(this)->_version;
148+
}
149+
150+
std::error_category const& server_api::error_category() {
151+
class type final : public std::error_category {
152+
char const* name() const noexcept override {
153+
return "mongocxx::v1::server_api";
154+
}
155+
156+
std::string message(int v) const noexcept override {
157+
switch (static_cast<code>(v)) {
158+
case code::zero:
159+
return "zero";
160+
case code::invalid_version:
161+
return "invalid server API version";
162+
default:
163+
return std::string(this->name()) + ':' + std::to_string(v);
164+
}
165+
}
166+
167+
bool equivalent(int v, std::error_condition const& ec) const noexcept override {
168+
if (ec.category() == v1::source_error_category()) {
169+
using condition = v1::source_errc;
170+
171+
auto const source = static_cast<condition>(ec.value());
172+
173+
switch (static_cast<code>(v)) {
174+
case code::invalid_version:
175+
return source == condition::mongocxx;
176+
177+
case code::zero:
178+
default:
179+
return false;
180+
}
181+
}
182+
183+
if (ec.category() == v1::type_error_category()) {
184+
using condition = v1::type_errc;
185+
186+
auto const type = static_cast<condition>(ec.value());
187+
188+
switch (static_cast<code>(v)) {
189+
case code::invalid_version:
190+
return type == condition::invalid_argument;
191+
192+
case code::zero:
193+
default:
194+
return false;
195+
}
196+
}
197+
198+
return false;
199+
}
200+
};
201+
202+
static bsoncxx::immortal<type> const instance;
203+
204+
return instance.value();
205+
}
206+
207+
} // namespace v1
208+
} // namespace mongocxx

0 commit comments

Comments
 (0)