When talking with server 3.4 or greater (maxWireVersion >=5), writeConcern should be a supported option for commands that write.
Helpers for the following commands therefore must be updated to support the option. The list is ordered according to likelihood that a driver has a helper for the command.
- aggregate with $out mongoc_collection_aggregate
- copydb - no helper function
- create - mongoc_database_create_collection
- createIndexes - mongoc_collection_create_index_2
- drop - mongoc_collection_drop
- dropDatabase - mongoc_database_drop
- dropIndexes - mongoc_collection_drop_index
- mapReduce with $out - no helper function
- clone - no helper function
- cloneCollection - no helper function
- cloneCollectionAsCapped - no helper function
- collMod - no helper function
- convertToCapped - no helper function
- renameCollection - mongoc_collection_rename
- reindex - no helper
When the writeConcern on a command that writes fails, the resulting document still comes back with ok: 1. Hence, to check for write concern and raise the appropriate error to your users, you will need to check the resulting document for a writeConcernError field, in command-specific helper methods. If it is present, then writeConcern failed.
Generic command methods like mongoc_client_command do not check the result for a writeConcernError subdocument, that's the user's responsibility.
We want to include a BSON document like this with commands that write, if the configured writeConcern is not the default:
First, we want to know whether a mongoc_write_concern_t is the default or not. Add bool is_default to the mongoc_write_concern_t struct. It's true at first. All the mongoc_write_concern_set_ functions will set it to false. Do not make a public function for checking if a write_concern_t has the default options: we don't want to expand our public API unnecessarily.
Write some tests in test-mongoc-write-concern.c that "is_default" is properly managed.
Add to mongoc-client-private.h:
*Update*: No mongoc_client_command_with_write_concern, mongoc_database_command_with_write_concern, or mongoc_collection_command_with_write_concern.
If you're running against a server with wire version 4 or older, you should not get an error. This test will verify that you're not sending writeConcern to older server versions.
Consider not testing mongoc_database_command_with_write_concern or mongoc_collection_command_with_write_concern, since they'll be very simple functions.
This is the first example of a new function with a name ending in "with_write_concern". All functions with names ending with "with_write_concern" follow this plan.
If selected_server->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN and write_concern is not the default, then append _mongoc_write_concern_get_bson (write_concern) to the "aggregate" command before sending to the server.
Parse the reply, if it's not a hard failure, for a writeConcernError subdocument, and if present fill out the error and return false along with the reply. *Update*: move this parsing back out of mongoc-rpc.c and put it in a private helper function _mongoc_parse_wc_err that all command helper functions like this one can use.
Document that mongoc_collection_aggregate_with_write_concern only sends writeConcern to the server if it's MongoDB 3.4+. Ask Kay Kim where in the MongoDB Manual your doc should send users for more info about writeConcern and commands.
To test mongoc_collection_aggregate_with_write_concern: use helper functions in test-libmongoc.h to determine the server config. If you're running against a server with wire version 5+ and it's a replica set, set write concern's "w" to 99. You should get a characteristic server error, and test that the error domain is MONGOC_ERROR_WRITE_CONCERN. If you're running against a server with wire version 5+ and it's a standalone you should get a slightly different error. Not sure what to expect if you're connected to mongos, see what happens and write your test accordingly. If you're connected to mongos, skip the test. If connected to a server with max_wire_version <=4, then you should not get an error (because you are not sending the write concern).
mongoc_collection_aggregate becomes a wrapper around mongoc_collection_aggregate_with_write_concern, which passes a NULL write concern.
Add mongoc_database_create_collection_with_write_concern, mongoc_database_create_collection becomes a thin wrapper that passes a NULL write concern. Consider not adding a test for its write concern handling, if it seems simple enough to trust.
Rename mongoc_collection_create_index_2 to mongoc_collection_create_index_with_write_concern.
Do test that it handles write concern properly, this might be slightly complicated.
The legacy fallback for mongoc_collection_create_index_with_write_concern just inserts into the system.indexes collection, no need to touch or test that code since writeConcern won't be used in that code path.
Like mongoc_database_create_collection: add mongoc_collection_drop_with_write_concern.