Loading...
Searching...
No Matches
Clients

How to use clients and client pools.

# Create a Client

## Single

### Basic Usage

void example() {
{
mongocxx::client client;
EXPECT(!client);
}
{
mongocxx::client client{mongocxx::uri{}};
EXPECT(client);
EXPECT(client.uri().to_string() == mongocxx::uri::k_default_uri);
}
}

### With a Custom URI

void example() {
mongocxx::uri uri{"mongodb://localhost:27017/?appName=example"};
mongocxx::client client{uri};
EXPECT(client);
EXPECT(client.uri().to_string() == uri.to_string());
}

### With Client Options

#### Stable API Options

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;
}

#### TLS Options

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;
}

#### Automatic Encryption Options

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);
auto_encryption_opts.extra_options(
bsoncxx::from_json(
R"({"mongocryptdURI": "mongodb://localhost:27027", "mongocryptdSpawnArgs": ["--port", "27027"]})"));
// ... 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);
}

#### APM Options

void on_command_started_callback(mongocxx::events::command_started_event const& 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);
}

## Pool

### Basic Usage

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());
}
}

### With Client Options

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);
}

### Try Acquire

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);
}

# Use a Client

## List Databases

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 == "admin") {
++count;
}
}
EXPECT(count == 1);
}

## List Databases With Options

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 == "admin") {
++count;
}
}
EXPECT(count == 1);
}

## List Database Names

void example(mongocxx::client client) {
std::vector<std::string> names = client.list_database_names();
EXPECT(std::count(names.begin(), names.end(), "admin") == 1);
}

## List Database Names With Options

void example(mongocxx::client client) {
auto opts = bsoncxx::from_json(R"({"authorizedDatabases": true})");
// ... other listDatabases options.
std::vector<std::string> names = client.list_database_names(opts.view());
EXPECT(std::count(names.begin(), names.end(), "admin") == 0);
}

# Error Handling

## Invalid Client

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 (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_client_object);
}
}

## Wait Queue Timeout

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 (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_pool_wait_queue_timeout);
}
}

## Invalid Stable API Options

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 (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
try {
std::string version = mongocxx::options::server_api::version_to_string(
static_cast<mongocxx::options::server_api::version>(1)); // Throws.
EXPECT(false && "should not reach this point");
} catch (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
}

## TLS Not Enabled

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 (mongocxx::exception const& 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);
}
}

## Invalid Auto Encryption Options

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 (mongocxx::exception const& 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 (mongocxx::exception const& 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 (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
}