Skip to content

Commit 265d9b1

Browse files
authored
CXX-3082 Add comprehensive examples (mongocxx, Part 2) (#1236)
* doxygen: apply consistent @see list syntax * db_lock: use write concern majority when dropping locked databases * db_lock: avoid server error due to lengthy API example component name * runner: add support for disabling forking even when available * runner: use bsoncxx::from_json instead of the basic builder * examples: avoid mongocryptd conflicting with sharded clusters * examples: add client sessions * examples: add index views * examples: add change streams * examples: database error handling * examples: add collection error handling * Refactor API examples runner CLI argument parsing * Add API examples runner support for filtering by component name
1 parent c2205c2 commit 265d9b1

File tree

29 files changed

+1745
-96
lines changed

29 files changed

+1745
-96
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Obtain a Change Stream
2+
3+
## From a Client
4+
5+
@snippet api/mongocxx/examples/change_streams/from_client.cpp Example
6+
7+
## From a Database
8+
9+
@snippet api/mongocxx/examples/change_streams/from_database.cpp Example
10+
11+
## From a Collection
12+
13+
@snippet api/mongocxx/examples/change_streams/from_collection.cpp Example
14+
15+
# Use a Change Stream
16+
17+
## Basic Usage
18+
19+
@snippet api/mongocxx/examples/change_streams/basic.cpp Example
20+
21+
## With Pipeline
22+
23+
@snippet api/mongocxx/examples/change_streams/with_pipeline.cpp Example
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Create a Client Session
2+
3+
## Basic Usage
4+
5+
@snippet api/mongocxx/examples/client_sessions/create/basic.cpp Example
6+
7+
## With Options
8+
9+
@snippet api/mongocxx/examples/client_sessions/create/with_options.cpp Example
10+
11+
# Use a Client Session
12+
13+
@see
14+
- [Causal Consistency and Read and Write Concerns (MongoDB Manual)](https://www.mongodb.com/docs/manual/core/causal-consistency-read-write-concerns/)
15+
16+
## Basic Usage
17+
18+
@snippet api/mongocxx/examples/client_sessions/use/basic.cpp Example
19+
20+
## With Transactions
21+
22+
@snippet api/mongocxx/examples/client_sessions/use/transactions.cpp Example

docs/api/mongocxx/examples/collections.md

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,50 @@
2626

2727
# Index Operations
2828

29-
## List Indexes
29+
## On a Collection
30+
31+
### List Indexes
3032

3133
@snippet examples/api/mongocxx/examples/collections/list_indexes.cpp Example
3234

33-
## Create an Index
35+
### Create an Index
3436

3537
@snippet examples/api/mongocxx/examples/collections/create_index.cpp Example
3638

37-
## Create an Index With Options
39+
### Create an Index With Options
3840

3941
@snippet examples/api/mongocxx/examples/collections/create_index_with_options.cpp Example
4042

43+
## With an Index View
44+
45+
### Obtain an Index View
46+
47+
@snippet examples/api/mongocxx/examples/collections/index_views/indexes.cpp Example
48+
49+
### List Indexes
50+
51+
@snippet examples/api/mongocxx/examples/collections/index_views/list.cpp Example
52+
53+
### Create an Index
54+
55+
@snippet examples/api/mongocxx/examples/collections/index_views/create.cpp Example
56+
57+
### Create an Index With Options
58+
59+
@snippet examples/api/mongocxx/examples/collections/index_views/create_with_options.cpp Example
60+
61+
### Create Multiple Indexes
62+
63+
@snippet examples/api/mongocxx/examples/collections/index_views/create_many.cpp Example
64+
65+
### Drop an Index
66+
67+
@snippet examples/api/mongocxx/examples/collections/index_views/drop.cpp Example
68+
69+
### Drop All Indexes
70+
71+
@snippet examples/api/mongocxx/examples/collections/index_views/drop_all.cpp Example
72+
4173
# Document Operations
4274

4375
## Query the Number of Documents
@@ -111,3 +143,17 @@
111143
## Execute an Aggregation Operation
112144

113145
@snippet examples/api/mongocxx/examples/collections/aggregate.cpp Example
146+
147+
# Error Handling
148+
149+
## Invalid Collection
150+
151+
@snippet examples/api/mongocxx/examples/collections/incompatible_options.cpp Example
152+
153+
## Invalid Parameter
154+
155+
@snippet examples/api/mongocxx/examples/collections/invalid_parameter.cpp Example
156+
157+
## Incompatible Options
158+
159+
@snippet examples/api/mongocxx/examples/collections/incompatible_options.cpp Example

docs/api/mongocxx/examples/databases.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,9 @@
4141
## List Collection Names in the Database
4242

4343
@snippet examples/api/mongocxx/examples/databases/list_collection_names.cpp Example
44+
45+
# Error Handling
46+
47+
## Invalid Database
48+
49+
@snippet examples/api/mongocxx/examples/databases/invalid.cpp Example

examples/api/db_lock.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <mongocxx/collection.hpp>
2222
#include <mongocxx/database.hpp>
2323

24+
#include <examples/api/concern.hh>
2425
#include <examples/api/db_lock.hh>
2526
#include <examples/macros.hh>
2627

@@ -32,14 +33,23 @@ std::mutex db_locks_mut;
3233
} // namespace
3334

3435
db_lock::~db_lock() {
35-
this->get().drop();
36+
this->get().drop(wc_majority());
3637
}
3738

3839
db_lock::db_lock(mongocxx::client& client, std::string name) : _client_ptr(&client), _name(name) {
40+
// https://www.mongodb.com/docs/manual/reference/limits/#mongodb-limit-Length-of-Database-Names
41+
static constexpr std::size_t db_name_size_max = 63u;
42+
43+
if (_name.size() > db_name_size_max) {
44+
// Strip prefix, which is more likely to be common across components.
45+
// e.g. `api_mongocxx_examples_very_long_component_name` -> `g_component_name` (length: 16).
46+
_name = std::move(_name).substr(_name.size() - db_name_size_max, db_name_size_max);
47+
}
48+
3949
((void)std::lock_guard<std::mutex>{db_locks_mut},
4050
_lock = std::unique_lock<std::mutex>(db_locks[name]));
4151

42-
this->get().drop();
52+
this->get().drop(wc_majority());
4353
}
4454

4555
mongocxx::database db_lock::get() const& {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <chrono>
16+
17+
#include <bsoncxx/json.hpp>
18+
19+
#include <mongocxx/client.hpp>
20+
#include <mongocxx/collection.hpp>
21+
#include <mongocxx/database.hpp>
22+
#include <mongocxx/uri.hpp>
23+
24+
#include <examples/api/concern.hh>
25+
#include <examples/api/db_lock.hh>
26+
#include <examples/api/runner.hh>
27+
#include <examples/macros.hh>
28+
29+
namespace {
30+
31+
// [Example]
32+
void example(mongocxx::database db) {
33+
mongocxx::collection coll = db.create_collection("coll");
34+
35+
mongocxx::change_stream stream = coll.watch();
36+
37+
auto result_opt = coll.insert_one(bsoncxx::from_json(R"({"x": 1})"));
38+
EXPECT(result_opt);
39+
auto id = result_opt->inserted_id();
40+
41+
int count = 0;
42+
auto now = [] { return std::chrono::steady_clock::now(); };
43+
auto start = now();
44+
45+
// periodicNoopIntervalSecs: 10 (default)
46+
while (count < 1 && now() - start < std::chrono::seconds(10)) {
47+
for (bsoncxx::document::view change : stream) {
48+
++count;
49+
50+
EXPECT(change["operationType"]);
51+
EXPECT(change["operationType"].get_string().value.compare("insert") == 0);
52+
53+
EXPECT(change["ns"]);
54+
EXPECT(change["ns"]["db"].get_string().value == db.name());
55+
EXPECT(change["ns"]["coll"].get_string().value == coll.name());
56+
57+
EXPECT(change["fullDocument"]);
58+
EXPECT(change["fullDocument"]["x"]);
59+
60+
EXPECT(change["documentKey"]);
61+
EXPECT(change["documentKey"]["_id"].get_oid().value == id);
62+
}
63+
}
64+
65+
EXPECT(count == 1);
66+
}
67+
// [Example]
68+
69+
} // namespace
70+
71+
RUNNER_REGISTER_COMPONENT_FOR_REPLICA() {
72+
mongocxx::client client{mongocxx::uri{}};
73+
74+
{
75+
db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR};
76+
77+
example(set_rw_concern_majority(guard.get()));
78+
}
79+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <bsoncxx/json.hpp>
16+
17+
#include <mongocxx/change_stream.hpp>
18+
#include <mongocxx/client.hpp>
19+
#include <mongocxx/options/change_stream.hpp>
20+
#include <mongocxx/uri.hpp>
21+
22+
#include <examples/api/runner.hh>
23+
#include <examples/macros.hh>
24+
25+
namespace {
26+
27+
// [Example]
28+
void example(mongocxx::client client) {
29+
// Basic usage.
30+
{
31+
mongocxx::change_stream stream = client.watch();
32+
33+
EXPECT(stream.get_resume_token());
34+
}
35+
36+
// With options.
37+
{
38+
mongocxx::options::change_stream opts;
39+
40+
opts.batch_size(1);
41+
// ... other change stream options.
42+
43+
mongocxx::change_stream stream = client.watch(opts);
44+
45+
EXPECT(stream.get_resume_token());
46+
}
47+
48+
// With a pipeline.
49+
{
50+
mongocxx::pipeline pipeline;
51+
52+
pipeline.match(bsoncxx::from_json(R"({"operationType": "insert"})"));
53+
// ... other pipeline options.
54+
55+
mongocxx::change_stream stream = client.watch(pipeline);
56+
57+
EXPECT(stream.get_resume_token());
58+
}
59+
}
60+
// [Example]
61+
62+
} // namespace
63+
64+
RUNNER_REGISTER_COMPONENT_FOR_REPLICA() {
65+
example(mongocxx::client{mongocxx::uri{}});
66+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <bsoncxx/json.hpp>
16+
17+
#include <mongocxx/change_stream.hpp>
18+
#include <mongocxx/client.hpp>
19+
#include <mongocxx/options/change_stream.hpp>
20+
#include <mongocxx/uri.hpp>
21+
22+
#include <examples/api/db_lock.hh>
23+
#include <examples/api/runner.hh>
24+
#include <examples/macros.hh>
25+
26+
namespace {
27+
28+
// [Example]
29+
void example(mongocxx::collection coll) {
30+
// Basic usage.
31+
{
32+
mongocxx::change_stream stream = coll.watch();
33+
34+
EXPECT(stream.get_resume_token());
35+
}
36+
37+
// With options.
38+
{
39+
mongocxx::options::change_stream opts;
40+
41+
opts.batch_size(1);
42+
// ... other change stream options.
43+
44+
mongocxx::change_stream stream = coll.watch(opts);
45+
46+
EXPECT(stream.get_resume_token());
47+
}
48+
49+
// With a pipeline.
50+
{
51+
mongocxx::pipeline pipeline;
52+
53+
pipeline.match(bsoncxx::from_json(R"({"operationType": "insert"})"));
54+
// ... other pipeline options.
55+
56+
mongocxx::change_stream stream = coll.watch(pipeline);
57+
58+
EXPECT(stream.get_resume_token());
59+
}
60+
}
61+
// [Example]
62+
63+
} // namespace
64+
65+
RUNNER_REGISTER_COMPONENT_FOR_REPLICA() {
66+
mongocxx::client client{mongocxx::uri{}};
67+
68+
{
69+
db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR};
70+
71+
example(guard.get()["coll"]);
72+
}
73+
}

0 commit comments

Comments
 (0)