Skip to content

Commit 19c16d3

Browse files
committed
Merge branch 'master' into CXX-2496
2 parents c75c32a + 49275f2 commit 19c16d3

File tree

4 files changed

+208
-15
lines changed

4 files changed

+208
-15
lines changed

benchmark/benchmark_runner.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
#include "benchmark_runner.hpp"
1616

17-
#include <bsoncxx/stdx/make_unique.hpp>
18-
1917
#include "bson/bson_encoding.hpp"
2018
#include "multi_doc/bulk_insert.hpp"
2119
#include "multi_doc/find_many.hpp"
@@ -28,6 +26,7 @@
2826
#include "single_doc/find_one_by_id.hpp"
2927
#include "single_doc/insert_one.hpp"
3028
#include "single_doc/run_command.hpp"
29+
#include <bsoncxx/stdx/make_unique.hpp>
3130

3231
namespace benchmark {
3332

@@ -187,4 +186,4 @@ void benchmark_runner::print_scores() {
187186
std::cout << "DriverBench: " << (read + write) / 2.0 << " MB/s" << std::endl;
188187
}
189188
}
190-
} // namespace benchmark
189+
} // namespace benchmark

examples/mongocxx/mongodb.com/documentation_examples.cpp

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <chrono>
1516
#include <iostream>
17+
#include <thread>
1618
#include <vector>
1719

1820
#include <bsoncxx/builder/basic/array.hpp>
@@ -22,6 +24,7 @@
2224
#include <bsoncxx/stdx/string_view.hpp>
2325
#include <bsoncxx/types.hpp>
2426
#include <mongocxx/client.hpp>
27+
#include <mongocxx/exception/operation_exception.hpp>
2528
#include <mongocxx/instance.hpp>
2629
#include <mongocxx/options/find.hpp>
2730
#include <mongocxx/uri.hpp>
@@ -54,6 +57,19 @@ void check_has_no_field(const T& document, const char* field, int example_no) {
5457
check_field(document, field, false, example_no);
5558
}
5659

60+
static bsoncxx::document::value get_is_master(const mongocxx::client& client) {
61+
using bsoncxx::builder::basic::kvp;
62+
using bsoncxx::builder::basic::make_document;
63+
64+
static auto reply = client["admin"].run_command(make_document(kvp("isMaster", 1)));
65+
return reply;
66+
}
67+
68+
static bool is_replica_set(const mongocxx::client& client) {
69+
auto reply = get_is_master(client);
70+
return static_cast<bool>(reply.view()["setName"]);
71+
}
72+
5773
void insert_examples(mongocxx::database db) {
5874
db["inventory"].drop();
5975

@@ -1180,6 +1196,178 @@ void delete_examples(mongocxx::database db) {
11801196
}
11811197
}
11821198

