diff --git a/.evergreen/test.sh b/.evergreen/test.sh index ade6af0449..54d86a2f98 100755 --- a/.evergreen/test.sh +++ b/.evergreen/test.sh @@ -297,6 +297,9 @@ else # API version to example clients, so examples will fail when requireApiVersion # is true. if [[ -z "${MONGODB_API_VERSION:-}" ]]; then + # Avoid `[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.` errors on MacOS. + export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES + echo "Running examples..." if ! "${cmake_binary:?}" --build . --target run-examples --parallel 1 >|output.txt 2>&1; then # Only emit output on failure. diff --git a/docs/api/mongocxx/examples/clients.md b/docs/api/mongocxx/examples/clients.md new file mode 100644 index 0000000000..5fb3bf0d7d --- /dev/null +++ b/docs/api/mongocxx/examples/clients.md @@ -0,0 +1,83 @@ +# Create a Client + +## Single + +### Basic Usage + +@snippet api/mongocxx/examples/clients/create/single/basic.cpp Example + +### With a Custom URI + +@snippet api/mongocxx/examples/clients/create/single/with_uri.cpp Example + +### With Client Options + +#### Stable API Options + +@snippet api/mongocxx/examples/clients/create/single/options/stable_api.cpp Example + +#### TLS Options + +@snippet api/mongocxx/examples/clients/create/single/options/tls.cpp Example + +#### Automatic Encryption Options + +@snippet api/mongocxx/examples/clients/create/single/options/auto_encryption.cpp Example + +#### APM Options + +@snippet api/mongocxx/examples/clients/create/single/options/apm.cpp Example + +## Pool + +### Basic Usage + +@snippet api/mongocxx/examples/clients/create/pool/basic.cpp Example + +### With Client Options + +@snippet api/mongocxx/examples/clients/create/pool/options.cpp Example + +### Try Acquire + +@snippet api/mongocxx/examples/clients/create/pool/try_acquire.cpp Example + +# Use a Client + +## List Databases + +@snippet api/mongocxx/examples/clients/use/list_databases.cpp Example + +## List Databases With Options + +@snippet api/mongocxx/examples/clients/use/list_databases_with_options.cpp Example + +## List Database Names + +@snippet api/mongocxx/examples/clients/use/list_database_names.cpp Example + +## List Database Names With Options + +@snippet api/mongocxx/examples/clients/use/list_database_names_with_options.cpp Example + +# Error Handling + +## Invalid Client + +@snippet api/mongocxx/examples/clients/errors/invalid_client.cpp Example + +## Wait Queue Timeout + +@snippet api/mongocxx/examples/clients/errors/wait_queue_timeout.cpp Example + +## Invalid Stable API Options + +@snippet api/mongocxx/examples/clients/errors/stable_api.cpp Example + +## TLS Not Enabled + +@snippet api/mongocxx/examples/clients/errors/tls.cpp Example + +## Invalid Auto Encryption Options + +@snippet api/mongocxx/examples/clients/errors/auto_encryption.cpp Example diff --git a/docs/api/mongocxx/examples/collections.md b/docs/api/mongocxx/examples/collections.md new file mode 100644 index 0000000000..16dcece429 --- /dev/null +++ b/docs/api/mongocxx/examples/collections.md @@ -0,0 +1,113 @@ +# Obtain a Collection + +@snippet examples/api/mongocxx/examples/collections/obtain.cpp Example + +# Collection Operations + +## Drop a Collection + +@snippet examples/api/mongocxx/examples/collections/drop.cpp Example + +## Rename a Collection + +@snippet examples/api/mongocxx/examples/collections/rename.cpp Example + +## Set a Read Concern + +@snippet examples/api/mongocxx/examples/collections/rc.cpp Example + +## Set a Write Concern + +@snippet examples/api/mongocxx/examples/collections/wc.cpp Example + +## Set a Read Preference + +@snippet examples/api/mongocxx/examples/collections/rp.cpp Example + +# Index Operations + +## List Indexes + +@snippet examples/api/mongocxx/examples/collections/list_indexes.cpp Example + +## Create an Index + +@snippet examples/api/mongocxx/examples/collections/create_index.cpp Example + +## Create an Index With Options + +@snippet examples/api/mongocxx/examples/collections/create_index_with_options.cpp Example + +# Document Operations + +## Query the Number of Documents + +@snippet examples/api/mongocxx/examples/collections/count.cpp Example + +## Estimate the Number of Documents + +@snippet examples/api/mongocxx/examples/collections/estimate_count.cpp Example + +## Find a Document + +@snippet examples/api/mongocxx/examples/collections/find_one.cpp Example + +## Find Multiple Documents + +@snippet examples/api/mongocxx/examples/collections/find.cpp Example + +## Delete a Document + +@snippet examples/api/mongocxx/examples/collections/delete_one.cpp Example + +## Delete Many Documents + +@snippet examples/api/mongocxx/examples/collections/delete_many.cpp Example + +## Insert a Document + +@snippet examples/api/mongocxx/examples/collections/insert_one.cpp Example + +## Insert Many Documents + +@snippet examples/api/mongocxx/examples/collections/insert_many.cpp Example + +## Replace a Document + +@snippet examples/api/mongocxx/examples/collections/replace_one.cpp Example + +## Update a Document + +@snippet examples/api/mongocxx/examples/collections/update_one.cpp Example + +## Update Multiple Documents + +@snippet examples/api/mongocxx/examples/collections/update_many.cpp Example + +## Find and Delete a Document + +@snippet examples/api/mongocxx/examples/collections/find_one_and_delete.cpp Example + +## Find and Replace a Document + +@snippet examples/api/mongocxx/examples/collections/find_one_and_replace.cpp Example + +## Find and Update a Document + +@snippet examples/api/mongocxx/examples/collections/find_one_and_update.cpp Example + +## Find Distinct Values + +@snippet examples/api/mongocxx/examples/collections/distinct.cpp Example + +## Execute a Single Bulk Write Operation + +@snippet examples/api/mongocxx/examples/collections/write.cpp Example + +## Execute Multiple Bulk Write Operations + +@snippet examples/api/mongocxx/examples/collections/bulk_write.cpp Example + +## Execute an Aggregation Operation + +@snippet examples/api/mongocxx/examples/collections/aggregate.cpp Example diff --git a/docs/api/mongocxx/examples/databases.md b/docs/api/mongocxx/examples/databases.md new file mode 100644 index 0000000000..c1574d6e09 --- /dev/null +++ b/docs/api/mongocxx/examples/databases.md @@ -0,0 +1,43 @@ +# Obtain a Database + +@snippet examples/api/mongocxx/examples/databases/obtain.cpp Example + +# Database Operations + +## Drop a Database + +@snippet examples/api/mongocxx/examples/databases/drop.cpp Example + +## Run a Command + +@snippet examples/api/mongocxx/examples/databases/run_command.cpp Example + +## Set a Read Concern + +@snippet examples/api/mongocxx/examples/databases/rc.cpp Example + +## Set a Write Concern + +@snippet examples/api/mongocxx/examples/databases/wc.cpp Example + +# Collection Operations + +## Create a Collection + +@snippet examples/api/mongocxx/examples/databases/create_collection.cpp Example + +## Create a Collection With Options + +@snippet examples/api/mongocxx/examples/databases/create_collection_with_options.cpp Example + +## Query a Collection Exists + +@snippet examples/api/mongocxx/examples/databases/has_collection.cpp Example + +## List Collections in the Database + +@snippet examples/api/mongocxx/examples/databases/list_collections.cpp Example + +## List Collection Names in the Database + +@snippet examples/api/mongocxx/examples/databases/list_collection_names.cpp Example diff --git a/docs/api/mongocxx/examples/instance.md b/docs/api/mongocxx/examples/instance.md new file mode 100644 index 0000000000..12918aa9af --- /dev/null +++ b/docs/api/mongocxx/examples/instance.md @@ -0,0 +1,21 @@ +# Initialize the C++ Driver + +## Basic Usage + +@snippet api/mongocxx/examples/instance/basic_usage.cpp Example + +## With Static Lifetime + +@warning This pattern depends on an exit-time destructor with indeterminate order relative to other objects with static lifetime being destroyed. + +@snippet api/mongocxx/examples/instance/current.cpp Example + +# Errors + +## Instance Recreation + +@snippet api/mongocxx/examples/instance/recreation.cpp Example + +## Destroyed Instance + +@snippet api/mongocxx/examples/instance/destroyed.cpp Example diff --git a/docs/api/mongocxx/examples/logger.md b/docs/api/mongocxx/examples/logger.md new file mode 100644 index 0000000000..7c9ae49a43 --- /dev/null +++ b/docs/api/mongocxx/examples/logger.md @@ -0,0 +1,7 @@ +# Basic Usage + +@snippet api/mongocxx/examples/logger/basic_usage.cpp Example + +# Convert a Log Level to a String + +@snippet api/mongocxx/examples/logger/to_string.cpp Example diff --git a/docs/api/mongocxx/examples/operation_exceptions.md b/docs/api/mongocxx/examples/operation_exceptions.md new file mode 100644 index 0000000000..1c63ad8e0d --- /dev/null +++ b/docs/api/mongocxx/examples/operation_exceptions.md @@ -0,0 +1,11 @@ +# As a Regular Exception + +@warning The @ref mongocxx::server_error_category error category is overloaded ([CXX-834](https://jira.mongodb.org/browse/CXX-834)). The error code value may belong to the server, libmongoc, or libmongocrypt depending on the context. Use error code values with caution. + +@snippet examples/api/mongocxx/examples/operation_exceptions/regular.cpp Example + +# As an Operation Exception + +@note Using @ref mongocxx::exception for error handling is recommended for forward compatibility. ([CXX-2377](https://jira.mongodb.org/browse/CXX-2377)) + +@snippet examples/api/mongocxx/examples/operation_exceptions/operation.cpp Example diff --git a/docs/api/mongocxx/examples/uri.md b/docs/api/mongocxx/examples/uri.md new file mode 100644 index 0000000000..5898baea6d --- /dev/null +++ b/docs/api/mongocxx/examples/uri.md @@ -0,0 +1,33 @@ +# Create a URI + +## Basic Usage + +@snippet api/mongocxx/examples/uri/basic_usage.cpp Example + +## Default Value + +@snippet api/mongocxx/examples/uri/default_value.cpp Example + +# Query a URI + +## User Credentials + +@snippet api/mongocxx/examples/uri/userpass.cpp Example + +## List of Hosts + +@snippet api/mongocxx/examples/uri/hosts.cpp Example + +## Optional Options + +@snippet api/mongocxx/examples/uri/optional.cpp Example + +## All URI Options + +@snippet api/mongocxx/examples/uri/all_options.cpp Example + +# Error Handling + +## Invalid URI + +@snippet api/mongocxx/examples/uri/invalid.cpp Example diff --git a/examples/api/bsoncxx/examples/bson_errors/big_string.hh b/examples/api/bsoncxx/examples/bson_errors/big_string.hh index f97e4b6060..76566165e3 100644 --- a/examples/api/bsoncxx/examples/bson_errors/big_string.hh +++ b/examples/api/bsoncxx/examples/bson_errors/big_string.hh @@ -26,7 +26,8 @@ namespace examples { // Used to trigger builder append failure. struct big_string { // BSON_SIZE_MAX == 0x7FFFFFFF - std::size_t length{static_cast(std::numeric_limits::max())}; + // Leave some room for CDRIVER-5732. + std::size_t length{static_cast(std::numeric_limits::max() - 32u)}; // Allocate an UNINITIALIZED blob of data that will not be accessed due to length checks. // Leaving memory unitialized (rather than zero-init) should hopefully avoid slow and expensive diff --git a/examples/api/concern.cpp b/examples/api/concern.cpp new file mode 100644 index 0000000000..451004ea91 --- /dev/null +++ b/examples/api/concern.cpp @@ -0,0 +1,46 @@ +// 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 + +// Preferred default for most operations. +mongocxx::collection set_rw_concern_majority(mongocxx::collection coll) { + coll.read_concern(rc_majority()); + coll.write_concern(wc_majority()); + return coll; +} + +// Preferred default for most operations. +mongocxx::database set_rw_concern_majority(mongocxx::database db) { + db.read_concern(rc_majority()); + db.write_concern(wc_majority()); + return db; +} + +mongocxx::read_concern rc_majority() { + mongocxx::read_concern rc; + rc.acknowledge_level(mongocxx::read_concern::level::k_majority); + return rc; +} + +mongocxx::write_concern wc_majority() { + mongocxx::write_concern wc; + wc.acknowledge_level(mongocxx::write_concern::level::k_majority); + return wc; +} diff --git a/examples/api/concern.hh b/examples/api/concern.hh new file mode 100644 index 0000000000..f0c3a20186 --- /dev/null +++ b/examples/api/concern.hh @@ -0,0 +1,27 @@ +// 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 +#include +#include +#include + +// Preferred default for most operations. +mongocxx::collection set_rw_concern_majority(mongocxx::collection coll); +mongocxx::database set_rw_concern_majority(mongocxx::database db); + +mongocxx::read_concern rc_majority(); +mongocxx::write_concern wc_majority(); diff --git a/examples/api/db_lock.cpp b/examples/api/db_lock.cpp new file mode 100644 index 0000000000..dbae316b63 --- /dev/null +++ b/examples/api/db_lock.cpp @@ -0,0 +1,49 @@ +// 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 + +namespace { + +std::unordered_map db_locks; +std::mutex db_locks_mut; + +} // namespace + +db_lock::~db_lock() { + this->get().drop(); +} + +db_lock::db_lock(mongocxx::client& client, std::string name) : _client_ptr(&client), _name(name) { + ((void)std::lock_guard{db_locks_mut}, + _lock = std::unique_lock(db_locks[name])); + + this->get().drop(); +} + +mongocxx::database db_lock::get() const& { + EXPECT(_client_ptr); + + return _client_ptr->database(_name); +} diff --git a/examples/api/db_lock.hh b/examples/api/db_lock.hh new file mode 100644 index 0000000000..d37beb21c0 --- /dev/null +++ b/examples/api/db_lock.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 +#include + +#include +#include + +// Ensure exclusive access to the associated database. +// For convenience, drops the database on both lock and unlock. +class db_lock { + private: + mongocxx::client* _client_ptr; + std::string _name; + std::unique_lock _lock; + + public: + ~db_lock(); + + db_lock(db_lock&&) = delete; + db_lock& operator=(db_lock&&) = delete; + db_lock(const db_lock&) = delete; + db_lock& operator=(const db_lock&) = delete; + + db_lock(mongocxx::client& client, std::string name); + + mongocxx::database get() const&; +}; diff --git a/examples/api/mongocxx/examples/clients/create/pool/basic.cpp b/examples/api/mongocxx/examples/clients/create/pool/basic.cpp new file mode 100644 index 0000000000..a43d256171 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/pool/basic.cpp @@ -0,0 +1,59 @@ +// 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 + +namespace { + +// [Example] +void example() { + { + mongocxx::pool pool; + + mongocxx::pool::entry entry = pool.acquire(); + + EXPECT(entry); + + mongocxx::client& client = *entry; + + EXPECT(client); + EXPECT(client.uri().to_string() == mongocxx::uri::k_default_uri); + } + + { + mongocxx::uri uri{"mongodb://localhost:27017/?appName=example"}; + mongocxx::pool pool{uri}; + + mongocxx::pool::entry entry = pool.acquire(); + + EXPECT(entry); + + mongocxx::client& client = *entry; + + EXPECT(client); + EXPECT(client.uri().to_string() == uri.to_string()); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/create/pool/options.cpp b/examples/api/mongocxx/examples/clients/create/pool/options.cpp new file mode 100644 index 0000000000..a978f226a1 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/pool/options.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::options::client client_opts; + + // ... set client options. + + mongocxx::uri uri; + mongocxx::pool pool{uri, mongocxx::options::pool{client_opts}}; + + mongocxx::pool::entry entry = pool.acquire(); + + EXPECT(entry); + + mongocxx::client& client = *entry; + + EXPECT(client); + EXPECT(client.uri().to_string() == mongocxx::uri::k_default_uri); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/create/pool/try_acquire.cpp b/examples/api/mongocxx/examples/clients/create/pool/try_acquire.cpp new file mode 100644 index 0000000000..1c32f7feb6 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/pool/try_acquire.cpp @@ -0,0 +1,55 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::uri uri{"mongodb://localhost:27017/?maxPoolSize=1&waitQueueTimeoutMS=1"}; + mongocxx::pool pool{uri}; + + auto entry_opt = pool.try_acquire(); + + EXPECT(entry_opt); + EXPECT(*entry_opt); + + { + mongocxx::pool::entry hold = std::move(*entry_opt); + + EXPECT(hold); + + entry_opt = pool.try_acquire(); + + EXPECT(!entry_opt); + } + + entry_opt = pool.try_acquire(); + + EXPECT(entry_opt); + EXPECT(*entry_opt); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/create/single/basic.cpp b/examples/api/mongocxx/examples/clients/create/single/basic.cpp new file mode 100644 index 0000000000..f9dd631946 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/basic.cpp @@ -0,0 +1,44 @@ +// 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 + +namespace { + +// [Example] +void example() { + { + mongocxx::client client; + + EXPECT(!client); + } + + { + mongocxx::client client{mongocxx::uri{}}; + + EXPECT(client); + EXPECT(client.uri().to_string() == mongocxx::uri::k_default_uri); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/create/single/options/apm.cpp b/examples/api/mongocxx/examples/clients/create/single/options/apm.cpp new file mode 100644 index 0000000000..033b179c55 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/options/apm.cpp @@ -0,0 +1,56 @@ +// 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 + +namespace { + +// [Example] +void on_command_started_callback(const mongocxx::events::command_started_event& event); + +void example() { + mongocxx::options::apm apm_opts; + + apm_opts.on_command_started(&on_command_started_callback); + // ... other APM options. + + mongocxx::options::client client_opts; + client_opts.apm_opts(apm_opts); + + mongocxx::client client{mongocxx::uri{}, client_opts}; + + EXPECT(client); +} +// [Example] + +void on_command_started_callback(const mongocxx::events::command_started_event& event) { + (void)event; +} + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/create/single/options/auto_encryption.cpp b/examples/api/mongocxx/examples/clients/create/single/options/auto_encryption.cpp new file mode 100644 index 0000000000..016799255a --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/options/auto_encryption.cpp @@ -0,0 +1,73 @@ +// 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 +#include + +#include +#include + +namespace { + +// [Example] +void example(bsoncxx::document::view kms_providers) { + mongocxx::options::auto_encryption auto_encryption_opts; + + auto_encryption_opts.key_vault_namespace({"keyvault", "datakeys"}); + auto_encryption_opts.kms_providers(kms_providers); + // ... other automatic encryption options. + + mongocxx::options::client client_opts; + client_opts.auto_encryption_opts(auto_encryption_opts); + + mongocxx::uri uri; + mongocxx::client client{uri, client_opts}; + + EXPECT(client); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + using bsoncxx::builder::basic::kvp; + using bsoncxx::builder::basic::make_document; + + try { + std::uint8_t local_key[96]{}; + + example(make_document(kvp( + "local", + make_document(kvp( + "key", + bsoncxx::types::b_binary{bsoncxx::binary_sub_type::k_binary, 96, local_key}))))); + } catch (const mongocxx::exception& ex) { + if (std::strstr(ex.what(), "ENABLE_CLIENT_SIDE_ENCRYPTION") != nullptr) { + // Library may not be configured with TLS/SSL support enabled. + } else { + throw; + } + } +} diff --git a/examples/api/mongocxx/examples/clients/create/single/options/stable_api.cpp b/examples/api/mongocxx/examples/clients/create/single/options/stable_api.cpp new file mode 100644 index 0000000000..17bf380547 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/options/stable_api.cpp @@ -0,0 +1,57 @@ +// 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 + +namespace { + +// [Example] +mongocxx::client example() { + mongocxx::options::server_api server_api_opts{ + mongocxx::options::server_api::version::k_version_1}; + + server_api_opts.strict(true); + // ... other Stable API options. + + mongocxx::options::client client_opts; + + client_opts.server_api_opts(server_api_opts); + + mongocxx::uri uri; + mongocxx::client client{uri, client_opts}; + + EXPECT(client); + EXPECT(client.uri().to_string() == mongocxx::uri::k_default_uri); + + return client; +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + auto client = example(); + + auto reply = client["admin"].run_command(bsoncxx::from_json(R"({"ping": 1})")); + + EXPECT(reply["ok"] && reply["ok"].get_double().value == 1.0); +} diff --git a/examples/api/mongocxx/examples/clients/create/single/options/tls.cpp b/examples/api/mongocxx/examples/clients/create/single/options/tls.cpp new file mode 100644 index 0000000000..882bd6cb3c --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/options/tls.cpp @@ -0,0 +1,68 @@ +// 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 { + +// [Example] +mongocxx::client example() { + mongocxx::options::tls tls_opts; + + // ... set TLS options. + + mongocxx::options::client client_opts; + client_opts.tls_opts(tls_opts); + + mongocxx::uri uri{"mongodb://bob:pwd123@localhost:27017/?tls=true"}; + mongocxx::client client{uri, client_opts}; + + EXPECT(client); + EXPECT(client.uri().to_string() == uri.to_string()); + + return client; +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + try { + auto client = example(); + + auto reply = client["admin"].run_command(bsoncxx::from_json(R"({"ping": 1})")); + + EXPECT(reply["ok"] && reply["ok"].get_double().value == 1.0); + } catch (const mongocxx::exception& ex) { + if (ex.code() == mongocxx::error_code::k_ssl_not_supported) { + // Library may not be configured with TLS/SSL support enabled. + } else if (std::strstr(ex.what(), "suitable server") != nullptr) { + // Authentication may not be supported by the live server. + } else { + throw; + } + } +} diff --git a/examples/api/mongocxx/examples/clients/create/single/with_uri.cpp b/examples/api/mongocxx/examples/clients/create/single/with_uri.cpp new file mode 100644 index 0000000000..363397004f --- /dev/null +++ b/examples/api/mongocxx/examples/clients/create/single/with_uri.cpp @@ -0,0 +1,37 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::uri uri{"mongodb://localhost:27017/?appName=example"}; + mongocxx::client client{uri}; + + EXPECT(client); + EXPECT(client.uri().to_string() == uri.to_string()); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/errors/auto_encryption.cpp b/examples/api/mongocxx/examples/clients/errors/auto_encryption.cpp new file mode 100644 index 0000000000..cf237289e6 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/errors/auto_encryption.cpp @@ -0,0 +1,99 @@ +// 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 +#include +#include + +#include +#include + +namespace { + +// [Example] +void example() { + // Missing keyvault namespace. + try { + mongocxx::client client{mongocxx::uri{}, + mongocxx::options::client{}.auto_encryption_opts( + mongocxx::options::auto_encryption{})}; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + // CXX-834: libmongoc error code. + EXPECT(ex.code().category() == mongocxx::server_error_category()); + EXPECT(ex.code().value() == 58); // MONGOC_ERROR_CLIENT_INVALID_ENCRYPTION_ARG + } + + // Invalid KMS providers. + try { + mongocxx::client client{ + mongocxx::uri{}, + mongocxx::options::client{}.auto_encryption_opts( + mongocxx::options::auto_encryption{} + .key_vault_namespace({"keyvault", "datakeys"}) + .kms_providers(bsoncxx::from_json(R"({"invalid": 1})")))}; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + // CXX-834: libmongocrypt error code. + EXPECT(ex.code().category() == mongocxx::server_error_category()); + EXPECT(ex.code().value() == 1); // MONGOCRYPT_GENERIC_ERROR_CODE + } + + // Incompatible options. + try { + mongocxx::client client{ + mongocxx::uri{}, + mongocxx::options::client{}.auto_encryption_opts( + mongocxx::options::auto_encryption{}.key_vault_client(nullptr).key_vault_pool( + nullptr))}; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + using bsoncxx::builder::basic::sub_document; + + try { + (void)mongocxx::client{ + mongocxx::uri{}, + mongocxx::options::client{}.auto_encryption_opts(mongocxx::options::auto_encryption{})}; + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + if (std::strstr(ex.what(), "ENABLE_CLIENT_SIDE_ENCRYPTION") != nullptr) { + // Library may not be configured with TLS/SSL support enabled. + } else { + example(); + } + } +} diff --git a/examples/api/mongocxx/examples/clients/errors/invalid_client.cpp b/examples/api/mongocxx/examples/clients/errors/invalid_client.cpp new file mode 100644 index 0000000000..73207997b1 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/errors/invalid_client.cpp @@ -0,0 +1,45 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::client client; + + EXPECT(!client); + + try { + mongocxx::uri uri = client.uri(); // DO NOT DO THIS. Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_client_object); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/errors/stable_api.cpp b/examples/api/mongocxx/examples/clients/errors/stable_api.cpp new file mode 100644 index 0000000000..c32deff377 --- /dev/null +++ b/examples/api/mongocxx/examples/clients/errors/stable_api.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example() { + try { + mongocxx::options::server_api::version version = + mongocxx::options::server_api::version_from_string("0"); // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter); + } + + try { + std::string version = mongocxx::options::server_api::version_to_string( + static_cast(1)); // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/errors/tls.cpp b/examples/api/mongocxx/examples/clients/errors/tls.cpp new file mode 100644 index 0000000000..3518975f8a --- /dev/null +++ b/examples/api/mongocxx/examples/clients/errors/tls.cpp @@ -0,0 +1,52 @@ +// 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 + +namespace { + +// [Example] +void example() { + try { + mongocxx::client client{ + mongocxx::uri{}, + mongocxx::options::client{}.tls_opts(mongocxx::options::tls{})}; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT( + // When TLS/SSL is enabled for both mongocxx and libmongoc. + ex.code() == mongocxx::error_code::k_invalid_parameter || + + // When TLS/SSL is not enabled for either mongocxx or libmongoc. + ex.code() == mongocxx::error_code::k_ssl_not_supported || + + false); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/errors/wait_queue_timeout.cpp b/examples/api/mongocxx/examples/clients/errors/wait_queue_timeout.cpp new file mode 100644 index 0000000000..c2bcab3f9a --- /dev/null +++ b/examples/api/mongocxx/examples/clients/errors/wait_queue_timeout.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example() { + try { + mongocxx::pool pool{ + mongocxx::uri{"mongodb://localhost:27017/?maxPoolSize=1&waitQueueTimeoutMS=1"}}; + + mongocxx::pool::entry hold = pool.acquire(); + + EXPECT(hold); + + mongocxx::pool::entry entry = pool.acquire(); // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_pool_wait_queue_timeout); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/clients/use/list_database_names.cpp b/examples/api/mongocxx/examples/clients/use/list_database_names.cpp new file mode 100644 index 0000000000..b78f55c4cb --- /dev/null +++ b/examples/api/mongocxx/examples/clients/use/list_database_names.cpp @@ -0,0 +1,44 @@ +// 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 +#include + +namespace { + +// [Example] +void example(mongocxx::client client) { + std::vector names = client.list_database_names(); + + EXPECT(std::count(names.begin(), names.end(), "admin") == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(mongocxx::client{mongocxx::uri{}}); +} diff --git a/examples/api/mongocxx/examples/clients/use/list_database_names_with_options.cpp b/examples/api/mongocxx/examples/clients/use/list_database_names_with_options.cpp new file mode 100644 index 0000000000..c95c76b61c --- /dev/null +++ b/examples/api/mongocxx/examples/clients/use/list_database_names_with_options.cpp @@ -0,0 +1,45 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::client client) { + auto opts = bsoncxx::from_json(R"({"authorizedDatabases": true})"); + // ... other listDatabases options. + + std::vector names = client.list_database_names(opts.view()); + + EXPECT(std::count(names.begin(), names.end(), "admin") == 0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(mongocxx::client{mongocxx::uri{}}); +} diff --git a/examples/api/mongocxx/examples/clients/use/list_databases.cpp b/examples/api/mongocxx/examples/clients/use/list_databases.cpp new file mode 100644 index 0000000000..f714eec97c --- /dev/null +++ b/examples/api/mongocxx/examples/clients/use/list_databases.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::client client) { + mongocxx::cursor databases = client.list_databases(); + + int count = 0; + + for (bsoncxx::document::view doc : databases) { + EXPECT(doc["name"]); + EXPECT(doc["sizeOnDisk"]); + EXPECT(doc["empty"]); + + if (doc["name"].get_string().value.compare("admin") == 0) { + ++count; + } + } + + EXPECT(count == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(mongocxx::client{mongocxx::uri{}}); +} diff --git a/examples/api/mongocxx/examples/clients/use/list_databases_with_options.cpp b/examples/api/mongocxx/examples/clients/use/list_databases_with_options.cpp new file mode 100644 index 0000000000..032e90d2af --- /dev/null +++ b/examples/api/mongocxx/examples/clients/use/list_databases_with_options.cpp @@ -0,0 +1,55 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::client client) { + auto opts = bsoncxx::from_json(R"({"nameOnly": true})"); + // ... other listDatabases options. + + mongocxx::cursor databases = client.list_databases(opts.view()); + + int count = 0; + + for (bsoncxx::document::view doc : databases) { + EXPECT(doc["name"]); + EXPECT(!doc["sizeOnDisk"]); + EXPECT(!doc["empty"]); + + if (doc["name"].get_string().value.compare("admin") == 0) { + ++count; + } + } + + EXPECT(count == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + example(mongocxx::client{mongocxx::uri{}}); +} diff --git a/examples/api/mongocxx/examples/collections/aggregate.cpp b/examples/api/mongocxx/examples/collections/aggregate.cpp new file mode 100644 index 0000000000..a18aa39395 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/aggregate.cpp @@ -0,0 +1,92 @@ +// 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 +#include +#include + +#include +#include +#include +#include + +namespace { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + { + mongocxx::pipeline pipeline; + + pipeline.match(bsoncxx::from_json(R"({"x": 1})")); + pipeline.sample(1); + // ... other pipeline stages. + + mongocxx::cursor cursor = coll.aggregate(pipeline); + + auto has_field_x = [](bsoncxx::document::view doc) -> bool { + return doc.find("x") != doc.end(); + }; + + EXPECT(std::count_if(cursor.begin(), cursor.end(), has_field_x) == 1); + } + + // With options. + { + mongocxx::options::aggregate opts; + + // ... set aggregate options. + + mongocxx::cursor cursor = coll.aggregate(mongocxx::pipeline{}, opts); + + EXPECT(std::distance(cursor.begin(), cursor.end()) == 2); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/bulk_write.cpp b/examples/api/mongocxx/examples/collections/bulk_write.cpp new file mode 100644 index 0000000000..7baee8cfeb --- /dev/null +++ b/examples/api/mongocxx/examples/collections/bulk_write.cpp @@ -0,0 +1,70 @@ +// 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 +#include +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})")) == 0); + + mongocxx::model::insert_one insert{bsoncxx::from_json(R"({"x": 10})")}; + mongocxx::model::update_one update{bsoncxx::from_json(R"({"x": {"$exists": 1}})"), + bsoncxx::from_json(R"({"$set": {"x": 20}})")}; + + mongocxx::bulk_write bulk_write = coll.create_bulk_write(); + + bulk_write.append(insert); + bulk_write.append(update); + // ... other bulk write operations. + + auto result_opt = bulk_write.execute(); + + EXPECT(result_opt); + + mongocxx::result::bulk_write& result = *result_opt; + + EXPECT(result.inserted_count() == 1); + EXPECT(result.modified_count() == 1); + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 20})")) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get().create_collection("coll"))); + } +} diff --git a/examples/api/mongocxx/examples/collections/bulk_write_with_options.cpp b/examples/api/mongocxx/examples/collections/bulk_write_with_options.cpp new file mode 100644 index 0000000000..f68bfd19ee --- /dev/null +++ b/examples/api/mongocxx/examples/collections/bulk_write_with_options.cpp @@ -0,0 +1,76 @@ +// 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 +#include +#include + +#include +#include +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})")) == 0); + + mongocxx::options::bulk_write opts; + + opts.ordered(true); + // ... other bulk write options. + + auto result_opt = + coll.create_bulk_write(opts) + .append(mongocxx::model::insert_one{bsoncxx::from_json(R"({"x": 10})")}) + .append(mongocxx::model::update_one{bsoncxx::from_json(R"({"x": {"$exists": 1}})"), + bsoncxx::from_json(R"({"$set": {"x": 20}})")}) + .execute(); + + EXPECT(result_opt); + + mongocxx::result::bulk_write& result = *result_opt; + + EXPECT(result.inserted_count() == 1); + EXPECT(result.modified_count() == 1); + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 20})")) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/count.cpp b/examples/api/mongocxx/examples/collections/count.cpp new file mode 100644 index 0000000000..83e45f00be --- /dev/null +++ b/examples/api/mongocxx/examples/collections/count.cpp @@ -0,0 +1,78 @@ +// 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 { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + { + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})")) == 3); + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$gt": 1}})")) == 2); + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$gt": 2}})")) == 1); + } + + // With options. + { + mongocxx::options::count opts; + + opts.limit(1); + // ... other count options. + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})"), opts) == 1); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/create_index.cpp b/examples/api/mongocxx/examples/collections/create_index.cpp new file mode 100644 index 0000000000..a25c221e21 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/create_index.cpp @@ -0,0 +1,64 @@ +// 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 +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + bsoncxx::document::value result = coll.create_index(bsoncxx::from_json(R"({"key": 1})")); + + EXPECT(result["name"]); + EXPECT(result["name"].get_string().value.compare("key_1") == 0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + auto count_indexes = [&coll] { + auto cursor = coll.list_indexes(); + + return std::distance(cursor.begin(), cursor.end()); + }; + + EXPECT(count_indexes() == 1); // _id + + example(coll); + + EXPECT(count_indexes() == 2); // _id, key_1 + } +} diff --git a/examples/api/mongocxx/examples/collections/create_index_with_options.cpp b/examples/api/mongocxx/examples/collections/create_index_with_options.cpp new file mode 100644 index 0000000000..a782b09dba --- /dev/null +++ b/examples/api/mongocxx/examples/collections/create_index_with_options.cpp @@ -0,0 +1,88 @@ +// 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 +#include + +#include +#include +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + // Index options. + { + auto opts = bsoncxx::from_json(R"({"name": "custom_name", "unique": true})"); + // ... other index options. + + bsoncxx::document::value result = + coll.create_index(bsoncxx::from_json(R"({"key_a": 1})"), opts.view()); + + EXPECT(result["name"]); + EXPECT(result["name"].get_string().value.compare("custom_name") == 0); + } + + // Create index options. + { + auto opts = bsoncxx::builder::basic::make_document(); + + mongocxx::options::index_view create_opts; + + // ... set create index options. + + bsoncxx::document::value result = + coll.create_index(bsoncxx::from_json(R"({"key_b": 1})"), opts.view()); + + EXPECT(result["name"]); + EXPECT(result["name"].get_string().value.compare("key_b_1") == 0); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + example(db.create_collection("coll")); + + for (auto doc : db["coll"].list_indexes()) { + EXPECT(doc["name"]); + + if (doc["name"].get_string().value.compare("custom_name") == 0) { + EXPECT(doc["unique"]); + EXPECT(doc["unique"].get_bool().value == true); + } + } + } +} diff --git a/examples/api/mongocxx/examples/collections/delete_many.cpp b/examples/api/mongocxx/examples/collections/delete_many.cpp new file mode 100644 index 0000000000..7c594580d4 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/delete_many.cpp @@ -0,0 +1,98 @@ +// 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 { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto x3 = bsoncxx::from_json(R"({"x": 3})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x1.view()) == 1); + EXPECT(coll.count_documents(x2.view()) == 1); + EXPECT(coll.count_documents(x3.view()) == 1); + + auto result_opt = coll.delete_many(bsoncxx::from_json(R"({"x": {"$gt": 1}})")); + + EXPECT(result_opt); + + mongocxx::result::delete_result& result = *result_opt; + + EXPECT(result.deleted_count() == 2); + EXPECT(result.result().deleted_count() == 2); + + EXPECT(coll.count_documents(x1.view()) == 1); + EXPECT(coll.count_documents(x2.view()) == 0); + EXPECT(coll.count_documents(x3.view()) == 0); + } + + // With options. + { + EXPECT(coll.count_documents(x1.view()) == 1); + + mongocxx::options::delete_options opts; + + // ... set delete options. + + EXPECT(coll.delete_many(bsoncxx::from_json(R"({"x": {"$exists": 1}})"), opts)); + + EXPECT(coll.count_documents(x1.view()) == 0); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/delete_one.cpp b/examples/api/mongocxx/examples/collections/delete_one.cpp new file mode 100644 index 0000000000..f89039a003 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/delete_one.cpp @@ -0,0 +1,96 @@ +// 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 { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto x3 = bsoncxx::from_json(R"({"x": 3})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x1.view()) == 1); + + auto result_opt = coll.delete_one(x1.view()); + + EXPECT(result_opt); + + mongocxx::result::delete_result& result = *result_opt; + + EXPECT(result.deleted_count() == 1); + EXPECT(result.result().deleted_count() == 1); + + EXPECT(coll.count_documents(x1.view()) == 0); + } + + // With options. + { + EXPECT(coll.count_documents(x2.view()) == 1); + + mongocxx::options::delete_options opts; + + // ... set delete options. + + EXPECT(coll.delete_one(x2.view(), opts)); + + EXPECT(coll.count_documents(x2.view()) == 0); + } + + EXPECT(coll.count_documents(x3.view()) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/distinct.cpp b/examples/api/mongocxx/examples/collections/distinct.cpp new file mode 100644 index 0000000000..b6ef69e445 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/distinct.cpp @@ -0,0 +1,98 @@ +// 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 +#include +#include + +#include +#include +#include +#include + +namespace { + +// [Example] +// [ +// {"x": 1, "flag": 1}, +// {"x": 2, "flag": 1}, +// {"x": 3, "flag": 0}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + { + mongocxx::cursor cursor = coll.distinct("x", bsoncxx::from_json(R"({"flag": 1})")); + + std::vector docs{cursor.begin(), cursor.end()}; + + EXPECT(docs.size() == 1u); + + auto doc = docs[0].view(); + + EXPECT(doc["values"]); + EXPECT(doc["values"].type() == bsoncxx::type::k_array); + + auto arr = doc["values"].get_array().value; + + EXPECT(std::distance(arr.begin(), arr.end()) == 2); + + EXPECT(arr[0].get_int32().value == 1); + EXPECT(arr[1].get_int32().value == 2); + } + + // With options. + { + mongocxx::options::distinct opts; + + // ... set distinct options. + + mongocxx::cursor cursor = coll.distinct("x", bsoncxx::from_json(R"({"flag": 1})"), opts); + + EXPECT(std::distance(cursor.begin(), cursor.end()) == 1); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "flag": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "flag": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "flag": 0})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/drop.cpp b/examples/api/mongocxx/examples/collections/drop.cpp new file mode 100644 index 0000000000..1ea5a24fe0 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/drop.cpp @@ -0,0 +1,53 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + mongocxx::collection coll = db["coll"]; + + EXPECT(db.has_collection("coll")); + + coll.drop(); + + EXPECT(!db.has_collection("coll")); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + (void)db.create_collection("coll"); + + example(db); + } +} diff --git a/examples/api/mongocxx/examples/collections/estimate_count.cpp b/examples/api/mongocxx/examples/collections/estimate_count.cpp new file mode 100644 index 0000000000..43bc493280 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/estimate_count.cpp @@ -0,0 +1,73 @@ +// 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 +#include + +namespace { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + EXPECT(coll.estimated_document_count() == 3); + + // With options. + { + mongocxx::options::estimated_document_count opts; + + // ... set estimated count options. + + EXPECT(coll.estimated_document_count(opts) == 3); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/find.cpp b/examples/api/mongocxx/examples/collections/find.cpp new file mode 100644 index 0000000000..a9f69b48b4 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/find.cpp @@ -0,0 +1,104 @@ +// 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 +#include +#include +#include + +namespace { + +// [Example]A +// [ +// {"x": 1, "found": true}, +// {"x": 2, "found": false}, +// {"x": 3, "found": true}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + { + auto filter = bsoncxx::from_json(R"({"found": true})"); + + mongocxx::cursor cursor = coll.find(filter.view()); + + int count = 0; + + for (bsoncxx::document::view doc : cursor) { + EXPECT(doc["_id"]); + + EXPECT(doc["x"]); + EXPECT(doc["x"].get_int32().value != 2); + + ++count; + } + + EXPECT(count == 2); + } + + // With options. + { + mongocxx::options::find opts; + + opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})")); + opts.sort(bsoncxx::from_json(R"({"x": 1})")); + // ... other find options. + + mongocxx::cursor cursor = coll.find(bsoncxx::builder::basic::make_document(), opts); + + std::vector docs{cursor.begin(), cursor.end()}; + + EXPECT(docs.size() == 3u); + + EXPECT(docs[0] == bsoncxx::from_json(R"({"x": 1})")); + EXPECT(docs[1] == bsoncxx::from_json(R"({"x": 2})")); + EXPECT(docs[2] == bsoncxx::from_json(R"({"x": 3})")); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "found": true})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "found": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "found": true})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/find_one.cpp b/examples/api/mongocxx/examples/collections/find_one.cpp new file mode 100644 index 0000000000..136b3803e1 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/find_one.cpp @@ -0,0 +1,91 @@ +// 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 { + +// [Example] +// [ +// {"x": 1, "found": false}, +// {"x": 2, "found": true}, +// {"x": 3, "found": false}, +// ] +void example(mongocxx::collection coll) { + // Basic usage. + { + auto filter = bsoncxx::from_json(R"({"found": true})"); + + auto result_opt = coll.find_one(filter.view()); + + EXPECT(result_opt); + + bsoncxx::document::view doc = result_opt->view(); + + EXPECT(doc["_id"]); + + EXPECT(doc["x"]); + EXPECT(doc["x"].get_int32().value == 2); + } + + // With options. + { + mongocxx::options::find opts; + + opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})")); + opts.sort(bsoncxx::from_json(R"({"x": 1})")); + // ... other find options. + + auto result_opt = coll.find_one(bsoncxx::builder::basic::make_document(), opts); + + EXPECT(result_opt); + EXPECT(*result_opt == bsoncxx::from_json(R"({"x": 1})")); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "found": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "found": true})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "found": false})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/find_one_and_delete.cpp b/examples/api/mongocxx/examples/collections/find_one_and_delete.cpp new file mode 100644 index 0000000000..ac7701396a --- /dev/null +++ b/examples/api/mongocxx/examples/collections/find_one_and_delete.cpp @@ -0,0 +1,104 @@ +// 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 { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + auto has_field_x = bsoncxx::from_json(R"({"x": {"$exists": true}})"); + + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto x3 = bsoncxx::from_json(R"({"x": 3})"); + + // Basic usage. + { + EXPECT(coll.count_documents(has_field_x.view()) == 3); + + auto result_opt = coll.find_one_and_delete(x2.view()); + + EXPECT(result_opt); + + bsoncxx::document::view doc = result_opt->view(); + + EXPECT(doc["_id"]); + + EXPECT(doc["x"]); + EXPECT(doc["x"].get_int32().value == 2); + + EXPECT(coll.count_documents(has_field_x.view()) == 2); + } + + // With options. + { + EXPECT(coll.count_documents(has_field_x.view()) == 2); + + mongocxx::options::find_one_and_delete opts; + + opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})")); + // ... other findOneAndDelete options. + + auto result_opt = coll.find_one_and_delete(x3.view(), opts); + + EXPECT(result_opt); + EXPECT(*result_opt == x3); + + EXPECT(coll.count_documents(has_field_x.view()) == 1); + } + + EXPECT(coll.count_documents(x1.view()) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/find_one_and_replace.cpp b/examples/api/mongocxx/examples/collections/find_one_and_replace.cpp new file mode 100644 index 0000000000..ec7b861db5 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/find_one_and_replace.cpp @@ -0,0 +1,103 @@ +// 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 { + +// [Example] +// [ +// {"x": 1}, +// {"x": 2}, +// {"x": 3}, +// ] +void example(mongocxx::collection coll) { + auto x0 = bsoncxx::from_json(R"({"x": 0})"); + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto x3 = bsoncxx::from_json(R"({"x": 3})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x0.view()) == 0); + + auto result_opt = coll.find_one_and_replace(x2.view(), x0.view()); + + EXPECT(result_opt); + + bsoncxx::document::view doc = result_opt->view(); + + EXPECT(doc["_id"]); + + EXPECT(doc["x"]); + EXPECT(doc["x"].get_int32().value == 2); + + EXPECT(coll.count_documents(x0.view()) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(x0.view()) == 1); + + mongocxx::options::find_one_and_replace opts; + + opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})")); + // ... other findOneAndReplace options. + + auto result_opt = coll.find_one_and_replace(x3.view(), x0.view(), opts); + + EXPECT(result_opt); + EXPECT(*result_opt == x3); + + EXPECT(coll.count_documents(x0.view()) == 2); + } + + EXPECT(coll.count_documents(x1.view()) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/find_one_and_update.cpp b/examples/api/mongocxx/examples/collections/find_one_and_update.cpp new file mode 100644 index 0000000000..2593257c5e --- /dev/null +++ b/examples/api/mongocxx/examples/collections/find_one_and_update.cpp @@ -0,0 +1,110 @@ +// 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 { + +// [Example] +// [ +// {"x": 1, "updated": false}, +// {"x": 2, "updated": false}, +// {"x": 3, "updated": false}, +// ] +void example(mongocxx::collection coll) { + auto updated = bsoncxx::from_json(R"({"updated": true})"); + + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto x3 = bsoncxx::from_json(R"({"x": 3})"); + + auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x2.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 0); + + auto result_opt = coll.find_one_and_update(x2.view(), update.view()); + + EXPECT(result_opt); + + bsoncxx::document::view doc = result_opt->view(); + + EXPECT(doc["_id"]); + + EXPECT(doc["x"]); + EXPECT(doc["x"].get_int32().value == 2); + + EXPECT(coll.count_documents(x2.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(x3.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 1); + + mongocxx::options::find_one_and_update opts; + + opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})")); + // ... other findOneAndReplace options. + + auto result_opt = coll.find_one_and_update(x3.view(), update.view(), opts); + + EXPECT(result_opt); + EXPECT(*result_opt == x3); + + EXPECT(coll.count_documents(x3.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 2); + } + + EXPECT(coll.count_documents(x1.view()) == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "updated": false})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/insert_many.cpp b/examples/api/mongocxx/examples/collections/insert_many.cpp new file mode 100644 index 0000000000..265039d671 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/insert_many.cpp @@ -0,0 +1,93 @@ +// 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 +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + auto y1 = bsoncxx::from_json(R"({"y": 1})"); + auto y2 = bsoncxx::from_json(R"({"y": 2})"); + auto z1 = bsoncxx::from_json(R"({"z": 1})"); + auto z2 = bsoncxx::from_json(R"({"z": 2})"); + + // Basic usage. + { + std::vector docs = {x1.view(), x2.view()}; + + auto result_opt = coll.insert_many(docs); + + EXPECT(result_opt); + + mongocxx::result::insert_many& result = *result_opt; + + EXPECT(result.inserted_count() == 2); + EXPECT(result.result().inserted_count() == 2); + } + + // Iterators. + { + bsoncxx::document::view docs[] = {y1.view(), y2.view()}; + + auto result_opt = coll.insert_many(std::begin(docs), std::end(docs)); + + EXPECT(result_opt); + + mongocxx::result::insert_many& result = *result_opt; + + EXPECT(result.inserted_count() == 2); + EXPECT(result.result().inserted_count() == 2); + } + + // With options. + { + std::array docs = {z1.view(), z2.view()}; + + mongocxx::options::insert opts; + + // ... set insert options. + + EXPECT(coll.insert_many(docs, opts)); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get().create_collection("coll"))); + } +} diff --git a/examples/api/mongocxx/examples/collections/insert_one.cpp b/examples/api/mongocxx/examples/collections/insert_one.cpp new file mode 100644 index 0000000000..1e05b3afde --- /dev/null +++ b/examples/api/mongocxx/examples/collections/insert_one.cpp @@ -0,0 +1,74 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + auto x1 = bsoncxx::from_json(R"({"x": 1})"); + auto x2 = bsoncxx::from_json(R"({"x": 2})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x1.view()) == 0); + + auto result_opt = coll.insert_one(x1.view()); + + EXPECT(result_opt); + + mongocxx::result::insert_one& result = *result_opt; + + EXPECT(result.result().inserted_count() == 1); + + EXPECT(coll.count_documents(x1.view()) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(x2.view()) == 0); + + mongocxx::options::insert opts; + + // ... set insert options. + + EXPECT(coll.insert_one(x2.view(), opts)); + + EXPECT(coll.count_documents(x2.view()) == 1); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get().create_collection("coll"))); + } +} diff --git a/examples/api/mongocxx/examples/collections/list_indexes.cpp b/examples/api/mongocxx/examples/collections/list_indexes.cpp new file mode 100644 index 0000000000..e0c16c23b0 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/list_indexes.cpp @@ -0,0 +1,58 @@ +// 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 +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + for (bsoncxx::document::view doc : coll.list_indexes()) { + EXPECT(doc["name"]); + EXPECT(doc["name"].type() == bsoncxx::type::k_string); + + EXPECT(doc["key"]); + EXPECT(doc["key"].type() == bsoncxx::type::k_document); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto coll = set_rw_concern_majority(guard.get().create_collection("coll")); + + (void)coll.create_index(bsoncxx::from_json(R"({"key": 1})")); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/obtain.cpp b/examples/api/mongocxx/examples/collections/obtain.cpp new file mode 100644 index 0000000000..c489e50a30 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/obtain.cpp @@ -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. + +#include +#include +#include +#include + +#include +#include + +namespace { + +// [Example] +void example(mongocxx::database db) { + mongocxx::collection coll = db["coll"]; + + EXPECT(coll); + EXPECT(coll.name().compare("coll") == 0); + + EXPECT(db.collection("coll").name().compare("coll") == 0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/collections/rc.cpp b/examples/api/mongocxx/examples/collections/rc.cpp new file mode 100644 index 0000000000..b366cc8921 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/rc.cpp @@ -0,0 +1,57 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + using rc_level = mongocxx::read_concern::level; + + // Default. + { + mongocxx::read_concern rc = coll.read_concern(); + + EXPECT(rc.acknowledge_level() == rc_level::k_server_default); + } + + // Explicit. + { + mongocxx::read_concern rc; + + rc.acknowledge_level(rc_level::k_majority); + // ... other read concern options. + + coll.read_concern(rc); + + EXPECT(coll.read_concern() == rc); + EXPECT(coll.read_concern().acknowledge_level() == rc_level::k_majority); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]["coll"]); +} diff --git a/examples/api/mongocxx/examples/collections/rename.cpp b/examples/api/mongocxx/examples/collections/rename.cpp new file mode 100644 index 0000000000..2d44ba4ac1 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/rename.cpp @@ -0,0 +1,59 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + mongocxx::collection coll = db["old"]; + + EXPECT(db.has_collection("old")); + EXPECT(!db.has_collection("new")); + + EXPECT(coll.name().compare("old") == 0); + + coll.rename("new"); + + EXPECT(coll.name().compare("new") == 0); + + EXPECT(!db.has_collection("old")); + EXPECT(db.has_collection("new")); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + (void)db.create_collection("old"); + + example(db); + } +} diff --git a/examples/api/mongocxx/examples/collections/replace_one.cpp b/examples/api/mongocxx/examples/collections/replace_one.cpp new file mode 100644 index 0000000000..ede04211f9 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/replace_one.cpp @@ -0,0 +1,110 @@ +// 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 + +namespace { + +// [Example] +// [ +// {"x": 1, "replaced": false}, +// {"x": 2, "replaced": false}, +// {"x": 3, "replaced": false}, +// ] +void example(mongocxx::collection coll) { + auto is_original = bsoncxx::from_json(R"({"replaced": false})"); + auto is_replaced = bsoncxx::from_json(R"({"replaced": true})"); + + auto x0 = bsoncxx::from_json(R"({"x": 0, "replaced": true})"); + + // Basic usage. + { + EXPECT(coll.count_documents(x0.view()) == 0); + + auto filter = bsoncxx::from_json(R"({"x": 2})"); + + auto result_opt = coll.replace_one(filter.view(), x0.view()); + + EXPECT(result_opt); + + mongocxx::result::replace_one& result = *result_opt; + + EXPECT(result.matched_count() == 1); + EXPECT(result.modified_count() == 1); + EXPECT(result.result().matched_count() == 1); + EXPECT(result.result().modified_count() == 1); + + EXPECT(coll.count_documents(x0.view()) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(is_original.view()) == 2); + EXPECT(coll.count_documents(is_replaced.view()) == 1); + + mongocxx::options::replace opts; + + opts.upsert(true); + // ... other replace options. + + auto filter = bsoncxx::from_json(R"({"replaced": false})"); + + EXPECT(coll.replace_one(filter.view(), x0.view(), opts)); + EXPECT(coll.count_documents(is_original.view()) == 1); + EXPECT(coll.count_documents(is_replaced.view()) == 2); + + EXPECT(coll.replace_one(filter.view(), x0.view(), opts)); + EXPECT(coll.count_documents(is_original.view()) == 0); + EXPECT(coll.count_documents(is_replaced.view()) == 3); + + EXPECT(coll.replace_one(filter.view(), x0.view(), opts)); + EXPECT(coll.count_documents(is_original.view()) == 0); + EXPECT(coll.count_documents(is_replaced.view()) == 4); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert(bsoncxx::from_json(R"({"x": 1, "replaced": false})"))) + .append(insert(bsoncxx::from_json(R"({"x": 2, "replaced": false})"))) + .append(insert(bsoncxx::from_json(R"({"x": 3, "replaced": false})"))) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/rp.cpp b/examples/api/mongocxx/examples/collections/rp.cpp new file mode 100644 index 0000000000..ba3fe47349 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/rp.cpp @@ -0,0 +1,55 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + // Default. + { + mongocxx::read_preference rp; + + EXPECT(coll.read_preference() == rp); + EXPECT(coll.read_preference().mode() == mongocxx::read_preference::read_mode::k_primary); + } + + // Explicit. + { + mongocxx::read_preference rp; + + rp.mode(mongocxx::read_preference::read_mode::k_secondary); + // ... other read preference options. + + coll.read_preference(rp); + + EXPECT(coll.read_preference() == rp); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]["coll"]); +} diff --git a/examples/api/mongocxx/examples/collections/update_many.cpp b/examples/api/mongocxx/examples/collections/update_many.cpp new file mode 100644 index 0000000000..4533d4cf67 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/update_many.cpp @@ -0,0 +1,109 @@ +// 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 +#include + +namespace { + +// [Example] +// [ +// {"x": 1, "updated": false}, +// {"x": 2, "updated": false}, +// {"x": 3, "updated": false}, +// ] +void example(mongocxx::collection coll) { + auto original = bsoncxx::from_json(R"({"updated": false})"); + auto updated = bsoncxx::from_json(R"({"updated": true})"); + + auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})"); + + // Basic usage. + { + EXPECT(coll.count_documents(updated.view()) == 0); + + auto filter = bsoncxx::from_json(R"({"x": {"$gt": 1}})"); + + auto result_opt = coll.update_many(filter.view(), update.view()); + + EXPECT(result_opt); + + mongocxx::result::update& result = *result_opt; + + EXPECT(result.matched_count() == 2); + EXPECT(result.modified_count() == 2); + EXPECT(result.result().matched_count() == 2); + EXPECT(result.result().modified_count() == 2); + + EXPECT(coll.count_documents(updated.view()) == 2); + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1, "updated": false})")) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(original.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 2); + + mongocxx::options::update opts; + + opts.upsert(true); + // ... other update options. + + EXPECT(coll.update_many(original.view(), update.view(), opts)); + + EXPECT(coll.count_documents(original.view()) == 0); + EXPECT(coll.count_documents(updated.view()) == 3); + + EXPECT(coll.update_many(original.view(), update.view(), opts)); + + EXPECT(coll.count_documents(original.view()) == 0); + EXPECT(coll.count_documents(updated.view()) == 4); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "updated": false})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/update_one.cpp b/examples/api/mongocxx/examples/collections/update_one.cpp new file mode 100644 index 0000000000..47be0524c9 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/update_one.cpp @@ -0,0 +1,107 @@ +// 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 +#include + +namespace { + +// [Example] +// [ +// {"x": 1, "updated": false}, +// {"x": 2, "updated": false}, +// {"x": 3, "updated": false}, +// ] +void example(mongocxx::collection coll) { + auto updated = bsoncxx::from_json(R"({"updated": true})"); + + // Basic usage. + { + EXPECT(coll.count_documents(updated.view()) == 0); + + auto filter = bsoncxx::from_json(R"({"x": 2})"); + auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})"); + + auto result_opt = coll.update_one(filter.view(), update.view()); + + EXPECT(result_opt); + + mongocxx::result::update& result = *result_opt; + + EXPECT(result.matched_count() == 1); + EXPECT(result.modified_count() == 1); + EXPECT(result.result().matched_count() == 1); + EXPECT(result.result().modified_count() == 1); + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 2, "updated": true})")) == 1); + EXPECT(coll.count_documents(updated.view()) == 1); + } + + // With options. + { + EXPECT(coll.count_documents(updated.view()) == 1); + + auto x4 = bsoncxx::from_json(R"({"x": 4, "updated": true})"); + + EXPECT(coll.count_documents(x4.view()) == 0); + + mongocxx::options::update opts; + + opts.upsert(true); + // ... other update options. + + EXPECT(coll.update_one(bsoncxx::from_json(R"({"x": 4})"), + bsoncxx::from_json(R"({"$set": {"updated": true}})"), + opts)); + + EXPECT(coll.count_documents(x4.view()) == 1); + EXPECT(coll.count_documents(updated.view()) == 2); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + auto coll = db.create_collection("coll"); + + using insert = mongocxx::model::insert_one; + + EXPECT(coll.create_bulk_write() + .append(insert{bsoncxx::from_json(R"({"x": 1, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 2, "updated": false})")}) + .append(insert{bsoncxx::from_json(R"({"x": 3, "updated": false})")}) + .execute()); + + example(coll); + } +} diff --git a/examples/api/mongocxx/examples/collections/wc.cpp b/examples/api/mongocxx/examples/collections/wc.cpp new file mode 100644 index 0000000000..c346a004e4 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/wc.cpp @@ -0,0 +1,59 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + using wc_level = mongocxx::write_concern::level; + + // Default. + { + mongocxx::write_concern wc = coll.write_concern(); + + EXPECT(wc.acknowledge_level() == wc_level::k_default); + EXPECT(wc.timeout() == std::chrono::milliseconds(0)); + } + + // Explicit. + { + mongocxx::write_concern wc; + + wc.majority(std::chrono::milliseconds(5000)); + // ... other write concern options. + + coll.write_concern(wc); + + EXPECT(coll.write_concern() == wc); + EXPECT(coll.write_concern().acknowledge_level() == wc_level::k_majority); + EXPECT(coll.write_concern().timeout() == std::chrono::seconds(5)); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]["coll"]); +} diff --git a/examples/api/mongocxx/examples/collections/write.cpp b/examples/api/mongocxx/examples/collections/write.cpp new file mode 100644 index 0000000000..57449cc994 --- /dev/null +++ b/examples/api/mongocxx/examples/collections/write.cpp @@ -0,0 +1,75 @@ +// 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 +#include + +#include +#include +#include +#include + +namespace { + +// [Example] +void example(mongocxx::collection coll) { + { + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1})")) == 0); + + mongocxx::model::insert_one insert{bsoncxx::from_json(R"({"x": 1})")}; + + auto result_opt = coll.write(insert); + + EXPECT(result_opt); + EXPECT(result_opt->inserted_count() == 1); + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1})")) == 1); + } + + { + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"y": 1})")) == 0); + + mongocxx::options::bulk_write opts; + + opts.ordered(true); + // ... other bulk write options. + + EXPECT(coll.write(mongocxx::model::insert_one{bsoncxx::from_json(R"({"y": 1})")}, opts)); + + EXPECT(coll.count_documents(bsoncxx::from_json(R"({"y": 1})")) == 1); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get().create_collection("coll"))); + } +} diff --git a/examples/api/mongocxx/examples/databases/create_collection.cpp b/examples/api/mongocxx/examples/databases/create_collection.cpp new file mode 100644 index 0000000000..99cb6afb80 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/create_collection.cpp @@ -0,0 +1,49 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + EXPECT(!db.has_collection("coll")); + + mongocxx::collection coll = db.create_collection("coll"); + + EXPECT(coll); + + EXPECT(db.has_collection("coll")); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get())); + } +} diff --git a/examples/api/mongocxx/examples/databases/create_collection_with_options.cpp b/examples/api/mongocxx/examples/databases/create_collection_with_options.cpp new file mode 100644 index 0000000000..9f6da98199 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/create_collection_with_options.cpp @@ -0,0 +1,52 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + EXPECT(!db.has_collection("coll")); + + auto opts = bsoncxx::from_json(R"({"validationLevel": "strict", "validationAction": "error"})"); + // ... other create options. + + mongocxx::collection coll = db.create_collection("coll", opts.view()); + + EXPECT(coll); + EXPECT(db.has_collection("coll")); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + example(set_rw_concern_majority(guard.get())); + } +} diff --git a/examples/api/mongocxx/examples/databases/drop.cpp b/examples/api/mongocxx/examples/databases/drop.cpp new file mode 100644 index 0000000000..f0538d2cc4 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/drop.cpp @@ -0,0 +1,61 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::client& client) { + mongocxx::database db = client["db"]; + + { + std::vector names = client.list_database_names(); + + EXPECT(std::count(names.begin(), names.end(), "db") == 1); + } + + db.drop(); + + { + std::vector names = client.list_database_names(); + + EXPECT(std::count(names.begin(), names.end(), "db") == 0); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, "db"}; + + (void)guard.get().create_collection("coll"); + + example(client); + } +} diff --git a/examples/api/mongocxx/examples/databases/has_collection.cpp b/examples/api/mongocxx/examples/databases/has_collection.cpp new file mode 100644 index 0000000000..cdec15e0be --- /dev/null +++ b/examples/api/mongocxx/examples/databases/has_collection.cpp @@ -0,0 +1,46 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + EXPECT(db.has_collection("present")); + EXPECT(!db.has_collection("missing")); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = guard.get(); + + (void)db.create_collection("present"); + + example(db); + } +} diff --git a/examples/api/mongocxx/examples/databases/list_collection_names.cpp b/examples/api/mongocxx/examples/databases/list_collection_names.cpp new file mode 100644 index 0000000000..5ae39b26f8 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/list_collection_names.cpp @@ -0,0 +1,73 @@ +// 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 +#include +#include + +namespace { + +// [Example] +void example(mongocxx::database db) { + // Basic usage. + { + std::vector names = db.list_collection_names(); + + EXPECT(std::count(names.begin(), names.end(), "a") == 1); // Present. + EXPECT(std::count(names.begin(), names.end(), "b") == 1); // Present. + EXPECT(std::count(names.begin(), names.end(), "c") == 0); // Missing. + } + + // With a filter. + { + auto filter = bsoncxx::from_json(R"({"name": {"$ne": "b"}})"); + + std::vector names = db.list_collection_names(filter.view()); + + EXPECT(std::count(names.begin(), names.end(), "a") == 1); // Present. + EXPECT(std::count(names.begin(), names.end(), "b") == 0); // Filtered. + EXPECT(std::count(names.begin(), names.end(), "c") == 0); // Missing. + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = set_rw_concern_majority(guard.get()); + + (void)db.create_collection("a"); + (void)db.create_collection("b"); + // (void)db.create_collection("c"); + + example(db); + } +} diff --git a/examples/api/mongocxx/examples/databases/list_collections.cpp b/examples/api/mongocxx/examples/databases/list_collections.cpp new file mode 100644 index 0000000000..d37e32634f --- /dev/null +++ b/examples/api/mongocxx/examples/databases/list_collections.cpp @@ -0,0 +1,95 @@ +// 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 +#include + +namespace { + +// [Example] +void example(mongocxx::database db) { + int a = 0; + int b = 0; + int c = 0; + + auto count_fields = [&a, &b, &c](mongocxx::cursor cursor) { + a = 0; + b = 0; + c = 0; + + for (bsoncxx::document::view doc : cursor) { + EXPECT(doc["name"]); + + auto name = bsoncxx::string::to_string(doc["name"].get_string().value); + + if (name == "a") { + ++a; + } else if (name == "b") { + ++b; + } else if (name == "c") { + ++c; + } + } + }; + + // Basic usage. + { + count_fields(db.list_collections()); + + EXPECT(a == 1); // Present. + EXPECT(b == 1); // Present. + EXPECT(c == 0); // Missing. + } + + // With a filter. + { + auto filter = bsoncxx::from_json(R"({"name": {"$ne": "b"}})"); + + count_fields(db.list_collections(filter.view())); + + EXPECT(a == 1); // Present. + EXPECT(b == 0); // Filtered. + EXPECT(c == 0); // Missing. + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + { + db_lock guard{client, EXAMPLES_COMPONENT_NAME_STR}; + + auto db = guard.get(); + + (void)db.create_collection("a"); + (void)db.create_collection("b"); + // (void)db.create_collection("c"); + + example(db); + } +} diff --git a/examples/api/mongocxx/examples/databases/obtain.cpp b/examples/api/mongocxx/examples/databases/obtain.cpp new file mode 100644 index 0000000000..7815ed93fb --- /dev/null +++ b/examples/api/mongocxx/examples/databases/obtain.cpp @@ -0,0 +1,39 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::client client) { + mongocxx::database db = client["db"]; + + EXPECT(db); + EXPECT(db.name().compare("db") == 0); + + EXPECT(client.database("db").name().compare("db") == 0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(mongocxx::client{mongocxx::uri{}}); +} diff --git a/examples/api/mongocxx/examples/databases/rc.cpp b/examples/api/mongocxx/examples/databases/rc.cpp new file mode 100644 index 0000000000..f58f8acb50 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/rc.cpp @@ -0,0 +1,60 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + using rc_level = mongocxx::read_concern::level; + + // Default. + { + mongocxx::read_concern rc = db.read_concern(); + + EXPECT(rc.acknowledge_level() == rc_level::k_server_default); + } + + // Explicit. + { + mongocxx::read_concern rc; + + rc.acknowledge_level(rc_level::k_majority); + // ... other read concern options. + + db.read_concern(rc); + + EXPECT(db.read_concern() == rc); + EXPECT(db.read_concern().acknowledge_level() == rc_level::k_majority); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + EXPECT(client.read_concern() == mongocxx::read_concern{}); + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/databases/rp.cpp b/examples/api/mongocxx/examples/databases/rp.cpp new file mode 100644 index 0000000000..3af6449d2b --- /dev/null +++ b/examples/api/mongocxx/examples/databases/rp.cpp @@ -0,0 +1,57 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + // Default. + { + mongocxx::read_preference rp; + + EXPECT(db.read_preference() == rp); + EXPECT(db.read_preference().mode() == mongocxx::read_preference::read_mode::k_primary); + } + + // Explicit. + { + mongocxx::read_preference rp; + + rp.mode(mongocxx::read_preference::read_mode::k_secondary); + // ... other read preference options. + + db.read_preference(rp); + + EXPECT(db.read_preference() == rp); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + EXPECT(client.read_preference() == mongocxx::read_preference{}); + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/databases/run_command.cpp b/examples/api/mongocxx/examples/databases/run_command.cpp new file mode 100644 index 0000000000..2308eae49d --- /dev/null +++ b/examples/api/mongocxx/examples/databases/run_command.cpp @@ -0,0 +1,44 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + auto cmd = bsoncxx::from_json(R"({"ping": 1})"); + + bsoncxx::document::value reply = db.run_command(cmd.view()); + + EXPECT(reply["ok"]); + EXPECT(reply["ok"].get_double().value == 1.0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/databases/wc.cpp b/examples/api/mongocxx/examples/databases/wc.cpp new file mode 100644 index 0000000000..8aa1810524 --- /dev/null +++ b/examples/api/mongocxx/examples/databases/wc.cpp @@ -0,0 +1,63 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + using wc_level = mongocxx::write_concern::level; + + // Default. + { + mongocxx::write_concern wc = db.write_concern(); + + EXPECT(wc.acknowledge_level() == wc_level::k_default); + EXPECT(wc.timeout() == std::chrono::milliseconds(0)); + } + + // Explicit. + { + mongocxx::write_concern wc; + + wc.majority(std::chrono::milliseconds(5000)); + // ... other write concern options. + + db.write_concern(wc); + + EXPECT(db.write_concern() == wc); + EXPECT(db.write_concern().acknowledge_level() == wc_level::k_majority); + EXPECT(db.write_concern().timeout() == std::chrono::seconds(5)); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + mongocxx::client client{mongocxx::uri{}}; + + EXPECT(client.write_concern() == mongocxx::write_concern{}); + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/instance/basic_usage.cpp b/examples/api/mongocxx/examples/instance/basic_usage.cpp new file mode 100644 index 0000000000..addfd04c4d --- /dev/null +++ b/examples/api/mongocxx/examples/instance/basic_usage.cpp @@ -0,0 +1,51 @@ +// 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 + +namespace { + +template +void use(Args&&...) {} + +// [Example] +void example() { + // Do not use mongocxx library interfaces at this point! + + { + // Initialize the MongoDB C++ Driver by constructing the instance object. + mongocxx::instance instance; + + EXPECT(&mongocxx::instance::current() == &instance); + + // Use mongocxx library interfaces at this point. + use(mongocxx::client{}); + + // Cleanup the MongoDB C++ Driver by destroying the instance object. + } + + // Do not use mongocxx library interfaces at this point! +} +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/instance/current.cpp b/examples/api/mongocxx/examples/instance/current.cpp new file mode 100644 index 0000000000..238e22e7c7 --- /dev/null +++ b/examples/api/mongocxx/examples/instance/current.cpp @@ -0,0 +1,53 @@ +// 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 + +namespace { + +template +void use(Args&&...) {} + +// [Example] +void example() { + // Do not use mongocxx library interfaces at this point! + + { + // Initialize the MongoDB C++ Driver. + auto& instance = mongocxx::instance::current(); + + EXPECT(&mongocxx::instance::current() == &instance); + + // Use mongocxx library interfaces at this point. + use(mongocxx::client{}); + } + + // Use mongocxx library interfaces at this point. + use(mongocxx::client{}); +} + +// Cleanup the MongoDB C++ Driver after returning from `main()` with indeterminate order relative to +// other objects with static lifetime being destroyed. +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/instance/destroyed.cpp b/examples/api/mongocxx/examples/instance/destroyed.cpp new file mode 100644 index 0000000000..c93e55f531 --- /dev/null +++ b/examples/api/mongocxx/examples/instance/destroyed.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example() { + { mongocxx::instance instance; } // Initialize and cleanup. + + try { + mongocxx::instance instance; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_cannot_recreate_instance); + } + + try { + auto& instance = mongocxx::instance::current(); // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_instance_destroyed); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/instance/recreation.cpp b/examples/api/mongocxx/examples/instance/recreation.cpp new file mode 100644 index 0000000000..0a2e353332 --- /dev/null +++ b/examples/api/mongocxx/examples/instance/recreation.cpp @@ -0,0 +1,48 @@ +// 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 + +namespace { + +// [Example] +void example() { + { + mongocxx::instance instance; + + EXPECT(&mongocxx::instance::current() == &instance); + + try { + mongocxx::instance another_instance; // Throws. + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_cannot_recreate_instance); + } + + EXPECT(&mongocxx::instance::current() == &instance); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/logger/basic_usage.cpp b/examples/api/mongocxx/examples/logger/basic_usage.cpp new file mode 100644 index 0000000000..ec2f27c314 --- /dev/null +++ b/examples/api/mongocxx/examples/logger/basic_usage.cpp @@ -0,0 +1,63 @@ +// 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 + +namespace { + +// [Example] +class example_logger : public mongocxx::logger { + private: + int* counter_ptr; + + public: + explicit example_logger(int* ptr) : counter_ptr(ptr) {} + + void operator()(mongocxx::log_level level, + bsoncxx::stdx::string_view domain, + bsoncxx::stdx::string_view message) noexcept override { + EXPECT(level == mongocxx::log_level::k_info); + EXPECT(domain.compare("mongocxx") == 0); + EXPECT(message.compare("libmongoc logging callback enabled") == 0); + + *counter_ptr += 1; + } +}; + +void example() { + int counter = 0; + + // Use `std::make_unique` with C++14 or newer. + auto logger = std::unique_ptr(new example_logger{&counter}); + + // Emit the informational mongocxx log message: "libmongoc logging callback enabled". + mongocxx::instance instance{std::move(logger)}; + + EXPECT(counter == 1); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/logger/to_string.cpp b/examples/api/mongocxx/examples/logger/to_string.cpp new file mode 100644 index 0000000000..9d649f2cc1 --- /dev/null +++ b/examples/api/mongocxx/examples/logger/to_string.cpp @@ -0,0 +1,51 @@ +// 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 + +namespace { + +// [Example] +void example() { + bsoncxx::stdx::string_view error = mongocxx::to_string(mongocxx::log_level::k_error); + bsoncxx::stdx::string_view critical = mongocxx::to_string(mongocxx::log_level::k_critical); + bsoncxx::stdx::string_view warning = mongocxx::to_string(mongocxx::log_level::k_warning); + bsoncxx::stdx::string_view message = mongocxx::to_string(mongocxx::log_level::k_message); + bsoncxx::stdx::string_view info = mongocxx::to_string(mongocxx::log_level::k_info); + bsoncxx::stdx::string_view debug = mongocxx::to_string(mongocxx::log_level::k_debug); + bsoncxx::stdx::string_view trace = mongocxx::to_string(mongocxx::log_level::k_trace); + + EXPECT(error.compare("error") == 0); + EXPECT(critical.compare("critical") == 0); + EXPECT(warning.compare("warning") == 0); + EXPECT(message.compare("message") == 0); + EXPECT(info.compare("info") == 0); + EXPECT(debug.compare("debug") == 0); + EXPECT(trace.compare("trace") == 0); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_FORKING_COMPONENT() { + example(); +} diff --git a/examples/api/mongocxx/examples/operation_exceptions/operation.cpp b/examples/api/mongocxx/examples/operation_exceptions/operation.cpp new file mode 100644 index 0000000000..96afd7ec73 --- /dev/null +++ b/examples/api/mongocxx/examples/operation_exceptions/operation.cpp @@ -0,0 +1,73 @@ +// 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 +#include + +namespace { + +// [Example] +void example(mongocxx::database db) { + EXPECT(db.name().compare("db") == 0); + + // The `getParameter` command can only be run in the `admin` database. + auto cmd = bsoncxx::from_json(R"({"getParameter": "*"})"); + + // This error handling pattern applies to all commands which may throw a + // `mongocxx::operation_exception` exception. + try { + auto reply = db.run_command(cmd.view()); + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::operation_exception& ex) { + EXPECT(ex.code().category() == mongocxx::server_error_category()); + EXPECT(ex.code().value() == 13); // Unauthorized + EXPECT(std::strstr(ex.what(), "admin") != nullptr); + + if (auto server_error_opt = ex.raw_server_error()) { + bsoncxx::document::view server_error = server_error_opt->view(); + + EXPECT(server_error["ok"]); + EXPECT(server_error["ok"].get_double().value == 0.0); + + EXPECT(server_error["code"]); + EXPECT(server_error["code"].get_int32().value == ex.code().value()); + + EXPECT(server_error["codeName"]); + EXPECT(server_error["errmsg"]); + // ... other error fields. + } + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/operation_exceptions/regular.cpp b/examples/api/mongocxx/examples/operation_exceptions/regular.cpp new file mode 100644 index 0000000000..30dc962e28 --- /dev/null +++ b/examples/api/mongocxx/examples/operation_exceptions/regular.cpp @@ -0,0 +1,57 @@ +// 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 + +namespace { + +// [Example] +void example(mongocxx::database db) { + EXPECT(db.name().compare("db") == 0); + + // The `getParameter` command can only be run in the `admin` database. + auto cmd = bsoncxx::from_json(R"({"getParameter": "*"})"); + + // This error handling pattern applies to all commands which may throw a + // `mongocxx::operation_exception` exception. + try { + auto reply = db.run_command(cmd.view()); + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code().category() == mongocxx::server_error_category()); + EXPECT(ex.code().value() == 13); // Unauthorized + EXPECT(std::strstr(ex.what(), "admin") != nullptr); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_FOR_SINGLE() { + mongocxx::client client{mongocxx::uri{}}; + + example(client["db"]); +} diff --git a/examples/api/mongocxx/examples/uri/all_options.cpp b/examples/api/mongocxx/examples/uri/all_options.cpp new file mode 100644 index 0000000000..dc4a151615 --- /dev/null +++ b/examples/api/mongocxx/examples/uri/all_options.cpp @@ -0,0 +1,49 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::uri uri{"mongodb://localhost:27017/?appName=example&tls=true&maxPoolSize=10"}; + + bsoncxx::document::view options = uri.options(); + + EXPECT(options["appname"]); + EXPECT(options["appname"].get_string().value.compare("example") == 0); + + EXPECT(options["tls"]); + EXPECT(options["tls"].get_bool().value == true); + + EXPECT(options["maxpoolsize"]); + EXPECT(options["maxpoolsize"].get_int32().value == 10); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/basic_usage.cpp b/examples/api/mongocxx/examples/uri/basic_usage.cpp new file mode 100644 index 0000000000..5922b32cea --- /dev/null +++ b/examples/api/mongocxx/examples/uri/basic_usage.cpp @@ -0,0 +1,40 @@ +// 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 + +namespace { + +// [Example] +void example() { + const auto uri_str = "mongodb://bob:pwd123@localhost:27017/?tls=true"; + + mongocxx::uri uri{uri_str}; + + EXPECT(uri.to_string() == uri_str); + + EXPECT(uri.username().compare("bob") == 0); + EXPECT(uri.password() == "pwd123"); + EXPECT(uri.tls() == true); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/default_value.cpp b/examples/api/mongocxx/examples/uri/default_value.cpp new file mode 100644 index 0000000000..6a6d46d5e4 --- /dev/null +++ b/examples/api/mongocxx/examples/uri/default_value.cpp @@ -0,0 +1,40 @@ +// 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 + +namespace { + +// [Example] +void example() { + const auto uri_str = "mongodb://localhost:27017"; + + mongocxx::uri a; + mongocxx::uri b{uri_str}; + mongocxx::uri c{mongocxx::uri::k_default_uri}; + + EXPECT(a.to_string() == uri_str); + EXPECT(b.to_string() == uri_str); + EXPECT(c.to_string() == uri_str); +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/hosts.cpp b/examples/api/mongocxx/examples/uri/hosts.cpp new file mode 100644 index 0000000000..0b0dc03986 --- /dev/null +++ b/examples/api/mongocxx/examples/uri/hosts.cpp @@ -0,0 +1,54 @@ +// 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 + +namespace { + +// [Example] +void example() { + mongocxx::uri uri{"mongodb://127.0.0.1,[::1]:27018,%2Fpath%2Fto.socket:27019"}; + + std::vector hosts = uri.hosts(); + + EXPECT(hosts.size() == 3u); + + const mongocxx::uri::host& first = hosts[0]; + const mongocxx::uri::host& second = hosts[1]; + const mongocxx::uri::host& third = hosts[2]; + + EXPECT(first.name == "127.0.0.1"); + EXPECT(first.port == 27017u); + EXPECT(first.family == 0); // AF_UNSPEC (AP_INET). + + EXPECT(second.name == "::1"); + EXPECT(second.port == 27018u); + EXPECT(second.family != 0); // AF_INET6. + + EXPECT(third.name == "/path/to.socket"); + EXPECT(third.port == 27019u); + EXPECT(third.family != 0); // AF_UNIX. +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/invalid.cpp b/examples/api/mongocxx/examples/uri/invalid.cpp new file mode 100644 index 0000000000..aab9a60759 --- /dev/null +++ b/examples/api/mongocxx/examples/uri/invalid.cpp @@ -0,0 +1,59 @@ +// 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 + +namespace { + +// [Example] +void example() { + try { + // Missing `mongodb://`. + mongocxx::uri invalid_uri{"invalid"}; + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_uri); + } + + try { + // Missing `=`. + mongocxx::uri invalid_uri{"mongodb://localhost:27017/?tls"}; + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_uri); + } + + try { + // Missing user credentials when authMechanism is provided. + mongocxx::uri invalid_uri{"mongodb://localhost:27017/?authMechanism=SCRAM-SHA-256"}; + + EXPECT(false && "should not reach this point"); + } catch (const mongocxx::exception& ex) { + EXPECT(ex.code() == mongocxx::error_code::k_invalid_uri); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/optional.cpp b/examples/api/mongocxx/examples/uri/optional.cpp new file mode 100644 index 0000000000..2f4050cf89 --- /dev/null +++ b/examples/api/mongocxx/examples/uri/optional.cpp @@ -0,0 +1,63 @@ +// 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 + +namespace { + +// [Example] +void example() { + { + mongocxx::uri uri{"mongodb://localhost:27017/"}; + + std::string database = uri.database(); + EXPECT(database.empty()); + + auto try_once_opt = uri.server_selection_try_once(); + EXPECT(!try_once_opt); + + auto appname_opt = uri.appname(); + EXPECT(!appname_opt); + } + + { + mongocxx::uri uri{"mongodb://localhost:27017/dbName?appName=example&retryReads=true"}; + + auto database = uri.database(); + EXPECT(database.compare("dbName") == 0); + + auto retry_reads_opt = uri.retry_reads(); + EXPECT(retry_reads_opt); + EXPECT(*retry_reads_opt == true); + + auto appname_opt = uri.appname(); + EXPECT(appname_opt); + EXPECT(appname_opt->compare("example") == 0); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/mongocxx/examples/uri/userpass.cpp b/examples/api/mongocxx/examples/uri/userpass.cpp new file mode 100644 index 0000000000..8d64b1712e --- /dev/null +++ b/examples/api/mongocxx/examples/uri/userpass.cpp @@ -0,0 +1,50 @@ +// 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 + +namespace { + +// [Example] +void example() { + { + mongocxx::uri uri{"mongodb://localhost:27017/"}; + + EXPECT(uri.username().empty()); + EXPECT(uri.password().empty()); + + EXPECT(uri.tls() == false); + } + + { + mongocxx::uri uri{"mongodb://bob:pwd123@localhost:27017/?tls=true"}; + + EXPECT(uri.username().compare("bob") == 0); + EXPECT(uri.password() == "pwd123"); + + EXPECT(uri.tls() == true); + } +} +// [Example] + +} // namespace + +RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() { + example(); +} diff --git a/examples/api/runner.cpp b/examples/api/runner.cpp index 98a17c920e..7360f1cd3c 100644 --- a/examples/api/runner.cpp +++ b/examples/api/runner.cpp @@ -20,6 +20,7 @@ // #include +#include #include #include #include @@ -30,23 +31,199 @@ #include #include +#include +#include + +#include +#include +#include +#include + #include +#if !defined(_MSC_VER) + +#include + +#include + +#endif // !defined(_MSC_VER) + namespace { class runner_type { public: using fn_type = void (*)(); + struct component { + fn_type fn; + const char* name; + + component(fn_type f, const char* n) : fn(f), name(n) {} + }; + private: - std::vector fns; + std::vector components; + + std::vector components_with_instance; + + std::vector components_for_single; + std::vector components_for_replica; + std::vector components_for_sharded; + + std::vector forking_components; + std::minstd_rand::result_type seed = 0u; std::minstd_rand gen; unsigned int jobs = 0; + static void run_with_jobs(const std::vector& components, unsigned int jobs) { + if (jobs == 1) { + for (const auto& component : components) { + component.fn(); + } + } else { + std::queue threads; + + // Rudimentary job scheduler. + for (const auto& component : components) { + while (threads.size() >= jobs) { + threads.front().join(); + threads.pop(); + } + + threads.emplace(component.fn); + } + + while (!threads.empty()) { + threads.front().join(); + threads.pop(); + } + } + } + + void run_components() { + run_with_jobs(components, jobs); + } + + enum struct action { + succeed, + fail, + return_from_main, + }; + +#if !defined(_MSC_VER) + action run_forking_components() { + // Forking with threads is difficult and the number of components that require forking are + // few in number. Run forking components sequentially. + for (const auto& component : forking_components) { + const auto& fn = component.fn; + const auto& name = component.name; + + const pid_t pid = ::fork(); + + // Child: do nothing more than call the registered function. + if (pid == 0) { + fn(); + return action::return_from_main; // Return from `main()`. + } + + // Parent: wait for child and handle returned status values. + else { + int status; + + const int ret = ::waitpid(pid, &status, 0); + + // For non-zero exit codes, permit continuation for example coverage. + if (WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS) { + std::cout << __func__ << ": failed: " << name + << " exited with a non-zero exit code: " << WEXITSTATUS(status) + << std::endl; + + return action::fail; + } + + // For unexpected signals, stop immediately. + else if (WIFSIGNALED(status)) { + const int signal = WTERMSIG(status); + const char* const sigstr = ::strsignal(signal); + + std::cout << __func__ << ": failed: " << name + << " was killed by signal: " << signal << " (" + << (sigstr ? sigstr : "") << ")" << std::endl; + + std::exit(EXIT_FAILURE); + } + + // We don't expect any other failure condition. + else { + assert(ret != -1); + } + } + } + + return action::succeed; + } +#else + action run_forking_components() { + std::cout << "Skipping API examples that require forked processes" << std::endl; + return action::succeed; + } +#endif // !defined(_MSC_VER) + + void run_components_with_instance() { + mongocxx::instance instance; + + run_with_jobs(components_with_instance, jobs); + + try { + mongocxx::client client{mongocxx::uri{"mongodb://localhost:27017/"}}; + + const auto reply = client["admin"].run_command(bsoncxx::builder::basic::make_document( + bsoncxx::builder::basic::kvp("isMaster", 1))); + + if (reply["msg"]) { + std::cout << "Running API examples against a live sharded server" << std::endl; + run_with_jobs(components_for_sharded, jobs); + run_with_jobs(components_for_replica, jobs); + run_with_jobs(components_for_single, jobs); + } else if (reply["setName"]) { + std::cout << "Running API examples against a live replica server" << std::endl; + run_with_jobs(components_for_replica, jobs); + run_with_jobs(components_for_single, jobs); + } else { + std::cout << "Running API examples against a live single server" << std::endl; + run_with_jobs(components_for_single, jobs); + } + } catch (const mongocxx::exception& ex) { + std::cout << "Skipping API examples that require a live server: " << ex.what() + << std::endl; + } + } + public: - void add(fn_type fn) { - fns.push_back(fn); + void add_component(fn_type fn, const char* name) { + components.emplace_back(fn, name); + } + + void add_component_with_instance(fn_type fn, const char* name) { + components_with_instance.emplace_back(fn, name); + } + + void add_component_for_single(fn_type fn, const char* name) { + components_for_single.emplace_back(fn, name); + } + + void add_component_for_replica(fn_type fn, const char* name) { + components_for_replica.emplace_back(fn, name); + } + + void add_component_for_sharded(fn_type fn, const char* name) { + components_for_sharded.emplace_back(fn, name); + } + + void add_forking_component(fn_type fn, const char* name) { + forking_components.emplace_back(fn, name); } void set_seed(std::minstd_rand::result_type seed) { @@ -62,33 +239,30 @@ class runner_type { } int run() { - EXPECT(jobs > 0u); + assert(jobs > 0u); std::cout << "seed: " << seed << std::endl; gen.seed(seed); // Prevent ordering dependencies across examples. - std::shuffle(fns.begin(), fns.end(), gen); - - std::queue threads; - - // Rudimentary job scheduler. - for (auto fn : fns) { - while (threads.size() >= jobs) { - threads.front().join(); - threads.pop(); - } - - threads.emplace(fn); + std::shuffle(components.begin(), components.end(), gen); + std::shuffle(forking_components.begin(), forking_components.end(), gen); + + run_components(); + + switch (run_forking_components()) { + case action::succeed: + break; // Continue example coverage. + case action::fail: + return EXIT_FAILURE; // A component failed. + case action::return_from_main: + return EXIT_SUCCESS; // Return directly from forked processes. } - while (!threads.empty()) { - threads.front().join(); - threads.pop(); - } + run_components_with_instance(); - return 0; + return EXIT_SUCCESS; } }; @@ -96,8 +270,28 @@ runner_type runner; } // namespace -void runner_register_fn(void (*fn)()) { - runner.add(fn); +void runner_register_component(void (*fn)(), const char* name) { + runner.add_component(fn, name); +} + +void runner_register_component_with_instance(void (*fn)(), const char* name) { + runner.add_component_with_instance(fn, name); +} + +void runner_register_component_for_single(void (*fn)(), const char* name) { + runner.add_component_for_single(fn, name); +} + +void runner_register_component_for_replica(void (*fn)(), const char* name) { + runner.add_component_for_replica(fn, name); +} + +void runner_register_component_for_sharded(void (*fn)(), const char* name) { + runner.add_component_for_sharded(fn, name); +} + +void runner_register_forking_component(void (*fn)(), const char* name) { + runner.add_forking_component(fn, name); } int EXAMPLES_CDECL main(int argc, char** argv) { diff --git a/examples/api/runner.hh b/examples/api/runner.hh index 0d4a5d6811..684553624b 100644 --- a/examples/api/runner.hh +++ b/examples/api/runner.hh @@ -14,17 +14,58 @@ #pragma once +#include + #include -void runner_register_fn(void (*fn)()); +void runner_register_component(void (*fn)(), const char* name); + +void runner_register_component_with_instance(void (*fn)(), const char* name); + +void runner_register_component_for_single(void (*fn)(), const char* name); +void runner_register_component_for_replica(void (*fn)(), const char* name); +void runner_register_component_for_sharded(void (*fn)(), const char* name); + +void runner_register_forking_component(void (*fn)(), const char* name); // Defined by examples/CMakeLists.txt. #if !defined(EXAMPLES_COMPONENT_NAME) #error "EXAMPLES_COMPONENT_NAME is not defined!" #endif // !defined(EXAMPLES_COMPONENT_NAME) -#define RUNNER_REGISTER_COMPONENT() \ - static void EXAMPLES_CONCAT(EXAMPLES_COMPONENT_NAME, _entry_point)(void); \ - static int EXAMPLES_CONCAT(EXAMPLES_COMPONENT_NAME, _registerator) = \ - (::runner_register_fn(&EXAMPLES_CONCAT(EXAMPLES_COMPONENT_NAME, _entry_point)), 0); \ - static void EXAMPLES_CONCAT(EXAMPLES_COMPONENT_NAME, _entry_point)(void) +#define EXAMPLES_COMPONENT_NAME_STR EXAMPLES_COMPONENT_NAME_STR_IMPL(EXAMPLES_COMPONENT_NAME) +#define EXAMPLES_COMPONENT_NAME_STR_IMPL(name) EXAMPLES_STR(name) + +#define RUNNER_REGISTER_COMPONENT_IMPL(name, register_fn) \ + static void EXAMPLES_CONCAT3(name, _entry_point_, __LINE__)(void); \ + static void EXAMPLES_CONCAT4(name, _entry_point_, __LINE__, _guarded)(void) try { \ + EXAMPLES_CONCAT3(name, _entry_point_, __LINE__)(); \ + } catch (...) { \ + std::cout << EXAMPLES_STR(name) ":" << __LINE__ << ": failed: uncaught exception" \ + << std::endl; \ + throw; \ + } \ + static int EXAMPLES_CONCAT2(name, _registrator) = \ + ((register_fn)(&EXAMPLES_CONCAT4(name, _entry_point_, __LINE__, _guarded), \ + EXAMPLES_STR(name)), \ + 0); \ + static void EXAMPLES_CONCAT3(EXAMPLES_COMPONENT_NAME, _entry_point_, __LINE__)(void) + +#define RUNNER_REGISTER_COMPONENT() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, ::runner_register_component) + +#define RUNNER_REGISTER_COMPONENT_WITH_INSTANCE() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, \ + ::runner_register_component_with_instance) + +#define RUNNER_REGISTER_COMPONENT_FOR_SINGLE() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, ::runner_register_component_for_single) + +#define RUNNER_REGISTER_COMPONENT_FOR_REPLICA() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, ::runner_register_component_for_replica) + +#define RUNNER_REGISTER_COMPONENT_FOR_SHARDED() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, ::runner_register_component_for_sharded) + +#define RUNNER_REGISTER_FORKING_COMPONENT() \ + RUNNER_REGISTER_COMPONENT_IMPL(EXAMPLES_COMPONENT_NAME, ::runner_register_forking_component) diff --git a/examples/macros.hh b/examples/macros.hh index f04b75cf9c..ac879df96e 100644 --- a/examples/macros.hh +++ b/examples/macros.hh @@ -23,8 +23,13 @@ #define EXAMPLES_CDECL #endif -#define EXAMPLES_CONCAT(a, b) EXAMPLES_CONCAT_1(a, b) -#define EXAMPLES_CONCAT_1(a, b) a##b +#define EXAMPLES_CONCAT2(a, b) EXAMPLES_CONCAT_IMPL(a, b) +#define EXAMPLES_CONCAT3(a, b, c) EXAMPLES_CONCAT2(EXAMPLES_CONCAT2(a, b), c) +#define EXAMPLES_CONCAT4(a, b, c, d) \ + EXAMPLES_CONCAT2(EXAMPLES_CONCAT2(a, b), EXAMPLES_CONCAT2(c, d)) +#define EXAMPLES_CONCAT_IMPL(a, b) a##b + +#define EXAMPLES_STR(e) #e // Unconditionally `assert()` expectations in examples. #define EXPECT(...) \ diff --git a/src/mongocxx/include/mongocxx/doc.hpp b/src/mongocxx/include/mongocxx/doc.hpp index 5ea25b9f2d..b37dc903dc 100644 --- a/src/mongocxx/include/mongocxx/doc.hpp +++ b/src/mongocxx/include/mongocxx/doc.hpp @@ -95,6 +95,64 @@ /// /// @page topic-mongocxx-examples How-To Guides /// @brief Examples of how to use the mongocxx library. +/// @li @subpage topic-mongocxx-examples-instance +/// @li @subpage topic-mongocxx-examples-logger +/// @li @subpage topic-mongocxx-examples-uri +/// @li @subpage topic-mongocxx-examples-clients +/// @li @subpage topic-mongocxx-examples-databases +/// @li @subpage topic-mongocxx-examples-collections +/// @li @subpage topic-mongocxx-examples-operation-exceptions +/// + +/// +/// @page topic-mongocxx-examples-instance Instance +/// @brief How to use a MongoDB C++ Driver instance. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/instance.md +/// + +/// +/// @page topic-mongocxx-examples-logger Logger +/// @brief How to use a custom logger with a MongoDB C++ Driver instance. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/logger.md +/// + +/// +/// @page topic-mongocxx-examples-uri URI +/// @brief How to create and use URIs. +/// @tableofcontents +/// @see [Connection Strings (MongoDB +/// Manual)](https://www.mongodb.com/docs/manual/reference/connection-string/) +/// @include{doc} api/mongocxx/examples/uri.md +/// + +/// +/// @page topic-mongocxx-examples-clients Clients +/// @brief How to use clients and client pools. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/clients.md +/// + +/// +/// @page topic-mongocxx-examples-databases Databases +/// @brief How to obtain and use databases. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/databases.md +/// + +/// +/// @page topic-mongocxx-examples-collections Collections +/// @brief How to obtain and use collections. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/collections.md +/// + +/// +/// @page topic-mongocxx-examples-operation-exceptions Operation Exceptions +/// @brief How to handle exceptions thrown by database and collection operations. +/// @tableofcontents +/// @include{doc} api/mongocxx/examples/operation_exceptions.md /// /// diff --git a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/uri.hpp b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/uri.hpp index 30e309b182..3870e2cae0 100644 --- a/src/mongocxx/include/mongocxx/v_noabi/mongocxx/uri.hpp +++ b/src/mongocxx/include/mongocxx/v_noabi/mongocxx/uri.hpp @@ -49,11 +49,14 @@ class uri { std::int32_t family; }; + /// + /// The default URI string: `"mongodb://localhost:27017"`. + /// static MONGOCXX_ABI_EXPORT const std::string k_default_uri; /// /// Constructs a uri from an optional MongoDB URI string. If no URI string is specified, - /// uses the default URI string, 'mongodb://localhost:27017'. + /// uses the default URI string: `"mongodb://localhost:27017"`. /// /// @see /// - https://mongoc.org/libmongoc/current/mongoc_uri_t.html