1199+
static bool is_snapshot_ready(mongocxx::client& client, mongocxx::collection& collection) {
1200+
auto opts = mongocxx::options::client_session{};
1201+
opts.snapshot(true);
1202+
1203+
auto session = client.start_session(opts);
1204+
try {
1205+
auto cursor = collection.aggregate(session, {});
1206+
for (const auto& it : cursor) {
1207+
(void)it;
1208+
break;
1209+
}
1210+
} catch (const mongocxx::operation_exception& e) {
1211+
if (e.code().value() == 246) { // snapshot unavailable
1212+
return false;
1213+
}
1214+
throw;
1215+
}
1216+
return true;
1217+
}
1218+
1219+
// Seed the pets database and wait for the snapshot to become available.
1220+
// This follows the pattern from the Python driver as seen below:
1221+
// https://github.com/mongodb/mongo-python-driver/commit/e325b24b78e431cb889c5902d00b8f4af2c700c3#diff-c5d782e261f04fca18024ab18c3ed38fb45ede24cde4f9092e012f6fcbbe0df5R1368
1222+
static void wait_for_snapshot_ready(mongocxx::client& client,
1223+
std::vector<mongocxx::collection> collections) {
1224+
size_t sleep_time = 1;
1225+
1226+
for (;;) {
1227+
bool is_ready = true;
1228+
for (auto& collection : collections) {
1229+
if (!is_snapshot_ready(client, collection)) {
1230+
is_ready = false;
1231+
break; // inner
1232+
}
1233+
}
1234+
if (is_ready) {
1235+
break; // outer
1236+
} else {
1237+
std::this_thread::sleep_for(std::chrono::seconds(sleep_time++));
1238+
}
1239+
}
1240+
}
1241+
1242+
static void setup_pets(mongocxx::client& client) {
1243+
using namespace mongocxx;
1244+
using bsoncxx::builder::basic::kvp;
1245+
using bsoncxx::builder::basic::make_document;
1246+
1247+
auto db = client["pets"];
1248+
db.drop();
1249+
db["cats"].insert_one(make_document(kvp("adoptable", true)));
1250+
db["dogs"].insert_one(make_document(kvp("adoptable", true)));
1251+
db["dogs"].insert_one(make_document(kvp("adoptable", false)));
1252+
wait_for_snapshot_ready(client, {db["cats"], db["dogs"]});
1253+
}
1254+
1255+
static void snapshot_example1(mongocxx::client& client) {
1256+
setup_pets(client);
1257+
1258+
// Start Snapshot Query Example 1
1259+
using namespace mongocxx;
1260+
using bsoncxx::builder::basic::kvp;
1261+
using bsoncxx::builder::basic::make_document;
1262+
1263+
auto db = client["pets"];
1264+
1265+
int64_t adoptable_pets_count = 0;
1266+
1267+
auto opts = mongocxx::options::client_session{};
1268+
opts.snapshot(true);
1269+
auto session = client.start_session(opts);
1270+
1271+
{
1272+
pipeline p;
1273+
1274+
p.match(make_document(kvp("adoptable", true))).count("adoptableCatsCount");
1275+
auto cursor = db["cats"].aggregate(session, p);
1276+
1277+
for (auto doc : cursor) {
1278+
adoptable_pets_count += doc.find("adoptableCatsCount")->get_int32();
1279+
}
1280+
}
1281+
1282+
{
1283+
pipeline p;
1284+
1285+
p.match(make_document(kvp("adoptable", true))).count("adoptableDogsCount");
1286+
auto cursor = db["dogs"].aggregate(session, p);
1287+
1288+
for (auto doc : cursor) {
1289+
adoptable_pets_count += doc.find("adoptableDogsCount")->get_int32();
1290+
}
1291+
}
1292+
1293+
// End Snapshot Query Example 1
1294+
1295+
if (adoptable_pets_count != 2) {
1296+
throw std::logic_error(
1297+
"wrong number of adoptable pets in Snapshot Query Example 1, expecting 2 got: " +
1298+
std::to_string(adoptable_pets_count));
1299+
}
1300+
}
1301+
1302+
static void setup_retail(mongocxx::client& client) {
1303+
using bsoncxx::builder::basic::kvp;
1304+
using bsoncxx::builder::basic::make_document;
1305+
using bsoncxx::types::b_date;
1306+
using std::chrono::system_clock;
1307+
1308+
auto db = client["retail"];
1309+
db.drop();
1310+
b_date sales_date{system_clock::now()};
1311+
db["sales"].insert_one(
1312+
make_document(kvp("shoeType", "boot"), kvp("price", 30), kvp("saleDate", sales_date)));
1313+
wait_for_snapshot_ready(client, {db["sales"]});
1314+
}
1315+
1316+
static void snapshot_example2(mongocxx::client& client) {
1317+
setup_retail(client);
1318+
1319+
// Start Snapshot Query Example 2
1320+
using namespace mongocxx;
1321+
using bsoncxx::builder::basic::kvp;
1322+
using bsoncxx::builder::basic::make_array;
1323+
using bsoncxx::builder::basic::make_document;
1324+
1325+
auto opts = mongocxx::options::client_session{};
1326+
opts.snapshot(true);
1327+
auto session = client.start_session(opts);
1328+
1329+
auto db = client["retail"];
1330+
1331+
pipeline p;
1332+
1333+
p.match(make_document(kvp("$expr",
1334+
make_document(kvp("$gt",
1335+
make_array("$saleDate",
1336+
make_document(kvp("startDate", "$$NOW"),
1337+
kvp("unit", "day"),
1338+
kvp("amount", 1))))))))
1339+
.count("totalDailySales");
1340+
1341+
auto cursor = db["sales"].aggregate(session, p);
1342+
1343+
auto doc = *cursor.begin();
1344+
auto total_daily_sales = doc.find("totalDailySales")->get_int32();
1345+
1346+
// End Snapshot Query Example 2
1347+
if (total_daily_sales != 1) {
1348+
throw std::logic_error("wrong number of total sales in example 60, expecting 1 got: " +
1349+
std::to_string(total_daily_sales));
1350+
}
1351+
}
1352+
1353+
static bool version_at_least(mongocxx::v_noabi::database& db, int minimum_major) {
1354+
using bsoncxx::builder::basic::kvp;
1355+
using bsoncxx::builder::basic::make_document;
1356+
1357+
auto resp = db.run_command(make_document(kvp("buildInfo", 1)));
1358+
auto version = resp.find("version")->get_string().value;
1359+
std::string major_string;
1360+
for (auto i : version) {
1361+
if (i == '.') {
1362+
break;
1363+
}
1364+
major_string += i;
1365+
}
1366+
int server_major = std::stoi(major_string);
1367+
1368+
return server_major >= minimum_major;
1369+
}
1370+
11831371
int main() {
11841372
// The mongocxx::instance constructor and destructor initialize and shut down the driver,
11851373
// respectively. Therefore, a mongocxx::instance must be created before using the driver and
@@ -1199,6 +1387,10 @@ int main() {
11991387
projection_examples(db);
12001388
update_examples(db);
12011389
delete_examples(db);
1390+
if (is_replica_set(conn) && version_at_least(db, 5)) {
1391+
snapshot_example1(conn);
1392+
snapshot_example2(conn);
1393+
}
12021394
} catch (const std::logic_error& e) {
12031395
std::cerr << e.what() << std::endl;
12041396
return EXIT_FAILURE;

src/mongocxx/test/collection.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,10 +2337,10 @@ TEST_CASE("read_concern is inherited from parent", "[collection]") {
23372337
}
23382338
}
23392339

2340-
void find_index_and_validate(collection& coll,
2341-
stdx::string_view index_name,
2342-
const std::function<void(bsoncxx::document::view)>& validate =
2343-
[](bsoncxx::document::view) {}) {
2340+
void find_index_and_validate(
2341+
collection& coll,
2342+
stdx::string_view index_name,
2343+
const std::function<void(bsoncxx::document::view)>& validate = [](bsoncxx::document::view) {}) {
23442344
auto cursor = coll.list_indexes();
23452345

23462346
for (auto&& index : cursor) {

src/mongocxx/test/uri.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,18 +333,20 @@ TEST_CASE("uri::compressors()", "[uri]") {
333333

334334
// Zero is not allowed for heartbeatFrequencyMS.
335335
TEST_CASE("uri::heartbeat_frequency_ms()", "[uri]") {
336-
_test_int32_option("heartbeatFrequencyMS",
337-
[](mongocxx::uri& uri) { return uri.heartbeat_frequency_ms(); },
338-
"1234",
339-
false);
336+
_test_int32_option(
337+
"heartbeatFrequencyMS",
338+
[](mongocxx::uri& uri) { return uri.heartbeat_frequency_ms(); },
339+
"1234",
340+
false);
340341
}
341342

342343
// -1 to 9 are only valid values of zlib compression level.
343344
TEST_CASE("uri::zlib_compression_level()", "[uri]") {
344-
_test_int32_option("zlibCompressionLevel",
345-
[](mongocxx::uri& uri) { return uri.zlib_compression_level(); },
346-
"5",
347-
true);
345+
_test_int32_option(
346+
"zlibCompressionLevel",
347+
[](mongocxx::uri& uri) { return uri.zlib_compression_level(); },
348+
"5",
349+
true);
348350
}
349351

350352
// End special cases.

0 commit comments

Comments
 (0)