1MONGOC_REFERENCE(3) libmongoc MONGOC_REFERENCE(3)
2
3
4
6 mongoc_reference - Index
7
9 A Cross Platform MongoDB Client Library for C
10
11 Introduction
12 The MongoDB C Driver, also known as "libmongoc", is a library for using
13 MongoDB from C applications, and for writing MongoDB drivers in
14 higher-level languages.
15
16 It depends on libbson to generate and parse BSON documents, the native
17 data format of MongoDB.
18
19 Installing the MongoDB C Driver (libmongoc) and BSON library (libbson)
20 The following guide will step you through the process of downloading,
21 building, and installing the current release of the MongoDB C Driver
22 (libmongoc) and BSON library (libbson).
23
24 Supported Platforms
25 The MongoDB C Driver is continuously tested on a variety of platforms
26 including:
27
28 • Archlinux
29
30 • Debian 9.2, 10.0
31
32 • macOS 10.14
33
34 • Microsoft Windows Server 2008, 2016
35
36 • RHEL 6.2, 7.0, 7.1, 8.2
37
38 • Ubuntu 16.04, 18.04
39
40 • Clang 3.4, 3.5, 3.7, 3.8, 6.0
41
42 • GCC 4.8, 4.9, 5.4, 6.3, 8.2, 8.3
43
44 • MinGW-W64
45
46 • Visual Studio 2013, 2015, 2017
47
48 • x86, x86_64, ARM (aarch64), Power8 (ppc64le), zSeries (s390x)
49
50 Install libmongoc with a Package Manager
51 Several Linux distributions provide packages for libmongoc and its de‐
52 pendencies. One advantage of installing libmongoc with a package man‐
53 ager is that its dependencies (including libbson) will be installed au‐
54 tomatically. If you choose to install libmongoc from distribution pack‐
55 ages, use the package manager to confirm the version being installed is
56 sufficient for your needs.
57
58 The libmongoc package is available on recent versions of Debian and
59 Ubuntu.
60
61 $ apt-get install libmongoc-1.0-0
62
63 On Fedora, a mongo-c-driver package is available in the default reposi‐
64 tories and can be installed with:
65
66 $ dnf install mongo-c-driver
67
68 On recent Red Hat systems, such as CentOS and RHEL 7, a mongo-c-driver
69 package is available in the EPEL repository. To check which version is
70 available, see https://apps.fedoraproject.org/packages/mongo-c-driver.
71 The package can be installed with:
72
73 $ yum install mongo-c-driver
74
75 On macOS systems with Homebrew, the mongo-c-driver package can be in‐
76 stalled with:
77
78 $ brew install mongo-c-driver
79
80 Install libbson with a Package Manager
81 The libbson package is available on recent versions of Debian and
82 Ubuntu. If you have installed libmongoc, then libbson will have already
83 been installed as a dependency. It is also possible to install libbson
84 without libmongoc.
85
86 $ apt-get install libbson-1.0-0
87
88 On Fedora, a libbson package is available in the default repositories
89 and can be installed with:
90
91 $ dnf install libbson
92
93 On recent Red Hat systems, such as CentOS and RHEL 7, a libbson package
94 is available in the EPEL repository. To check which version is avail‐
95 able, see https://apps.fedoraproject.org/packages/libbson. The package
96 can be installed with:
97
98 $ yum install libbson
99
100 Build environment
101 Build environment on Unix
102 Prerequisites for libmongoc
103 OpenSSL is required for authentication or for TLS connections to Mon‐
104 goDB. Kerberos or LDAP support requires Cyrus SASL.
105
106 To install all optional dependencies on RedHat / Fedora:
107
108 $ sudo yum install cmake openssl-devel cyrus-sasl-devel
109
110 On Debian / Ubuntu:
111
112 $ sudo apt-get install cmake libssl-dev libsasl2-dev
113
114 On FreeBSD:
115
116 $ su -c 'pkg install cmake openssl cyrus-sasl'
117
118 Prerequisites for libbson
119 The only prerequisite for building libbson is cmake. The command lines
120 above can be adjusted to install only cmake.
121
122 Build environment on macOS
123 Install the XCode Command Line Tools:
124
125 $ xcode-select --install
126
127 The cmake utility is also required. First install Homebrew according to
128 its instructions, then:
129
130 $ brew install cmake
131
132 Build environment on Windows with Visual Studio
133 Building on Windows requires Windows Vista or newer and Visual Studio
134 2010 or newer. Additionally, cmake is required to generate Visual Stu‐
135 dio project files. Installation of these components on Windows is be‐
136 yond the scope of this document.
137
138 Build environment on Windows with MinGW-W64 and MSYS2
139 Install MSYS2 from msys2.github.io. Choose the x86_64 version, not
140 i686.
141
142 Open the MingGW shell with c:\msys64\ming64.exe (not the msys2_shell).
143 Install dependencies:
144
145 $ pacman --noconfirm -Syu
146 $ pacman --noconfirm -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake
147 $ pacman --noconfirm -S mingw-w64-x86_64-extra-cmake-modules make tar
148 $ pacman --noconfirm -S mingw64/mingw-w64-x86_64-cyrus-sasl
149
150 Configuring the build
151 Before building libmongoc and/or libbson, it is necessary to configure,
152 or prepare, the build. The steps to prepare the build depend on how
153 you obtained the source code and the build platform.
154
155 Preparing a build from a release tarball
156 The most recent release of libmongoc and libbson, both of which are in‐
157 cluded in mongo-c-driver, can be downloaded here. The instructions in
158 this document utilize cmake's out-of-source build feature to keep build
159 artifacts separate from source files. While the $ prompt is used
160 throughout, the instructions below will work on Linux, macOS, and Win‐
161 dows (assuming that CMake is in the user's shell path in all cases).
162 See the subsequent sections for additional platform-specific instruc‐
163 tions.
164
165 The following snippet will download and extract the driver, and config‐
166 ure it:
167
168 $ wget https://github.com/mongodb/mongo-c-driver/releases/download/1.20.0/mongo-c-driver-1.20.0.tar.gz
169 $ tar xzf mongo-c-driver-1.20.0.tar.gz
170 $ cd mongo-c-driver-1.20.0
171 $ mkdir cmake-build
172 $ cd cmake-build
173 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
174
175 The -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF option is recommended, see
176 init-cleanup. Another useful cmake option is -DCMAKE_BUILD_TYPE=Release
177 for a release optimized build and -DCMAKE_BUILD_TYPE=Debug for a debug
178 build. For a list of all configure options, run cmake -L ...
179
180 If cmake completed successfully, you will see a considerable amount of
181 output describing your build configuration. The final line of output
182 should look something like this:
183
184 -- Build files have been written to: /home/user/mongo-c-driver-1.20.0/cmake-build
185
186 If cmake concludes with anything different, then it is likely an error
187 occurred.
188
189 mongo-c-driver contains a copy of libbson, in case your system does not
190 already have libbson installed. The configuration will detect if libb‐
191 son is not installed and use the bundled libbson.
192
193 Additionally, it is possible to build only libbson by setting the -DEN‐
194 ABLE_MONGOC=OFF option:
195
196 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF ..
197
198 A build configuration description similar to the one above will be dis‐
199 played, though with fewer entries. Once the configuration is complete,
200 the selected items can be built and installed with these commands:
201
202 Preparing a build from a git repository clone
203 Clone the repository and prepare the build on the current branch or a
204 particular release tag:
205
206 $ git clone https://github.com/mongodb/mongo-c-driver.git
207 $ cd mongo-c-driver
208 $ git checkout 1.20.0 # To build a particular release
209 $ python build/calc_release_version.py > VERSION_CURRENT
210 $ mkdir cmake-build
211 $ cd cmake-build
212 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
213
214 Preparing a build on Windows with Visual Studio
215 On the Windows platform with Visual Studio, it may be necessary to
216 specify the CMake generator to use. This is especially important if
217 multiple versions of Visual Studio are installed on the system or if
218 alternate build tools (e.g., MinGW, MSYS2, Cygwin, etc.) are present on
219 the system. Specifying the generator will ensure that the build con‐
220 figuration is known with certainty, rather than relying on the
221 toolchain that CMake happens to find.
222
223 Start by generating Visual Studio project files. The following assumes
224 you are compiling for 64-bit Windows using Visual Studio 2015 Express,
225 which can be freely downloaded from Microsoft. The sample commands uti‐
226 lize cmake's out-of-source build feature to keep build artifacts sepa‐
227 rate from source files.
228
229 $ cd mongo-c-driver-1.20.0
230 $ mkdir cmake-build
231 $ cd cmake-build
232 $ cmake -G "Visual Studio 14 2015 Win64" \
233 "-DCMAKE_INSTALL_PREFIX=C:\mongo-c-driver" \
234 "-DCMAKE_PREFIX_PATH=C:\mongo-c-driver" \
235 ..
236
237 (Run cmake -LH .. for a list of other options.)
238
239 To see a complete list of the CMake generators available on your spe‐
240 cific system, use a command like this:
241
242 $ cmake --help
243
244 Executing a build
245 Building on Unix, macOS, and Windows (MinGW-W64 and MSYS2)
246 $ cmake --build .
247 $ sudo cmake --build . --target install
248
249 (Note that the sudo command may not be applicable or available depend‐
250 ing on the configuration of your system.)
251
252 In the above commands, the first relies on the default target which
253 builds all configured components. For fine grained control over what
254 gets built, the following command can be used (for Ninja and Make‐
255 file-based build systems) to list all available targets:
256
257 $ cmake --build . help
258
259 Building on Windows with Visual Studio
260 Once the project files are generated, the project can be opened di‐
261 rectly in Visual Studio or compiled from the command line.
262
263 Build using the CMake build tool mode:
264
265 $ cmake --build . --config RelWithDebInfo
266
267 Visual Studio's default build type is Debug, but we recommend a release
268 build with debug info for production use. Now that libmongoc and libb‐
269 son are compiled, install them. Components will be installed to the
270 path specified by CMAKE_INSTALL_PREFIX.
271
272 $ cmake --build . --config RelWithDebInfo --target install
273
274 You should now see libmongoc and libbson installed in C:\mongo-c-driver
275
276 For Visual Studio 2019 (16.4 and newer), this command can be used to
277 list all available targets:
278
279 $ cmake --build . -- /targets
280
281 Alternately, you can examine the files matching the glob *.vcxproj in
282 the cmake-build directory.
283
284 To use the driver libraries in your program, see visual-studio-guide.
285
286 Generating the documentation
287 Install Sphinx, then:
288
289 $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
290 $ cmake --build . --target mongoc-doc
291
292 To build only the libbson documentation:
293
294 $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
295 $ cmake --build . --target bson-doc
296
297 The -DENABLE_MAN_PAGES=ON and -DENABLE_HTML_DOCS=ON can also be added
298 as options to a normal build from a release tarball or from git so that
299 the documentation is built at the same time as other components.
300
301 Uninstalling the installed components
302 There are two ways to uninstall the components that have been in‐
303 stalled. The first is to invoke the uninstall program directly. On
304 Linux/Unix:
305
306 $ sudo /usr/local/share/mongo-c-driver/uninstall.sh
307
308 On Windows:
309
310 $ C:\mongo-c-driver\share\mongo-c-driver\uninstall.bat
311
312 The second way to uninstall is from within the build directory, assum‐
313 ing that it is in the exact same state as when the install command was
314 invoked:
315
316 $ sudo cmake --build . --target uninstall
317
318 The second approach simply invokes the uninstall program referenced in
319 the first approach.
320
321 Dealing with Build Failures
322 If your attempt to build the C driver fails, please see the README
323 <https://github.com/mongodb/mongo-c-driver#how-to-ask-for-help> for in‐
324 structions on requesting assistance.
325
326 Additional Options for Integrators
327 In the event that you are building the BSON library and/or the C driver
328 to embed with other components and you wish to avoid the potential for
329 collision with components installed from a standard build or from a
330 distribution package manager, you can make use of the BSON_OUTPUT_BASE‐
331 NAME and MONGOC_OUTPUT_BASENAME options to cmake.
332
333 $ cmake -DBSON_OUTPUT_BASENAME=custom_bson -DMONGOC_OUTPUT_BASENAME=custom_mongoc ..
334
335 The above command would produce libraries named libcustom_bson.so and
336 libcustom_mongoc.so (or with the extension appropriate for the build
337 platform). Those libraries could be placed in a standard system direc‐
338 tory or in an alternate location and could be linked to by specifying
339 something like -lcustom_mongoc -lcustom_bson on the linker command line
340 (possibly adjusting the specific flags to those required by your
341 linker).
342
343 Tutorial
344 This guide offers a brief introduction to the MongoDB C Driver.
345
346 For more information on the C API, please refer to the api.
347
348 Contents
349 • Tutorial
350
351 • Installing
352
353 • Starting MongoDB
354
355 • Include and link libmongoc in your C program
356
357 • Use libmongoc in a Microsoft Visual Studio Project
358
359 • Making a Connection
360
361 • Creating BSON Documents
362
363 • Basic CRUD Operations
364
365 • Executing Commands
366
367 • Threading
368
369 • Next Steps
370
371 Installing
372 For detailed instructions on installing the MongoDB C Driver on a par‐
373 ticular platform, please see the installation guide.
374
375 Starting MongoDB
376 To run the examples in this tutorial, MongoDB must be installed and
377 running on localhost on the default port, 27017. To check if it is up
378 and running, connect to it with the MongoDB shell.
379
380 $ mongo --host localhost --port 27017
381 MongoDB shell version: 3.0.6
382 connecting to: localhost:27017/test
383 >
384
385 Include and link libmongoc in your C program
386 Include mongoc.h
387 All libmongoc's functions and types are available in one header file.
388 Simply include mongoc/mongoc.h:
389
390 #include <mongoc/mongoc.h>
391
392 CMake
393 The libmongoc installation includes a CMake config-file package, so you
394 can use CMake's find_package command to import libmongoc's CMake target
395 and link to libmongoc (as a shared library):
396
397 CMakeLists.txt
398
399 # Specify the minimum version you require.
400 find_package (mongoc-1.0 1.7 REQUIRED)
401
402 # The "hello_mongoc.c" sample program is shared among four tests.
403 add_executable (hello_mongoc ../../hello_mongoc.c)
404 target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_shared)
405
406
407 You can also use libmongoc as a static library instead: Use the
408 mongo::mongoc_static CMake target:
409
410 # Specify the minimum version you require.
411 find_package (mongoc-1.0 1.7 REQUIRED)
412
413 # The "hello_mongoc.c" sample program is shared among four tests.
414 add_executable (hello_mongoc ../../hello_mongoc.c)
415 target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_static)
416
417
418 pkg-config
419 If you're not using CMake, use pkg-config on the command line to set
420 header and library paths:
421
422 gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0)
423
424
425 Or to statically link to libmongoc:
426
427 gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0)
428
429
430 Specifying header and include paths manually
431 If you aren't using CMake or pkg-config, paths and libraries can be
432 managed manually.
433
434 $ gcc -o hello_mongoc hello_mongoc.c \
435 -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
436 -lmongoc-1.0 -lbson-1.0
437 $ ./hello_mongoc
438 { "ok" : 1.000000 }
439
440 For Windows users, the code can be compiled and run with the following
441 commands. (This assumes that the MongoDB C Driver has been installed to
442 C:\mongo-c-driver; change the include directory as needed.)
443
444 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 hello_mongoc.c
445 C:\> hello_mongoc
446 { "ok" : 1.000000 }
447
448 Use libmongoc in a Microsoft Visual Studio Project
449 See the libmongoc and Visual Studio guide.
450
451 Making a Connection
452 Access MongoDB with a mongoc_client_t. It transparently connects to
453 standalone servers, replica sets and sharded clusters on demand. To
454 perform operations on a database or collection, create a mongoc_data‐
455 base_t or mongoc_collection_t struct from the mongoc_client_t.
456
457 At the start of an application, call mongoc_init before any other lib‐
458 mongoc functions. At the end, call the appropriate destroy function for
459 each collection, database, or client handle, in reverse order from how
460 they were constructed. Call mongoc_cleanup before exiting.
461
462 The example below establishes a connection to a standalone server on
463 localhost, registers the client application as "connect-example," and
464 performs a simple command.
465
466 More information about database operations can be found in the CRUD Op‐
467 erations and Executing Commands sections. Examples of connecting to
468 replica sets and sharded clusters can be found on the Advanced Connec‐
469 tions page.
470
471 hello_mongoc.c
472
473 #include <mongoc/mongoc.h>
474
475 int
476 main (int argc, char *argv[])
477 {
478 const char *uri_string = "mongodb://localhost:27017";
479 mongoc_uri_t *uri;
480 mongoc_client_t *client;
481 mongoc_database_t *database;
482 mongoc_collection_t *collection;
483 bson_t *command, reply, *insert;
484 bson_error_t error;
485 char *str;
486 bool retval;
487
488 /*
489 * Required to initialize libmongoc's internals
490 */
491 mongoc_init ();
492
493 /*
494 * Optionally get MongoDB URI from command line
495 */
496 if (argc > 1) {
497 uri_string = argv[1];
498 }
499
500 /*
501 * Safely create a MongoDB URI object from the given string
502 */
503 uri = mongoc_uri_new_with_error (uri_string, &error);
504 if (!uri) {
505 fprintf (stderr,
506 "failed to parse URI: %s\n"
507 "error message: %s\n",
508 uri_string,
509 error.message);
510 return EXIT_FAILURE;
511 }
512
513 /*
514 * Create a new client instance
515 */
516 client = mongoc_client_new_from_uri (uri);
517 if (!client) {
518 return EXIT_FAILURE;
519 }
520
521 /*
522 * Register the application name so we can track it in the profile logs
523 * on the server. This can also be done from the URI (see other examples).
524 */
525 mongoc_client_set_appname (client, "connect-example");
526
527 /*
528 * Get a handle on the database "db_name" and collection "coll_name"
529 */
530 database = mongoc_client_get_database (client, "db_name");
531 collection = mongoc_client_get_collection (client, "db_name", "coll_name");
532
533 /*
534 * Do work. This example pings the database, prints the result as JSON and
535 * performs an insert
536 */
537 command = BCON_NEW ("ping", BCON_INT32 (1));
538
539 retval = mongoc_client_command_simple (
540 client, "admin", command, NULL, &reply, &error);
541
542 if (!retval) {
543 fprintf (stderr, "%s\n", error.message);
544 return EXIT_FAILURE;
545 }
546
547 str = bson_as_json (&reply, NULL);
548 printf ("%s\n", str);
549
550 insert = BCON_NEW ("hello", BCON_UTF8 ("world"));
551
552 if (!mongoc_collection_insert_one (collection, insert, NULL, NULL, &error)) {
553 fprintf (stderr, "%s\n", error.message);
554 }
555
556 bson_destroy (insert);
557 bson_destroy (&reply);
558 bson_destroy (command);
559 bson_free (str);
560
561 /*
562 * Release our handles and clean up libmongoc
563 */
564 mongoc_collection_destroy (collection);
565 mongoc_database_destroy (database);
566 mongoc_uri_destroy (uri);
567 mongoc_client_destroy (client);
568 mongoc_cleanup ();
569
570 return EXIT_SUCCESS;
571 }
572
573
574 Creating BSON Documents
575 Documents are stored in MongoDB's data format, BSON. The C driver uses
576 libbson to create BSON documents. There are several ways to construct
577 them: appending key-value pairs, using BCON, or parsing JSON.
578
579 Appending BSON
580 A BSON document, represented as a bson_t in code, can be constructed
581 one field at a time using libbson's append functions.
582
583 For example, to create a document like this:
584
585 {
586 born : ISODate("1906-12-09"),
587 died : ISODate("1992-01-01"),
588 name : {
589 first : "Grace",
590 last : "Hopper"
591 },
592 languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ],
593 degrees: [ { degree: "BA", school: "Vassar" }, { degree: "PhD", school: "Yale" } ]
594 }
595
596 Use the following code:
597
598 #include <bson/bson.h>
599
600 int
601 main (int argc,
602 char *argv[])
603 {
604 struct tm born = { 0 };
605 struct tm died = { 0 };
606 const char *lang_names[] = {"MATH-MATIC", "FLOW-MATIC", "COBOL"};
607 const char *schools[] = {"Vassar", "Yale"};
608 const char *degrees[] = {"BA", "PhD"};
609 uint32_t i;
610 char buf[16];
611 const char *key;
612 size_t keylen;
613 bson_t *document;
614 bson_t child;
615 bson_t child2;
616 char *str;
617
618 document = bson_new ();
619
620 /*
621 * Append { "born" : ISODate("1906-12-09") } to the document.
622 * Passing -1 for the length argument tells libbson to calculate the string length.
623 */
624 born.tm_year = 6; /* years are 1900-based */
625 born.tm_mon = 11; /* months are 0-based */
626 born.tm_mday = 9;
627 bson_append_date_time (document, "born", -1, mktime (&born) * 1000);
628
629 /*
630 * Append { "died" : ISODate("1992-01-01") } to the document.
631 */
632 died.tm_year = 92;
633 died.tm_mon = 0;
634 died.tm_mday = 1;
635
636 /*
637 * For convenience, this macro passes length -1 by default.
638 */
639 BSON_APPEND_DATE_TIME (document, "died", mktime (&died) * 1000);
640
641 /*
642 * Append a subdocument.
643 */
644 BSON_APPEND_DOCUMENT_BEGIN (document, "name", &child);
645 BSON_APPEND_UTF8 (&child, "first", "Grace");
646 BSON_APPEND_UTF8 (&child, "last", "Hopper");
647 bson_append_document_end (document, &child);
648
649 /*
650 * Append array of strings. Generate keys "0", "1", "2".
651 */
652 BSON_APPEND_ARRAY_BEGIN (document, "languages", &child);
653 for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) {
654 keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
655 bson_append_utf8 (&child, key, (int) keylen, lang_names[i], -1);
656 }
657 bson_append_array_end (document, &child);
658
659 /*
660 * Array of subdocuments:
661 * degrees: [ { degree: "BA", school: "Vassar" }, ... ]
662 */
663 BSON_APPEND_ARRAY_BEGIN (document, "degrees", &child);
664 for (i = 0; i < sizeof degrees / sizeof (char *); ++i) {
665 keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
666 bson_append_document_begin (&child, key, (int) keylen, &child2);
667 BSON_APPEND_UTF8 (&child2, "degree", degrees[i]);
668 BSON_APPEND_UTF8 (&child2, "school", schools[i]);
669 bson_append_document_end (&child, &child2);
670 }
671 bson_append_array_end (document, &child);
672
673 /*
674 * Print the document as a JSON string.
675 */
676 str = bson_as_canonical_extended_json (document, NULL);
677 printf ("%s\n", str);
678 bson_free (str);
679
680 /*
681 * Clean up allocated bson documents.
682 */
683 bson_destroy (document);
684 return 0;
685 }
686
687 See the libbson documentation for all of the types that can be appended
688 to a bson_t.
689
690 Using BCON
691 BSON C Object Notation, BCON for short, is an alternative way of con‐
692 structing BSON documents in a manner closer to the intended format. It
693 has less type-safety than BSON's append functions but results in less
694 code.
695
696 #include <bson/bson.h>
697
698 int
699 main (int argc,
700 char *argv[])
701 {
702 struct tm born = { 0 };
703 struct tm died = { 0 };
704 bson_t *document;
705 char *str;
706
707 born.tm_year = 6;
708 born.tm_mon = 11;
709 born.tm_mday = 9;
710
711 died.tm_year = 92;
712 died.tm_mon = 0;
713 died.tm_mday = 1;
714
715 document = BCON_NEW (
716 "born", BCON_DATE_TIME (mktime (&born) * 1000),
717 "died", BCON_DATE_TIME (mktime (&died) * 1000),
718 "name", "{",
719 "first", BCON_UTF8 ("Grace"),
720 "last", BCON_UTF8 ("Hopper"),
721 "}",
722 "languages", "[",
723 BCON_UTF8 ("MATH-MATIC"),
724 BCON_UTF8 ("FLOW-MATIC"),
725 BCON_UTF8 ("COBOL"),
726 "]",
727 "degrees", "[",
728 "{", "degree", BCON_UTF8 ("BA"), "school", BCON_UTF8 ("Vassar"), "}",
729 "{", "degree", BCON_UTF8 ("PhD"), "school", BCON_UTF8 ("Yale"), "}",
730 "]");
731
732 /*
733 * Print the document as a JSON string.
734 */
735 str = bson_as_canonical_extended_json (document, NULL);
736 printf ("%s\n", str);
737 bson_free (str);
738
739 /*
740 * Clean up allocated bson documents.
741 */
742 bson_destroy (document);
743 return 0;
744 }
745
746 Notice that BCON can create arrays, subdocuments and arbitrary fields.
747
748 Creating BSON from JSON
749 For single documents, BSON can be created from JSON strings via
750 bson_new_from_json.
751
752 #include <bson/bson.h>
753
754 int
755 main (int argc,
756 char *argv[])
757 {
758 bson_error_t error;
759 bson_t *bson;
760 char *string;
761
762 const char *json = "{\"name\": {\"first\":\"Grace\", \"last\":\"Hopper\"}}";
763 bson = bson_new_from_json ((const uint8_t *)json, -1, &error);
764
765 if (!bson) {
766 fprintf (stderr, "%s\n", error.message);
767 return EXIT_FAILURE;
768 }
769
770 string = bson_as_canonical_extended_json (bson, NULL);
771 printf ("%s\n", string);
772 bson_free (string);
773
774 return 0;
775 }
776
777 To initialize BSON from a sequence of JSON documents, use
778 bson_json_reader_t.
779
780 Basic CRUD Operations
781 This section demonstrates the basics of using the C Driver to interact
782 with MongoDB.
783
784 Inserting a Document
785 To insert documents into a collection, first obtain a handle to a mon‐
786 goc_collection_t via a mongoc_client_t. Then, use mongoc_collection_in‐
787 sert_one to add BSON documents to the collection. This example inserts
788 into the database "mydb" and collection "mycoll".
789
790 When finished, ensure that allocated structures are freed by using
791 their respective destroy functions.
792
793 #include <bson/bson.h>
794 #include <mongoc/mongoc.h>
795 #include <stdio.h>
796
797 int
798 main (int argc,
799 char *argv[])
800 {
801 mongoc_client_t *client;
802 mongoc_collection_t *collection;
803 bson_error_t error;
804 bson_oid_t oid;
805 bson_t *doc;
806
807 mongoc_init ();
808
809 client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
810 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
811
812 doc = bson_new ();
813 bson_oid_init (&oid, NULL);
814 BSON_APPEND_OID (doc, "_id", &oid);
815 BSON_APPEND_UTF8 (doc, "hello", "world");
816
817 if (!mongoc_collection_insert_one (
818 collection, doc, NULL, NULL, &error)) {
819 fprintf (stderr, "%s\n", error.message);
820 }
821
822 bson_destroy (doc);
823 mongoc_collection_destroy (collection);
824 mongoc_client_destroy (client);
825 mongoc_cleanup ();
826
827 return 0;
828 }
829
830 Compile the code and run it:
831
832 $ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0)
833 $ ./insert
834
835 On Windows:
836
837 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c
838 C:\> insert
839
840 To verify that the insert succeeded, connect with the MongoDB shell.
841
842 $ mongo
843 MongoDB shell version: 3.0.6
844 connecting to: test
845 > use mydb
846 switched to db mydb
847 > db.mycoll.find()
848 { "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" }
849 >
850
851 Finding a Document
852 To query a MongoDB collection with the C driver, use the function mon‐
853 goc_collection_find_with_opts(). This returns a cursor to the matching
854 documents. The following examples iterate through the result cursors
855 and print the matches to stdout as JSON strings.
856
857 Use a document as a query specifier; for example,
858
859 { "color" : "red" }
860
861 will match any document with a field named "color" with value "red". An
862 empty document {} can be used to match all documents.
863
864 This first example uses an empty query specifier to find all documents
865 in the database "mydb" and collection "mycoll".
866
867 #include <bson/bson.h>
868 #include <mongoc/mongoc.h>
869 #include <stdio.h>
870
871 int
872 main (int argc, char *argv[])
873 {
874 mongoc_client_t *client;
875 mongoc_collection_t *collection;
876 mongoc_cursor_t *cursor;
877 const bson_t *doc;
878 bson_t *query;
879 char *str;
880
881 mongoc_init ();
882
883 client =
884 mongoc_client_new ("mongodb://localhost:27017/?appname=find-example");
885 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
886 query = bson_new ();
887 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
888
889 while (mongoc_cursor_next (cursor, &doc)) {
890 str = bson_as_canonical_extended_json (doc, NULL);
891 printf ("%s\n", str);
892 bson_free (str);
893 }
894
895 bson_destroy (query);
896 mongoc_cursor_destroy (cursor);
897 mongoc_collection_destroy (collection);
898 mongoc_client_destroy (client);
899 mongoc_cleanup ();
900
901 return 0;
902 }
903
904 Compile the code and run it:
905
906 $ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0)
907 $ ./find
908 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
909
910 On Windows:
911
912 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c
913 C:\> find
914 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
915
916 To look for a specific document, add a specifier to query. This example
917 adds a call to BSON_APPEND_UTF8() to look for all documents matching
918 {"hello" : "world"}.
919
920 #include <bson/bson.h>
921 #include <mongoc/mongoc.h>
922 #include <stdio.h>
923
924 int
925 main (int argc, char *argv[])
926 {
927 mongoc_client_t *client;
928 mongoc_collection_t *collection;
929 mongoc_cursor_t *cursor;
930 const bson_t *doc;
931 bson_t *query;
932 char *str;
933
934 mongoc_init ();
935
936 client = mongoc_client_new (
937 "mongodb://localhost:27017/?appname=find-specific-example");
938 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
939 query = bson_new ();
940 BSON_APPEND_UTF8 (query, "hello", "world");
941
942 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
943
944 while (mongoc_cursor_next (cursor, &doc)) {
945 str = bson_as_canonical_extended_json (doc, NULL);
946 printf ("%s\n", str);
947 bson_free (str);
948 }
949
950 bson_destroy (query);
951 mongoc_cursor_destroy (cursor);
952 mongoc_collection_destroy (collection);
953 mongoc_client_destroy (client);
954 mongoc_cleanup ();
955
956 return 0;
957 }
958
959 $ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0)
960 $ ./find-specific
961 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
962
963 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c
964 C:\> find-specific
965 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
966
967 Updating a Document
968 This code snippet gives an example of using mongoc_collection_up‐
969 date_one() to update the fields of a document.
970
971 Using the "mydb" database, the following example inserts an example
972 document into the "mycoll" collection. Then, using its _id field, the
973 document is updated with different values and a new field.
974
975 #include <bson/bson.h>
976 #include <mongoc/mongoc.h>
977 #include <stdio.h>
978
979 int
980 main (int argc, char *argv[])
981 {
982 mongoc_collection_t *collection;
983 mongoc_client_t *client;
984 bson_error_t error;
985 bson_oid_t oid;
986 bson_t *doc = NULL;
987 bson_t *update = NULL;
988 bson_t *query = NULL;
989
990 mongoc_init ();
991
992 client =
993 mongoc_client_new ("mongodb://localhost:27017/?appname=update-example");
994 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
995
996 bson_oid_init (&oid, NULL);
997 doc = BCON_NEW ("_id", BCON_OID (&oid), "key", BCON_UTF8 ("old_value"));
998
999 if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
1000 fprintf (stderr, "%s\n", error.message);
1001 goto fail;
1002 }
1003
1004 query = BCON_NEW ("_id", BCON_OID (&oid));
1005 update = BCON_NEW ("$set",
1006 "{",
1007 "key",
1008 BCON_UTF8 ("new_value"),
1009 "updated",
1010 BCON_BOOL (true),
1011 "}");
1012
1013 if (!mongoc_collection_update_one (
1014 collection, query, update, NULL, NULL, &error)) {
1015 fprintf (stderr, "%s\n", error.message);
1016 goto fail;
1017 }
1018
1019 fail:
1020 if (doc)
1021 bson_destroy (doc);
1022 if (query)
1023 bson_destroy (query);
1024 if (update)
1025 bson_destroy (update);
1026
1027 mongoc_collection_destroy (collection);
1028 mongoc_client_destroy (client);
1029 mongoc_cleanup ();
1030
1031 return 0;
1032 }
1033
1034 Compile the code and run it:
1035
1036 $ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0)
1037 $ ./update
1038
1039 On Windows:
1040
1041 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c
1042 C:\> update
1043 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
1044
1045 To verify that the update succeeded, connect with the MongoDB shell.
1046
1047 $ mongo
1048 MongoDB shell version: 3.0.6
1049 connecting to: test
1050 > use mydb
1051 switched to db mydb
1052 > db.mycoll.find({"updated" : true})
1053 { "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" }
1054 >
1055
1056 Deleting a Document
1057 This example illustrates the use of mongoc_collection_delete_one() to
1058 delete a document.
1059
1060 The following code inserts a sample document into the database "mydb"
1061 and collection "mycoll". Then, it deletes all documents matching
1062 {"hello" : "world"}.
1063
1064 #include <bson/bson.h>
1065 #include <mongoc/mongoc.h>
1066 #include <stdio.h>
1067
1068 int
1069 main (int argc, char *argv[])
1070 {
1071 mongoc_client_t *client;
1072 mongoc_collection_t *collection;
1073 bson_error_t error;
1074 bson_oid_t oid;
1075 bson_t *doc;
1076
1077 mongoc_init ();
1078
1079 client =
1080 mongoc_client_new ("mongodb://localhost:27017/?appname=delete-example");
1081 collection = mongoc_client_get_collection (client, "test", "test");
1082
1083 doc = bson_new ();
1084 bson_oid_init (&oid, NULL);
1085 BSON_APPEND_OID (doc, "_id", &oid);
1086 BSON_APPEND_UTF8 (doc, "hello", "world");
1087
1088 if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
1089 fprintf (stderr, "Insert failed: %s\n", error.message);
1090 }
1091
1092 bson_destroy (doc);
1093
1094 doc = bson_new ();
1095 BSON_APPEND_OID (doc, "_id", &oid);
1096
1097 if (!mongoc_collection_delete_one (
1098 collection, doc, NULL, NULL, &error)) {
1099 fprintf (stderr, "Delete failed: %s\n", error.message);
1100 }
1101
1102 bson_destroy (doc);
1103 mongoc_collection_destroy (collection);
1104 mongoc_client_destroy (client);
1105 mongoc_cleanup ();
1106
1107 return 0;
1108 }
1109
1110 Compile the code and run it:
1111
1112 $ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0)
1113 $ ./delete
1114
1115 On Windows:
1116
1117 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c
1118 C:\> delete
1119
1120 Use the MongoDB shell to prove that the documents have been removed
1121 successfully.
1122
1123 $ mongo
1124 MongoDB shell version: 3.0.6
1125 connecting to: test
1126 > use mydb
1127 switched to db mydb
1128 > db.mycoll.count({"hello" : "world"})
1129 0
1130 >
1131
1132 Counting Documents
1133 Counting the number of documents in a MongoDB collection is similar to
1134 performing a find operation. This example counts the number of docu‐
1135 ments matching {"hello" : "world"} in the database "mydb" and collec‐
1136 tion "mycoll".
1137
1138 #include <bson/bson.h>
1139 #include <mongoc/mongoc.h>
1140 #include <stdio.h>
1141
1142 int
1143 main (int argc, char *argv[])
1144 {
1145 mongoc_client_t *client;
1146 mongoc_collection_t *collection;
1147 bson_error_t error;
1148 bson_t *doc;
1149 int64_t count;
1150
1151 mongoc_init ();
1152
1153 client =
1154 mongoc_client_new ("mongodb://localhost:27017/?appname=count-example");
1155 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
1156 doc = bson_new_from_json (
1157 (const uint8_t *) "{\"hello\" : \"world\"}", -1, &error);
1158
1159 count = mongoc_collection_count (
1160 collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
1161
1162 if (count < 0) {
1163 fprintf (stderr, "%s\n", error.message);
1164 } else {
1165 printf ("%" PRId64 "\n", count);
1166 }
1167
1168 bson_destroy (doc);
1169 mongoc_collection_destroy (collection);
1170 mongoc_client_destroy (client);
1171 mongoc_cleanup ();
1172
1173 return 0;
1174 }
1175
1176 Compile the code and run it:
1177
1178 $ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0)
1179 $ ./count
1180 1
1181
1182 On Windows:
1183
1184 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c
1185 C:\> count
1186 1
1187
1188 Executing Commands
1189 The driver provides helper functions for executing MongoDB commands on
1190 client, database and collection structures. These functions return cur‐
1191 sors; the _simple variants return booleans indicating success or fail‐
1192 ure.
1193
1194 This example executes the collStats command against the collection "my‐
1195 coll" in database "mydb".
1196
1197 #include <bson/bson.h>
1198 #include <mongoc/mongoc.h>
1199 #include <stdio.h>
1200
1201 int
1202 main (int argc, char *argv[])
1203 {
1204 mongoc_client_t *client;
1205 mongoc_collection_t *collection;
1206 bson_error_t error;
1207 bson_t *command;
1208 bson_t reply;
1209 char *str;
1210
1211 mongoc_init ();
1212
1213 client = mongoc_client_new (
1214 "mongodb://localhost:27017/?appname=executing-example");
1215 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
1216
1217 command = BCON_NEW ("collStats", BCON_UTF8 ("mycoll"));
1218 if (mongoc_collection_command_simple (
1219 collection, command, NULL, &reply, &error)) {
1220 str = bson_as_canonical_extended_json (&reply, NULL);
1221 printf ("%s\n", str);
1222 bson_free (str);
1223 } else {
1224 fprintf (stderr, "Failed to run command: %s\n", error.message);
1225 }
1226
1227 bson_destroy (command);
1228 bson_destroy (&reply);
1229 mongoc_collection_destroy (collection);
1230 mongoc_client_destroy (client);
1231 mongoc_cleanup ();
1232
1233 return 0;
1234 }
1235
1236 Compile the code and run it:
1237
1238 $ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0)
1239 $ ./executing
1240 { "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
1241 "lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
1242 "indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
1243
1244 On Windows:
1245
1246 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c
1247 C:\> executing
1248 { "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
1249 "lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
1250 "indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
1251
1252 Threading
1253 The MongoDB C Driver is thread-unaware in the vast majority of its op‐
1254 erations. This means it is up to the programmer to guarantee
1255 thread-safety.
1256
1257 However, mongoc_client_pool_t is thread-safe and is used to fetch a
1258 mongoc_client_t in a thread-safe manner. After retrieving a client from
1259 the pool, the client structure should be considered owned by the call‐
1260 ing thread. When the thread is finished, the client should be placed
1261 back into the pool.
1262
1263 example-pool.c
1264
1265 /* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
1266 * libmongoc-1.0) */
1267
1268 /* ./example-pool [CONNECTION_STRING] */
1269
1270 #include <mongoc/mongoc.h>
1271 #include <pthread.h>
1272 #include <stdio.h>
1273
1274 static pthread_mutex_t mutex;
1275 static bool in_shutdown = false;
1276
1277 static void *
1278 worker (void *data)
1279 {
1280 mongoc_client_pool_t *pool = data;
1281 mongoc_client_t *client;
1282 bson_t ping = BSON_INITIALIZER;
1283 bson_error_t error;
1284 bool r;
1285
1286 BSON_APPEND_INT32 (&ping, "ping", 1);
1287
1288 while (true) {
1289 client = mongoc_client_pool_pop (pool);
1290 /* Do something with client. If you are writing an HTTP server, you
1291 * probably only want to hold onto the client for the portion of the
1292 * request performing database queries.
1293 */
1294 r = mongoc_client_command_simple (
1295 client, "admin", &ping, NULL, NULL, &error);
1296
1297 if (!r) {
1298 fprintf (stderr, "%s\n", error.message);
1299 }
1300
1301 mongoc_client_pool_push (pool, client);
1302
1303 pthread_mutex_lock (&mutex);
1304 if (in_shutdown || !r) {
1305 pthread_mutex_unlock (&mutex);
1306 break;
1307 }
1308
1309 pthread_mutex_unlock (&mutex);
1310 }
1311
1312 bson_destroy (&ping);
1313 return NULL;
1314 }
1315
1316 int
1317 main (int argc, char *argv[])
1318 {
1319 const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
1320 mongoc_uri_t *uri;
1321 bson_error_t error;
1322 mongoc_client_pool_t *pool;
1323 pthread_t threads[10];
1324 unsigned i;
1325 void *ret;
1326
1327 pthread_mutex_init (&mutex, NULL);
1328 mongoc_init ();
1329
1330 if (argc > 1) {
1331 uri_string = argv[1];
1332 }
1333
1334 uri = mongoc_uri_new_with_error (uri_string, &error);
1335 if (!uri) {
1336 fprintf (stderr,
1337 "failed to parse URI: %s\n"
1338 "error message: %s\n",
1339 uri_string,
1340 error.message);
1341 return EXIT_FAILURE;
1342 }
1343
1344 pool = mongoc_client_pool_new (uri);
1345 mongoc_client_pool_set_error_api (pool, 2);
1346
1347 for (i = 0; i < 10; i++) {
1348 pthread_create (&threads[i], NULL, worker, pool);
1349 }
1350
1351 sleep (10);
1352 pthread_mutex_lock (&mutex);
1353 in_shutdown = true;
1354 pthread_mutex_unlock (&mutex);
1355
1356 for (i = 0; i < 10; i++) {
1357 pthread_join (threads[i], &ret);
1358 }
1359
1360 mongoc_client_pool_destroy (pool);
1361 mongoc_uri_destroy (uri);
1362
1363 mongoc_cleanup ();
1364
1365 return EXIT_SUCCESS;
1366 }
1367
1368
1369 Next Steps
1370 To find information on advanced topics, browse the rest of the C driver
1371 guide or the official MongoDB documentation.
1372
1373 For help with common issues, consult the Troubleshooting page. To re‐
1374 port a bug or request a new feature, follow these instructions.
1375
1376 Authentication
1377 This guide covers the use of authentication options with the MongoDB C
1378 Driver. Ensure that the MongoDB server is also properly configured for
1379 authentication before making a connection. For more information, see
1380 the MongoDB security documentation.
1381
1382 The MongoDB C driver supports several authentication mechanisms through
1383 the use of MongoDB connection URIs.
1384
1385 By default, if a username and password are provided as part of the con‐
1386 nection string (and an optional authentication database), they are used
1387 to connect via the default authentication mechanism of the server.
1388
1389 To select a specific authentication mechanism other than the default,
1390 see the list of supported mechanism below.
1391
1392 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");
1393
1394 Currently supported values for the authMechanism connection string op‐
1395 tion are:
1396
1397 • SCRAM-SHA-1
1398
1399 • MONGODB-CR (deprecated)
1400
1401 • GSSAPI
1402
1403 • PLAIN
1404
1405 • X509
1406
1407 • MONGODB-AWS
1408
1409 Basic Authentication (SCRAM-SHA-256)
1410 MongoDB 4.0 introduces support for authenticating using the SCRAM pro‐
1411 tocol with the more secure SHA-256 hash described in RFC 7677. Using
1412 this authentication mechanism means that the password is never actually
1413 sent over the wire when authenticating, but rather a computed proof
1414 that the client password is the same as the password the server knows.
1415 In MongoDB 4.0, the C driver can determine the correct default authen‐
1416 tication mechanism for users with stored SCRAM-SHA-1 and SCRAM-SHA-256
1417 credentials:
1418
1419 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");
1420 /* the correct authMechanism is negotiated between the driver and server. */
1421
1422 Alternatively, SCRAM-SHA-256 can be explicitly specified as an auth‐
1423 Mechanism.
1424
1425 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256&authSource=mydb");
1426
1427 Passwords for SCRAM-SHA-256 undergo the preprocessing step known as
1428 SASLPrep specified in RFC 4013. SASLPrep will only be performed for
1429 passwords containing non-ASCII characters. SASLPrep requires libicu.
1430 If libicu is not available, attempting to authenticate over
1431 SCRAM-SHA-256 with non-ASCII passwords will result in error.
1432
1433 Usernames never undergo SASLPrep.
1434
1435 By default, when building the C driver libicu is linked if available.
1436 This can be changed with the ENABLE_ICU cmake option. To specify an in‐
1437 stallation path of libicu, specify ICU_ROOT as a cmake option. See the
1438 FindICU documentation for more information.
1439
1440 Basic Authentication (SCRAM-SHA-1)
1441 The default authentication mechanism before MongoDB 4.0 is SCRAM-SHA-1
1442 (RFC 5802). Using this authentication mechanism means that the password
1443 is never actually sent over the wire when authenticating, but rather a
1444 computed proof that the client password is the same as the password the
1445 server knows.
1446
1447 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1&authSource=mydb");
1448
1449 NOTE:
1450 SCRAM-SHA-1 authenticates against the admin database by default. If
1451 the user is created in another database, then specifying the auth‐
1452 Source is required.
1453
1454 Legacy Authentication (MONGODB-CR)
1455 The MONGODB-CR authMechanism is deprecated and will no longer function
1456 in MongoDB 4.0. Instead, specify no authMechanism and the driver will
1457 use an authentication mechanism compatible with your server.
1458
1459 GSSAPI (Kerberos) Authentication
1460 NOTE:
1461 Kerberos support requires compiling the driver against cyrus-sasl on
1462 UNIX-like environments. On Windows, configure the driver to build
1463 against the Windows Native SSPI.
1464
1465 GSSAPI (Kerberos) authentication is available in the Enterprise Edition
1466 of MongoDB. To authenticate using GSSAPI, the MongoDB C driver must be
1467 installed with SASL support.
1468
1469 On UNIX-like environments, run the kinit command before using the fol‐
1470 lowing authentication methods:
1471
1472 $ kinit mongodbuser@EXAMPLE.COM
1473 mongodbuser@EXAMPLE.COM's Password:
1474 $ klistCredentials cache: FILE:/tmp/krb5cc_1000
1475 Principal: mongodbuser@EXAMPLE.COM
1476
1477 Issued Expires Principal
1478 Feb 9 13:48:51 2013 Feb 9 23:48:51 2013 krbtgt/EXAMPLE.COM@EXAMPLE.COM
1479
1480 Now authenticate using the MongoDB URI. GSSAPI authenticates against
1481 the $external virtual database, so a database does not need to be spec‐
1482 ified in the URI. Note that the Kerberos principal must be URL-encoded:
1483
1484 mongoc_client_t *client;
1485
1486 client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI");
1487
1488 NOTE:
1489 GSSAPI authenticates against the $external database, so specifying
1490 the authSource database is not required.
1491
1492 The driver supports these GSSAPI properties:
1493
1494 • CANONICALIZE_HOST_NAME: This might be required with Cyrus-SASL when
1495 the hosts report different hostnames than what is used in the Ker‐
1496 beros database. The default is "false".
1497
1498 • SERVICE_NAME: Use a different service name than the default, "mon‐
1499 godb".
1500
1501 Set properties in the URL:
1502
1503 mongoc_client_t *client;
1504
1505 client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI&"
1506 "authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true");
1507
1508 If you encounter errors such as Invalid net address, check if the ap‐
1509 plication is behind a NAT (Network Address Translation) firewall. If
1510 so, create a ticket that uses forwardable and addressless Kerberos
1511 tickets. This can be done by passing -f -A to kinit.
1512
1513 $ kinit -f -A mongodbuser@EXAMPLE.COM
1514
1515 SASL Plain Authentication
1516 NOTE:
1517 The MongoDB C Driver must be compiled with SASL support in order to
1518 use SASL PLAIN authentication.
1519
1520 MongoDB Enterprise Edition supports the SASL PLAIN authentication mech‐
1521 anism, initially intended for delegating authentication to an LDAP
1522 server. Using the SASL PLAIN mechanism is very similar to the challenge
1523 response mechanism with usernames and passwords. This authentication
1524 mechanism uses the $external virtual database for LDAP support:
1525
1526 NOTE:
1527 SASL PLAIN is a clear-text authentication mechanism. It is strongly
1528 recommended to connect to MongoDB using TLS with certificate valida‐
1529 tion when using the PLAIN mechanism.
1530
1531 mongoc_client_t *client;
1532
1533 client = mongoc_client_new ("mongodb://user:password@example.com/?authMechanism=PLAIN");
1534
1535 PLAIN authenticates against the $external database, so specifying the
1536 authSource database is not required.
1537
1538 X.509 Certificate Authentication
1539 NOTE:
1540 The MongoDB C Driver must be compiled with TLS support for X.509 au‐
1541 thentication support. Once this is done, start a server with the
1542 following options:
1543
1544 $ mongod --tlsMode requireTLS --tlsCertificateKeyFile server.pem --tlsCAFile ca.pem
1545
1546 The MONGODB-X509 mechanism authenticates a username derived from the
1547 distinguished subject name of the X.509 certificate presented by the
1548 driver during TLS negotiation. This authentication method requires the
1549 use of TLS connections with certificate validation.
1550
1551 mongoc_client_t *client;
1552 mongoc_ssl_opt_t ssl_opts = { 0 };
1553
1554 ssl_opts.pem_file = "mycert.pem";
1555 ssl_opts.pem_pwd = "mycertpassword";
1556 ssl_opts.ca_file = "myca.pem";
1557 ssl_opts.ca_dir = "trust_dir";
1558 ssl_opts.weak_cert_validation = false;
1559
1560 client = mongoc_client_new ("mongodb://x509_derived_username@localhost/?authMechanism=MONGODB-X509");
1561 mongoc_client_set_ssl_opts (client, &ssl_opts);
1562
1563 MONGODB-X509 authenticates against the $external database, so specify‐
1564 ing the authSource database is not required. For more information on
1565 the x509_derived_username, see the MongoDB server x.509 tutorial.
1566
1567 NOTE:
1568 The MongoDB C Driver will attempt to determine the x509 derived
1569 username when none is provided, and as of MongoDB 3.4 providing the
1570 username is not required at all.
1571
1572 Authentication via AWS IAM
1573 The MONGODB-AWS mechanism authenticates to MongoDB servers with creden‐
1574 tials provided by AWS Identity and Access Management (IAM).
1575
1576 To authenticate, create a user with an associated Amazon Resource Name
1577 (ARN) on the $external database, and specify the MONGODB-AWS authMecha‐
1578 nism in the URI.
1579
1580 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost/?authMechanism=MONGODB-AWS");
1581
1582 Since MONGODB-AWS always authenticates against the $external database,
1583 so specifying the authSource database is not required.
1584
1585 Credentials include the access key id, secret access key, and optional
1586 session token. They may be obtained from the following ways.
1587
1588 AWS credentials via URI
1589 Credentials may be passed directly in the URI as username/password.
1590
1591 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://<access key id>:<secret access key>localhost/?authMechanism=MONGODB-AWS");
1592
1593 This may include a session token passed with authMechanismProperties.
1594
1595 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://<access key id>:<secret access key>localhost/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:<token>");
1596
1597 AWS credentials via environment
1598 If credentials are not passed through the URI, libmongoc will check for
1599 the following environment variables.
1600
1601 • AWS_ACCESS_KEY_ID
1602
1603 • AWS_SECRET_ACCESS_KEY
1604
1605 • AWS_SESSION_TOKEN (optional)
1606
1607 AWS Credentials via ECS
1608 If credentials are not passed in the URI or with environment variables,
1609 libmongoc will check if the environment variable AWS_CONTAINER_CREDEN‐
1610 TIALS_RELATIVE_URI is set, and if so, attempt to retrieve temporary
1611 credentials from the ECS task metadata by querying a link local ad‐
1612 dress.
1613
1614 AWS Credentials via EC2
1615 If credentials are not passed in the URI or with environment variables,
1616 and the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is
1617 not set, libmongoc will attempt to retrieve temporary credentials from
1618 the EC2 machine metadata by querying link local addresses.
1619
1620 Basic Troubleshooting
1621 Troubleshooting Checklist
1622 The following is a short list of things to check when you have a prob‐
1623 lem.
1624
1625 • Did you call mongoc_init() in main()? If not, you will likely see a
1626 segfault.
1627
1628 • Have you leaked any clients or cursors as can be found with mon‐
1629 goc-stat <PID>?
1630
1631 • Have packets been delivered to the server? See egress bytes from mon‐
1632 goc-stat <PID>.
1633
1634 • Does valgrind show any leaks? Ensure you call mongoc_cleanup() at the
1635 end of your process to cleanup lingering allocations from the MongoDB
1636 C driver.
1637
1638 • If compiling your own copy of MongoDB C Driver, consider using the
1639 cmake option -DENABLE_TRACING=ON to enable function tracing and hex
1640 dumps of network packets to STDERR and STDOUT.
1641
1642 Performance Counters
1643 The MongoDB C driver comes with an optional unique feature to help de‐
1644 velopers and sysadmins troubleshoot problems in production. Perfor‐
1645 mance counters are available for each process using the driver. If
1646 available, the counters can be accessed outside of the application
1647 process via a shared memory segment. This means that you can graph
1648 statistics about your application process easily from tools like Munin
1649 or Nagios. Your author often uses watch --interval=0.5 -d mongoc-stat
1650 $PID to monitor an application.
1651
1652 Performance counters are only available on Linux platforms supporting
1653 shared memory segments. On supported platforms they are enabled by de‐
1654 fault. Applications can be built without the counters by specifying
1655 the cmake option -DENABLE_SHM_COUNTERS=OFF. Additionally, if perfor‐
1656 mance counters are already compiled, they can be disabled at runtime by
1657 specifying the environment variable MONGOC_DISABLE_SHM.
1658
1659 Performance counters keep track of the following:
1660
1661 • Active and Disposed Cursors
1662
1663 • Active and Disposed Clients, Client Pools, and Socket Streams.
1664
1665 • Number of operations sent and received, by type.
1666
1667 • Bytes transferred and received.
1668
1669 • Authentication successes and failures.
1670
1671 • Number of wire protocol errors.
1672
1673 To access counters for a given process, simply provide the process id
1674 to the mongoc-stat program installed with the MongoDB C Driver.
1675
1676 $ mongoc-stat 22203
1677 Operations : Egress Total : The number of sent operations. : 13247
1678 Operations : Ingress Total : The number of received operations. : 13246
1679 Operations : Egress Queries : The number of sent Query operations. : 13247
1680 Operations : Ingress Queries : The number of received Query operations. : 0
1681 Operations : Egress GetMore : The number of sent GetMore operations. : 0
1682 Operations : Ingress GetMore : The number of received GetMore operations. : 0
1683 Operations : Egress Insert : The number of sent Insert operations. : 0
1684 Operations : Ingress Insert : The number of received Insert operations. : 0
1685 Operations : Egress Delete : The number of sent Delete operations. : 0
1686 Operations : Ingress Delete : The number of received Delete operations. : 0
1687 Operations : Egress Update : The number of sent Update operations. : 0
1688 Operations : Ingress Update : The number of received Update operations. : 0
1689 Operations : Egress KillCursors : The number of sent KillCursors operations. : 0
1690 Operations : Ingress KillCursors : The number of received KillCursors operations. : 0
1691 Operations : Egress Msg : The number of sent Msg operations. : 0
1692 Operations : Ingress Msg : The number of received Msg operations. : 0
1693 Operations : Egress Reply : The number of sent Reply operations. : 0
1694 Operations : Ingress Reply : The number of received Reply operations. : 13246
1695 Cursors : Active : The number of active cursors. : 1
1696 Cursors : Disposed : The number of disposed cursors. : 13246
1697 Clients : Active : The number of active clients. : 1
1698 Clients : Disposed : The number of disposed clients. : 0
1699 Streams : Active : The number of active streams. : 1
1700 Streams : Disposed : The number of disposed streams. : 0
1701 Streams : Egress Bytes : The number of bytes sent. : 794931
1702 Streams : Ingress Bytes : The number of bytes received. : 589694
1703 Streams : N Socket Timeouts : The number of socket timeouts. : 0
1704 Client Pools : Active : The number of active client pools. : 1
1705 Client Pools : Disposed : The number of disposed client pools. : 0
1706 Protocol : Ingress Errors : The number of protocol errors on ingress. : 0
1707 Auth : Failures : The number of failed authentication requests. : 0
1708 Auth : Success : The number of successful authentication requests. : 0
1709
1710 Submitting a Bug Report
1711 Think you've found a bug? Want to see a new feature in the MongoDB C
1712 driver? Please open a case in our issue management tool, JIRA:
1713
1714 • Create an account and login.
1715
1716 • Navigate to the CDRIVER project.
1717
1718 • Click Create Issue - Please provide as much information as possible
1719 about the issue type and how to reproduce it.
1720
1721 Bug reports in JIRA for all driver projects (i.e. CDRIVER, CSHARP,
1722 JAVA) and the Core Server (i.e. SERVER) project are public.
1723
1724 Guides
1725 Configuring TLS
1726 Configuration with URI options
1727 Enable TLS by including tls=true in the URI.
1728
1729 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/");
1730 mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true);
1731
1732 mongoc_client_t *client = mongoc_client_new_from_uri (uri);
1733
1734 The following URI options may be used to further configure TLS:
1735
1736 ┌────────────────────┬─────────────────────┬─────────────────────┐
1737 │Constant │ Key │ Description │
1738 ├────────────────────┼─────────────────────┼─────────────────────┤
1739 │MONGOC_URI_TLS │ tls │ {true|false}, indi‐ │
1740 │ │ │ cating if TLS must │
1741 │ │ │ be used. │
1742 ├────────────────────┼─────────────────────┼─────────────────────┤
1743 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ Path to PEM format‐ │
1744 │TIFICATEKEYFILE │ file │ ted Private Key, │
1745 │ │ │ with its Public │
1746 │ │ │ Certificate con‐ │
1747 │ │ │ catenated at the │
1748 │ │ │ end. │
1749 ├────────────────────┼─────────────────────┼─────────────────────┤
1750 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ The password, if │
1751 │TIFICATEKEY‐ │ password │ any, to use to un‐ │
1752 │FILEPASSWORD │ │ lock encrypted Pri‐ │
1753 │ │ │ vate Key. │
1754 ├────────────────────┼─────────────────────┼─────────────────────┤
1755 │MON‐ │ tlscafile │ One, or a bundle │
1756 │GOC_URI_TLSCAFILE │ │ of, Certificate Au‐ │
1757 │ │ │ thorities whom │
1758 │ │ │ should be consid‐ │
1759 │ │ │ ered to be trusted. │
1760 ├────────────────────┼─────────────────────┼─────────────────────┤
1761 │MONGOC_URI_TLSAL‐ │ tlsallowinvalidcer‐ │ Accept and ignore │
1762 │LOWINVALIDCERTIFI‐ │ tificates │ certificate verifi‐ │
1763 │CATES │ │ cation errors (e.g. │
1764 │ │ │ untrusted issuer, │
1765 │ │ │ expired, etc.) │
1766 └────────────────────┴─────────────────────┴─────────────────────┘
1767
1768
1769
1770
1771
1772 │MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │ Ignore hostname │
1773 │LOWINVALIDHOSTNAMES │ hostnames │ verification of the │
1774 │ │ │ certificate (e.g. │
1775 │ │ │ Man In The Middle, │
1776 │ │ │ using valid cer‐ │
1777 │ │ │ tificate, but is‐ │
1778 │ │ │ sued for another │
1779 │ │ │ hostname) │
1780 ├────────────────────┼─────────────────────┼─────────────────────┤
1781 │MONGOC_URI_TLSINSE‐ │ tlsinsecure │ {true|false}, indi‐ │
1782 │CURE │ │ cating if insecure │
1783 │ │ │ TLS options should │
1784 │ │ │ be used. Currently │
1785 │ │ │ this implies MON‐ │
1786 │ │ │ GOC_URI_TLSALLOWIN‐ │
1787 │ │ │ VALIDCERTIFICATES │
1788 │ │ │ and MONGOC_URI_TL‐ │
1789 │ │ │ SALLOWINVALIDHOST‐ │
1790 │ │ │ NAMES. │
1791 ├────────────────────┼─────────────────────┼─────────────────────┤
1792 │MONGOC_URI_TLSDIS‐ │ tlsdisablecertifi‐ │ {true|false}, indi‐ │
1793 │ABLECERTIFICATERE‐ │ caterevocationcheck │ cates if revocation │
1794 │VOCATIONCHECK │ │ checking (CRL / │
1795 │ │ │ OCSP) should be │
1796 │ │ │ disabled. │
1797 ├────────────────────┼─────────────────────┼─────────────────────┤
1798 │MONGOC_URI_TLSDIS‐ │ tlsdisableocspend‐ │ {true|false}, indi‐ │
1799 │ABLEOCSPEND‐ │ pointcheck │ cates if OCSP re‐ │
1800 │POINTCHECK │ │ sponder endpoints │
1801 │ │ │ should not be re‐ │
1802 │ │ │ quested when an │
1803 │ │ │ OCSP response is │
1804 │ │ │ not stapled. │
1805 └────────────────────┴─────────────────────┴─────────────────────┘
1806
1807 Configuration with mongoc_ssl_opt_t
1808 Alternatively, the mongoc_ssl_opt_t struct may be used to configure TLS
1809 with mongoc_client_set_ssl_opts() or mongoc_client_pool_set_ssl_opts().
1810 Most of the configurable options can be set using the Connection String
1811 URI.
1812
1813 ┌───────────────────────┬──────────────────────────┐
1814 │mongoc_ssl_opt_t key │ URI key │
1815 ├───────────────────────┼──────────────────────────┤
1816 │pem_file │ tlsClientCertificateKey‐ │
1817 │ │ File │
1818 ├───────────────────────┼──────────────────────────┤
1819 │pem_pwd │ tlsClientCertificateKey‐ │
1820 │ │ Password │
1821 ├───────────────────────┼──────────────────────────┤
1822 │ca_file │ tlsCAFile │
1823 ├───────────────────────┼──────────────────────────┤
1824 │weak_cert_validation │ tlsAllowInvalidCertifi‐ │
1825 │ │ cates │
1826 ├───────────────────────┼──────────────────────────┤
1827 │allow_invalid_hostname │ tlsAllowInvalidHostnames │
1828 └───────────────────────┴──────────────────────────┘
1829
1830 The only exclusions are crl_file and ca_dir. Those may only be set with
1831 mongoc_ssl_opt_t.
1832
1833 Client Authentication
1834 When MongoDB is started with TLS enabled, it will by default require
1835 the client to provide a client certificate issued by a certificate au‐
1836 thority specified by --tlsCAFile, or an authority trusted by the native
1837 certificate store in use on the server.
1838
1839 To provide the client certificate, set the tlsCertificateKeyFile in the
1840 URI to a PEM armored certificate file.
1841
1842 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/");
1843 mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true);
1844 mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "/path/to/client-certificate.pem");
1845
1846 mongoc_client_t *client = mongoc_client_new_from_uri (uri);
1847
1848 Server Certificate Verification
1849 The MongoDB C Driver will automatically verify the validity of the
1850 server certificate, such as issued by configured Certificate Authority,
1851 hostname validation, and expiration.
1852
1853 To overwrite this behavior, it is possible to disable hostname valida‐
1854 tion, OCSP endpoint revocation checking, revocation checking entirely,
1855 and allow invalid certificates.
1856
1857 This behavior is controlled using the tlsAllowInvalidHostnames, tlsDis‐
1858 ableOCSPEndpointCheck, tlsDisableCertificateRevocationCheck, and tlsAl‐
1859 lowInvalidCertificates options respectively. By default, all are set to
1860 false.
1861
1862 It is not recommended to change these defaults as it exposes the client
1863 to Man In The Middle attacks (when tlsAllowInvalidHostnames is set),
1864 invalid certificates (when tlsAllowInvalidCertificates is set), or po‐
1865 tentially revoked certificates (when tlsDisableOCSPEndpointCheck or
1866 tlsDisableCertificateRevocationCheck are set).
1867
1868 Supported Libraries
1869 By default, libmongoc will attempt to find a supported TLS library and
1870 enable TLS support. This is controlled by the cmake flag ENABLE_SSL,
1871 which is set to AUTO by default. Valid values are:
1872
1873 • AUTO the default behavior. Link to the system's native TLS library,
1874 or attempt to find OpenSSL.
1875
1876 • DARWIN link to Secure Transport, the native TLS library on macOS.
1877
1878 • WINDOWS link to Secure Channel, the native TLS library on Windows.
1879
1880 • OPENSSL link to OpenSSL (libssl). An optional install path may be
1881 specified with OPENSSL_ROOT.
1882
1883 • LIBRESSL link to LibreSSL's libtls. (LibreSSL's compatible libssl may
1884 be linked to by setting OPENSSL).
1885
1886 • OFF disable TLS support.
1887
1888 OpenSSL
1889 The MongoDB C Driver uses OpenSSL, if available, on Linux and Unix
1890 platforms (besides macOS). Industry best practices and some regulations
1891 require the use of TLS 1.1 or newer, which requires at least OpenSSL
1892 1.0.1. Check your OpenSSL version like so:
1893
1894 $ openssl version
1895
1896 Ensure your system's OpenSSL is a recent version (at least 1.0.1), or
1897 install a recent version in a non-system path and build against it
1898 with:
1899
1900 cmake -DOPENSSL_ROOT_DIR=/absolute/path/to/openssl
1901
1902 When compiled against OpenSSL, the driver will attempt to load the sys‐
1903 tem default certificate store, as configured by the distribution. That
1904 can be overridden by setting the tlsCAFile URI option or with the
1905 fields ca_file and ca_dir in the mongoc_ssl_opt_t.
1906
1907 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is fully
1908 supported when using OpenSSL 1.0.1+ with the following notes:
1909
1910 • When a crl_file is set with mongoc_ssl_opt_t, and the crl_file re‐
1911 vokes the server's certificate, the certificate is considered revoked
1912 (even if the certificate has a valid stapled OCSP response)
1913
1914 LibreSSL / libtls
1915 The MongoDB C Driver supports LibreSSL through the use of OpenSSL com‐
1916 patibility checks when configured to compile against openssl. It also
1917 supports the new libtls library when configured to build against li‐
1918 bressl.
1919
1920 When compiled against the Windows native libraries, the crl_file option
1921 of a mongoc_ssl_opt_t is not supported, and will issue an error if
1922 used.
1923
1924 Setting tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevoca‐
1925 tionCheck has no effect.
1926
1927 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
1928 tially supported with the following notes:
1929
1930 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
1931 continue if a Must-Staple certificate is presented with no stapled
1932 response (unless the client receives a revoked response from an OCSP
1933 responder).
1934
1935 • Connection will continue if a Must-Staple certificate is presented
1936 without a stapled response and the OCSP responder is down.
1937
1938 Native TLS Support on Windows (Secure Channel)
1939 The MongoDB C Driver supports the Windows native TLS library (Secure
1940 Channel, or SChannel), and its native crypto library (Cryptography API:
1941 Next Generation, or CNG).
1942
1943 When compiled against the Windows native libraries, the ca_dir option
1944 of a mongoc_ssl_opt_t is not supported, and will issue an error if
1945 used.
1946
1947 Encrypted PEM files (e.g., setting tlsCertificateKeyPassword) are also
1948 not supported, and will result in error when attempting to load them.
1949
1950 When tlsCAFile is set, the driver will only allow server certificates
1951 issued by the authority (or authorities) provided. When no tlsCAFile is
1952 set, the driver will look up the Certificate Authority using the System
1953 Local Machine Root certificate store to confirm the provided certifi‐
1954 cate.
1955
1956 When crl_file is set with mongoc_ssl_opt_t, the driver will import the
1957 revocation list to the System Local Machine Root certificate store.
1958
1959 Setting tlsDisableOCSPEndpointCheck has no effect.
1960
1961 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
1962 tially supported with the following notes:
1963
1964 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
1965 continue if a Must-Staple certificate is presented with no stapled
1966 response (unless the client receives a revoked response from an OCSP
1967 responder).
1968
1969 • When a crl_file is set with mongoc_ssl_opt_t, and the crl_file re‐
1970 vokes the server's certificate, the OCSP response takes precedence.
1971 E.g. if the server presents a certificate with a valid stapled OCSP
1972 response, the certificate is considered valid even if the crl_file
1973 marks it as revoked.
1974
1975 • Connection will continue if a Must-Staple certificate is presented
1976 without a stapled response and the OCSP responder is down.
1977
1978 Native TLS Support on macOS / Darwin (Secure Transport)
1979 The MongoDB C Driver supports the Darwin (OS X, macOS, iOS, etc.) na‐
1980 tive TLS library (Secure Transport), and its native crypto library
1981 (Common Crypto, or CC).
1982
1983 When compiled against Secure Transport, the ca_dir and crl_file options
1984 of a mongoc_ssl_opt_t are not supported. An error is issued if either
1985 are used.
1986
1987 When tlsCAFile is set, the driver will only allow server certificates
1988 issued by the authority (or authorities) provided. When no tlsCAFile is
1989 set, the driver will use the Certificate Authorities in the currently
1990 unlocked keychains.
1991
1992 Setting tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevoca‐
1993 tionCheck has no effect.
1994
1995 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
1996 tially supported with the following notes.
1997
1998 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
1999 continue if a Must-Staple certificate is presented with no stapled
2000 response (unless the client receives a revoked response from an OCSP
2001 responder).
2002
2003 • Connection will continue if a Must-Staple certificate is presented
2004 without a stapled response and the OCSP responder is down.
2005
2006 Common Tasks
2007 Drivers for some other languages provide helper functions to perform
2008 certain common tasks. In the C Driver we must explicitly build commands
2009 to send to the server.
2010
2011 Setup
2012 First we'll write some code to insert sample data:
2013
2014 doc-common-insert.c
2015
2016 /* Don't try to compile this file on its own. It's meant to be #included
2017 by example code */
2018
2019 /* Insert some sample data */
2020 bool
2021 insert_data (mongoc_collection_t *collection)
2022 {
2023 mongoc_bulk_operation_t *bulk;
2024 enum N { ndocs = 4 };
2025 bson_t *docs[ndocs];
2026 bson_error_t error;
2027 int i = 0;
2028 bool ret;
2029
2030 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2031
2032 docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
2033 docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
2034 docs[2] = BCON_NEW (
2035 "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
2036 docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");
2037
2038 for (i = 0; i < ndocs; i++) {
2039 mongoc_bulk_operation_insert (bulk, docs[i]);
2040 bson_destroy (docs[i]);
2041 docs[i] = NULL;
2042 }
2043
2044 ret = mongoc_bulk_operation_execute (bulk, NULL, &error);
2045
2046 if (!ret) {
2047 fprintf (stderr, "Error inserting data: %s\n", error.message);
2048 }
2049
2050 mongoc_bulk_operation_destroy (bulk);
2051 return ret;
2052 }
2053
2054 /* A helper which we'll use a lot later on */
2055 void
2056 print_res (const bson_t *reply)
2057 {
2058 char *str;
2059 BSON_ASSERT (reply);
2060 str = bson_as_canonical_extended_json (reply, NULL);
2061 printf ("%s\n", str);
2062 bson_free (str);
2063 }
2064
2065
2066 explain Command
2067 This is how to use the explain command in MongoDB 3.2+:
2068
2069 explain.c
2070
2071 bool
2072 explain (mongoc_collection_t *collection)
2073 {
2074 bson_t *command;
2075 bson_t reply;
2076 bson_error_t error;
2077 bool res;
2078
2079 command = BCON_NEW ("explain",
2080 "{",
2081 "find",
2082 BCON_UTF8 (COLLECTION_NAME),
2083 "filter",
2084 "{",
2085 "x",
2086 BCON_INT32 (1),
2087 "}",
2088 "}");
2089 res = mongoc_collection_command_simple (
2090 collection, command, NULL, &reply, &error);
2091 if (!res) {
2092 fprintf (stderr, "Error with explain: %s\n", error.message);
2093 goto cleanup;
2094 }
2095
2096 /* Do something with the reply */
2097 print_res (&reply);
2098
2099 cleanup:
2100 bson_destroy (&reply);
2101 bson_destroy (command);
2102 return res;
2103 }
2104
2105
2106 Running the Examples
2107 common-operations.c
2108
2109 /*
2110 * Copyright 2016 MongoDB, Inc.
2111 *
2112 * Licensed under the Apache License, Version 2.0 (the "License");
2113 * you may not use this file except in compliance with the License.
2114 * You may obtain a copy of the License at
2115 *
2116 * http://www.apache.org/licenses/LICENSE-2.0
2117 *
2118 * Unless required by applicable law or agreed to in writing, software
2119 * distributed under the License is distributed on an "AS IS" BASIS,
2120 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2121 * See the License for the specific language governing permissions and
2122 * limitations under the License.
2123 */
2124
2125
2126 #include <mongoc/mongoc.h>
2127 #include <stdio.h>
2128
2129
2130 const char *COLLECTION_NAME = "things";
2131
2132 #include "../doc-common-insert.c"
2133 #include "explain.c"
2134
2135
2136 int
2137 main (int argc, char *argv[])
2138 {
2139 mongoc_database_t *database = NULL;
2140 mongoc_client_t *client = NULL;
2141 mongoc_collection_t *collection = NULL;
2142 mongoc_uri_t *uri = NULL;
2143 bson_error_t error;
2144 char *host_and_port;
2145 int res = 0;
2146
2147 if (argc < 2 || argc > 3) {
2148 fprintf (stderr,
2149 "usage: %s MONGOD-1-CONNECTION-STRING "
2150 "[MONGOD-2-HOST-NAME:MONGOD-2-PORT]\n",
2151 argv[0]);
2152 fprintf (stderr,
2153 "MONGOD-1-CONNECTION-STRING can be "
2154 "of the following forms:\n");
2155 fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
2156 fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
2157 fprintf (stderr,
2158 "mongodb://user:pass@localhost:27017\t"
2159 "local machine on port 27017, and authenticate with username "
2160 "user and password pass\n");
2161 return EXIT_FAILURE;
2162 }
2163
2164 mongoc_init ();
2165
2166 if (strncmp (argv[1], "mongodb://", 10) == 0) {
2167 host_and_port = bson_strdup (argv[1]);
2168 } else {
2169 host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
2170 }
2171
2172 uri = mongoc_uri_new_with_error (host_and_port, &error);
2173 if (!uri) {
2174 fprintf (stderr,
2175 "failed to parse URI: %s\n"
2176 "error message: %s\n",
2177 host_and_port,
2178 error.message);
2179 res = EXIT_FAILURE;
2180 goto cleanup;
2181 }
2182
2183 client = mongoc_client_new_from_uri (uri);
2184 if (!client) {
2185 res = EXIT_FAILURE;
2186 goto cleanup;
2187 }
2188
2189 mongoc_client_set_error_api (client, 2);
2190 database = mongoc_client_get_database (client, "test");
2191 collection = mongoc_database_get_collection (database, COLLECTION_NAME);
2192
2193 printf ("Inserting data\n");
2194 if (!insert_data (collection)) {
2195 res = EXIT_FAILURE;
2196 goto cleanup;
2197 }
2198
2199 printf ("explain\n");
2200 if (!explain (collection)) {
2201 res = EXIT_FAILURE;
2202 goto cleanup;
2203 }
2204
2205 cleanup:
2206 if (collection) {
2207 mongoc_collection_destroy (collection);
2208 }
2209
2210 if (database) {
2211 mongoc_database_destroy (database);
2212 }
2213
2214 if (client) {
2215 mongoc_client_destroy (client);
2216 }
2217
2218 if (uri) {
2219 mongoc_uri_destroy (uri);
2220 }
2221
2222 bson_free (host_and_port);
2223 mongoc_cleanup ();
2224 return res;
2225 }
2226
2227
2228 First launch two separate instances of mongod (must be done from sepa‐
2229 rate shells):
2230
2231 $ mongod
2232
2233 $ mkdir /tmp/db2
2234 $ mongod --dbpath /tmp/db2 --port 27018 # second instance
2235
2236 Now compile and run the example program:
2237
2238 $ cd examples/common_operations/$ gcc -Wall -o example common-operations.c $(pkg-config --cflags --libs libmongoc-1.0)$ ./example localhost:27017 localhost:27018
2239 Inserting data
2240 explain
2241 {
2242 "executionStats" : {
2243 "allPlansExecution" : [],
2244 "executionStages" : {
2245 "advanced" : 19,
2246 "direction" : "forward" ,
2247 "docsExamined" : 76,
2248 "executionTimeMillisEstimate" : 0,
2249 "filter" : {
2250 "x" : {
2251 "$eq" : 1
2252 }
2253 },
2254 "invalidates" : 0,
2255 "isEOF" : 1,
2256 "nReturned" : 19,
2257 "needTime" : 58,
2258 "needYield" : 0,
2259 "restoreState" : 0,
2260 "saveState" : 0,
2261 "stage" : "COLLSCAN" ,
2262 "works" : 78
2263 },
2264 "executionSuccess" : true,
2265 "executionTimeMillis" : 0,
2266 "nReturned" : 19,
2267 "totalDocsExamined" : 76,
2268 "totalKeysExamined" : 0
2269 },
2270 "ok" : 1,
2271 "queryPlanner" : {
2272 "indexFilterSet" : false,
2273 "namespace" : "test.things",
2274 "parsedQuery" : {
2275 "x" : {
2276 "$eq" : 1
2277 }
2278 },
2279 "plannerVersion" : 1,
2280 "rejectedPlans" : [],
2281 "winningPlan" : {
2282 "direction" : "forward" ,
2283 "filter" : {
2284 "x" : {
2285 "$eq" : 1
2286 }
2287 },
2288 "stage" : "COLLSCAN"
2289 }
2290 },
2291 "serverInfo" : {
2292 "gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25" ,
2293 "host" : "MacBook-Pro-57.local",
2294 "port" : 27017,
2295 "version" : "3.2.6"
2296 }
2297 }
2298
2299 Advanced Connections
2300 The following guide contains information specific to certain types of
2301 MongoDB configurations.
2302
2303 For an example of connecting to a simple standalone server, see the Tu‐
2304 torial. To establish a connection with authentication options enabled,
2305 see the Authentication page.
2306
2307 Connecting to a Replica Set
2308 Connecting to a replica set is much like connecting to a standalone
2309 MongoDB server. Simply specify the replica set name using the ?repli‐
2310 caSet=myreplset URI option.
2311
2312 #include <bson/bson.h>
2313 #include <mongoc/mongoc.h>
2314
2315 int
2316 main (int argc, char *argv[])
2317 {
2318 mongoc_client_t *client;
2319
2320 mongoc_init ();
2321
2322 /* Create our MongoDB Client */
2323 client = mongoc_client_new (
2324 "mongodb://host01:27017,host02:27017,host03:27017/?replicaSet=myreplset");
2325
2326 /* Do some work */
2327 /* TODO */
2328
2329 /* Clean up */
2330 mongoc_client_destroy (client);
2331 mongoc_cleanup ();
2332
2333 return 0;
2334 }
2335
2336 TIP:
2337 Multiple hostnames can be specified in the MongoDB connection string
2338 URI, with a comma separating hosts in the seed list.
2339
2340 It is recommended to use a seed list of members of the replica set
2341 to allow the driver to connect to any node.
2342
2343 Connecting to a Sharded Cluster
2344 To connect to a sharded cluster, specify the mongos nodes the client
2345 should connect to. The C Driver will automatically detect that it has
2346 connected to a mongos sharding server.
2347
2348 If more than one hostname is specified, a seed list will be created to
2349 attempt failover between the mongos instances.
2350
2351 WARNING:
2352 Specifying the replicaSet parameter when connecting to a mongos
2353 sharding server is invalid.
2354
2355 #include <bson/bson.h>
2356 #include <mongoc/mongoc.h>
2357
2358 int
2359 main (int argc, char *argv[])
2360 {
2361 mongoc_client_t *client;
2362
2363 mongoc_init ();
2364
2365 /* Create our MongoDB Client */
2366 client = mongoc_client_new ("mongodb://myshard01:27017/");
2367
2368 /* Do something with client ... */
2369
2370 /* Free the client */
2371 mongoc_client_destroy (client);
2372
2373 mongoc_cleanup ();
2374
2375 return 0;
2376 }
2377
2378 Connecting to an IPv6 Address
2379 The MongoDB C Driver will automatically resolve IPv6 addresses from
2380 host names. However, to specify an IPv6 address directly, wrap the ad‐
2381 dress in [].
2382
2383 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://[::1]:27017");
2384
2385 Connecting with IPv4 and IPv6
2386 If connecting to a hostname that has both IPv4 and IPv6 DNS records,
2387 the behavior follows RFC-6555. A connection to the IPv6 address is at‐
2388 tempted first. If IPv6 fails, then a connection is attempted to the
2389 IPv4 address. If the connection attempt to IPv6 does not complete
2390 within 250ms, then IPv4 is tried in parallel. Whichever succeeds con‐
2391 nection first cancels the other. The successful DNS result is cached
2392 for 10 minutes.
2393
2394 As a consequence, attempts to connect to a mongod only listening on
2395 IPv4 may be delayed if there are both A (IPv4) and AAAA (IPv6) DNS
2396 records associated with the host.
2397
2398 To avoid a delay, configure hostnames to match the MongoDB configura‐
2399 tion. That is, only create an A record if the mongod is only listening
2400 on IPv4.
2401
2402 Connecting to a UNIX Domain Socket
2403 On UNIX-like systems, the C Driver can connect directly to a MongoDB
2404 server using a UNIX domain socket. Pass the URL-encoded path to the
2405 socket, which must be suffixed with .sock. For example, to connect to a
2406 domain socket at /tmp/mongodb-27017.sock:
2407
2408 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-27017.sock");
2409
2410 Include username and password like so:
2411
2412 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://user:pass@%2Ftmp%2Fmongodb-27017.sock");
2413
2414 Connecting to a server over TLS
2415 These are instructions for configuring TLS/SSL connections.
2416
2417 To run a server locally (on port 27017, for example):
2418
2419 $ mongod --port 27017 --tlsMode requireTLS --tlsCertificateKeyFile server.pem --tlsCAFile ca.pem
2420
2421 Add /?tls=true to the end of a client URI.
2422
2423 mongoc_client_t *client = NULL;
2424 client = mongoc_client_new ("mongodb://localhost:27017/?tls=true");
2425
2426 MongoDB requires client certificates by default, unless the --tlsAllow‐
2427 ConnectionsWithoutCertificates is provided. The C Driver can be config‐
2428 ured to present a client certificate using the URI option tlsCertifi‐
2429 cateKeyFile, which may be referenced through the constant MON‐
2430 GOC_URI_TLSCERTIFICATEKEYFILE.
2431
2432 mongoc_client_t *client = NULL;
2433 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/?tls=true");
2434 mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "client.pem");
2435
2436 client = mongoc_client_new_from_uri (uri);
2437
2438 The client certificate provided by tlsCertificateKeyFile must be issued
2439 by one of the server trusted Certificate Authorities listed in
2440 --tlsCAFile, or issued by a CA in the native certificate store on the
2441 server when omitted.
2442
2443 See configuring_tls for more information on the various TLS related op‐
2444 tions.
2445
2446 Compressing data to and from MongoDB
2447 MongoDB 3.4 added Snappy compression support, zlib compression in 3.6,
2448 and zstd compression in 4.2. To enable compression support the client
2449 must be configured with which compressors to use:
2450
2451 mongoc_client_t *client = NULL;
2452 client = mongoc_client_new ("mongodb://localhost:27017/?compressors=snappy,zlib,zstd");
2453
2454 The compressors option specifies the priority order of compressors the
2455 client wants to use. Messages are compressed if the client and server
2456 share any compressors in common.
2457
2458 Note that the compressor used by the server might not be the same com‐
2459 pressor as the client used. For example, if the client uses the con‐
2460 nection string compressors=zlib,snappy the client will use zlib com‐
2461 pression to send data (if possible), but the server might still reply
2462 using snappy, depending on how the server was configured.
2463
2464 The driver must be built with zlib and/or snappy and/or zstd support to
2465 enable compression support, any unknown (or not compiled in) compressor
2466 value will be ignored. Note: to build with zstd requires cmake 3.12 or
2467 higher.
2468
2469 Additional Connection Options
2470 The full list of connection options can be found in the mongoc_uri_t
2471 docs.
2472
2473 Certain socket/connection related options are not configurable:
2474
2475 ┌──────────────┬─────────────────────┬─────────────────────┐
2476 │Option │ Description │ Value │
2477 ├──────────────┼─────────────────────┼─────────────────────┤
2478 │SO_KEEPALIVE │ TCP Keep Alive │ Enabled │
2479 ├──────────────┼─────────────────────┼─────────────────────┤
2480 │TCP_KEEPIDLE │ How long a connec‐ │ 120 seconds │
2481 │ │ tion needs to re‐ │ │
2482 │ │ main idle before │ │
2483 │ │ TCP starts sending │ │
2484 │ │ keepalive probes │ │
2485 ├──────────────┼─────────────────────┼─────────────────────┤
2486 │TCP_KEEPINTVL │ The time in seconds │ 10 seconds │
2487 │ │ between TCP probes │ │
2488 ├──────────────┼─────────────────────┼─────────────────────┤
2489 │TCP_KEEPCNT │ How many probes to │ 9 probes │
2490 │ │ send, without ac‐ │ │
2491 │ │ knowledgement, be‐ │ │
2492 │ │ fore dropping the │ │
2493 │ │ connection │ │
2494 └──────────────┴─────────────────────┴─────────────────────┘
2495
2496
2497
2498
2499
2500
2501 │TCP_NODELAY │ Send packets as │ Enabled (no buffer‐ │
2502 │ │ soon as possible or │ ing) │
2503 │ │ buffer small pack‐ │ │
2504 │ │ ets (Nagle algo‐ │ │
2505 │ │ rithm) │ │
2506 └──────────────┴─────────────────────┴─────────────────────┘
2507
2508 Connection Pooling
2509 The MongoDB C driver has two connection modes: single-threaded and
2510 pooled. Single-threaded mode is optimized for embedding the driver
2511 within languages like PHP. Multi-threaded programs should use pooled
2512 mode: this mode minimizes the total connection count, and in pooled
2513 mode background threads monitor the MongoDB server topology, so the
2514 program need not block to scan it.
2515
2516 Single Mode
2517 In single mode, your program creates a mongoc_client_t directly:
2518
2519 mongoc_client_t *client = mongoc_client_new (
2520 "mongodb://hostA,hostB/?replicaSet=my_rs");
2521
2522 The client connects on demand when your program first uses it for a
2523 MongoDB operation. Using a non-blocking socket per server, it begins a
2524 check on each server concurrently, and uses the asynchronous poll or
2525 select function to receive events from the sockets, until all have re‐
2526 sponded or timed out. Put another way, in single-threaded mode the C
2527 Driver fans out to begin all checks concurrently, then fans in once all
2528 checks have completed or timed out. Once the scan completes, the client
2529 executes your program's operation and returns.
2530
2531 In single mode, the client re-scans the server topology roughly once
2532 per minute. If more than a minute has elapsed since the previous scan,
2533 the next operation on the client will block while the client completes
2534 its scan. This interval is configurable with heartbeatFrequencyMS in
2535 the connection string. (See mongoc_uri_t.)
2536
2537 A single client opens one connection per server in your topology: these
2538 connections are used both for scanning the topology and performing nor‐
2539 mal operations.
2540
2541 Pooled Mode
2542 To activate pooled mode, create a mongoc_client_pool_t:
2543
2544 mongoc_uri_t *uri = mongoc_uri_new (
2545 "mongodb://hostA,hostB/?replicaSet=my_rs");
2546
2547 mongoc_client_pool_t *pool = mongoc_client_pool_new (uri);
2548
2549 When your program first calls mongoc_client_pool_pop, the pool launches
2550 monitoring threads in the background. Monitoring threads independently
2551 connect to all servers in the connection string. As monitoring threads
2552 receive hello responses from the servers, they update the shared view
2553 of the server topology. Additional monitoring threads and connections
2554 are created as new servers are discovered. Monitoring threads are ter‐
2555 minated when servers are removed from the shared view of the server
2556 topology.
2557
2558 Each thread that executes MongoDB operations must check out a client
2559 from the pool:
2560
2561 mongoc_client_t *client = mongoc_client_pool_pop (pool);
2562
2563 /* use the client for operations ... */
2564
2565 mongoc_client_pool_push (pool, client);
2566
2567 The mongoc_client_t object is not thread-safe, only the mon‐
2568 goc_client_pool_t is.
2569
2570 When the driver is in pooled mode, your program's operations are un‐
2571 blocked as soon as monitoring discovers a usable server. For example,
2572 if a thread in your program is waiting to execute an "insert" on the
2573 primary, it is unblocked as soon as the primary is discovered, rather
2574 than waiting for all secondaries to be checked as well.
2575
2576 The pool opens one connection per server for monitoring, and each
2577 client opens its own connection to each server it uses for application
2578 operations. Background monitoring threads re-scan servers independently
2579 roughly every 10 seconds. This interval is configurable with heartbeat‐
2580 FrequencyMS in the connection string. (See mongoc_uri_t.)
2581
2582 The connection string can also specify waitQueueTimeoutMS to limit the
2583 time that mongoc_client_pool_pop will wait for a client from the pool.
2584 (See mongoc_uri_t.) If waitQueueTimeoutMS is specified, then it is
2585 necessary to confirm that a client was actually returned:
2586
2587 mongoc_uri_t *uri = mongoc_uri_new (
2588 "mongodb://hostA,hostB/?replicaSet=my_rs&waitQueueTimeoutMS=1000");
2589
2590 mongoc_client_pool_t *pool = mongoc_client_pool_new (uri);
2591
2592 mongoc_client_t *client = mongoc_client_pool_pop (pool);
2593
2594 if (client) {
2595 /* use the client for operations ... */
2596
2597 mongoc_client_pool_push (pool, client);
2598 } else {
2599 /* take appropriate action for a timeout */
2600 }
2601
2602 See connection_pool_options to configure pool size and behavior, and
2603 see mongoc_client_pool_t for an extended example of a multi-threaded
2604 program that uses the driver in pooled mode.
2605
2606 Cursors
2607 Handling Cursor Failures
2608 Cursors exist on a MongoDB server. However, the mongoc_cursor_t struc‐
2609 ture gives the local process a handle to the cursor. It is possible for
2610 errors to occur on the server while iterating a cursor on the client.
2611 Even a network partition may occur. This means that applications should
2612 be robust in handling cursor failures.
2613
2614 While iterating cursors, you should check to see if an error has oc‐
2615 curred. See the following example for how to robustly check for errors.
2616
2617 static void
2618 print_all_documents (mongoc_collection_t *collection)
2619 {
2620 mongoc_cursor_t *cursor;
2621 const bson_t *doc;
2622 bson_error_t error;
2623 bson_t query = BSON_INITIALIZER;
2624 char *str;
2625
2626 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
2627
2628 while (mongoc_cursor_next (cursor, &doc)) {
2629 str = bson_as_canonical_extended_json (doc, NULL);
2630 printf ("%s\n", str);
2631 bson_free (str);
2632 }
2633
2634 if (mongoc_cursor_error (cursor, &error)) {
2635 fprintf (stderr, "Failed to iterate all documents: %s\n", error.message);
2636 }
2637
2638 mongoc_cursor_destroy (cursor);
2639 }
2640
2641 Destroying Server-Side Cursors
2642 The MongoDB C driver will automatically destroy a server-side cursor
2643 when mongoc_cursor_destroy() is called. Failure to call this function
2644 when done with a cursor will leak memory client side as well as consume
2645 extra memory server side. If the cursor was configured to never time‐
2646 out, it will become a memory leak on the server.
2647
2648 Tailable Cursors
2649 Tailable cursors are cursors that remain open even after they've re‐
2650 turned a final result. This way, if more documents are added to a col‐
2651 lection (i.e., to the cursor's result set), then you can continue to
2652 call mongoc_cursor_next() to retrieve those additional results.
2653
2654 Here's a complete test case that demonstrates the use of tailable cur‐
2655 sors.
2656
2657 NOTE:
2658 Tailable cursors are for capped collections only.
2659
2660 An example to tail the oplog from a replica set.
2661
2662 mongoc-tail.c
2663
2664 #include <bson/bson.h>
2665 #include <mongoc/mongoc.h>
2666 #include <stdio.h>
2667 #include <stdlib.h>
2668
2669 #ifdef _WIN32
2670 #define sleep(_n) Sleep ((_n) *1000)
2671 #endif
2672
2673
2674 static void
2675 print_bson (const bson_t *b)
2676 {
2677 char *str;
2678
2679 str = bson_as_canonical_extended_json (b, NULL);
2680 fprintf (stdout, "%s\n", str);
2681 bson_free (str);
2682 }
2683
2684
2685 static mongoc_cursor_t *
2686 query_collection (mongoc_collection_t *collection, uint32_t last_time)
2687 {
2688 mongoc_cursor_t *cursor;
2689 bson_t query;
2690 bson_t gt;
2691 bson_t opts;
2692
2693 BSON_ASSERT (collection);
2694
2695 bson_init (&query);
2696 BSON_APPEND_DOCUMENT_BEGIN (&query, "ts", >);
2697 BSON_APPEND_TIMESTAMP (>, "$gt", last_time, 0);
2698 bson_append_document_end (&query, >);
2699
2700 bson_init (&opts);
2701 BSON_APPEND_BOOL (&opts, "tailable", true);
2702 BSON_APPEND_BOOL (&opts, "awaitData", true);
2703
2704 cursor = mongoc_collection_find_with_opts (collection, &query, &opts, NULL);
2705
2706 bson_destroy (&query);
2707 bson_destroy (&opts);
2708
2709 return cursor;
2710 }
2711
2712
2713 static void
2714 tail_collection (mongoc_collection_t *collection)
2715 {
2716 mongoc_cursor_t *cursor;
2717 uint32_t last_time;
2718 const bson_t *doc;
2719 bson_error_t error;
2720 bson_iter_t iter;
2721
2722 BSON_ASSERT (collection);
2723
2724 last_time = (uint32_t) time (NULL);
2725
2726 while (true) {
2727 cursor = query_collection (collection, last_time);
2728 while (!mongoc_cursor_error (cursor, &error) &&
2729 mongoc_cursor_more (cursor)) {
2730 if (mongoc_cursor_next (cursor, &doc)) {
2731 if (bson_iter_init_find (&iter, doc, "ts") &&
2732 BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
2733 bson_iter_timestamp (&iter, &last_time, NULL);
2734 }
2735 print_bson (doc);
2736 }
2737 }
2738 if (mongoc_cursor_error (cursor, &error)) {
2739 if (error.domain == MONGOC_ERROR_SERVER) {
2740 fprintf (stderr, "%s\n", error.message);
2741 exit (1);
2742 }
2743 }
2744
2745 mongoc_cursor_destroy (cursor);
2746 sleep (1);
2747 }
2748 }
2749
2750
2751 int
2752 main (int argc, char *argv[])
2753 {
2754 mongoc_collection_t *collection;
2755 mongoc_client_t *client;
2756 mongoc_uri_t *uri;
2757 bson_error_t error;
2758
2759 if (argc != 2) {
2760 fprintf (stderr, "usage: %s MONGO_URI\n", argv[0]);
2761 return EXIT_FAILURE;
2762 }
2763
2764 mongoc_init ();
2765
2766 uri = mongoc_uri_new_with_error (argv[1], &error);
2767 if (!uri) {
2768 fprintf (stderr,
2769 "failed to parse URI: %s\n"
2770 "error message: %s\n",
2771 argv[1],
2772 error.message);
2773 return EXIT_FAILURE;
2774 }
2775
2776 client = mongoc_client_new_from_uri (uri);
2777 if (!client) {
2778 return EXIT_FAILURE;
2779 }
2780
2781 mongoc_client_set_error_api (client, 2);
2782
2783 collection = mongoc_client_get_collection (client, "local", "oplog.rs");
2784
2785 tail_collection (collection);
2786
2787 mongoc_collection_destroy (collection);
2788 mongoc_uri_destroy (uri);
2789 mongoc_client_destroy (client);
2790
2791 return EXIT_SUCCESS;
2792 }
2793
2794
2795 Let's compile and run this example against a replica set to see updates
2796 as they are made.
2797
2798 $ gcc -Wall -o mongoc-tail mongoc-tail.c $(pkg-config --cflags --libs libmongoc-1.0)
2799 $ ./mongoc-tail mongodb://example.com/?replicaSet=myReplSet
2800 {
2801 "h" : -8458503739429355503,
2802 "ns" : "test.test",
2803 "o" : {
2804 "_id" : {
2805 "$oid" : "5372ab0a25164be923d10d50"
2806 }
2807 },
2808 "op" : "i",
2809 "ts" : {
2810 "$timestamp" : {
2811 "i" : 1,
2812 "t" : 1400023818
2813 }
2814 },
2815 "v" : 2
2816 }
2817
2818 The line of output is a sample from performing db.test.insert({}) from
2819 the mongo shell on the replica set.
2820
2821 SEE ALSO:
2822 mongoc_cursor_set_max_await_time_ms.
2823
2824
2825 Bulk Write Operations
2826 This tutorial explains how to take advantage of MongoDB C driver bulk
2827 write operation features. Executing write operations in batches reduces
2828 the number of network round trips, increasing write throughput.
2829
2830 Bulk Insert
2831 First we need to fetch a bulk operation handle from the mongoc_collec‐
2832 tion_t.
2833
2834 mongoc_bulk_operation_t *bulk =
2835 mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2836
2837 We can now start inserting documents to the bulk operation. These will
2838 be buffered until we execute the operation.
2839
2840 The bulk operation will coalesce insertions as a single batch for each
2841 consecutive call to mongoc_bulk_operation_insert(). This creates a
2842 pipelined effect when possible.
2843
2844 To execute the bulk operation and receive the result we call mon‐
2845 goc_bulk_operation_execute().
2846
2847 bulk1.c
2848
2849 #include <assert.h>
2850 #include <mongoc/mongoc.h>
2851 #include <stdio.h>
2852
2853 static void
2854 bulk1 (mongoc_collection_t *collection)
2855 {
2856 mongoc_bulk_operation_t *bulk;
2857 bson_error_t error;
2858 bson_t *doc;
2859 bson_t reply;
2860 char *str;
2861 bool ret;
2862 int i;
2863
2864 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2865
2866 for (i = 0; i < 10000; i++) {
2867 doc = BCON_NEW ("i", BCON_INT32 (i));
2868 mongoc_bulk_operation_insert (bulk, doc);
2869 bson_destroy (doc);
2870 }
2871
2872 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
2873
2874 str = bson_as_canonical_extended_json (&reply, NULL);
2875 printf ("%s\n", str);
2876 bson_free (str);
2877
2878 if (!ret) {
2879 fprintf (stderr, "Error: %s\n", error.message);
2880 }
2881
2882 bson_destroy (&reply);
2883 mongoc_bulk_operation_destroy (bulk);
2884 }
2885
2886 int
2887 main (int argc, char *argv[])
2888 {
2889 mongoc_client_t *client;
2890 mongoc_collection_t *collection;
2891 const char *uri_string = "mongodb://localhost/?appname=bulk1-example";
2892 mongoc_uri_t *uri;
2893 bson_error_t error;
2894
2895 mongoc_init ();
2896
2897 uri = mongoc_uri_new_with_error (uri_string, &error);
2898 if (!uri) {
2899 fprintf (stderr,
2900 "failed to parse URI: %s\n"
2901 "error message: %s\n",
2902 uri_string,
2903 error.message);
2904 return EXIT_FAILURE;
2905 }
2906
2907 client = mongoc_client_new_from_uri (uri);
2908 if (!client) {
2909 return EXIT_FAILURE;
2910 }
2911
2912 mongoc_client_set_error_api (client, 2);
2913 collection = mongoc_client_get_collection (client, "test", "test");
2914
2915 bulk1 (collection);
2916
2917 mongoc_uri_destroy (uri);
2918 mongoc_collection_destroy (collection);
2919 mongoc_client_destroy (client);
2920
2921 mongoc_cleanup ();
2922
2923 return EXIT_SUCCESS;
2924 }
2925
2926
2927 Example reply document:
2928
2929 {"nInserted" : 10000,
2930 "nMatched" : 0,
2931 "nModified" : 0,
2932 "nRemoved" : 0,
2933 "nUpserted" : 0,
2934 "writeErrors" : []
2935 "writeConcernErrors" : [] }
2936
2937 Mixed Bulk Write Operations
2938 MongoDB C driver also supports executing mixed bulk write operations. A
2939 batch of insert, update, and remove operations can be executed together
2940 using the bulk write operations API.
2941
2942 Ordered Bulk Write Operations
2943 Ordered bulk write operations are batched and sent to the server in the
2944 order provided for serial execution. The reply document describes the
2945 type and count of operations performed.
2946
2947 bulk2.c
2948
2949 #include <assert.h>
2950 #include <mongoc/mongoc.h>
2951 #include <stdio.h>
2952
2953 static void
2954 bulk2 (mongoc_collection_t *collection)
2955 {
2956 mongoc_bulk_operation_t *bulk;
2957 bson_error_t error;
2958 bson_t *query;
2959 bson_t *doc;
2960 bson_t *opts;
2961 bson_t reply;
2962 char *str;
2963 bool ret;
2964 int i;
2965
2966 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2967
2968 /* Remove everything */
2969 query = bson_new ();
2970 mongoc_bulk_operation_remove (bulk, query);
2971 bson_destroy (query);
2972
2973 /* Add a few documents */
2974 for (i = 1; i < 4; i++) {
2975 doc = BCON_NEW ("_id", BCON_INT32 (i));
2976 mongoc_bulk_operation_insert (bulk, doc);
2977 bson_destroy (doc);
2978 }
2979
2980 /* {_id: 1} => {$set: {foo: "bar"}} */
2981 query = BCON_NEW ("_id", BCON_INT32 (1));
2982 doc = BCON_NEW ("$set", "{", "foo", BCON_UTF8 ("bar"), "}");
2983 mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, NULL, &error);
2984 bson_destroy (query);
2985 bson_destroy (doc);
2986
2987 /* {_id: 4} => {'$inc': {'j': 1}} (upsert) */
2988 opts = BCON_NEW ("upsert", BCON_BOOL (true));
2989 query = BCON_NEW ("_id", BCON_INT32 (4));
2990 doc = BCON_NEW ("$inc", "{", "j", BCON_INT32 (1), "}");
2991 mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, opts, &error);
2992 bson_destroy (query);
2993 bson_destroy (doc);
2994 bson_destroy (opts);
2995
2996 /* replace {j:1} with {j:2} */
2997 query = BCON_NEW ("j", BCON_INT32 (1));
2998 doc = BCON_NEW ("j", BCON_INT32 (2));
2999 mongoc_bulk_operation_replace_one_with_opts (bulk, query, doc, NULL, &error);
3000 bson_destroy (query);
3001 bson_destroy (doc);
3002
3003 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3004
3005 str = bson_as_canonical_extended_json (&reply, NULL);
3006 printf ("%s\n", str);
3007 bson_free (str);
3008
3009 if (!ret) {
3010 printf ("Error: %s\n", error.message);
3011 }
3012
3013 bson_destroy (&reply);
3014 mongoc_bulk_operation_destroy (bulk);
3015 }
3016
3017 int
3018 main (int argc, char *argv[])
3019 {
3020 mongoc_client_t *client;
3021 mongoc_collection_t *collection;
3022 const char *uri_string = "mongodb://localhost/?appname=bulk2-example";
3023 mongoc_uri_t *uri;
3024 bson_error_t error;
3025
3026 mongoc_init ();
3027
3028 uri = mongoc_uri_new_with_error (uri_string, &error);
3029 if (!uri) {
3030 fprintf (stderr,
3031 "failed to parse URI: %s\n"
3032 "error message: %s\n",
3033 uri_string,
3034 error.message);
3035 return EXIT_FAILURE;
3036 }
3037
3038 client = mongoc_client_new_from_uri (uri);
3039 if (!client) {
3040 return EXIT_FAILURE;
3041 }
3042
3043 mongoc_client_set_error_api (client, 2);
3044 collection = mongoc_client_get_collection (client, "test", "test");
3045
3046 bulk2 (collection);
3047
3048 mongoc_uri_destroy (uri);
3049 mongoc_collection_destroy (collection);
3050 mongoc_client_destroy (client);
3051
3052 mongoc_cleanup ();
3053
3054 return EXIT_SUCCESS;
3055 }
3056
3057
3058 Example reply document:
3059
3060 { "nInserted" : 3,
3061 "nMatched" : 2,
3062 "nModified" : 2,
3063 "nRemoved" : 10000,
3064 "nUpserted" : 1,
3065 "upserted" : [{"index" : 5, "_id" : 4}],
3066 "writeErrors" : []
3067 "writeConcernErrors" : [] }
3068
3069 The index field in the upserted array is the 0-based index of the up‐
3070 sert operation; in this example, the sixth operation of the overall
3071 bulk operation was an upsert, so its index is 5.
3072
3073 Unordered Bulk Write Operations
3074 Unordered bulk write operations are batched and sent to the server in
3075 arbitrary order where they may be executed in parallel. Any errors that
3076 occur are reported after all operations are attempted.
3077
3078 In the next example the first and third operations fail due to the
3079 unique constraint on _id. Since we are doing unordered execution the
3080 second and fourth operations succeed.
3081
3082 bulk3.c
3083
3084 #include <assert.h>
3085 #include <mongoc/mongoc.h>
3086 #include <stdio.h>
3087
3088 static void
3089 bulk3 (mongoc_collection_t *collection)
3090 {
3091 bson_t opts = BSON_INITIALIZER;
3092 mongoc_bulk_operation_t *bulk;
3093 bson_error_t error;
3094 bson_t *query;
3095 bson_t *doc;
3096 bson_t reply;
3097 char *str;
3098 bool ret;
3099
3100 /* false indicates unordered */
3101 BSON_APPEND_BOOL (&opts, "ordered", false);
3102 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3103 bson_destroy (&opts);
3104
3105 /* Add a document */
3106 doc = BCON_NEW ("_id", BCON_INT32 (1));
3107 mongoc_bulk_operation_insert (bulk, doc);
3108 bson_destroy (doc);
3109
3110 /* remove {_id: 2} */
3111 query = BCON_NEW ("_id", BCON_INT32 (2));
3112 mongoc_bulk_operation_remove_one (bulk, query);
3113 bson_destroy (query);
3114
3115 /* insert {_id: 3} */
3116 doc = BCON_NEW ("_id", BCON_INT32 (3));
3117 mongoc_bulk_operation_insert (bulk, doc);
3118 bson_destroy (doc);
3119
3120 /* replace {_id:4} {'i': 1} */
3121 query = BCON_NEW ("_id", BCON_INT32 (4));
3122 doc = BCON_NEW ("i", BCON_INT32 (1));
3123 mongoc_bulk_operation_replace_one (bulk, query, doc, false);
3124 bson_destroy (query);
3125 bson_destroy (doc);
3126
3127 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3128
3129 str = bson_as_canonical_extended_json (&reply, NULL);
3130 printf ("%s\n", str);
3131 bson_free (str);
3132
3133 if (!ret) {
3134 printf ("Error: %s\n", error.message);
3135 }
3136
3137 bson_destroy (&reply);
3138 mongoc_bulk_operation_destroy (bulk);
3139 bson_destroy (&opts);
3140 }
3141
3142 int
3143 main (int argc, char *argv[])
3144 {
3145 mongoc_client_t *client;
3146 mongoc_collection_t *collection;
3147 const char *uri_string = "mongodb://localhost/?appname=bulk3-example";
3148 mongoc_uri_t *uri;
3149 bson_error_t error;
3150
3151 mongoc_init ();
3152
3153 uri = mongoc_uri_new_with_error (uri_string, &error);
3154 if (!uri) {
3155 fprintf (stderr,
3156 "failed to parse URI: %s\n"
3157 "error message: %s\n",
3158 uri_string,
3159 error.message);
3160 return EXIT_FAILURE;
3161 }
3162
3163 client = mongoc_client_new_from_uri (uri);
3164 if (!client) {
3165 return EXIT_FAILURE;
3166 }
3167
3168 mongoc_client_set_error_api (client, 2);
3169 collection = mongoc_client_get_collection (client, "test", "test");
3170
3171 bulk3 (collection);
3172
3173 mongoc_uri_destroy (uri);
3174 mongoc_collection_destroy (collection);
3175 mongoc_client_destroy (client);
3176
3177 mongoc_cleanup ();
3178
3179 return EXIT_SUCCESS;
3180 }
3181
3182
3183 Example reply document:
3184
3185 { "nInserted" : 0,
3186 "nMatched" : 1,
3187 "nModified" : 1,
3188 "nRemoved" : 1,
3189 "nUpserted" : 0,
3190 "writeErrors" : [
3191 { "index" : 0,
3192 "code" : 11000,
3193 "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }" },
3194 { "index" : 2,
3195 "code" : 11000,
3196 "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 3 }" } ],
3197 "writeConcernErrors" : [] }
3198
3199 Error: E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }
3200
3201 The bson_error_t domain is MONGOC_ERROR_COMMAND and its code is 11000.
3202
3203 Bulk Operation Bypassing Document Validation
3204 This feature is only available when using MongoDB 3.2 and later.
3205
3206 By default bulk operations are validated against the schema, if any is
3207 defined. In certain cases however it may be necessary to bypass the
3208 document validation.
3209
3210 bulk5.c
3211
3212 #include <assert.h>
3213 #include <mongoc/mongoc.h>
3214 #include <stdio.h>
3215
3216 static void
3217 bulk5_fail (mongoc_collection_t *collection)
3218 {
3219 mongoc_bulk_operation_t *bulk;
3220 bson_error_t error;
3221 bson_t *doc;
3222 bson_t reply;
3223 char *str;
3224 bool ret;
3225
3226 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3227
3228 /* Two inserts */
3229 doc = BCON_NEW ("_id", BCON_INT32 (31));
3230 mongoc_bulk_operation_insert (bulk, doc);
3231 bson_destroy (doc);
3232
3233 doc = BCON_NEW ("_id", BCON_INT32 (32));
3234 mongoc_bulk_operation_insert (bulk, doc);
3235 bson_destroy (doc);
3236
3237 /* The above documents do not comply to the schema validation rules
3238 * we created previously, so this will result in an error */
3239 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3240
3241 str = bson_as_canonical_extended_json (&reply, NULL);
3242 printf ("%s\n", str);
3243 bson_free (str);
3244
3245 if (!ret) {
3246 printf ("Error: %s\n", error.message);
3247 }
3248
3249 bson_destroy (&reply);
3250 mongoc_bulk_operation_destroy (bulk);
3251 }
3252
3253 static void
3254 bulk5_success (mongoc_collection_t *collection)
3255 {
3256 mongoc_bulk_operation_t *bulk;
3257 bson_error_t error;
3258 bson_t *doc;
3259 bson_t reply;
3260 char *str;
3261 bool ret;
3262
3263 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3264
3265 /* Allow this document to bypass document validation.
3266 * NOTE: When authentication is enabled, the authenticated user must have
3267 * either the "dbadmin" or "restore" roles to bypass document validation */
3268 mongoc_bulk_operation_set_bypass_document_validation (bulk, true);
3269
3270 /* Two inserts */
3271 doc = BCON_NEW ("_id", BCON_INT32 (31));
3272 mongoc_bulk_operation_insert (bulk, doc);
3273 bson_destroy (doc);
3274
3275 doc = BCON_NEW ("_id", BCON_INT32 (32));
3276 mongoc_bulk_operation_insert (bulk, doc);
3277 bson_destroy (doc);
3278
3279 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3280
3281 str = bson_as_canonical_extended_json (&reply, NULL);
3282 printf ("%s\n", str);
3283 bson_free (str);
3284
3285 if (!ret) {
3286 printf ("Error: %s\n", error.message);
3287 }
3288
3289 bson_destroy (&reply);
3290 mongoc_bulk_operation_destroy (bulk);
3291 }
3292
3293 int
3294 main (int argc, char *argv[])
3295 {
3296 bson_t *options;
3297 bson_error_t error;
3298 mongoc_client_t *client;
3299 mongoc_collection_t *collection;
3300 mongoc_database_t *database;
3301 const char *uri_string = "mongodb://localhost/?appname=bulk5-example";
3302 mongoc_uri_t *uri;
3303
3304 mongoc_init ();
3305
3306 uri = mongoc_uri_new_with_error (uri_string, &error);
3307 if (!uri) {
3308 fprintf (stderr,
3309 "failed to parse URI: %s\n"
3310 "error message: %s\n",
3311 uri_string,
3312 error.message);
3313 return EXIT_FAILURE;
3314 }
3315
3316 client = mongoc_client_new_from_uri (uri);
3317 if (!client) {
3318 return EXIT_FAILURE;
3319 }
3320
3321 mongoc_client_set_error_api (client, 2);
3322 database = mongoc_client_get_database (client, "testasdf");
3323
3324 /* Create schema validator */
3325 options = BCON_NEW (
3326 "validator", "{", "number", "{", "$gte", BCON_INT32 (5), "}", "}");
3327 collection =
3328 mongoc_database_create_collection (database, "collname", options, &error);
3329
3330 if (collection) {
3331 bulk5_fail (collection);
3332 bulk5_success (collection);
3333 mongoc_collection_destroy (collection);
3334 } else {
3335 fprintf (stderr, "Couldn't create collection: '%s'\n", error.message);
3336 }
3337
3338 bson_free (options);
3339 mongoc_uri_destroy (uri);
3340 mongoc_database_destroy (database);
3341 mongoc_client_destroy (client);
3342
3343 mongoc_cleanup ();
3344
3345 return EXIT_SUCCESS;
3346 }
3347
3348
3349 Running the above example will result in:
3350
3351 { "nInserted" : 0,
3352 "nMatched" : 0,
3353 "nModified" : 0,
3354 "nRemoved" : 0,
3355 "nUpserted" : 0,
3356 "writeErrors" : [
3357 { "index" : 0,
3358 "code" : 121,
3359 "errmsg" : "Document failed validation" } ] }
3360
3361 Error: Document failed validation
3362
3363 { "nInserted" : 2,
3364 "nMatched" : 0,
3365 "nModified" : 0,
3366 "nRemoved" : 0,
3367 "nUpserted" : 0,
3368 "writeErrors" : [] }
3369
3370 The bson_error_t domain is MONGOC_ERROR_COMMAND.
3371
3372 Bulk Operation Write Concerns
3373 By default bulk operations are executed with the write_concern of the
3374 collection they are executed against. A custom write concern can be
3375 passed to the mongoc_collection_create_bulk_operation_with_opts()
3376 method. Write concern errors (e.g. wtimeout) will be reported after all
3377 operations are attempted, regardless of execution order.
3378
3379 bulk4.c
3380
3381 #include <assert.h>
3382 #include <mongoc/mongoc.h>
3383 #include <stdio.h>
3384
3385 static void
3386 bulk4 (mongoc_collection_t *collection)
3387 {
3388 bson_t opts = BSON_INITIALIZER;
3389 mongoc_write_concern_t *wc;
3390 mongoc_bulk_operation_t *bulk;
3391 bson_error_t error;
3392 bson_t *doc;
3393 bson_t reply;
3394 char *str;
3395 bool ret;
3396
3397 wc = mongoc_write_concern_new ();
3398 mongoc_write_concern_set_w (wc, 4);
3399 mongoc_write_concern_set_wtimeout_int64 (wc, 100); /* milliseconds */
3400 mongoc_write_concern_append (wc, &opts);
3401
3402 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3403
3404 /* Two inserts */
3405 doc = BCON_NEW ("_id", BCON_INT32 (10));
3406 mongoc_bulk_operation_insert (bulk, doc);
3407 bson_destroy (doc);
3408
3409 doc = BCON_NEW ("_id", BCON_INT32 (11));
3410 mongoc_bulk_operation_insert (bulk, doc);
3411 bson_destroy (doc);
3412
3413 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3414
3415 str = bson_as_canonical_extended_json (&reply, NULL);
3416 printf ("%s\n", str);
3417 bson_free (str);
3418
3419 if (!ret) {
3420 printf ("Error: %s\n", error.message);
3421 }
3422
3423 bson_destroy (&reply);
3424 mongoc_bulk_operation_destroy (bulk);
3425 mongoc_write_concern_destroy (wc);
3426 bson_destroy (&opts);
3427 }
3428
3429 int
3430 main (int argc, char *argv[])
3431 {
3432 mongoc_client_t *client;
3433 mongoc_collection_t *collection;
3434 const char *uri_string = "mongodb://localhost/?appname=bulk4-example";
3435 mongoc_uri_t *uri;
3436 bson_error_t error;
3437
3438 mongoc_init ();
3439
3440 uri = mongoc_uri_new_with_error (uri_string, &error);
3441 if (!uri) {
3442 fprintf (stderr,
3443 "failed to parse URI: %s\n"
3444 "error message: %s\n",
3445 uri_string,
3446 error.message);
3447 return EXIT_FAILURE;
3448 }
3449
3450 client = mongoc_client_new_from_uri (uri);
3451 if (!client) {
3452 return EXIT_FAILURE;
3453 }
3454
3455 mongoc_client_set_error_api (client, 2);
3456 collection = mongoc_client_get_collection (client, "test", "test");
3457
3458 bulk4 (collection);
3459
3460 mongoc_uri_destroy (uri);
3461 mongoc_collection_destroy (collection);
3462 mongoc_client_destroy (client);
3463
3464 mongoc_cleanup ();
3465
3466 return EXIT_SUCCESS;
3467 }
3468
3469
3470 Example reply document and error message:
3471
3472 { "nInserted" : 2,
3473 "nMatched" : 0,
3474 "nModified" : 0,
3475 "nRemoved" : 0,
3476 "nUpserted" : 0,
3477 "writeErrors" : [],
3478 "writeConcernErrors" : [
3479 { "code" : 64,
3480 "errmsg" : "waiting for replication timed out" }
3481 ] }
3482
3483 Error: waiting for replication timed out
3484
3485 The bson_error_t domain is MONGOC_ERROR_WRITE_CONCERN if there are
3486 write concern errors and no write errors. Write errors indicate failed
3487 operations, so they take precedence over write concern errors, which
3488 mean merely that the write concern is not satisfied yet.
3489
3490 Setting Collation Order
3491 This feature is only available when using MongoDB 3.4 and later.
3492
3493 bulk-collation.c
3494
3495 #include <mongoc/mongoc.h>
3496 #include <stdio.h>
3497
3498 static void
3499 bulk_collation (mongoc_collection_t *collection)
3500 {
3501 mongoc_bulk_operation_t *bulk;
3502 bson_t *opts;
3503 bson_t *doc;
3504 bson_t *selector;
3505 bson_t *update;
3506 bson_error_t error;
3507 bson_t reply;
3508 char *str;
3509 uint32_t ret;
3510
3511 /* insert {_id: "one"} and {_id: "One"} */
3512 bulk = mongoc_collection_create_bulk_operation_with_opts (
3513 collection, NULL);
3514 doc = BCON_NEW ("_id", BCON_UTF8 ("one"));
3515 mongoc_bulk_operation_insert (bulk, doc);
3516 bson_destroy (doc);
3517
3518 doc = BCON_NEW ("_id", BCON_UTF8 ("One"));
3519 mongoc_bulk_operation_insert (bulk, doc);
3520 bson_destroy (doc);
3521
3522 /* "One" normally sorts before "one"; make "one" come first */
3523 opts = BCON_NEW ("collation",
3524 "{",
3525 "locale",
3526 BCON_UTF8 ("en_US"),
3527 "caseFirst",
3528 BCON_UTF8 ("lower"),
3529 "}");
3530
3531 /* set x=1 on the document with _id "One", which now sorts after "one" */
3532 update = BCON_NEW ("$set", "{", "x", BCON_INT64 (1), "}");
3533 selector = BCON_NEW ("_id", "{", "$gt", BCON_UTF8 ("one"), "}");
3534 mongoc_bulk_operation_update_one_with_opts (
3535 bulk, selector, update, opts, &error);
3536
3537 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3538
3539 str = bson_as_canonical_extended_json (&reply, NULL);
3540 printf ("%s\n", str);
3541 bson_free (str);
3542
3543 if (!ret) {
3544 printf ("Error: %s\n", error.message);
3545 }
3546
3547 bson_destroy (&reply);
3548 bson_destroy (update);
3549 bson_destroy (selector);
3550 bson_destroy (opts);
3551 mongoc_bulk_operation_destroy (bulk);
3552 }
3553
3554 int
3555 main (int argc, char *argv[])
3556 {
3557 mongoc_client_t *client;
3558 mongoc_collection_t *collection;
3559 const char *uri_string = "mongodb://localhost/?appname=bulk-collation";
3560 mongoc_uri_t *uri;
3561 bson_error_t error;
3562
3563 mongoc_init ();
3564
3565 uri = mongoc_uri_new_with_error (uri_string, &error);
3566 if (!uri) {
3567 fprintf (stderr,
3568 "failed to parse URI: %s\n"
3569 "error message: %s\n",
3570 uri_string,
3571 error.message);
3572 return EXIT_FAILURE;
3573 }
3574
3575 client = mongoc_client_new_from_uri (uri);
3576 if (!client) {
3577 return EXIT_FAILURE;
3578 }
3579
3580 mongoc_client_set_error_api (client, 2);
3581 collection = mongoc_client_get_collection (client, "db", "collection");
3582 bulk_collation (collection);
3583
3584 mongoc_uri_destroy (uri);
3585 mongoc_collection_destroy (collection);
3586 mongoc_client_destroy (client);
3587
3588 mongoc_cleanup ();
3589
3590 return EXIT_SUCCESS;
3591 }
3592
3593
3594 Running the above example will result in:
3595
3596 { "nInserted" : 2,
3597 "nMatched" : 1,
3598 "nModified" : 1,
3599 "nRemoved" : 0,
3600 "nUpserted" : 0,
3601 "writeErrors" : [ ]
3602 }
3603
3604 Unacknowledged Bulk Writes
3605 Set "w" to zero for an unacknowledged write. The driver sends unac‐
3606 knowledged writes using the legacy opcodes OP_INSERT, OP_UPDATE, and
3607 OP_DELETE.
3608
3609 bulk6.c
3610
3611 #include <mongoc/mongoc.h>
3612 #include <stdio.h>
3613
3614 static void
3615 bulk6 (mongoc_collection_t *collection)
3616 {
3617 bson_t opts = BSON_INITIALIZER;
3618 mongoc_write_concern_t *wc;
3619 mongoc_bulk_operation_t *bulk;
3620 bson_error_t error;
3621 bson_t *doc;
3622 bson_t *selector;
3623 bson_t reply;
3624 char *str;
3625 bool ret;
3626
3627 wc = mongoc_write_concern_new ();
3628 mongoc_write_concern_set_w (wc, 0);
3629 mongoc_write_concern_append (wc, &opts);
3630
3631 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3632
3633 doc = BCON_NEW ("_id", BCON_INT32 (10));
3634 mongoc_bulk_operation_insert (bulk, doc);
3635 bson_destroy (doc);
3636
3637 selector = BCON_NEW ("_id", BCON_INT32 (11));
3638 mongoc_bulk_operation_remove_one (bulk, selector);
3639 bson_destroy (selector);
3640
3641 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3642
3643 str = bson_as_canonical_extended_json (&reply, NULL);
3644 printf ("%s\n", str);
3645 bson_free (str);
3646
3647 if (!ret) {
3648 printf ("Error: %s\n", error.message);
3649 }
3650
3651 bson_destroy (&reply);
3652 mongoc_bulk_operation_destroy (bulk);
3653 mongoc_write_concern_destroy (wc);
3654 bson_destroy (&opts);
3655 }
3656
3657 int
3658 main (int argc, char *argv[])
3659 {
3660 mongoc_client_t *client;
3661 mongoc_collection_t *collection;
3662 const char *uri_string = "mongodb://localhost/?appname=bulk6-example";
3663 mongoc_uri_t *uri;
3664 bson_error_t error;
3665
3666 mongoc_init ();
3667
3668 uri = mongoc_uri_new_with_error (uri_string, &error);
3669 if (!uri) {
3670 fprintf (stderr,
3671 "failed to parse URI: %s\n"
3672 "error message: %s\n",
3673 uri_string,
3674 error.message);
3675 return EXIT_FAILURE;
3676 }
3677
3678 client = mongoc_client_new_from_uri (uri);
3679 if (!client) {
3680 return EXIT_FAILURE;
3681 }
3682
3683 mongoc_client_set_error_api (client, 2);
3684 collection = mongoc_client_get_collection (client, "test", "test");
3685
3686 bulk6 (collection);
3687
3688 mongoc_uri_destroy (uri);
3689 mongoc_collection_destroy (collection);
3690 mongoc_client_destroy (client);
3691
3692 mongoc_cleanup ();
3693
3694 return EXIT_SUCCESS;
3695 }
3696
3697
3698 The reply document is empty:
3699
3700 { }
3701
3702 Further Reading
3703 See the Driver Bulk API Spec, which describes bulk write operations for
3704 all MongoDB drivers.
3705
3706 Aggregation Framework Examples
3707 This document provides a number of practical examples that display the
3708 capabilities of the aggregation framework.
3709
3710 The Aggregations using the Zip Codes Data Set examples uses a publicly
3711 available data set of all zipcodes and populations in the United
3712 States. These data are available at: zips.json.
3713
3714 Requirements
3715 Let's check if everything is installed.
3716
3717 Use the following command to load zips.json data set into mongod in‐
3718 stance:
3719
3720 $ mongoimport --drop -d test -c zipcodes zips.json
3721
3722 Let's use the MongoDB shell to verify that everything was imported suc‐
3723 cessfully.
3724
3725 $ mongo test
3726 connecting to: test
3727 > db.zipcodes.count()
3728 29467
3729 > db.zipcodes.findOne()
3730 {
3731 "_id" : "35004",
3732 "city" : "ACMAR",
3733 "loc" : [
3734 -86.51557,
3735 33.584132
3736 ],
3737 "pop" : 6055,
3738 "state" : "AL"
3739 }
3740
3741 Aggregations using the Zip Codes Data Set
3742 Each document in this collection has the following form:
3743
3744 {
3745 "_id" : "35004",
3746 "city" : "Acmar",
3747 "state" : "AL",
3748 "pop" : 6055,
3749 "loc" : [-86.51557, 33.584132]
3750 }
3751
3752 In these documents:
3753
3754 • The _id field holds the zipcode as a string.
3755
3756 • The city field holds the city name.
3757
3758 • The state field holds the two letter state abbreviation.
3759
3760 • The pop field holds the population.
3761
3762 • The loc field holds the location as a [latitude, longitude] array.
3763
3764 States with Populations Over 10 Million
3765 To get all states with a population greater than 10 million, use the
3766 following aggregation pipeline:
3767
3768 aggregation1.c
3769
3770 #include <mongoc/mongoc.h>
3771 #include <stdio.h>
3772
3773 static void
3774 print_pipeline (mongoc_collection_t *collection)
3775 {
3776 mongoc_cursor_t *cursor;
3777 bson_error_t error;
3778 const bson_t *doc;
3779 bson_t *pipeline;
3780 char *str;
3781
3782 pipeline = BCON_NEW ("pipeline",
3783 "[",
3784 "{",
3785 "$group",
3786 "{",
3787 "_id",
3788 "$state",
3789 "total_pop",
3790 "{",
3791 "$sum",
3792 "$pop",
3793 "}",
3794 "}",
3795 "}",
3796 "{",
3797 "$match",
3798 "{",
3799 "total_pop",
3800 "{",
3801 "$gte",
3802 BCON_INT32 (10000000),
3803 "}",
3804 "}",
3805 "}",
3806 "]");
3807
3808 cursor = mongoc_collection_aggregate (
3809 collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL);
3810
3811 while (mongoc_cursor_next (cursor, &doc)) {
3812 str = bson_as_canonical_extended_json (doc, NULL);
3813 printf ("%s\n", str);
3814 bson_free (str);
3815 }
3816
3817 if (mongoc_cursor_error (cursor, &error)) {
3818 fprintf (stderr, "Cursor Failure: %s\n", error.message);
3819 }
3820
3821 mongoc_cursor_destroy (cursor);
3822 bson_destroy (pipeline);
3823 }
3824
3825 int
3826 main (int argc, char *argv[])
3827 {
3828 mongoc_client_t *client;
3829 mongoc_collection_t *collection;
3830 const char *uri_string =
3831 "mongodb://localhost:27017/?appname=aggregation-example";
3832 mongoc_uri_t *uri;
3833 bson_error_t error;
3834
3835 mongoc_init ();
3836
3837 uri = mongoc_uri_new_with_error (uri_string, &error);
3838 if (!uri) {
3839 fprintf (stderr,
3840 "failed to parse URI: %s\n"
3841 "error message: %s\n",
3842 uri_string,
3843 error.message);
3844 return EXIT_FAILURE;
3845 }
3846
3847 client = mongoc_client_new_from_uri (uri);
3848 if (!client) {
3849 return EXIT_FAILURE;
3850 }
3851
3852 mongoc_client_set_error_api (client, 2);
3853 collection = mongoc_client_get_collection (client, "test", "zipcodes");
3854
3855 print_pipeline (collection);
3856
3857 mongoc_uri_destroy (uri);
3858 mongoc_collection_destroy (collection);
3859 mongoc_client_destroy (client);
3860
3861 mongoc_cleanup ();
3862
3863 return EXIT_SUCCESS;
3864 }
3865
3866
3867 You should see a result like the following:
3868
3869 { "_id" : "PA", "total_pop" : 11881643 }
3870 { "_id" : "OH", "total_pop" : 10847115 }
3871 { "_id" : "NY", "total_pop" : 17990455 }
3872 { "_id" : "FL", "total_pop" : 12937284 }
3873 { "_id" : "TX", "total_pop" : 16986510 }
3874 { "_id" : "IL", "total_pop" : 11430472 }
3875 { "_id" : "CA", "total_pop" : 29760021 }
3876
3877 The above aggregation pipeline is build from two pipeline operators:
3878 $group and $match.
3879
3880 The $group pipeline operator requires _id field where we specify group‐
3881 ing; remaining fields specify how to generate composite value and must
3882 use one of the group aggregation functions: $addToSet, $first, $last,
3883 $max, $min, $avg, $push, $sum. The $match pipeline operator syntax is
3884 the same as the read operation query syntax.
3885
3886 The $group process reads all documents and for each state it creates a
3887 separate document, for example:
3888
3889 { "_id" : "WA", "total_pop" : 4866692 }
3890
3891 The total_pop field uses the $sum aggregation function to sum the val‐
3892 ues of all pop fields in the source documents.
3893
3894 Documents created by $group are piped to the $match pipeline operator.
3895 It returns the documents with the value of total_pop field greater than
3896 or equal to 10 million.
3897
3898 Average City Population by State
3899 To get the first three states with the greatest average population per
3900 city, use the following aggregation:
3901
3902 pipeline = BCON_NEW ("pipeline", "[",
3903 "{", "$group", "{", "_id", "{", "state", "$state", "city", "$city", "}", "pop", "{", "$sum", "$pop", "}", "}", "}",
3904 "{", "$group", "{", "_id", "$_id.state", "avg_city_pop", "{", "$avg", "$pop", "}", "}", "}",
3905 "{", "$sort", "{", "avg_city_pop", BCON_INT32 (-1), "}", "}",
3906 "{", "$limit", BCON_INT32 (3) "}",
3907 "]");
3908
3909 This aggregate pipeline produces:
3910
3911 { "_id" : "DC", "avg_city_pop" : 303450.0 }
3912 { "_id" : "FL", "avg_city_pop" : 27942.29805615551 }
3913 { "_id" : "CA", "avg_city_pop" : 27735.341099720412 }
3914
3915 The above aggregation pipeline is build from three pipeline operators:
3916 $group, $sort and $limit.
3917
3918 The first $group operator creates the following documents:
3919
3920 { "_id" : { "state" : "WY", "city" : "Smoot" }, "pop" : 414 }
3921
3922 Note, that the $group operator can't use nested documents except the
3923 _id field.
3924
3925 The second $group uses these documents to create the following docu‐
3926 ments:
3927
3928 { "_id" : "FL", "avg_city_pop" : 27942.29805615551 }
3929
3930 These documents are sorted by the avg_city_pop field in descending or‐
3931 der. Finally, the $limit pipeline operator returns the first 3 docu‐
3932 ments from the sorted set.
3933
3934 distinct and mapReduce
3935 This document provides some practical, simple, examples to demonstrate
3936 the distinct and mapReduce commands.
3937
3938 Setup
3939 First we'll write some code to insert sample data:
3940
3941 doc-common-insert.c
3942
3943 /* Don't try to compile this file on its own. It's meant to be #included
3944 by example code */
3945
3946 /* Insert some sample data */
3947 bool
3948 insert_data (mongoc_collection_t *collection)
3949 {
3950 mongoc_bulk_operation_t *bulk;
3951 enum N { ndocs = 4 };
3952 bson_t *docs[ndocs];
3953 bson_error_t error;
3954 int i = 0;
3955 bool ret;
3956
3957 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3958
3959 docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
3960 docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
3961 docs[2] = BCON_NEW (
3962 "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
3963 docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");
3964
3965 for (i = 0; i < ndocs; i++) {
3966 mongoc_bulk_operation_insert (bulk, docs[i]);
3967 bson_destroy (docs[i]);
3968 docs[i] = NULL;
3969 }
3970
3971 ret = mongoc_bulk_operation_execute (bulk, NULL, &error);
3972
3973 if (!ret) {
3974 fprintf (stderr, "Error inserting data: %s\n", error.message);
3975 }
3976
3977 mongoc_bulk_operation_destroy (bulk);
3978 return ret;
3979 }
3980
3981 /* A helper which we'll use a lot later on */
3982 void
3983 print_res (const bson_t *reply)
3984 {
3985 char *str;
3986 BSON_ASSERT (reply);
3987 str = bson_as_canonical_extended_json (reply, NULL);
3988 printf ("%s\n", str);
3989 bson_free (str);
3990 }
3991
3992
3993 distinct command
3994 This is how to use the distinct command to get the distinct values of x
3995 which are greater than 1:
3996
3997 distinct.c
3998
3999 bool
4000 distinct (mongoc_database_t *database)
4001 {
4002 bson_t *command;
4003 bson_t reply;
4004 bson_error_t error;
4005 bool res;
4006 bson_iter_t iter;
4007 bson_iter_t array_iter;
4008 double val;
4009
4010 command = BCON_NEW ("distinct",
4011 BCON_UTF8 (COLLECTION_NAME),
4012 "key",
4013 BCON_UTF8 ("x"),
4014 "query",
4015 "{",
4016 "x",
4017 "{",
4018 "$gt",
4019 BCON_DOUBLE (1.0),
4020 "}",
4021 "}");
4022 res =
4023 mongoc_database_command_simple (database, command, NULL, &reply, &error);
4024 if (!res) {
4025 fprintf (stderr, "Error with distinct: %s\n", error.message);
4026 goto cleanup;
4027 }
4028
4029 /* Do something with reply (in this case iterate through the values) */
4030 if (!(bson_iter_init_find (&iter, &reply, "values") &&
4031 BSON_ITER_HOLDS_ARRAY (&iter) &&
4032 bson_iter_recurse (&iter, &array_iter))) {
4033 fprintf (stderr, "Couldn't extract \"values\" field from response\n");
4034 goto cleanup;
4035 }
4036
4037 while (bson_iter_next (&array_iter)) {
4038 if (BSON_ITER_HOLDS_DOUBLE (&array_iter)) {
4039 val = bson_iter_double (&array_iter);
4040 printf ("Next double: %f\n", val);
4041 }
4042 }
4043
4044 cleanup:
4045 /* cleanup */
4046 bson_destroy (command);
4047 bson_destroy (&reply);
4048 return res;
4049 }
4050
4051
4052 mapReduce - basic example
4053 A simple example using the map reduce framework. It simply adds up the
4054 number of occurrences of each "tag".
4055
4056 First define the map and reduce functions:
4057
4058 constants.c
4059
4060 const char *const COLLECTION_NAME = "things";
4061
4062 /* Our map function just emits a single (key, 1) pair for each tag
4063 in the array: */
4064 const char *const MAPPER = "function () {"
4065 "this.tags.forEach(function(z) {"
4066 "emit(z, 1);"
4067 "});"
4068 "}";
4069
4070 /* The reduce function sums over all of the emitted values for a
4071 given key: */
4072 const char *const REDUCER = "function (key, values) {"
4073 "var total = 0;"
4074 "for (var i = 0; i < values.length; i++) {"
4075 "total += values[i];"
4076 "}"
4077 "return total;"
4078 "}";
4079 /* Note We can't just return values.length as the reduce function
4080 might be called iteratively on the results of other reduce
4081 steps. */
4082
4083
4084 Run the mapReduce command. Use the generic command helpers (e.g. mon‐
4085 goc_database_command_simple()). Do not the read command helpers (e.g.
4086 mongoc_database_read_command_with_opts()) because they are considered
4087 retryable read operations. If retryable reads are enabled, those opera‐
4088 tions will retry once on a retryable error, giving undesirable behavior
4089 for mapReduce.
4090
4091 map-reduce-basic.c
4092
4093 bool
4094 map_reduce_basic (mongoc_database_t *database)
4095 {
4096 bson_t reply;
4097 bson_t *command;
4098 bool res;
4099 bson_error_t error;
4100 mongoc_cursor_t *cursor;
4101 const bson_t *doc;
4102
4103 bool query_done = false;
4104
4105 const char *out_collection_name = "outCollection";
4106 mongoc_collection_t *out_collection;
4107
4108 /* Empty find query */
4109 bson_t find_query = BSON_INITIALIZER;
4110
4111 /* Construct the mapReduce command */
4112
4113 /* Other arguments can also be specified here, like "query" or
4114 "limit" and so on */
4115 command = BCON_NEW ("mapReduce",
4116 BCON_UTF8 (COLLECTION_NAME),
4117 "map",
4118 BCON_CODE (MAPPER),
4119 "reduce",
4120 BCON_CODE (REDUCER),
4121 "out",
4122 BCON_UTF8 (out_collection_name));
4123 res =
4124 mongoc_database_command_simple (database, command, NULL, &reply, &error);
4125
4126 if (!res) {
4127 fprintf (stderr, "MapReduce failed: %s\n", error.message);
4128 goto cleanup;
4129 }
4130
4131 /* Do something with the reply (it doesn't contain the mapReduce results) */
4132 print_res (&reply);
4133
4134 /* Now we'll query outCollection to see what the results are */
4135 out_collection =
4136 mongoc_database_get_collection (database, out_collection_name);
4137 cursor = mongoc_collection_find_with_opts (
4138 out_collection, &find_query, NULL, NULL);
4139 query_done = true;
4140
4141 /* Do something with the results */
4142 while (mongoc_cursor_next (cursor, &doc)) {
4143 print_res (doc);
4144 }
4145
4146 if (mongoc_cursor_error (cursor, &error)) {
4147 fprintf (stderr, "ERROR: %s\n", error.message);
4148 res = false;
4149 goto cleanup;
4150 }
4151
4152 cleanup:
4153 /* cleanup */
4154 if (query_done) {
4155 mongoc_cursor_destroy (cursor);
4156 mongoc_collection_destroy (out_collection);
4157 }
4158
4159 bson_destroy (&reply);
4160 bson_destroy (command);
4161
4162 return res;
4163 }
4164
4165
4166 mapReduce - more complicated example
4167 You must have replica set running for this.
4168
4169 In this example we contact a secondary in the replica set and do an
4170 "inline" map reduce, so the results are returned immediately:
4171
4172 map-reduce-advanced.c
4173
4174 bool
4175 map_reduce_advanced (mongoc_database_t *database)
4176 {
4177 bson_t *command;
4178 bson_error_t error;
4179 bool res = true;
4180 mongoc_cursor_t *cursor;
4181 mongoc_read_prefs_t *read_pref;
4182 const bson_t *doc;
4183
4184 /* Construct the mapReduce command */
4185 /* Other arguments can also be specified here, like "query" or "limit"
4186 and so on */
4187
4188 /* Read the results inline from a secondary replica */
4189 command = BCON_NEW ("mapReduce",
4190 BCON_UTF8 (COLLECTION_NAME),
4191 "map",
4192 BCON_CODE (MAPPER),
4193 "reduce",
4194 BCON_CODE (REDUCER),
4195 "out",
4196 "{",
4197 "inline",
4198 "1",
4199 "}");
4200
4201 read_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
4202 cursor = mongoc_database_command (
4203 database, MONGOC_QUERY_NONE, 0, 0, 0, command, NULL, read_pref);
4204
4205 /* Do something with the results */
4206 while (mongoc_cursor_next (cursor, &doc)) {
4207 print_res (doc);
4208 }
4209
4210 if (mongoc_cursor_error (cursor, &error)) {
4211 fprintf (stderr, "ERROR: %s\n", error.message);
4212 res = false;
4213 }
4214
4215 mongoc_cursor_destroy (cursor);
4216 mongoc_read_prefs_destroy (read_pref);
4217 bson_destroy (command);
4218
4219 return res;
4220 }
4221
4222
4223 Running the Examples
4224 Here's how to run the example code
4225
4226 basic-aggregation.c
4227
4228 /*
4229 * Copyright 2016 MongoDB, Inc.
4230 *
4231 * Licensed under the Apache License, Version 2.0 (the "License");
4232 * you may not use this file except in compliance with the License.
4233 * You may obtain a copy of the License at
4234 *
4235 * http://www.apache.org/licenses/LICENSE-2.0
4236 *
4237 * Unless required by applicable law or agreed to in writing, software
4238 * distributed under the License is distributed on an "AS IS" BASIS,
4239 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4240 * See the License for the specific language governing permissions and
4241 * limitations under the License.
4242 */
4243
4244
4245 #include <mongoc/mongoc.h>
4246 #include <stdio.h>
4247
4248
4249 #include "constants.c"
4250
4251 #include "../doc-common-insert.c"
4252 #include "distinct.c"
4253 #include "map-reduce-basic.c"
4254 #include "map-reduce-advanced.c"
4255
4256
4257 int
4258 main (int argc, char *argv[])
4259 {
4260 mongoc_database_t *database = NULL;
4261 mongoc_client_t *client = NULL;
4262 mongoc_collection_t *collection = NULL;
4263 mongoc_uri_t *uri = NULL;
4264 bson_error_t error;
4265 char *host_and_port = NULL;
4266 int exit_code = EXIT_FAILURE;
4267
4268 if (argc != 2) {
4269 fprintf (stderr, "usage: %s CONNECTION-STRING\n", argv[0]);
4270 fprintf (stderr,
4271 "the connection string can be of the following forms:\n");
4272 fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
4273 fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
4274 fprintf (stderr,
4275 "mongodb://user:pass@localhost:27017\t"
4276 "local machine on port 27017, and authenticate with username "
4277 "user and password pass\n");
4278 return exit_code;
4279 }
4280
4281 mongoc_init ();
4282
4283 if (strncmp (argv[1], "mongodb://", 10) == 0) {
4284 host_and_port = bson_strdup (argv[1]);
4285 } else {
4286 host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
4287 }
4288
4289 uri = mongoc_uri_new_with_error (host_and_port, &error);
4290 if (!uri) {
4291 fprintf (stderr,
4292 "failed to parse URI: %s\n"
4293 "error message: %s\n",
4294 host_and_port,
4295 error.message);
4296 goto cleanup;
4297 }
4298
4299 client = mongoc_client_new_from_uri (uri);
4300 if (!client) {
4301 goto cleanup;
4302 }
4303
4304 mongoc_client_set_error_api (client, 2);
4305 database = mongoc_client_get_database (client, "test");
4306 collection = mongoc_database_get_collection (database, COLLECTION_NAME);
4307
4308 printf ("Inserting data\n");
4309 if (!insert_data (collection)) {
4310 goto cleanup;
4311 }
4312
4313 printf ("distinct\n");
4314 if (!distinct (database)) {
4315 goto cleanup;
4316 }
4317
4318 printf ("map reduce\n");
4319 if (!map_reduce_basic (database)) {
4320 goto cleanup;
4321 }
4322
4323 printf ("more complicated map reduce\n");
4324 if (!map_reduce_advanced (database)) {
4325 goto cleanup;
4326 }
4327
4328 exit_code = EXIT_SUCCESS;
4329
4330 cleanup:
4331 if (collection) {
4332 mongoc_collection_destroy (collection);
4333 }
4334
4335 if (database) {
4336 mongoc_database_destroy (database);
4337 }
4338
4339 if (client) {
4340 mongoc_client_destroy (client);
4341 }
4342
4343 if (uri) {
4344 mongoc_uri_destroy (uri);
4345 }
4346
4347 if (host_and_port) {
4348 bson_free (host_and_port);
4349 }
4350
4351 mongoc_cleanup ();
4352 return exit_code;
4353 }
4354
4355
4356 If you want to try the advanced map reduce example with a secondary,
4357 start a replica set (instructions for how to do this can be found
4358 here).
4359
4360 Otherwise, just start an instance of MongoDB:
4361
4362 $ mongod
4363
4364 Now compile and run the example program:
4365
4366 $ cd examples/basic_aggregation/
4367 $ gcc -Wall -o agg-example basic-aggregation.c $(pkg-config --cflags --libs libmongoc-1.0)
4368 $ ./agg-example localhost
4369
4370 Inserting data
4371 distinct
4372 Next double: 2.000000
4373 Next double: 3.000000
4374 map reduce
4375 { "result" : "outCollection", "timeMillis" : 155, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 }
4376 { "_id" : "cat", "value" : 63 }
4377 { "_id" : "dog", "value" : 42 }
4378 { "_id" : "mouse", "value" : 21 }
4379 more complicated map reduce
4380 { "results" : [ { "_id" : "cat", "value" : 63 }, { "_id" : "dog", "value" : 42 }, { "_id" : "mouse", "value" : 21 } ], "timeMillis" : 14, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 }
4381
4382 Using libmongoc in a Microsoft Visual Studio project
4383 Download and install libmongoc on your system, then open Visual Studio,
4384 select "File→New→Project...", and create a new Win32 Console Applica‐
4385 tion. [image]
4386
4387 Remember to switch the platform from 32-bit to 64-bit: [image]
4388
4389 Right-click on your console application in the Solution Explorer and
4390 select "Properties". Choose to edit properties for "All Configura‐
4391 tions", expand the "C/C++" options and choose "General". Add to the
4392 "Additional Include Directories" these paths:
4393
4394 C:\mongo-c-driver\include\libbson-1.0
4395 C:\mongo-c-driver\include\libmongoc-1.0
4396 [image]
4397
4398 (If you chose a different CMAKE_INSTALL_PREFIX when you ran CMake, your
4399 include paths will be different.)
4400
4401 Also in the Properties dialog, expand the "Linker" options and choose
4402 "Input", and add to the "Additional Dependencies" these libraries:
4403
4404 C:\mongo-c-driver\lib\bson-1.0.lib
4405 C:\mongo-c-driver\lib\mongoc-1.0.lib
4406 [image]
4407
4408 Adding these libraries as dependencies provides linker symbols to build
4409 your application, but to actually run it, libbson's and libmongoc's
4410 DLLs must be in your executable path. Select "Debugging" in the Proper‐
4411 ties dialog, and set the "Environment" option to:
4412
4413 PATH=c:/mongo-c-driver/bin
4414 [image]
4415
4416 Finally, include "mongoc/mongoc.h" in your project's "stdafx.h":
4417
4418 #include <mongoc/mongoc.h>
4419
4420 Static linking
4421 Following the instructions above, you have dynamically linked your ap‐
4422 plication to the libbson and libmongoc DLLs. This is usually the right
4423 choice. If you want to link statically instead, update your "Additional
4424 Dependencies" list by removing bson-1.0.lib and mongoc-1.0.lib and re‐
4425 placing them with these libraries:
4426
4427 C:\mongo-c-driver\lib\bson-static-1.0.lib
4428 C:\mongo-c-driver\lib\mongoc-static-1.0.lib
4429 ws2_32.lib
4430 Secur32.lib
4431 Crypt32.lib
4432 BCrypt.lib
4433 [image]
4434
4435 (To explain the purpose of each library: bson-static-1.0.lib and mon‐
4436 goc-static-1.0.lib are static archives of the driver code. The socket
4437 library ws2_32 is required by libbson, which uses the socket routine
4438 gethostname to help guarantee ObjectId uniqueness. The BCrypt library
4439 is used by libmongoc for TLS connections to MongoDB, and Secur32 and
4440 Crypt32 are required for enterprise authentication methods like Ker‐
4441 beros.)
4442
4443 Finally, define two preprocessor symbols before including mongoc/mon‐
4444 goc.h in your stdafx.h:
4445
4446 #define BSON_STATIC
4447 #define MONGOC_STATIC
4448 #include <mongoc/mongoc.h>
4449
4450 Making these changes to your project is only required for static link‐
4451 ing; for most people, the dynamic-linking instructions above are pre‐
4452 ferred.
4453
4454 Next Steps
4455 Now you can build and debug applications in Visual Studio that use
4456 libbson and libmongoc. Proceed to making-a-connection in the tutorial
4457 to learn how connect to MongoDB and perform operations.
4458
4459 Creating Indexes
4460 To create indexes on a MongoDB collection, execute the createIndexes
4461 command with a command function like mongoc_database_write_com‐
4462 mand_with_opts or mongoc_collection_write_command_with_opts. See the
4463 MongoDB Manual entry for the createIndexes command for details.
4464
4465 WARNING:
4466 The commitQuorum option to the createIndexes command is only sup‐
4467 ported in MongoDB 4.4+ servers, but it is not validated in the com‐
4468 mand functions. Do not pass commitQuorum if connected to server ver‐
4469 sions less than 4.4. Using the commitQuorum option on server ver‐
4470 sions less than 4.4 may have adverse effects on index builds.
4471
4472 Example
4473 example-create-indexes.c
4474
4475 /* gcc example-create-indexes.c -o example-create-indexes $(pkg-config --cflags
4476 * --libs libmongoc-1.0) */
4477
4478 /* ./example-create-indexes [CONNECTION_STRING [COLLECTION_NAME]] */
4479
4480 #include <mongoc/mongoc.h>
4481 #include <stdio.h>
4482 #include <stdlib.h>
4483
4484 int
4485 main (int argc, char *argv[])
4486 {
4487 mongoc_client_t *client;
4488 const char *uri_string =
4489 "mongodb://127.0.0.1/?appname=create-indexes-example";
4490 mongoc_uri_t *uri;
4491 mongoc_database_t *db;
4492 const char *collection_name = "test";
4493 bson_t keys;
4494 char *index_name;
4495 bson_t *create_indexes;
4496 bson_t reply;
4497 char *reply_str;
4498 bson_error_t error;
4499 bool r;
4500
4501 mongoc_init ();
4502
4503 if (argc > 1) {
4504 uri_string = argv[1];
4505 }
4506
4507 if (argc > 2) {
4508 collection_name = argv[2];
4509 }
4510
4511 uri = mongoc_uri_new_with_error (uri_string, &error);
4512 if (!uri) {
4513 fprintf (stderr,
4514 "failed to parse URI: %s\n"
4515 "error message: %s\n",
4516 uri_string,
4517 error.message);
4518 return EXIT_FAILURE;
4519 }
4520
4521 client = mongoc_client_new_from_uri (uri);
4522 if (!client) {
4523 return EXIT_FAILURE;
4524 }
4525
4526 mongoc_client_set_error_api (client, 2);
4527 db = mongoc_client_get_database (client, "test");
4528
4529 /* ascending index on field "x" */
4530 bson_init (&keys);
4531 BSON_APPEND_INT32 (&keys, "x", 1);
4532 index_name = mongoc_collection_keys_to_index_string (&keys);
4533 create_indexes = BCON_NEW ("createIndexes",
4534 BCON_UTF8 (collection_name),
4535 "indexes",
4536 "[",
4537 "{",
4538 "key",
4539 BCON_DOCUMENT (&keys),
4540 "name",
4541 BCON_UTF8 (index_name),
4542 "}",
4543 "]");
4544
4545 r = mongoc_database_write_command_with_opts (
4546 db, create_indexes, NULL /* opts */, &reply, &error);
4547
4548 reply_str = bson_as_json (&reply, NULL);
4549 printf ("%s\n", reply_str);
4550
4551 if (!r) {
4552 fprintf (stderr, "Error in createIndexes: %s\n", error.message);
4553 }
4554
4555 bson_free (index_name);
4556 bson_free (reply_str);
4557 bson_destroy (&reply);
4558 bson_destroy (create_indexes);
4559 mongoc_database_destroy (db);
4560 mongoc_uri_destroy (uri);
4561 mongoc_client_destroy (client);
4562
4563 mongoc_cleanup ();
4564
4565 return r ? EXIT_SUCCESS : EXIT_FAILURE;
4566 }
4567
4568
4569 Aids for Debugging
4570 GDB
4571 This repository contains a .gdbinit file that contains helper functions
4572 to aid debugging of data structures. GDB will load this file
4573 automatically if you have added the directory which contains the
4574 .gdbinit file to GDB's auto-load safe-path, and you start GDB from the
4575 directory which holds the .gdbinit file.
4576
4577 You can see the safe-path with show auto-load safe-path on a GDB
4578 prompt. You can configure it by setting it in ~/.gdbinit with:
4579
4580 add-auto-load-safe-path /path/to/mongo-c-driver
4581
4582 If you haven't added the path to your auto-load safe-path, or start GDB
4583 in another directory, load the file with:
4584
4585 source path/to/mongo-c-driver/.gdbinit
4586
4587 The .gdbinit file defines the printbson function, which shows the con‐
4588 tents of a bson_t * variable. If you have a local bson_t, then you
4589 must prefix the variable with a &.
4590
4591 An example GDB session looks like:
4592
4593 (gdb) printbson bson
4594 ALLOC [0x555556cd7310 + 0] (len=475)
4595 {
4596 'bool' : true,
4597 'int32' : NumberInt("42"),
4598 'int64' : NumberLong("3000000042"),
4599 'string' : "Stŕìñg",
4600 'objectId' : ObjectID("5A1442F3122D331C3C6757E1"),
4601 'utcDateTime' : UTCDateTime(1511277299031),
4602 'arrayOfInts' : [
4603 '0' : NumberInt("1"),
4604 '1' : NumberInt("2")
4605 ],
4606 'embeddedDocument' : {
4607 'arrayOfStrings' : [
4608 '0' : "one",
4609 '1' : "two"
4610 ],
4611 'double' : 2.718280,
4612 'notherDoc' : {
4613 'true' : NumberInt("1"),
4614 'false' : false
4615 }
4616 },
4617 'binary' : Binary("02", "3031343532333637"),
4618 'regex' : Regex("@[a-z]+@", "im"),
4619 'null' : null,
4620 'js' : JavaScript("print foo"),
4621 'jsws' : JavaScript("print foo") with scope: {
4622 'f' : NumberInt("42"),
4623 'a' : [
4624 '0' : 3.141593,
4625 '1' : 2.718282
4626 ]
4627 },
4628 'timestamp' : Timestamp(4294967295, 4294967295),
4629 'double' : 3.141593
4630 }
4631
4632 LLDB
4633 This repository also includes a script that customizes LLDB's standard
4634 print command to print a bson_t or bson_t * as JSON:
4635
4636 (lldb) print b
4637 (bson_t) $0 = {"x": 1, "y": 2}
4638
4639 The custom bson command provides more options:
4640
4641 (lldb) bson --verbose b
4642 len=19
4643 flags=INLINE|STATIC
4644 {
4645 "x": 1,
4646 "y": 2
4647 }
4648 (lldb) bson --raw b
4649 '\x13\x00\x00\x00\x10x\x00\x01\x00\x00\x00\x10y\x00\x02\x00\x00\x00\x00'
4650
4651 Type help bson for a list of options.
4652
4653 The script requires a build of libbson with debug symbols, and an in‐
4654 stallation of PyMongo. Install PyMongo with:
4655
4656 python -m pip install pymongo
4657
4658 If you see "No module named pip" then you must install pip, then run
4659 the previous command again.
4660
4661 Create a file ~/.lldbinit containing:
4662
4663 command script import /path/to/mongo-c-driver/lldb_bson.py
4664
4665 If you see "bson command installed by lldb_bson" at the beginning of
4666 your LLDB session, you've installed the script correctly.
4667
4668 Debug assertions
4669 To enable runtime debug assertions, configure with -DENABLE_DEBUG_AS‐
4670 SERTIONS=ON.
4671
4672 Using Client-Side Field Level Encryption
4673 New in MongoDB 4.2, Client-Side Field Level Encryption (also referred
4674 to as Client-Side Encryption) allows administrators and developers to
4675 encrypt specific data fields in addition to other MongoDB encryption
4676 features.
4677
4678 With Client-Side Encryption, developers can encrypt fields client side
4679 without any server-side configuration or directives. Client-Side En‐
4680 cryption supports workloads where applications must guarantee that
4681 unauthorized parties, including server administrators, cannot read the
4682 encrypted data.
4683
4684 Automatic encryption, where sensitive fields in commands are encrypted
4685 automatically, requires an Enterprise-only process to do query analy‐
4686 sis.
4687
4688 Installation
4689 libmongocrypt
4690 There is a separate library, libmongocrypt, that must be installed
4691 prior to configuring libmongoc to enable Client-Side Encryption.
4692
4693 libmongocrypt depends on libbson. To build libmongoc with Client-Side
4694 Encryption support you must:
4695
4696 1. Install libbson
4697
4698 2. Build and install libmongocrypt
4699
4700 3. Build libmongoc
4701
4702 To install libbson, follow the instructions to install with a package
4703 manager: Install libbson with a Package Manager or build from source
4704 with cmake (disable building libmongoc with -DENABLE_MONGOC=OFF):
4705
4706 $ cd mongo-c-driver
4707 $ mkdir cmake-build && cd cmake-build
4708 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF ..
4709 $ cmake --build . --target install
4710
4711 To build and install libmongocrypt, clone the repository and configure
4712 as follows:
4713
4714 $ cd libmongocrypt
4715 $ mkdir cmake-build && cd cmake-build
4716 $ cmake -DENABLE_SHARED_BSON=ON ..
4717 $ cmake --build . --target install
4718
4719 Then, you should be able to build libmongoc with Client-Side Encryp‐
4720 tion.
4721
4722 $ cd mongo-c-driver
4723 $ mkdir cmake-build && cd cmake-build
4724 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=ON -DENABLE_CLIENT_SIDE_ENCRYPTION=ON ..
4725 $ cmake --build . --target install
4726
4727 mongocryptd
4728 The mongocryptd binary is required for automatic Client-Side Encryption
4729 and is included as a component in the MongoDB Enterprise Server pack‐
4730 age. For detailed installation instructions see the MongoDB documenta‐
4731 tion on mongocryptd.
4732
4733 mongocryptd performs the following:
4734
4735 • Parses the automatic encryption rules specified to the database con‐
4736 nection. If the JSON schema contains invalid automatic encryption
4737 syntax or any document validation syntax, mongocryptd returns an er‐
4738 ror.
4739
4740 • Uses the specified automatic encryption rules to mark fields in read
4741 and write operations for encryption.
4742
4743 • Rejects read/write operations that may return unexpected or incorrect
4744 results when applied to an encrypted field. For supported and unsup‐
4745 ported operations, see Read/Write Support with Automatic Field Level
4746 Encryption.
4747
4748 A mongoc_client_t configured with auto encryption will automatically
4749 spawn the mongocryptd process from the application's PATH. Applications
4750 can control the spawning behavior as part of the automatic encryption
4751 options. For example, to set a custom path to the mongocryptd process,
4752 set the mongocryptdSpawnPath with mongoc_auto_encryption_opts_set_ex‐
4753 tra().
4754
4755 bson_t *extra = BCON_NEW ("mongocryptdSpawnPath", "/path/to/mongocryptd");
4756 mongoc_auto_encryption_opts_set_extra (opts, extra);
4757
4758 To control the logging output of mongocryptd pass mongocryptdSpawnArgs
4759 to mongoc_auto_encryption_opts_set_extra():
4760
4761 bson_t *extra = BCON_NEW ("mongocryptdSpawnArgs",
4762 "[", "--logpath=/path/to/mongocryptd.log", "--logappend", "]");
4763 mongoc_auto_encryption_opts_set_extra (opts, extra);
4764
4765 If your application wishes to manage the mongocryptd process manually,
4766 it is possible to disable spawning mongocryptd:
4767
4768 bson_t *extra = BCON_NEW ("mongocryptdBypassSpawn",
4769 BCON_BOOL(true), "mongocryptdURI", "mongodb://localhost:27020");
4770 mongoc_auto_encryption_opts_set_extra (opts, extra);
4771
4772 mongocryptd is only responsible for supporting automatic Client-Side
4773 Encryption in the driver and does not itself perform any encryption or
4774 decryption.
4775
4776 Automatic Client-Side Field Level Encryption
4777 Automatic Client-Side Encryption is enabled by calling mon‐
4778 goc_client_enable_auto_encryption() on a mongoc_client_t. The following
4779 examples show how to set up automatic client-side field level encryp‐
4780 tion using mongoc_client_encryption_t to create a new encryption data
4781 key.
4782
4783 NOTE:
4784 Automatic client-side field level encryption requires MongoDB 4.2
4785 enterprise or a MongoDB 4.2 Atlas cluster. The community version of
4786 the server supports automatic decryption as well as Explicit Encryp‐
4787 tion.
4788
4789 Providing Local Automatic Encryption Rules
4790 The following example shows how to specify automatic encryption rules
4791 using a schema map set with mongoc_auto_encryp‐
4792 tion_opts_set_schema_map(). The automatic encryption rules are ex‐
4793 pressed using a strict subset of the JSON Schema syntax.
4794
4795 Supplying a schema map provides more security than relying on JSON
4796 Schemas obtained from the server. It protects against a malicious
4797 server advertising a false JSON Schema, which could trick the client
4798 into sending unencrypted data that should be encrypted.
4799
4800 JSON Schemas supplied in the schema map only apply to configuring auto‐
4801 matic client-side field level encryption. Other validation rules in the
4802 JSON schema will not be enforced by the driver and will result in an
4803 error:
4804
4805 client-side-encryption-schema-map.c
4806
4807 #include <mongoc/mongoc.h>
4808 #include <stdio.h>
4809 #include <stdlib.h>
4810
4811 #include "client-side-encryption-helpers.h"
4812
4813 /* Helper method to create a new data key in the key vault, a schema to use that
4814 * key, and writes the schema to a file for later use. */
4815 static bool
4816 create_schema_file (bson_t *kms_providers,
4817 const char *keyvault_db,
4818 const char *keyvault_coll,
4819 mongoc_client_t *keyvault_client,
4820 bson_error_t *error)
4821 {
4822 mongoc_client_encryption_t *client_encryption = NULL;
4823 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
4824 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
4825 bson_value_t datakey_id = {0};
4826 char *keyaltnames[] = {"mongoc_encryption_example_1"};
4827 bson_t *schema = NULL;
4828 char *schema_string = NULL;
4829 size_t schema_string_len;
4830 FILE *outfile = NULL;
4831 bool ret = false;
4832
4833 client_encryption_opts = mongoc_client_encryption_opts_new ();
4834 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
4835 kms_providers);
4836 mongoc_client_encryption_opts_set_keyvault_namespace (
4837 client_encryption_opts, keyvault_db, keyvault_coll);
4838 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
4839 keyvault_client);
4840
4841 client_encryption =
4842 mongoc_client_encryption_new (client_encryption_opts, error);
4843 if (!client_encryption) {
4844 goto fail;
4845 }
4846
4847 /* Create a new data key and json schema for the encryptedField.
4848 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
4849 */
4850 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
4851 mongoc_client_encryption_datakey_opts_set_keyaltnames (
4852 datakey_opts, keyaltnames, 1);
4853 if (!mongoc_client_encryption_create_datakey (
4854 client_encryption, "local", datakey_opts, &datakey_id, error)) {
4855 goto fail;
4856 }
4857
4858 /* Create a schema describing that "encryptedField" is a string encrypted
4859 * with the newly created data key using deterministic encryption. */
4860 schema = BCON_NEW ("properties",
4861 "{",
4862 "encryptedField",
4863 "{",
4864 "encrypt",
4865 "{",
4866 "keyId",
4867 "[",
4868 BCON_BIN (datakey_id.value.v_binary.subtype,
4869 datakey_id.value.v_binary.data,
4870 datakey_id.value.v_binary.data_len),
4871 "]",
4872 "bsonType",
4873 "string",
4874 "algorithm",
4875 MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
4876 "}",
4877 "}",
4878 "}",
4879 "bsonType",
4880 "object");
4881
4882 /* Use canonical JSON so that other drivers and tools will be
4883 * able to parse the MongoDB extended JSON file. */
4884 schema_string = bson_as_canonical_extended_json (schema, &schema_string_len);
4885 outfile = fopen ("jsonSchema.json", "w");
4886 if (0 == fwrite (schema_string, sizeof (char), schema_string_len, outfile)) {
4887 fprintf (stderr, "failed to write to file\n");
4888 goto fail;
4889 }
4890
4891 ret = true;
4892 fail:
4893 mongoc_client_encryption_destroy (client_encryption);
4894 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
4895 mongoc_client_encryption_opts_destroy (client_encryption_opts);
4896 bson_free (schema_string);
4897 bson_destroy (schema);
4898 bson_value_destroy (&datakey_id);
4899 if (outfile) {
4900 fclose (outfile);
4901 }
4902 return true;
4903 }
4904
4905 /* This example demonstrates how to use automatic encryption with a client-side
4906 * schema map using the enterprise version of MongoDB */
4907 int
4908 main (int argc, char **argv)
4909 {
4910 /* The collection used to store the encryption data keys. */
4911 #define KEYVAULT_DB "encryption"
4912 #define KEYVAULT_COLL "__libmongocTestKeyVault"
4913 /* The collection used to store the encrypted documents in this example. */
4914 #define ENCRYPTED_DB "test"
4915 #define ENCRYPTED_COLL "coll"
4916
4917 int exit_status = EXIT_FAILURE;
4918 bool ret;
4919 uint8_t *local_masterkey = NULL;
4920 uint32_t local_masterkey_len;
4921 bson_t *kms_providers = NULL;
4922 bson_error_t error = {0};
4923 bson_t *index_keys = NULL;
4924 char *index_name = NULL;
4925 bson_t *create_index_cmd = NULL;
4926 bson_json_reader_t *reader = NULL;
4927 bson_t schema = BSON_INITIALIZER;
4928 bson_t *schema_map = NULL;
4929
4930 /* The MongoClient used to access the key vault (keyvault_namespace). */
4931 mongoc_client_t *keyvault_client = NULL;
4932 mongoc_collection_t *keyvault_coll = NULL;
4933 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
4934 mongoc_client_t *client = NULL;
4935 mongoc_collection_t *coll = NULL;
4936 bson_t *to_insert = NULL;
4937 mongoc_client_t *unencrypted_client = NULL;
4938 mongoc_collection_t *unencrypted_coll = NULL;
4939
4940 mongoc_init ();
4941
4942 /* Configure the master key. This must be the same master key that was used
4943 * to create the encryption key. */
4944 local_masterkey =
4945 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
4946 if (!local_masterkey || local_masterkey_len != 96) {
4947 fprintf (stderr,
4948 "Specify LOCAL_MASTERKEY environment variable as a "
4949 "secure random 96 byte hex value.\n");
4950 goto fail;
4951 }
4952
4953 kms_providers = BCON_NEW ("local",
4954 "{",
4955 "key",
4956 BCON_BIN (0, local_masterkey, local_masterkey_len),
4957 "}");
4958
4959 /* Set up the key vault for this example. */
4960 keyvault_client = mongoc_client_new (
4961 "mongodb://localhost/?appname=client-side-encryption-keyvault");
4962 keyvault_coll = mongoc_client_get_collection (
4963 keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
4964 mongoc_collection_drop (keyvault_coll, NULL);
4965
4966 /* Create a unique index to ensure that two data keys cannot share the same
4967 * keyAltName. This is recommended practice for the key vault. */
4968 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
4969 index_name = mongoc_collection_keys_to_index_string (index_keys);
4970 create_index_cmd = BCON_NEW ("createIndexes",
4971 KEYVAULT_COLL,
4972 "indexes",
4973 "[",
4974 "{",
4975 "key",
4976 BCON_DOCUMENT (index_keys),
4977 "name",
4978 index_name,
4979 "unique",
4980 BCON_BOOL (true),
4981 "partialFilterExpression",
4982 "{",
4983 "keyAltNames",
4984 "{",
4985 "$exists",
4986 BCON_BOOL (true),
4987 "}",
4988 "}",
4989 "}",
4990 "]");
4991 ret = mongoc_client_command_simple (keyvault_client,
4992 KEYVAULT_DB,
4993 create_index_cmd,
4994 NULL /* read prefs */,
4995 NULL /* reply */,
4996 &error);
4997
4998 if (!ret) {
4999 goto fail;
5000 }
5001
5002 /* Create a new data key and a schema using it for encryption. Save the
5003 * schema to the file jsonSchema.json */
5004 ret = create_schema_file (
5005 kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
5006
5007 if (!ret) {
5008 goto fail;
5009 }
5010
5011 /* Load the JSON Schema and construct the local schema_map option. */
5012 reader = bson_json_reader_new_from_file ("jsonSchema.json", &error);
5013 if (!reader) {
5014 goto fail;
5015 }
5016
5017 bson_json_reader_read (reader, &schema, &error);
5018
5019 /* Construct the schema map, mapping the namespace of the collection to the
5020 * schema describing encryption. */
5021 schema_map =
5022 BCON_NEW (ENCRYPTED_DB "." ENCRYPTED_COLL, BCON_DOCUMENT (&schema));
5023
5024 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
5025 mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts,
5026 keyvault_client);
5027 mongoc_auto_encryption_opts_set_keyvault_namespace (
5028 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5029 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
5030 kms_providers);
5031 mongoc_auto_encryption_opts_set_schema_map (auto_encryption_opts,
5032 schema_map);
5033
5034 client =
5035 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5036
5037 /* Enable automatic encryption. It will determine that encryption is
5038 * necessary from the schema map instead of relying on the server to provide
5039 * a schema. */
5040 ret = mongoc_client_enable_auto_encryption (
5041 client, auto_encryption_opts, &error);
5042 if (!ret) {
5043 goto fail;
5044 }
5045
5046 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5047
5048 /* Clear old data */
5049 mongoc_collection_drop (coll, NULL);
5050
5051 to_insert = BCON_NEW ("encryptedField", "123456789");
5052 ret = mongoc_collection_insert_one (
5053 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5054 if (!ret) {
5055 goto fail;
5056 }
5057 printf ("decrypted document: ");
5058 if (!print_one_document (coll, &error)) {
5059 goto fail;
5060 }
5061 printf ("\n");
5062
5063 unencrypted_client = mongoc_client_new (
5064 "mongodb://localhost/?appname=client-side-encryption-unencrypted");
5065 unencrypted_coll = mongoc_client_get_collection (
5066 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
5067 printf ("encrypted document: ");
5068 if (!print_one_document (unencrypted_coll, &error)) {
5069 goto fail;
5070 }
5071 printf ("\n");
5072
5073 exit_status = EXIT_SUCCESS;
5074 fail:
5075 if (error.code) {
5076 fprintf (stderr, "error: %s\n", error.message);
5077 }
5078
5079 bson_free (local_masterkey);
5080 bson_destroy (kms_providers);
5081 mongoc_collection_destroy (keyvault_coll);
5082 bson_destroy (index_keys);
5083 bson_free (index_name);
5084 bson_destroy (create_index_cmd);
5085 bson_json_reader_destroy (reader);
5086 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
5087 mongoc_collection_destroy (coll);
5088 mongoc_client_destroy (client);
5089 bson_destroy (to_insert);
5090 mongoc_collection_destroy (unencrypted_coll);
5091 mongoc_client_destroy (unencrypted_client);
5092 mongoc_client_destroy (keyvault_client);
5093 bson_destroy (&schema);
5094 bson_destroy (schema_map);
5095 mongoc_cleanup ();
5096 return exit_status;
5097 }
5098
5099 Server-Side Field Level Encryption Enforcement
5100 The MongoDB 4.2 server supports using schema validation to enforce en‐
5101 cryption of specific fields in a collection. This schema validation
5102 will prevent an application from inserting unencrypted values for any
5103 fields marked with the "encrypt" JSON schema keyword.
5104
5105 The following example shows how to set up automatic client-side field
5106 level encryption using mongoc_client_encryption_t to create a new en‐
5107 cryption data key and create a collection with the Automatic Encryption
5108 JSON Schema Syntax:
5109
5110 client-side-encryption-server-schema.c
5111
5112 #include <mongoc/mongoc.h>
5113 #include <stdio.h>
5114 #include <stdlib.h>
5115
5116 #include "client-side-encryption-helpers.h"
5117
5118 /* Helper method to create and return a JSON schema to use for encryption.
5119 The caller will use the returned schema for server-side encryption validation.
5120 */
5121 static bson_t *
5122 create_schema (bson_t *kms_providers,
5123 const char *keyvault_db,
5124 const char *keyvault_coll,
5125 mongoc_client_t *keyvault_client,
5126 bson_error_t *error)
5127 {
5128 mongoc_client_encryption_t *client_encryption = NULL;
5129 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5130 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5131 bson_value_t datakey_id = {0};
5132 char *keyaltnames[] = {"mongoc_encryption_example_2"};
5133 bson_t *schema = NULL;
5134
5135 client_encryption_opts = mongoc_client_encryption_opts_new ();
5136 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5137 kms_providers);
5138 mongoc_client_encryption_opts_set_keyvault_namespace (
5139 client_encryption_opts, keyvault_db, keyvault_coll);
5140 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5141 keyvault_client);
5142
5143 client_encryption =
5144 mongoc_client_encryption_new (client_encryption_opts, error);
5145 if (!client_encryption) {
5146 goto fail;
5147 }
5148
5149 /* Create a new data key and json schema for the encryptedField.
5150 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5151 */
5152 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5153 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5154 datakey_opts, keyaltnames, 1);
5155 if (!mongoc_client_encryption_create_datakey (
5156 client_encryption, "local", datakey_opts, &datakey_id, error)) {
5157 goto fail;
5158 }
5159
5160 /* Create a schema describing that "encryptedField" is a string encrypted
5161 * with the newly created data key using deterministic encryption. */
5162 schema = BCON_NEW ("properties",
5163 "{",
5164 "encryptedField",
5165 "{",
5166 "encrypt",
5167 "{",
5168 "keyId",
5169 "[",
5170 BCON_BIN (datakey_id.value.v_binary.subtype,
5171 datakey_id.value.v_binary.data,
5172 datakey_id.value.v_binary.data_len),
5173 "]",
5174 "bsonType",
5175 "string",
5176 "algorithm",
5177 MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
5178 "}",
5179 "}",
5180 "}",
5181 "bsonType",
5182 "object");
5183
5184 fail:
5185 mongoc_client_encryption_destroy (client_encryption);
5186 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5187 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5188 bson_value_destroy (&datakey_id);
5189 return schema;
5190 }
5191
5192 /* This example demonstrates how to use automatic encryption with a server-side
5193 * schema using the enterprise version of MongoDB */
5194 int
5195 main (int argc, char **argv)
5196 {
5197 /* The collection used to store the encryption data keys. */
5198 #define KEYVAULT_DB "encryption"
5199 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5200 /* The collection used to store the encrypted documents in this example. */
5201 #define ENCRYPTED_DB "test"
5202 #define ENCRYPTED_COLL "coll"
5203
5204 int exit_status = EXIT_FAILURE;
5205 bool ret;
5206 uint8_t *local_masterkey = NULL;
5207 uint32_t local_masterkey_len;
5208 bson_t *kms_providers = NULL;
5209 bson_error_t error = {0};
5210 bson_t *index_keys = NULL;
5211 char *index_name = NULL;
5212 bson_t *create_index_cmd = NULL;
5213 bson_json_reader_t *reader = NULL;
5214 bson_t *schema = NULL;
5215
5216 /* The MongoClient used to access the key vault (keyvault_namespace). */
5217 mongoc_client_t *keyvault_client = NULL;
5218 mongoc_collection_t *keyvault_coll = NULL;
5219 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
5220 mongoc_client_t *client = NULL;
5221 mongoc_collection_t *coll = NULL;
5222 bson_t *to_insert = NULL;
5223 mongoc_client_t *unencrypted_client = NULL;
5224 mongoc_collection_t *unencrypted_coll = NULL;
5225 bson_t *create_cmd = NULL;
5226 bson_t *create_cmd_opts = NULL;
5227 mongoc_write_concern_t *wc = NULL;
5228
5229 mongoc_init ();
5230
5231 /* Configure the master key. This must be the same master key that was used
5232 * to create
5233 * the encryption key. */
5234 local_masterkey =
5235 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5236 if (!local_masterkey || local_masterkey_len != 96) {
5237 fprintf (stderr,
5238 "Specify LOCAL_MASTERKEY environment variable as a "
5239 "secure random 96 byte hex value.\n");
5240 goto fail;
5241 }
5242
5243 kms_providers = BCON_NEW ("local",
5244 "{",
5245 "key",
5246 BCON_BIN (0, local_masterkey, local_masterkey_len),
5247 "}");
5248
5249 /* Set up the key vault for this example. */
5250 keyvault_client = mongoc_client_new (
5251 "mongodb://localhost/?appname=client-side-encryption-keyvault");
5252 keyvault_coll = mongoc_client_get_collection (
5253 keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
5254 mongoc_collection_drop (keyvault_coll, NULL);
5255
5256 /* Create a unique index to ensure that two data keys cannot share the same
5257 * keyAltName. This is recommended practice for the key vault. */
5258 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5259 index_name = mongoc_collection_keys_to_index_string (index_keys);
5260 create_index_cmd = BCON_NEW ("createIndexes",
5261 KEYVAULT_COLL,
5262 "indexes",
5263 "[",
5264 "{",
5265 "key",
5266 BCON_DOCUMENT (index_keys),
5267 "name",
5268 index_name,
5269 "unique",
5270 BCON_BOOL (true),
5271 "partialFilterExpression",
5272 "{",
5273 "keyAltNames",
5274 "{",
5275 "$exists",
5276 BCON_BOOL (true),
5277 "}",
5278 "}",
5279 "}",
5280 "]");
5281 ret = mongoc_client_command_simple (keyvault_client,
5282 KEYVAULT_DB,
5283 create_index_cmd,
5284 NULL /* read prefs */,
5285 NULL /* reply */,
5286 &error);
5287
5288 if (!ret) {
5289 goto fail;
5290 }
5291
5292 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
5293 mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts,
5294 keyvault_client);
5295 mongoc_auto_encryption_opts_set_keyvault_namespace (
5296 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5297 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
5298 kms_providers);
5299 schema = create_schema (
5300 kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
5301
5302 if (!schema) {
5303 goto fail;
5304 }
5305
5306 client =
5307 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5308 ret = mongoc_client_enable_auto_encryption (
5309 client, auto_encryption_opts, &error);
5310 if (!ret) {
5311 goto fail;
5312 }
5313
5314 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5315
5316 /* Clear old data */
5317 mongoc_collection_drop (coll, NULL);
5318
5319 /* Create the collection with the encryption JSON Schema. */
5320 create_cmd = BCON_NEW ("create",
5321 ENCRYPTED_COLL,
5322 "validator",
5323 "{",
5324 "$jsonSchema",
5325 BCON_DOCUMENT (schema),
5326 "}");
5327 wc = mongoc_write_concern_new ();
5328 mongoc_write_concern_set_wmajority (wc, 0);
5329 create_cmd_opts = bson_new ();
5330 mongoc_write_concern_append (wc, create_cmd_opts);
5331 ret = mongoc_client_command_with_opts (client,
5332 ENCRYPTED_DB,
5333 create_cmd,
5334 NULL /* read prefs */,
5335 create_cmd_opts,
5336 NULL /* reply */,
5337 &error);
5338 if (!ret) {
5339 goto fail;
5340 }
5341
5342 to_insert = BCON_NEW ("encryptedField", "123456789");
5343 ret = mongoc_collection_insert_one (
5344 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5345 if (!ret) {
5346 goto fail;
5347 }
5348 printf ("decrypted document: ");
5349 if (!print_one_document (coll, &error)) {
5350 goto fail;
5351 }
5352 printf ("\n");
5353
5354 unencrypted_client = mongoc_client_new (
5355 "mongodb://localhost/?appname=client-side-encryption-unencrypted");
5356 unencrypted_coll = mongoc_client_get_collection (
5357 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
5358 printf ("encrypted document: ");
5359 if (!print_one_document (unencrypted_coll, &error)) {
5360 goto fail;
5361 }
5362 printf ("\n");
5363
5364 /* Expect a server-side error if inserting with the unencrypted collection.
5365 */
5366 ret = mongoc_collection_insert_one (
5367 unencrypted_coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5368 if (!ret) {
5369 printf ("insert with unencrypted collection failed: %s\n", error.message);
5370 memset (&error, 0, sizeof (error));
5371 }
5372
5373 exit_status = EXIT_SUCCESS;
5374 fail:
5375 if (error.code) {
5376 fprintf (stderr, "error: %s\n", error.message);
5377 }
5378
5379 bson_free (local_masterkey);
5380 bson_destroy (kms_providers);
5381 mongoc_collection_destroy (keyvault_coll);
5382 bson_destroy (index_keys);
5383 bson_free (index_name);
5384 bson_destroy (create_index_cmd);
5385 bson_json_reader_destroy (reader);
5386 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
5387 mongoc_collection_destroy (coll);
5388 mongoc_client_destroy (client);
5389 bson_destroy (to_insert);
5390 mongoc_collection_destroy (unencrypted_coll);
5391 mongoc_client_destroy (unencrypted_client);
5392 mongoc_client_destroy (keyvault_client);
5393 bson_destroy (schema);
5394 bson_destroy (create_cmd);
5395 bson_destroy (create_cmd_opts);
5396 mongoc_write_concern_destroy (wc);
5397
5398 mongoc_cleanup ();
5399 return exit_status;
5400 }
5401
5402 Explicit Encryption
5403 Explicit encryption is a MongoDB community feature and does not use the
5404 mongocryptd process. Explicit encryption is provided by the mon‐
5405 goc_client_encryption_t class, for example:
5406
5407 client-side-encryption-explicit.c
5408
5409 #include <mongoc/mongoc.h>
5410 #include <stdio.h>
5411 #include <stdlib.h>
5412
5413 #include "client-side-encryption-helpers.h"
5414
5415 /* This example demonstrates how to use explicit encryption and decryption using
5416 * the community version of MongoDB */
5417 int
5418 main (int argc, char **argv)
5419 {
5420 /* The collection used to store the encryption data keys. */
5421 #define KEYVAULT_DB "encryption"
5422 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5423 /* The collection used to store the encrypted documents in this example. */
5424 #define ENCRYPTED_DB "test"
5425 #define ENCRYPTED_COLL "coll"
5426
5427 int exit_status = EXIT_FAILURE;
5428 bool ret;
5429 uint8_t *local_masterkey = NULL;
5430 uint32_t local_masterkey_len;
5431 bson_t *kms_providers = NULL;
5432 bson_error_t error = {0};
5433 bson_t *index_keys = NULL;
5434 char *index_name = NULL;
5435 bson_t *create_index_cmd = NULL;
5436 bson_t *schema = NULL;
5437 mongoc_client_t *client = NULL;
5438 mongoc_collection_t *coll = NULL;
5439 mongoc_collection_t *keyvault_coll = NULL;
5440 bson_t *to_insert = NULL;
5441 bson_t *create_cmd = NULL;
5442 bson_t *create_cmd_opts = NULL;
5443 mongoc_write_concern_t *wc = NULL;
5444 mongoc_client_encryption_t *client_encryption = NULL;
5445 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5446 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5447 char *keyaltnames[] = {"mongoc_encryption_example_3"};
5448 bson_value_t datakey_id = {0};
5449 bson_value_t encrypted_field = {0};
5450 bson_value_t to_encrypt = {0};
5451 mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
5452 bson_value_t decrypted = {0};
5453
5454 mongoc_init ();
5455
5456 /* Configure the master key. This must be the same master key that was used
5457 * to create the encryption key. */
5458 local_masterkey =
5459 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5460 if (!local_masterkey || local_masterkey_len != 96) {
5461 fprintf (stderr,
5462 "Specify LOCAL_MASTERKEY environment variable as a "
5463 "secure random 96 byte hex value.\n");
5464 goto fail;
5465 }
5466
5467 kms_providers = BCON_NEW ("local",
5468 "{",
5469 "key",
5470 BCON_BIN (0, local_masterkey, local_masterkey_len),
5471 "}");
5472
5473 /* The mongoc_client_t used to read/write application data. */
5474 client =
5475 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5476 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5477
5478 /* Clear old data */
5479 mongoc_collection_drop (coll, NULL);
5480
5481 /* Set up the key vault for this example. */
5482 keyvault_coll =
5483 mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
5484 mongoc_collection_drop (keyvault_coll, NULL);
5485
5486 /* Create a unique index to ensure that two data keys cannot share the same
5487 * keyAltName. This is recommended practice for the key vault. */
5488 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5489 index_name = mongoc_collection_keys_to_index_string (index_keys);
5490 create_index_cmd = BCON_NEW ("createIndexes",
5491 KEYVAULT_COLL,
5492 "indexes",
5493 "[",
5494 "{",
5495 "key",
5496 BCON_DOCUMENT (index_keys),
5497 "name",
5498 index_name,
5499 "unique",
5500 BCON_BOOL (true),
5501 "partialFilterExpression",
5502 "{",
5503 "keyAltNames",
5504 "{",
5505 "$exists",
5506 BCON_BOOL (true),
5507 "}",
5508 "}",
5509 "}",
5510 "]");
5511 ret = mongoc_client_command_simple (client,
5512 KEYVAULT_DB,
5513 create_index_cmd,
5514 NULL /* read prefs */,
5515 NULL /* reply */,
5516 &error);
5517
5518 if (!ret) {
5519 goto fail;
5520 }
5521
5522 client_encryption_opts = mongoc_client_encryption_opts_new ();
5523 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5524 kms_providers);
5525 mongoc_client_encryption_opts_set_keyvault_namespace (
5526 client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5527
5528 /* Set a mongoc_client_t to use for reading/writing to the key vault. This
5529 * can be the same mongoc_client_t used by the main application. */
5530 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5531 client);
5532 client_encryption =
5533 mongoc_client_encryption_new (client_encryption_opts, &error);
5534 if (!client_encryption) {
5535 goto fail;
5536 }
5537
5538 /* Create a new data key for the encryptedField.
5539 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5540 */
5541 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5542 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5543 datakey_opts, keyaltnames, 1);
5544 if (!mongoc_client_encryption_create_datakey (
5545 client_encryption, "local", datakey_opts, &datakey_id, &error)) {
5546 goto fail;
5547 }
5548
5549 /* Explicitly encrypt a field */
5550 encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
5551 mongoc_client_encryption_encrypt_opts_set_algorithm (
5552 encrypt_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
5553 mongoc_client_encryption_encrypt_opts_set_keyid (encrypt_opts, &datakey_id);
5554 to_encrypt.value_type = BSON_TYPE_UTF8;
5555 to_encrypt.value.v_utf8.str = "123456789";
5556 to_encrypt.value.v_utf8.len = strlen (to_encrypt.value.v_utf8.str);
5557
5558 ret = mongoc_client_encryption_encrypt (
5559 client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
5560 if (!ret) {
5561 goto fail;
5562 }
5563
5564 to_insert = bson_new ();
5565 BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
5566 ret = mongoc_collection_insert_one (
5567 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5568 if (!ret) {
5569 goto fail;
5570 }
5571
5572 printf ("encrypted document: ");
5573 if (!print_one_document (coll, &error)) {
5574 goto fail;
5575 }
5576 printf ("\n");
5577
5578 /* Explicitly decrypt a field */
5579 ret = mongoc_client_encryption_decrypt (
5580 client_encryption, &encrypted_field, &decrypted, &error);
5581 if (!ret) {
5582 goto fail;
5583 }
5584 printf ("decrypted value: %s\n", decrypted.value.v_utf8.str);
5585
5586 exit_status = EXIT_SUCCESS;
5587 fail:
5588 if (error.code) {
5589 fprintf (stderr, "error: %s\n", error.message);
5590 }
5591
5592 bson_free (local_masterkey);
5593 bson_destroy (kms_providers);
5594 mongoc_collection_destroy (keyvault_coll);
5595 bson_destroy (index_keys);
5596 bson_free (index_name);
5597 bson_destroy (create_index_cmd);
5598 mongoc_collection_destroy (coll);
5599 mongoc_client_destroy (client);
5600 bson_destroy (to_insert);
5601 bson_destroy (schema);
5602 bson_destroy (create_cmd);
5603 bson_destroy (create_cmd_opts);
5604 mongoc_write_concern_destroy (wc);
5605 mongoc_client_encryption_destroy (client_encryption);
5606 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5607 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5608 bson_value_destroy (&encrypted_field);
5609 mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
5610 bson_value_destroy (&decrypted);
5611 bson_value_destroy (&datakey_id);
5612
5613 mongoc_cleanup ();
5614 return exit_status;
5615 }
5616
5617 Explicit Encryption with Automatic Decryption
5618 Although automatic encryption requires MongoDB 4.2 enterprise or a Mon‐
5619 goDB 4.2 Atlas cluster, automatic decryption is supported for all
5620 users. To configure automatic decryption without automatic encryption
5621 set bypass_auto_encryption=True in mongoc_auto_encryption_opts_t:
5622
5623 client-side-encryption-auto-decryption.c
5624
5625 #include <mongoc/mongoc.h>
5626 #include <stdio.h>
5627 #include <stdlib.h>
5628
5629 #include "client-side-encryption-helpers.h"
5630
5631 /* This example demonstrates how to set up automatic decryption without
5632 * automatic encryption using the community version of MongoDB */
5633 int
5634 main (int argc, char **argv)
5635 {
5636 /* The collection used to store the encryption data keys. */
5637 #define KEYVAULT_DB "encryption"
5638 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5639 /* The collection used to store the encrypted documents in this example. */
5640 #define ENCRYPTED_DB "test"
5641 #define ENCRYPTED_COLL "coll"
5642
5643 int exit_status = EXIT_FAILURE;
5644 bool ret;
5645 uint8_t *local_masterkey = NULL;
5646 uint32_t local_masterkey_len;
5647 bson_t *kms_providers = NULL;
5648 bson_error_t error = {0};
5649 bson_t *index_keys = NULL;
5650 char *index_name = NULL;
5651 bson_t *create_index_cmd = NULL;
5652 bson_t *schema = NULL;
5653 mongoc_client_t *client = NULL;
5654 mongoc_collection_t *coll = NULL;
5655 mongoc_collection_t *keyvault_coll = NULL;
5656 bson_t *to_insert = NULL;
5657 bson_t *create_cmd = NULL;
5658 bson_t *create_cmd_opts = NULL;
5659 mongoc_write_concern_t *wc = NULL;
5660 mongoc_client_encryption_t *client_encryption = NULL;
5661 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5662 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5663 char *keyaltnames[] = {"mongoc_encryption_example_4"};
5664 bson_value_t datakey_id = {0};
5665 bson_value_t encrypted_field = {0};
5666 bson_value_t to_encrypt = {0};
5667 mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
5668 bson_value_t decrypted = {0};
5669 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
5670 mongoc_client_t *unencrypted_client = NULL;
5671 mongoc_collection_t *unencrypted_coll = NULL;
5672
5673 mongoc_init ();
5674
5675 /* Configure the master key. This must be the same master key that was used
5676 * to create the encryption key. */
5677 local_masterkey =
5678 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5679 if (!local_masterkey || local_masterkey_len != 96) {
5680 fprintf (stderr,
5681 "Specify LOCAL_MASTERKEY environment variable as a "
5682 "secure random 96 byte hex value.\n");
5683 goto fail;
5684 }
5685
5686 kms_providers = BCON_NEW ("local",
5687 "{",
5688 "key",
5689 BCON_BIN (0, local_masterkey, local_masterkey_len),
5690 "}");
5691
5692 client =
5693 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5694 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
5695 mongoc_auto_encryption_opts_set_keyvault_namespace (
5696 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5697 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
5698 kms_providers);
5699
5700 /* Setting bypass_auto_encryption to true disables automatic encryption but
5701 * keeps the automatic decryption behavior. bypass_auto_encryption will also
5702 * disable spawning mongocryptd */
5703 mongoc_auto_encryption_opts_set_bypass_auto_encryption (auto_encryption_opts,
5704 true);
5705
5706 /* Once bypass_auto_encryption is set, community users can enable auto
5707 * encryption on the client. This will, in fact, only perform automatic
5708 * decryption. */
5709 ret = mongoc_client_enable_auto_encryption (
5710 client, auto_encryption_opts, &error);
5711 if (!ret) {
5712 goto fail;
5713 }
5714
5715 /* Now that automatic decryption is on, we can test it by inserting a
5716 * document with an explicitly encrypted value into the collection. When we
5717 * look up the document later, it should be automatically decrypted for us.
5718 */
5719 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5720
5721 /* Clear old data */
5722 mongoc_collection_drop (coll, NULL);
5723
5724 /* Set up the key vault for this example. */
5725 keyvault_coll =
5726 mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
5727 mongoc_collection_drop (keyvault_coll, NULL);
5728
5729 /* Create a unique index to ensure that two data keys cannot share the same
5730 * keyAltName. This is recommended practice for the key vault. */
5731 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5732 index_name = mongoc_collection_keys_to_index_string (index_keys);
5733 create_index_cmd = BCON_NEW ("createIndexes",
5734 KEYVAULT_COLL,
5735 "indexes",
5736 "[",
5737 "{",
5738 "key",
5739 BCON_DOCUMENT (index_keys),
5740 "name",
5741 index_name,
5742 "unique",
5743 BCON_BOOL (true),
5744 "partialFilterExpression",
5745 "{",
5746 "keyAltNames",
5747 "{",
5748 "$exists",
5749 BCON_BOOL (true),
5750 "}",
5751 "}",
5752 "}",
5753 "]");
5754 ret = mongoc_client_command_simple (client,
5755 KEYVAULT_DB,
5756 create_index_cmd,
5757 NULL /* read prefs */,
5758 NULL /* reply */,
5759 &error);
5760
5761 if (!ret) {
5762 goto fail;
5763 }
5764
5765 client_encryption_opts = mongoc_client_encryption_opts_new ();
5766 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5767 kms_providers);
5768 mongoc_client_encryption_opts_set_keyvault_namespace (
5769 client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5770
5771 /* The key vault client is used for reading to/from the key vault. This can
5772 * be the same mongoc_client_t used by the application. */
5773 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5774 client);
5775 client_encryption =
5776 mongoc_client_encryption_new (client_encryption_opts, &error);
5777 if (!client_encryption) {
5778 goto fail;
5779 }
5780
5781 /* Create a new data key for the encryptedField.
5782 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5783 */
5784 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5785 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5786 datakey_opts, keyaltnames, 1);
5787 ret = mongoc_client_encryption_create_datakey (
5788 client_encryption, "local", datakey_opts, &datakey_id, &error);
5789 if (!ret) {
5790 goto fail;
5791 }
5792
5793 /* Explicitly encrypt a field. */
5794 encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
5795 mongoc_client_encryption_encrypt_opts_set_algorithm (
5796 encrypt_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
5797 mongoc_client_encryption_encrypt_opts_set_keyaltname (
5798 encrypt_opts, "mongoc_encryption_example_4");
5799 to_encrypt.value_type = BSON_TYPE_UTF8;
5800 to_encrypt.value.v_utf8.str = "123456789";
5801 to_encrypt.value.v_utf8.len = strlen (to_encrypt.value.v_utf8.str);
5802
5803 ret = mongoc_client_encryption_encrypt (
5804 client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
5805 if (!ret) {
5806 goto fail;
5807 }
5808
5809 to_insert = bson_new ();
5810 BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
5811 ret = mongoc_collection_insert_one (
5812 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5813 if (!ret) {
5814 goto fail;
5815 }
5816
5817 /* When we retrieve the document, any encrypted fields will get automatically
5818 * decrypted by the driver. */
5819 printf ("decrypted document: ");
5820 if (!print_one_document (coll, &error)) {
5821 goto fail;
5822 }
5823 printf ("\n");
5824
5825 unencrypted_client =
5826 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5827 unencrypted_coll = mongoc_client_get_collection (
5828 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
5829
5830 printf ("encrypted document: ");
5831 if (!print_one_document (unencrypted_coll, &error)) {
5832 goto fail;
5833 }
5834 printf ("\n");
5835
5836 exit_status = EXIT_SUCCESS;
5837 fail:
5838 if (error.code) {
5839 fprintf (stderr, "error: %s\n", error.message);
5840 }
5841
5842 bson_free (local_masterkey);
5843 bson_destroy (kms_providers);
5844 mongoc_collection_destroy (keyvault_coll);
5845 bson_destroy (index_keys);
5846 bson_free (index_name);
5847 bson_destroy (create_index_cmd);
5848 mongoc_collection_destroy (coll);
5849 mongoc_client_destroy (client);
5850 bson_destroy (to_insert);
5851 bson_destroy (schema);
5852 bson_destroy (create_cmd);
5853 bson_destroy (create_cmd_opts);
5854 mongoc_write_concern_destroy (wc);
5855 mongoc_client_encryption_destroy (client_encryption);
5856 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5857 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5858 bson_value_destroy (&encrypted_field);
5859 mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
5860 bson_value_destroy (&decrypted);
5861 bson_value_destroy (&datakey_id);
5862 mongoc_collection_destroy (unencrypted_coll);
5863 mongoc_client_destroy (unencrypted_client);
5864 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
5865
5866 mongoc_cleanup ();
5867 return exit_status;
5868 }
5869
5870 API Reference
5871 Initialization and cleanup
5872 Synopsis
5873 Initialize the MongoDB C Driver by calling mongoc_init exactly once at
5874 the beginning of your program. It is responsible for initializing
5875 global state such as process counters, SSL, and threading primitives.
5876
5877 Exception to this is mongoc_log_set_handler(), which should be called
5878 before mongoc_init() or some log traces would not use your log handling
5879 function. See Custom Log Handlers for a detailed example.
5880
5881 Call mongoc_cleanup exactly once at the end of your program to release
5882 all memory and other resources allocated by the driver. You must not
5883 call any other MongoDB C Driver functions after mongoc_cleanup. Note
5884 that mongoc_init does not reinitialize the driver after mongoc_cleanup.
5885
5886 Deprecated feature: automatic initialization and cleanup
5887 On some platforms the driver can automatically call mongoc_init before
5888 main, and call mongoc_cleanup as the process exits. This is problematic
5889 in situations where related libraries also execute cleanup code on
5890 shutdown, and it creates inconsistent rules across platforms. Therefore
5891 the automatic initialization and cleanup feature is deprecated, and
5892 will be dropped in version 2.0. Meanwhile, for backward compatibility,
5893 the feature is enabled by default on platforms where it is available.
5894
5895 For portable, future-proof code, always call mongoc_init and mon‐
5896 goc_cleanup yourself, and configure the driver like:
5897
5898 cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF
5899
5900 Logging
5901 MongoDB C driver Logging Abstraction
5902
5903 Synopsis
5904 typedef enum {
5905 MONGOC_LOG_LEVEL_ERROR,
5906 MONGOC_LOG_LEVEL_CRITICAL,
5907 MONGOC_LOG_LEVEL_WARNING,
5908 MONGOC_LOG_LEVEL_MESSAGE,
5909 MONGOC_LOG_LEVEL_INFO,
5910 MONGOC_LOG_LEVEL_DEBUG,
5911 MONGOC_LOG_LEVEL_TRACE,
5912 } mongoc_log_level_t;
5913
5914 #define MONGOC_ERROR(...)
5915 #define MONGOC_CRITICAL(...)
5916 #define MONGOC_WARNING(...)
5917 #define MONGOC_MESSAGE(...)
5918 #define MONGOC_INFO(...)
5919 #define MONGOC_DEBUG(...)
5920
5921 typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level,
5922 const char *log_domain,
5923 const char *message,
5924 void *user_data);
5925
5926 void
5927 mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data);
5928 void
5929 mongoc_log (mongoc_log_level_t log_level,
5930 const char *log_domain,
5931 const char *format,
5932 ...) BSON_GNUC_PRINTF (3, 4);
5933 const char *
5934 mongoc_log_level_str (mongoc_log_level_t log_level);
5935 void
5936 mongoc_log_default_handler (mongoc_log_level_t log_level,
5937 const char *log_domain,
5938 const char *message,
5939 void *user_data);
5940 void
5941 mongoc_log_trace_enable (void);
5942 void
5943 mongoc_log_trace_disable (void);
5944
5945 The MongoDB C driver comes with an abstraction for logging that you can
5946 use in your application, or integrate with an existing logging system.
5947
5948 Macros
5949 To make logging a little less painful, various helper macros are pro‐
5950 vided. See the following example.
5951
5952 #undef MONGOC_LOG_DOMAIN
5953 #define MONGOC_LOG_DOMAIN "my-custom-domain"
5954
5955 MONGOC_WARNING ("An error occurred: %s", strerror (errno));
5956
5957 Custom Log Handlers
5958 The default log handler prints a timestamp and the log message to std‐
5959 out, or to stderr for warnings, critical messages, and errors.
5960 You can override the handler with mongoc_log_set_handler().
5961 Your handler function is called in a mutex for thread safety.
5962
5963 For example, you could register a custom handler to suppress messages
5964 at INFO level and below:
5965
5966 void
5967 my_logger (mongoc_log_level_t log_level,
5968 const char *log_domain,
5969 const char *message,
5970 void *user_data)
5971 {
5972 /* smaller values are more important */
5973 if (log_level < MONGOC_LOG_LEVEL_INFO) {
5974 mongoc_log_default_handler (log_level, log_domain, message, user_data);
5975 }
5976 }
5977
5978 int
5979 main (int argc, char *argv[])
5980 {
5981 mongoc_log_set_handler (my_logger, NULL);
5982 mongoc_init ();
5983
5984 /* ... your code ... */
5985
5986 mongoc_cleanup ();
5987 return 0;
5988 }
5989
5990 Note that in the example above mongoc_log_set_handler() is called be‐
5991 fore mongoc_init(). Otherwise, some log traces could not be processed
5992 by the log handler.
5993
5994 To restore the default handler:
5995
5996 mongoc_log_set_handler (mongoc_log_default_handler, NULL);
5997
5998 Disable logging
5999 To disable all logging, including warnings, critical messages and er‐
6000 rors, provide an empty log handler:
6001
6002 mongoc_log_set_handler (NULL, NULL);
6003
6004 Tracing
6005 If compiling your own copy of the MongoDB C driver, consider configur‐
6006 ing with -DENABLE_TRACING=ON to enable function tracing and hex dumps
6007 of network packets to STDERR and STDOUT during development and debug‐
6008 ging.
6009
6010 This is especially useful when debugging what may be going on inter‐
6011 nally in the driver.
6012
6013 Trace messages can be enabled and disabled by calling mon‐
6014 goc_log_trace_enable() and mongoc_log_trace_disable()
6015
6016 NOTE:
6017 Compiling the driver with -DENABLE_TRACING=ON will affect its per‐
6018 formance. Disabling tracing with mongoc_log_trace_disable() signifi‐
6019 cantly reduces the overhead, but cannot remove it completely.
6020 « index
6021
6022 Error Reporting
6023 Description
6024 Many C Driver functions report errors by returning false or -1 and
6025 filling out a bson_error_t structure with an error domain, error code,
6026 and message. Use domain to determine which subsystem generated the er‐
6027 ror, and code for the specific error. message is a human-readable error
6028 description.
6029
6030 SEE ALSO:
6031 Handling Errors in libbson.
6032
6033
6034 ┌────────────────────┬──────────────────────────────────┬────────────────────────┐
6035 │Domain │ Code │ Description │
6036 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6037 │MONGOC_ERROR_CLIENT │ MONGOC_ER‐ │ You tried to send a │
6038 │ │ ROR_CLIENT_TOO_BIG │ message larger than │
6039 │ │ │ the server's max │
6040 │ │ │ message size. │
6041 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6042 │ │ MONGOC_ER‐ │ Wrong credentials, │
6043 │ │ ROR_CLIENT_AUTHEN‐ │ or failure sending │
6044 │ │ TICATE │ or receiving au‐ │
6045 │ │ │ thentication mes‐ │
6046 │ │ │ sages. │
6047 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6048 │ │ MONGOC_ER‐ │ You tried an TLS │
6049 │ │ ROR_CLIENT_NO_AC‐ │ connection but the │
6050 │ │ CEPTABLE_PEER │ driver was not │
6051 │ │ │ built with TLS. │
6052 └────────────────────┴──────────────────────────────────┴────────────────────────┘
6053
6054
6055
6056
6057 │ │ MONGOC_ER‐ │ You began iterating │
6058 │ │ ROR_CLIENT_IN_EX‐ │ an exhaust cursor, │
6059 │ │ HAUST │ then tried to begin │
6060 │ │ │ another operation │
6061 │ │ │ with the same mon‐ │
6062 │ │ │ goc_client_t. │
6063 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6064 │ │ MONGOC_ER‐ │ Failure related to │
6065 │ │ ROR_CLIENT_SES‐ │ creating or using a │
6066 │ │ SION_FAILURE │ logical session. │
6067 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6068 │ │ MONGOC_ER‐ │ Failure related to │
6069 │ │ ROR_CLIENT_IN‐ │ arguments passed │
6070 │ │ VALID_ENCRYP‐ │ when initializing │
6071 │ │ TION_ARG │ Client-Side Field │
6072 │ │ │ Level Encryption. │
6073 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6074 │ │ MONGOC_ER‐ │ Failure related to │
6075 │ │ ROR_CLIENT_IN‐ │ Client-Side Field │
6076 │ │ VALID_ENCRYP‐ │ Level Encryption. │
6077 │ │ TION_STATE │ │
6078 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6079 │ │ MONGOC_ER‐ │ You attempted to │
6080 │ │ ROR_CLIENT_IN‐ │ connect to a Mon‐ │
6081 │ │ VALID_LOAD_BALANCER │ goDB server behind │
6082 │ │ │ a load balancer, │
6083 │ │ │ but the server does │
6084 │ │ │ not advertize load │
6085 │ │ │ balanced support. │
6086 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6087 │MONGOC_ERROR_STREAM │ MONGOC_ER‐ │ DNS failure. │
6088 │ │ ROR_STREAM_NAME_RES‐ │ │
6089 │ │ OLUTION │ │
6090 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6091 │ │ MONGOC_ER‐ │ Timeout communicat‐ │
6092 │ │ ROR_STREAM_SOCKET │ ing with server, or │
6093 │ │ │ connection closed. │
6094 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6095 │ │ MONGOC_ER‐ │ Failed to connect │
6096 │ │ ROR_STREAM_CONNECT │ to server. │
6097 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6098 │MONGOC_ERROR_PROTO‐ │ MONGOC_ERROR_PROTO‐ │ Corrupt response │
6099 │COL │ COL_INVALID_REPLY │ from server. │
6100 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6101 │ │ MONGOC_ERROR_PROTO‐ │ The server version │
6102 │ │ COL_BAD_WIRE_VERSION │ is too old or too │
6103 │ │ │ new to communicate │
6104 │ │ │ with the driver. │
6105 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6106 │MONGOC_ERROR_CURSOR │ MONGOC_ERROR_CUR‐ │ You passed bad ar‐ │
6107 │ │ SOR_INVALID_CURSOR │ guments to mon‐ │
6108 │ │ │ goc_collec‐ │
6109 │ │ │ tion_find_with_opts, │
6110 │ │ │ or you called mon‐ │
6111 │ │ │ goc_cursor_next on │
6112 │ │ │ a completed or │
6113 │ │ │ failed cursor, or │
6114 │ │ │ the cursor timed │
6115 │ │ │ out on the server. │
6116 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6117 │ │ MONGOC_ER‐ │ A resume token was │
6118 │ │ ROR_CHANGE_STREAM_NO_RE‐ │ not returned in a │
6119 │ │ SUME_TOKEN │ document found with │
6120 │ │ │ mon‐ │
6121 │ │ │ goc_change_stream_next │
6122 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6123 │MONGOC_ERROR_QUERY │ MONGOC_ERROR_QUERY_FAIL‐ │ Error API Version 1: │
6124 │ │ URE │ Server error from com‐ │
6125 │ │ │ mand or query. The │
6126 │ │ │ server error message │
6127 │ │ │ is in message. │
6128 └────────────────────┴──────────────────────────────────┴────────────────────────┘
6129
6130
6131
6132
6133
6134 │MONGOC_ERROR_SERVER │ MONGOC_ERROR_QUERY_FAIL‐ │ Error API Version 2: │
6135 │ │ URE │ Server error from com‐ │
6136 │ │ │ mand or query. The │
6137 │ │ │ server error message │
6138 │ │ │ is in message. │
6139 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6140 │MONGOC_ERROR_SASL │ A SASL error code. │ man sasl_errors for a │
6141 │ │ │ list of codes. │
6142 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6143 │MONGOC_ERROR_BSON │ MONGOC_ERROR_BSON_IN‐ │ You passed an invalid │
6144 │ │ VALID │ or oversized BSON doc‐ │
6145 │ │ │ ument as a parameter, │
6146 │ │ │ or called mongoc_col‐ │
6147 │ │ │ lection_create_index │
6148 │ │ │ with invalid keys, or │
6149 │ │ │ the server reply was │
6150 │ │ │ corrupt. │
6151 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6152 │MONGOC_ERROR_NAME‐ │ MONGOC_ERROR_NAME‐ │ You tried to create a │
6153 │SPACE │ SPACE_INVALID │ collection with an in‐ │
6154 │ │ │ valid name. │
6155 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6156 │MONGOC_ERROR_COM‐ │ MONGOC_ERROR_COMMAND_IN‐ │ Many functions set │
6157 │MAND │ VALID_ARG │ this error code when │
6158 │ │ │ passed bad parameters. │
6159 │ │ │ Print the error mes‐ │
6160 │ │ │ sage for details. │
6161 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6162 │ │ MONGOC_ERROR_PROTO‐ │ You tried to use a │
6163 │ │ COL_BAD_WIRE_VERSION │ command option the │
6164 │ │ │ server does not sup‐ │
6165 │ │ │ port. │
6166 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6167 │ │ MONGOC_ERROR_DUPLI‐ │ An insert or update │
6168 │ │ CATE_KEY │ failed because because │
6169 │ │ │ of a duplicate _id or │
6170 │ │ │ other unique-index vi‐ │
6171 │ │ │ olation. │
6172 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6173 │ │ MONGOC_ER‐ │ The operation failed │
6174 │ │ ROR_MAX_TIME_MS_EXPIRED │ because maxTimeMS ex‐ │
6175 │ │ │ pired. │
6176 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6177 │ │ MONGOC_ERROR_SERVER_SE‐ │ The serverId option │
6178 │ │ LECTION_INVALID_ID │ for an operation con‐ │
6179 │ │ │ flicts with the pinned │
6180 │ │ │ server for that opera‐ │
6181 │ │ │ tion's client session │
6182 │ │ │ (denoted by the ses‐ │
6183 │ │ │ sionId option). │
6184 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6185 │MONGOC_ERROR_COM‐ │ Error code from server. │ Error API Version 1: │
6186 │MAND │ │ Server error from a │
6187 │ │ │ command. The server │
6188 │ │ │ error message is in │
6189 │ │ │ message. │
6190 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6191 │MONGOC_ERROR_SERVER │ Error code from server. │ Error API Version 2: │
6192 │ │ │ Server error from a │
6193 │ │ │ command. The server │
6194 │ │ │ error message is in │
6195 │ │ │ message. │
6196 └────────────────────┴──────────────────────────────────┴────────────────────────┘
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211 │MONGOC_ERROR_COL‐ │ MONGOC_ERROR_COLLEC‐ │ Invalid or empty input │
6212 │LECTION │ TION_INSERT_FAILED, MON‐ │ to mongoc_collec‐ │
6213 │ │ GOC_ERROR_COLLECTION_UP‐ │ tion_insert_one, mon‐ │
6214 │ │ DATE_FAILED, MONGOC_ER‐ │ goc_collection_in‐ │
6215 │ │ ROR_COLLEC‐ │ sert_bulk, mongoc_col‐ │
6216 │ │ TION_DELETE_FAILED. │ lection_update_one, │
6217 │ │ │ mongoc_collection_up‐ │
6218 │ │ │ date_many, mongoc_col‐ │
6219 │ │ │ lection_replace_one, │
6220 │ │ │ mongoc_collec‐ │
6221 │ │ │ tion_delete_one, or │
6222 │ │ │ mongoc_collec‐ │
6223 │ │ │ tion_delete_many. │
6224 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6225 │MONGOC_ERROR_COL‐ │ Error code from server. │ Error API Version 1: │
6226 │LECTION │ │ Server error from mon‐ │
6227 │ │ │ goc_collection_in‐ │
6228 │ │ │ sert_one, mongoc_col‐ │
6229 │ │ │ lection_insert_bulk, │
6230 │ │ │ mongoc_collection_up‐ │
6231 │ │ │ date_one, mongoc_col‐ │
6232 │ │ │ lection_update_many, │
6233 │ │ │ mongoc_collection_re‐ │
6234 │ │ │ place_one, │
6235 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6236 │MONGOC_ERROR_SERVER │ Error code from server. │ Error API Version 2: │
6237 │ │ │ Server error from mon‐ │
6238 │ │ │ goc_collection_in‐ │
6239 │ │ │ sert_one, mongoc_col‐ │
6240 │ │ │ lection_insert_bulk, │
6241 │ │ │ mongoc_collection_up‐ │
6242 │ │ │ date_one, mongoc_col‐ │
6243 │ │ │ lection_update_many, │
6244 │ │ │ mongoc_collection_re‐ │
6245 │ │ │ place_one, │
6246 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6247 │MONGOC_ERROR_GRIDFS │ MONGOC_ER‐ │ The GridFS file is │
6248 │ │ ROR_GRIDFS_CHUNK_MISSING │ missing a document in │
6249 │ │ │ its chunks collection. │
6250 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6251 │ │ MONGOC_ERROR_GRIDFS_COR‐ │ A data inconsistency │
6252 │ │ RUPT │ was detected in │
6253 │ │ │ GridFS. │
6254 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6255 │ │ MONGOC_ERROR_GRIDFS_IN‐ │ You passed a NULL │
6256 │ │ VALID_FILENAME │ filename to mon‐ │
6257 │ │ │ goc_gridfs_re‐ │
6258 │ │ │ move_by_filename. │
6259 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6260 │ │ MONGOC_ERROR_GRIDFS_PRO‐ │ You called mon‐ │
6261 │ │ TOCOL_ERROR │ goc_gridfs_file_set_id │
6262 │ │ │ after mon‐ │
6263 │ │ │ goc_gridfs_file_save, │
6264 │ │ │ or tried to write on a │
6265 │ │ │ closed GridFS stream. │
6266 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6267 │ │ MONGOC_ER‐ │ A GridFS file is miss‐ │
6268 │ │ ROR_GRIDFS_BUCKET_FILE_NOT_FOUND │ ing from files collec‐ │
6269 │ │ │ tion. │
6270 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6271 │ │ MONGOC_ER‐ │ An error occurred on a │
6272 │ │ ROR_GRIDFS_BUCKET_STREAM │ stream created from a │
6273 │ │ │ GridFS operation like │
6274 │ │ │ mon‐ │
6275 │ │ │ goc_gridfs_bucket_up‐ │
6276 │ │ │ load_from_stream. │
6277 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6278 │MONGOC_ERROR_SCRAM │ MONGOC_ERROR_SCRAM_PROTOCOL_ER‐ │ Failure in SCRAM-SHA-1 │
6279 │ │ ROR │ authentication. │
6280 └────────────────────┴──────────────────────────────────┴────────────────────────┘
6281
6282
6283
6284
6285
6286
6287
6288 │MONGOC_ER‐ │ MONGOC_ERROR_SERVER_SELEC‐ │ No replica set member │
6289 │ROR_SERVER_SELEC‐ │ TION_FAILURE │ or mongos is avail‐ │
6290 │TION │ │ able, or none matches │
6291 │ │ │ your read preference, │
6292 │ │ │ or you supplied an in‐ │
6293 │ │ │ valid mon‐ │
6294 │ │ │ goc_read_prefs_t. │
6295 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6296 │MONGOC_ER‐ │ Error code from server. │ There was a write con‐ │
6297 │ROR_WRITE_CONCERN │ │ cern error or timeout │
6298 │ │ │ from the server. │
6299 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6300 │MONGOC_ERROR_TRANS‐ │ MONGOC_ERROR_TRANSACTION_INVALID │ You attempted to start │
6301 │ACTION │ │ a transaction when one │
6302 │ │ │ is already in │
6303 │ │ │ progress, or commit or │
6304 │ │ │ abort when there is no │
6305 │ │ │ transaction. │
6306 ├────────────────────┼──────────────────────────────────┼────────────────────────┤
6307 │MONGOC_ER‐ │ Error code produced by libmon‐ │ An error occurred in │
6308 │ROR_CLIENT_SIDE_EN‐ │ gocrypt. │ the library responsi‐ │
6309 │CRYPTION │ │ ble for Client Side │
6310 │ │ │ Encryption │
6311 └────────────────────┴──────────────────────────────────┴────────────────────────┘
6312
6313 Error Labels
6314 In some cases your application must make decisions based on what cate‐
6315 gory of error the driver has returned, but these categories do not cor‐
6316 respond perfectly to an error domain or code. In such cases, error la‐
6317 bels provide a reliable way to determine how your application should
6318 respond to an error.
6319
6320 Any C Driver function that has a bson_t out-parameter named reply may
6321 include error labels to the reply, in the form of a BSON field named
6322 "errorLabels" containing an array of strings:
6323
6324 { "errorLabels": [ "TransientTransactionError" ] }
6325
6326 Use mongoc_error_has_label to test if a reply contains a specific la‐
6327 bel. See mongoc_client_session_start_transaction for example code that
6328 demonstrates the use of error labels in application logic.
6329
6330 The following error labels are currently defined. Future versions of
6331 MongoDB may introduce new labels.
6332
6333 TransientTransactionError
6334 Within a multi-document transaction, certain errors can leave the
6335 transaction in an unknown or aborted state. These include write con‐
6336 flicts, primary stepdowns, and network errors. In response, the appli‐
6337 cation should abort the transaction and try the same sequence of opera‐
6338 tions again in a new transaction.
6339
6340 UnknownTransactionCommitResult
6341 When mongoc_client_session_commit_transaction encounters a network er‐
6342 ror or certain server errors, it is not known whether the transaction
6343 was committed. Applications should attempt to commit the transaction
6344 again until: the commit succeeds, the commit fails with an error not
6345 labeled "UnknownTransactionCommitResult", or the application chooses to
6346 give up.
6347
6348 Setting the Error API Version
6349 The driver's error reporting began with a design flaw: when the error
6350 domain is MONGOC_ERROR_COLLECTION, MONGOC_ERROR_QUERY, or MONGOC_ER‐
6351 ROR_COMMAND, the error code might originate from the server or the
6352 driver. An application cannot always know where an error originated,
6353 and therefore cannot tell what the code means.
6354
6355 For example, if mongoc_collection_update_one sets the error's domain to
6356 MONGOC_ERROR_COLLECTION and its code to 24, the application cannot know
6357 whether 24 is the generic driver error code MONGOC_ERROR_COLLECTION_UP‐
6358 DATE_FAILED or the specific server error code "LockTimeout".
6359
6360 To fix this flaw while preserving backward compatibility, the C Driver
6361 1.4 introduces "Error API Versions". Version 1, the default Error API
6362 Version, maintains the flawed behavior. Version 2 adds a new error do‐
6363 main, MONGOC_ERROR_SERVER. In Version 2, error codes originating on the
6364 server always have error domain MONGOC_ERROR_SERVER or MONGOC_ER‐
6365 ROR_WRITE_CONCERN. When the driver uses Version 2 the application can
6366 always determine the origin and meaning of error codes. New applica‐
6367 tions should use Version 2, and existing applications should be updated
6368 to use Version 2 as well.
6369
6370 ┌──────────────────────┬────────────────────┬─────────────────────┐
6371 │Error Source │ API Version 1 │ API Version 2 │
6372 ├──────────────────────┼────────────────────┼─────────────────────┤
6373 │mongoc_cursor_error │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6374 ├──────────────────────┼────────────────────┼─────────────────────┤
6375 │mongoc_client_com‐ │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6376 │mand_with_opts, │ │ │
6377 │mongoc_data‐ │ │ │
6378 │base_com‐ │ │ │
6379 │mand_with_opts, and │ │ │
6380 │other command func‐ │ │ │
6381 │tions │ │ │
6382 ├──────────────────────┼────────────────────┼─────────────────────┤
6383 │mongoc_collec‐ │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6384 │tion_count_with_opts │ │ │
6385 │mon‐ │ │ │
6386 │goc_client_get_data‐ │ │ │
6387 │base_names_with_opts, │ │ │
6388 │and other command │ │ │
6389 │helper functions │ │ │
6390 ├──────────────────────┼────────────────────┼─────────────────────┤
6391 │mongoc_collection_in‐ │ MONGOC_ERROR_COM‐ │ MONGOC_ERROR_SERVER │
6392 │sert_one mongoc_col‐ │ MAND │ │
6393 │lection_insert_bulk │ │ │
6394 │mongoc_collection_up‐ │ │ │
6395 │date_one mongoc_col‐ │ │ │
6396 │lection_update_many │ │ │
6397 │mongoc_collection_re‐ │ │ │
6398 │place_one mongoc_col‐ │ │ │
6399 │lection_delete_one │ │ │
6400 │mongoc_collec‐ │ │ │
6401 │tion_delete_many │ │ │
6402 ├──────────────────────┼────────────────────┼─────────────────────┤
6403 │mongoc_bulk_opera‐ │ MONGOC_ERROR_COM‐ │ MONGOC_ERROR_SERVER │
6404 │tion_execute │ MAND │ │
6405 ├──────────────────────┼────────────────────┼─────────────────────┤
6406 │Write-concern timeout │ MONGOC_ER‐ │ MONGOC_ER‐ │
6407 │ │ ROR_WRITE_CONCERN │ ROR_WRITE_CONCERN │
6408 └──────────────────────┴────────────────────┴─────────────────────┘
6409
6410 The Error API Versions are defined with MONGOC_ERROR_API_VERSION_LEGACY
6411 and MONGOC_ERROR_API_VERSION_2. Set the version with mon‐
6412 goc_client_set_error_api or mongoc_client_pool_set_error_api.
6413
6414 SEE ALSO:
6415 MongoDB Server Error Codes
6416
6417
6418 Object Lifecycle
6419 This page documents the order of creation and destruction for libmon‐
6420 goc's main struct types.
6421
6422 Clients and pools
6423 Call mongoc_init() once, before calling any other libmongoc functions,
6424 and call mongoc_cleanup() once before your program exits.
6425
6426 A program that uses libmongoc from multiple threads should create a
6427 mongoc_client_pool_t with mongoc_client_pool_new(). Each thread ac‐
6428 quires a mongoc_client_t from the pool with mongoc_client_pool_pop()
6429 and returns it with mongoc_client_pool_push() when the thread is fin‐
6430 ished using it. To destroy the pool, first return all clients, then
6431 call mongoc_client_pool_destroy().
6432
6433 If your program uses libmongoc from only one thread, create a mon‐
6434 goc_client_t directly with mongoc_client_new() or mon‐
6435 goc_client_new_from_uri(). Destroy it with mongoc_client_destroy().
6436
6437 Databases, collections, and related objects
6438 You can create a mongoc_database_t or mongoc_collection_t from a mon‐
6439 goc_client_t, and create a mongoc_cursor_t or mongoc_bulk_operation_t
6440 from a mongoc_collection_t.
6441
6442 Each of these objects must be destroyed before the client they were
6443 created from, but their lifetimes are otherwise independent.
6444
6445 GridFS objects
6446 You can create a mongoc_gridfs_t from a mongoc_client_t, create a mon‐
6447 goc_gridfs_file_t or mongoc_gridfs_file_list_t from a mongoc_gridfs_t,
6448 create a mongoc_gridfs_file_t from a mongoc_gridfs_file_list_t, and
6449 create a mongoc_stream_t from a mongoc_gridfs_file_t.
6450
6451 Each of these objects depends on the object it was created from. Always
6452 destroy GridFS objects in the reverse of the order they were created.
6453 The sole exception is that a mongoc_gridfs_file_t need not be destroyed
6454 before the mongoc_gridfs_file_list_t it was created from.
6455
6456 GridFS bucket objects
6457 Create mongoc_gridfs_bucket_t with a mongoc_database_t derived from a
6458 mongoc_client_t. The mongoc_database_t is independent from the mon‐
6459 goc_gridfs_bucket_t. But the mongoc_client_t must outlive the mon‐
6460 goc_gridfs_bucket_t.
6461
6462 A mongoc_stream_t may be created from the mongoc_gridfs_bucket_t. The
6463 mongoc_gridfs_bucket_t must outlive the mongoc_stream_t.
6464
6465 Sessions
6466 Start a session with mongoc_client_start_session, use the session for a
6467 sequence of operations and multi-document transactions, then free it
6468 with mongoc_client_session_destroy(). Any mongoc_cursor_t or mon‐
6469 goc_change_stream_t using a session must be destroyed before the ses‐
6470 sion, and a session must be destroyed before the mongoc_client_t it
6471 came from.
6472
6473 By default, sessions are causally consistent. To disable causal consis‐
6474 tency, before starting a session create a mongoc_session_opt_t with
6475 mongoc_session_opts_new() and call mongoc_session_opts_set_causal_con‐
6476 sistency(), then free the struct with mongoc_session_opts_destroy.
6477
6478 Unacknowledged writes are prohibited with sessions.
6479
6480 A mongoc_client_session_t must be used by only one thread at a time.
6481 Due to session pooling, mongoc_client_start_session may return a ses‐
6482 sion that has been idle for some time and is about to be closed after
6483 its idle timeout. Use the session within one minute of acquiring it to
6484 refresh the session and avoid a timeout.
6485
6486 Client Side Encryption
6487 When configuring a mongoc_client_t for automatic encryption via mon‐
6488 goc_client_enable_auto_encryption(), if a separate key vault client is
6489 set in the options (via mongoc_auto_encryption_opts_set_key‐
6490 vault_client()) the key vault client must outlive the encrypted client.
6491
6492 When configuring a mongoc_client_pool_t for automatic encryption via
6493 mongoc_client_pool_enable_auto_encryption(), if a separate key vault
6494 client pool is set in the options (via mongoc_auto_encryp‐
6495 tion_opts_set_keyvault_client_pool()) the key vault client pool must
6496 outlive the encrypted client pool.
6497
6498 When creating a mongoc_client_encryption_t, the configured key vault
6499 client (set via mongoc_client_encryption_opts_set_keyvault_client())
6500 must outlive the mongoc_client_encryption_t.
6501
6502 GridFS
6503 The C driver includes two APIs for GridFS.
6504
6505 The older API consists of mongoc_gridfs_t and its derivatives. It con‐
6506 tains deprecated API, does not support read preferences, and is not
6507 recommended in new applications. It does not conform to the MongoDB
6508 GridFS specification.
6509
6510 The newer API consists of mongoc_gridfs_bucket_t and allows upload‐
6511 ing/downloading through derived mongoc_stream_t objects. It conforms to
6512 the MongoDB GridFS specification.
6513
6514 There is not always a straightforward upgrade path from an application
6515 built with mongoc_gridfs_t to mongoc_gridfs_bucket_t (e.g. a mon‐
6516 goc_gridfs_file_t provides functions to seek but mongoc_stream_t does
6517 not). But users are encouraged to upgrade when possible.
6518
6519 mongoc_auto_encryption_opts_t
6520 Options for enabling automatic encryption and decryption for
6521 Client-Side Field Level Encryption.
6522
6523 Synopsis
6524 typedef struct _mongoc_auto_encryption_opts_t mongoc_auto_encryption_opts_t;
6525
6526 SEE ALSO:
6527 The guide for Using Client-Side Field Level Encryption
6528
6529
6530 mongoc_bulk_operation_t
6531 Bulk Write Operations
6532
6533 Synopsis
6534 typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t;
6535
6536 The opaque type mongoc_bulk_operation_t provides an abstraction for
6537 submitting multiple write operations as a single batch.
6538
6539 After adding all of the write operations to the mongoc_bulk_opera‐
6540 tion_t, call mongoc_bulk_operation_execute() to execute the operation.
6541
6542 WARNING:
6543 It is only valid to call mongoc_bulk_operation_execute() once. The
6544 mongoc_bulk_operation_t must be destroyed afterwards.
6545
6546 SEE ALSO:
6547 Bulk Write Operations
6548
6549
6550 mongoc_change_stream_t
6551 Synopsis
6552 #include <mongoc/mongoc.h>
6553
6554 typedef struct _mongoc_change_stream_t mongoc_change_stream_t;
6555
6556 mongoc_change_stream_t is a handle to a change stream. A collection
6557 change stream can be obtained using mongoc_collection_watch.
6558
6559 It is recommended to use a mongoc_change_stream_t and its functions in‐
6560 stead of a raw aggregation with a $changeStream stage. For more infor‐
6561 mation see the MongoDB Manual Entry on Change Streams.
6562
6563 Example
6564 example-collection-watch.c
6565
6566 #include <mongoc/mongoc.h>
6567
6568 int
6569 main ()
6570 {
6571 bson_t empty = BSON_INITIALIZER;
6572 const bson_t *doc;
6573 bson_t *to_insert = BCON_NEW ("x", BCON_INT32 (1));
6574 const bson_t *err_doc;
6575 bson_error_t error;
6576 const char *uri_string;
6577 mongoc_uri_t *uri;
6578 mongoc_client_t *client;
6579 mongoc_collection_t *coll;
6580 mongoc_change_stream_t *stream;
6581 mongoc_write_concern_t *wc = mongoc_write_concern_new ();
6582 bson_t opts = BSON_INITIALIZER;
6583 bool r;
6584
6585 mongoc_init ();
6586
6587 uri_string = "mongodb://"
6588 "localhost:27017,localhost:27018,localhost:"
6589 "27019/db?replicaSet=rs0";
6590
6591 uri = mongoc_uri_new_with_error (uri_string, &error);
6592 if (!uri) {
6593 fprintf (stderr,
6594 "failed to parse URI: %s\n"
6595 "error message: %s\n",
6596 uri_string,
6597 error.message);
6598 return EXIT_FAILURE;
6599 }
6600
6601 client = mongoc_client_new_from_uri (uri);
6602 if (!client) {
6603 return EXIT_FAILURE;
6604 }
6605
6606 coll = mongoc_client_get_collection (client, "db", "coll");
6607 stream = mongoc_collection_watch (coll, &empty, NULL);
6608
6609 mongoc_write_concern_set_wmajority (wc, 10000);
6610 mongoc_write_concern_append (wc, &opts);
6611 r = mongoc_collection_insert_one (coll, to_insert, &opts, NULL, &error);
6612 if (!r) {
6613 fprintf (stderr, "Error: %s\n", error.message);
6614 return EXIT_FAILURE;
6615 }
6616
6617 while (mongoc_change_stream_next (stream, &doc)) {
6618 char *as_json = bson_as_relaxed_extended_json (doc, NULL);
6619 fprintf (stderr, "Got document: %s\n", as_json);
6620 bson_free (as_json);
6621 }
6622
6623 if (mongoc_change_stream_error_document (stream, &error, &err_doc)) {
6624 if (!bson_empty (err_doc)) {
6625 fprintf (stderr,
6626 "Server Error: %s\n",
6627 bson_as_relaxed_extended_json (err_doc, NULL));
6628 } else {
6629 fprintf (stderr, "Client Error: %s\n", error.message);
6630 }
6631 return EXIT_FAILURE;
6632 }
6633
6634 bson_destroy (to_insert);
6635 mongoc_write_concern_destroy (wc);
6636 bson_destroy (&opts);
6637 mongoc_change_stream_destroy (stream);
6638 mongoc_collection_destroy (coll);
6639 mongoc_uri_destroy (uri);
6640 mongoc_client_destroy (client);
6641 mongoc_cleanup ();
6642
6643 return EXIT_SUCCESS;
6644 }
6645
6646
6647 Starting and Resuming
6648 All watch functions accept several options to indicate where a change
6649 stream should start returning changes from: resumeAfter, startAfter,
6650 and startAtOperationTime.
6651
6652 All changes returned by mongoc_change_stream_next include a resume to‐
6653 ken in the _id field. MongoDB 4.2 also includes an additional resume
6654 token in each "aggregate" and "getMore" command response, which points
6655 to the end of that response's batch. The current token is automatically
6656 cached by libmongoc. In the event of an error, libmongoc attempts to
6657 recreate the change stream starting where it left off by passing the
6658 cached resume token. libmongoc only attempts to resume once, but client
6659 applications can access the cached resume token with mon‐
6660 goc_change_stream_get_resume_token and use it for their own resume
6661 logic by passing it as either the resumeAfter or startAfter option.
6662
6663 Additionally, change streams can start returning changes at an opera‐
6664 tion time by using the startAtOperationTime field. This can be the
6665 timestamp returned in the operationTime field of a command reply.
6666
6667 resumeAfter, startAfter, and startAtOperationTime are mutually exclu‐
6668 sive options. Setting more than one will result in a server error.
6669
6670 The following example implements custom resuming logic, persisting the
6671 resume token in a file.
6672
6673 example-resume.c
6674
6675 #include <mongoc/mongoc.h>
6676
6677 /* An example implementation of custom resume logic in a change stream.
6678 * example-resume starts a client-wide change stream and persists the resume
6679 * token in a file "resume-token.json". On restart, if "resume-token.json"
6680 * exists, the change stream starts watching after the persisted resume token.
6681 *
6682 * This behavior allows a user to exit example-resume, and restart it later
6683 * without missing any change events.
6684 */
6685 #include <unistd.h>
6686
6687 static const char *RESUME_TOKEN_PATH = "resume-token.json";
6688
6689 static bool
6690 _save_resume_token (const bson_t *doc)
6691 {
6692 FILE *file_stream;
6693 bson_iter_t iter;
6694 bson_t resume_token_doc;
6695 char *as_json = NULL;
6696 size_t as_json_len;
6697 ssize_t r, n_written;
6698 const bson_value_t *resume_token;
6699
6700 if (!bson_iter_init_find (&iter, doc, "_id")) {
6701 fprintf (stderr, "reply does not contain operationTime.");
6702 return false;
6703 }
6704 resume_token = bson_iter_value (&iter);
6705 /* store the resume token in a document, { resumeAfter: <resume token> }
6706 * which we can later append easily. */
6707 file_stream = fopen (RESUME_TOKEN_PATH, "w+");
6708 if (!file_stream) {
6709 fprintf (stderr, "failed to open %s for writing\n", RESUME_TOKEN_PATH);
6710 return false;
6711 }
6712 bson_init (&resume_token_doc);
6713 BSON_APPEND_VALUE (&resume_token_doc, "resumeAfter", resume_token);
6714 as_json = bson_as_canonical_extended_json (&resume_token_doc, &as_json_len);
6715 bson_destroy (&resume_token_doc);
6716 n_written = 0;
6717 while (n_written < as_json_len) {
6718 r = fwrite ((void *) (as_json + n_written),
6719 sizeof (char),
6720 as_json_len - n_written,
6721 file_stream);
6722 if (r == -1) {
6723 fprintf (stderr, "failed to write to %s\n", RESUME_TOKEN_PATH);
6724 bson_free (as_json);
6725 fclose (file_stream);
6726 return false;
6727 }
6728 n_written += r;
6729 }
6730
6731 bson_free (as_json);
6732 fclose (file_stream);
6733 return true;
6734 }
6735
6736 bool
6737 _load_resume_token (bson_t *opts)
6738 {
6739 bson_error_t error;
6740 bson_json_reader_t *reader;
6741 bson_t doc;
6742
6743 /* if the file does not exist, skip. */
6744 if (-1 == access (RESUME_TOKEN_PATH, R_OK)) {
6745 return true;
6746 }
6747 reader = bson_json_reader_new_from_file (RESUME_TOKEN_PATH, &error);
6748 if (!reader) {
6749 fprintf (stderr,
6750 "failed to open %s for reading: %s\n",
6751 RESUME_TOKEN_PATH,
6752 error.message);
6753 return false;
6754 }
6755
6756 bson_init (&doc);
6757 if (-1 == bson_json_reader_read (reader, &doc, &error)) {
6758 fprintf (stderr, "failed to read doc from %s\n", RESUME_TOKEN_PATH);
6759 bson_destroy (&doc);
6760 bson_json_reader_destroy (reader);
6761 return false;
6762 }
6763
6764 printf ("found cached resume token in %s, resuming change stream.\n",
6765 RESUME_TOKEN_PATH);
6766
6767 bson_concat (opts, &doc);
6768 bson_destroy (&doc);
6769 bson_json_reader_destroy (reader);
6770 return true;
6771 }
6772
6773 int
6774 main ()
6775 {
6776 int exit_code = EXIT_FAILURE;
6777 const char *uri_string;
6778 mongoc_uri_t *uri = NULL;
6779 bson_error_t error;
6780 mongoc_client_t *client = NULL;
6781 bson_t pipeline = BSON_INITIALIZER;
6782 bson_t opts = BSON_INITIALIZER;
6783 mongoc_change_stream_t *stream = NULL;
6784 const bson_t *doc;
6785
6786 const int max_time = 30; /* max amount of time, in seconds, that
6787 mongoc_change_stream_next can block. */
6788
6789 mongoc_init ();
6790 uri_string = "mongodb://localhost:27017/db?replicaSet=rs0";
6791 uri = mongoc_uri_new_with_error (uri_string, &error);
6792 if (!uri) {
6793 fprintf (stderr,
6794 "failed to parse URI: %s\n"
6795 "error message: %s\n",
6796 uri_string,
6797 error.message);
6798 goto cleanup;
6799 }
6800
6801 client = mongoc_client_new_from_uri (uri);
6802 if (!client) {
6803 goto cleanup;
6804 }
6805
6806 if (!_load_resume_token (&opts)) {
6807 goto cleanup;
6808 }
6809 BSON_APPEND_INT64 (&opts, "maxAwaitTimeMS", max_time * 1000);
6810
6811 printf ("listening for changes on the client (max %d seconds).\n", max_time);
6812 stream = mongoc_client_watch (client, &pipeline, &opts);
6813
6814 while (mongoc_change_stream_next (stream, &doc)) {
6815 char *as_json;
6816
6817 as_json = bson_as_canonical_extended_json (doc, NULL);
6818 printf ("change received: %s\n", as_json);
6819 bson_free (as_json);
6820 if (!_save_resume_token (doc)) {
6821 goto cleanup;
6822 }
6823 }
6824
6825 exit_code = EXIT_SUCCESS;
6826
6827 cleanup:
6828 mongoc_uri_destroy (uri);
6829 bson_destroy (&pipeline);
6830 bson_destroy (&opts);
6831 mongoc_change_stream_destroy (stream);
6832 mongoc_client_destroy (client);
6833 mongoc_cleanup ();
6834 return exit_code;
6835 }
6836
6837
6838 The following example shows using startAtOperationTime to synchronize a
6839 change stream with another operation.
6840
6841 example-start-at-optime.c
6842
6843 /* An example of starting a change stream with startAtOperationTime. */
6844 #include <mongoc/mongoc.h>
6845
6846 int
6847 main ()
6848 {
6849 int exit_code = EXIT_FAILURE;
6850 const char *uri_string;
6851 mongoc_uri_t *uri = NULL;
6852 bson_error_t error;
6853 mongoc_client_t *client = NULL;
6854 mongoc_collection_t *coll = NULL;
6855 bson_t pipeline = BSON_INITIALIZER;
6856 bson_t opts = BSON_INITIALIZER;
6857 mongoc_change_stream_t *stream = NULL;
6858 bson_iter_t iter;
6859 const bson_t *doc;
6860 bson_value_t cached_operation_time = {0};
6861 int i;
6862 bool r;
6863
6864 mongoc_init ();
6865 uri_string = "mongodb://localhost:27017/db?replicaSet=rs0";
6866 uri = mongoc_uri_new_with_error (uri_string, &error);
6867 if (!uri) {
6868 fprintf (stderr,
6869 "failed to parse URI: %s\n"
6870 "error message: %s\n",
6871 uri_string,
6872 error.message);
6873 goto cleanup;
6874 }
6875
6876 client = mongoc_client_new_from_uri (uri);
6877 if (!client) {
6878 goto cleanup;
6879 }
6880
6881 /* insert five documents. */
6882 coll = mongoc_client_get_collection (client, "db", "coll");
6883 for (i = 0; i < 5; i++) {
6884 bson_t reply;
6885 bson_t *insert_cmd = BCON_NEW ("insert",
6886 "coll",
6887 "documents",
6888 "[",
6889 "{",
6890 "x",
6891 BCON_INT64 (i),
6892 "}",
6893 "]");
6894
6895 r = mongoc_collection_write_command_with_opts (
6896 coll, insert_cmd, NULL, &reply, &error);
6897 bson_destroy (insert_cmd);
6898 if (!r) {
6899 bson_destroy (&reply);
6900 fprintf (stderr, "failed to insert: %s\n", error.message);
6901 goto cleanup;
6902 }
6903 if (i == 0) {
6904 /* cache the operation time in the first reply. */
6905 if (bson_iter_init_find (&iter, &reply, "operationTime")) {
6906 bson_value_copy (bson_iter_value (&iter), &cached_operation_time);
6907 } else {
6908 fprintf (stderr, "reply does not contain operationTime.");
6909 bson_destroy (&reply);
6910 goto cleanup;
6911 }
6912 }
6913 bson_destroy (&reply);
6914 }
6915
6916 /* start a change stream at the first returned operationTime. */
6917 BSON_APPEND_VALUE (&opts, "startAtOperationTime", &cached_operation_time);
6918 stream = mongoc_collection_watch (coll, &pipeline, &opts);
6919
6920 /* since the change stream started at the operation time of the first
6921 * insert, the five inserts are returned. */
6922 printf ("listening for changes on db.coll:\n");
6923 while (mongoc_change_stream_next (stream, &doc)) {
6924 char *as_json;
6925
6926 as_json = bson_as_canonical_extended_json (doc, NULL);
6927 printf ("change received: %s\n", as_json);
6928 bson_free (as_json);
6929 }
6930
6931 exit_code = EXIT_SUCCESS;
6932
6933 cleanup:
6934 mongoc_uri_destroy (uri);
6935 bson_destroy (&pipeline);
6936 bson_destroy (&opts);
6937 if (cached_operation_time.value_type) {
6938 bson_value_destroy (&cached_operation_time);
6939 }
6940 mongoc_change_stream_destroy (stream);
6941 mongoc_collection_destroy (coll);
6942 mongoc_client_destroy (client);
6943 mongoc_cleanup ();
6944 return exit_code;
6945 }
6946
6947
6948 mongoc_client_encryption_t
6949 Synopsis
6950 typedef struct _mongoc_client_encryption_t mongoc_client_encryption_t;
6951
6952 mongoc_client_encryption_t provides utility functions for Client-Side
6953 Field Level Encryption. See the guide for Using Client-Side Field Level
6954 Encryption.
6955
6956 Thread Safety
6957 mongoc_client_encryption_t is NOT thread-safe and should only be used
6958 in the same thread as the mongoc_client_t that is configured via mon‐
6959 goc_client_encryption_opts_set_keyvault_client().
6960
6961 Lifecycle
6962 The key vault client, configured via mongoc_client_encryp‐
6963 tion_opts_set_keyvault_client(), must outlive the mongoc_client_encryp‐
6964 tion_t.
6965
6966 SEE ALSO:
6967 mongoc_client_enable_auto_encryption()
6968
6969 mongoc_client_pool_enable_auto_encryption()
6970
6971 The guide for Using Client-Side Field Level Encryption for libmongoc
6972
6973 The MongoDB Manual for Client-Side Field Level Encryption
6974
6975
6976 mongoc_client_encryption_datakey_opts_t
6977 Synopsis
6978 typedef struct _mongoc_client_encryption_datakey_opts_t mongoc_client_encryption_datakey_opts_t;
6979
6980 Used to set options for mongoc_client_encryption_create_datakey().
6981
6982 SEE ALSO:
6983 mongoc_client_encryption_create_datakey()
6984
6985
6986 mongoc_client_encryption_encrypt_opts_t
6987 Synopsis
6988 typedef struct _mongoc_client_encryption_encrypt_opts_t mongoc_client_encryption_encrypt_opts_t;
6989
6990 Used to set options for mongoc_client_encryption_encrypt().
6991
6992 SEE ALSO:
6993 mongoc_client_encryption_encrypt()
6994
6995
6996 mongoc_client_encryption_opts_t
6997 Synopsis
6998 typedef struct _mongoc_client_encryption_opts_t mongoc_client_encryption_opts_t;
6999
7000 Used to set options for mongoc_client_encryption_new().
7001
7002 SEE ALSO:
7003 mongoc_client_encryption_new()
7004
7005
7006 mongoc_client_pool_t
7007 A connection pool for multi-threaded programs. See connection-pooling.
7008
7009 Synopsis
7010 typedef struct _mongoc_client_pool_t mongoc_client_pool_t
7011
7012 mongoc_client_pool_t is the basis for multi-threading in the MongoDB C
7013 driver. Since mongoc_client_t structures are not thread-safe, this
7014 structure is used to retrieve a new mongoc_client_t for a given thread.
7015 This structure is thread-safe, except for its destructor method, mon‐
7016 goc_client_pool_destroy, which is not thread-safe and must only be
7017 called from one thread.
7018
7019 Example
7020 example-pool.c
7021
7022 /* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
7023 * libmongoc-1.0) */
7024
7025 /* ./example-pool [CONNECTION_STRING] */
7026
7027 #include <mongoc/mongoc.h>
7028 #include <pthread.h>
7029 #include <stdio.h>
7030
7031 static pthread_mutex_t mutex;
7032 static bool in_shutdown = false;
7033
7034 static void *
7035 worker (void *data)
7036 {
7037 mongoc_client_pool_t *pool = data;
7038 mongoc_client_t *client;
7039 bson_t ping = BSON_INITIALIZER;
7040 bson_error_t error;
7041 bool r;
7042
7043 BSON_APPEND_INT32 (&ping, "ping", 1);
7044
7045 while (true) {
7046 client = mongoc_client_pool_pop (pool);
7047 /* Do something with client. If you are writing an HTTP server, you
7048 * probably only want to hold onto the client for the portion of the
7049 * request performing database queries.
7050 */
7051 r = mongoc_client_command_simple (
7052 client, "admin", &ping, NULL, NULL, &error);
7053
7054 if (!r) {
7055 fprintf (stderr, "%s\n", error.message);
7056 }
7057
7058 mongoc_client_pool_push (pool, client);
7059
7060 pthread_mutex_lock (&mutex);
7061 if (in_shutdown || !r) {
7062 pthread_mutex_unlock (&mutex);
7063 break;
7064 }
7065
7066 pthread_mutex_unlock (&mutex);
7067 }
7068
7069 bson_destroy (&ping);
7070 return NULL;
7071 }
7072
7073 int
7074 main (int argc, char *argv[])
7075 {
7076 const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
7077 mongoc_uri_t *uri;
7078 bson_error_t error;
7079 mongoc_client_pool_t *pool;
7080 pthread_t threads[10];
7081 unsigned i;
7082 void *ret;
7083
7084 pthread_mutex_init (&mutex, NULL);
7085 mongoc_init ();
7086
7087 if (argc > 1) {
7088 uri_string = argv[1];
7089 }
7090
7091 uri = mongoc_uri_new_with_error (uri_string, &error);
7092 if (!uri) {
7093 fprintf (stderr,
7094 "failed to parse URI: %s\n"
7095 "error message: %s\n",
7096 uri_string,
7097 error.message);
7098 return EXIT_FAILURE;
7099 }
7100
7101 pool = mongoc_client_pool_new (uri);
7102 mongoc_client_pool_set_error_api (pool, 2);
7103
7104 for (i = 0; i < 10; i++) {
7105 pthread_create (&threads[i], NULL, worker, pool);
7106 }
7107
7108 sleep (10);
7109 pthread_mutex_lock (&mutex);
7110 in_shutdown = true;
7111 pthread_mutex_unlock (&mutex);
7112
7113 for (i = 0; i < 10; i++) {
7114 pthread_join (threads[i], &ret);
7115 }
7116
7117 mongoc_client_pool_destroy (pool);
7118 mongoc_uri_destroy (uri);
7119
7120 mongoc_cleanup ();
7121
7122 return EXIT_SUCCESS;
7123 }
7124
7125
7126 mongoc_client_session_t
7127 Use a session for a sequence of operations, optionally with causal con‐
7128 sistency. See the MongoDB Manual Entry for Causal Consistency.
7129
7130 Synopsis
7131 Start a session with mongoc_client_start_session, use the session for a
7132 sequence of operations and multi-document transactions, then free it
7133 with mongoc_client_session_destroy(). Any mongoc_cursor_t or mon‐
7134 goc_change_stream_t using a session must be destroyed before the ses‐
7135 sion, and a session must be destroyed before the mongoc_client_t it
7136 came from.
7137
7138 By default, sessions are causally consistent. To disable causal consis‐
7139 tency, before starting a session create a mongoc_session_opt_t with
7140 mongoc_session_opts_new() and call mongoc_session_opts_set_causal_con‐
7141 sistency(), then free the struct with mongoc_session_opts_destroy.
7142
7143 Unacknowledged writes are prohibited with sessions.
7144
7145 A mongoc_client_session_t must be used by only one thread at a time.
7146 Due to session pooling, mongoc_client_start_session may return a ses‐
7147 sion that has been idle for some time and is about to be closed after
7148 its idle timeout. Use the session within one minute of acquiring it to
7149 refresh the session and avoid a timeout.
7150
7151 Example
7152 example-session.c
7153
7154 /* gcc example-session.c -o example-session \
7155 * $(pkg-config --cflags --libs libmongoc-1.0) */
7156
7157 /* ./example-session [CONNECTION_STRING] */
7158
7159 #include <stdio.h>
7160 #include <mongoc/mongoc.h>
7161
7162
7163 int
7164 main (int argc, char *argv[])
7165 {
7166 int exit_code = EXIT_FAILURE;
7167
7168 mongoc_client_t *client = NULL;
7169 const char *uri_string = "mongodb://127.0.0.1/?appname=session-example";
7170 mongoc_uri_t *uri = NULL;
7171 mongoc_client_session_t *client_session = NULL;
7172 mongoc_collection_t *collection = NULL;
7173 bson_error_t error;
7174 bson_t *selector = NULL;
7175 bson_t *update = NULL;
7176 bson_t *update_opts = NULL;
7177 bson_t *find_opts = NULL;
7178 mongoc_read_prefs_t *secondary = NULL;
7179 mongoc_cursor_t *cursor = NULL;
7180 const bson_t *doc;
7181 char *str;
7182 bool r;
7183
7184 mongoc_init ();
7185
7186 if (argc > 1) {
7187 uri_string = argv[1];
7188 }
7189
7190 uri = mongoc_uri_new_with_error (uri_string, &error);
7191 if (!uri) {
7192 fprintf (stderr,
7193 "failed to parse URI: %s\n"
7194 "error message: %s\n",
7195 uri_string,
7196 error.message);
7197 goto done;
7198 }
7199
7200 client = mongoc_client_new_from_uri (uri);
7201 if (!client) {
7202 goto done;
7203 }
7204
7205 mongoc_client_set_error_api (client, 2);
7206
7207 /* pass NULL for options - by default the session is causally consistent */
7208 client_session = mongoc_client_start_session (client, NULL, &error);
7209 if (!client_session) {
7210 fprintf (stderr, "Failed to start session: %s\n", error.message);
7211 goto done;
7212 }
7213
7214 collection = mongoc_client_get_collection (client, "test", "collection");
7215 selector = BCON_NEW ("_id", BCON_INT32 (1));
7216 update = BCON_NEW ("$inc", "{", "x", BCON_INT32 (1), "}");
7217 update_opts = bson_new ();
7218 if (!mongoc_client_session_append (client_session, update_opts, &error)) {
7219 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
7220 goto done;
7221 }
7222
7223 r = mongoc_collection_update_one (
7224 collection, selector, update, update_opts, NULL /* reply */, &error);
7225
7226 if (!r) {
7227 fprintf (stderr, "Update failed: %s\n", error.message);
7228 goto done;
7229 }
7230
7231 bson_destroy (selector);
7232 selector = BCON_NEW ("_id", BCON_INT32 (1));
7233 secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
7234
7235 find_opts = BCON_NEW ("maxTimeMS", BCON_INT32 (2000));
7236 if (!mongoc_client_session_append (client_session, find_opts, &error)) {
7237 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
7238 goto done;
7239 };
7240
7241 /* read from secondary. since we're in a causally consistent session, the
7242 * data is guaranteed to reflect the update we did on the primary. the query
7243 * blocks waiting for the secondary to catch up, if necessary, or times out
7244 * and fails after 2000 ms.
7245 */
7246 cursor = mongoc_collection_find_with_opts (
7247 collection, selector, find_opts, secondary);
7248
7249 while (mongoc_cursor_next (cursor, &doc)) {
7250 str = bson_as_json (doc, NULL);
7251 fprintf (stdout, "%s\n", str);
7252 bson_free (str);
7253 }
7254
7255 if (mongoc_cursor_error (cursor, &error)) {
7256 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7257 goto done;
7258 }
7259
7260 exit_code = EXIT_SUCCESS;
7261
7262 done:
7263 if (find_opts) {
7264 bson_destroy (find_opts);
7265 }
7266 if (update) {
7267 bson_destroy (update);
7268 }
7269 if (selector) {
7270 bson_destroy (selector);
7271 }
7272 if (update_opts) {
7273 bson_destroy (update_opts);
7274 }
7275 if (secondary) {
7276 mongoc_read_prefs_destroy (secondary);
7277 }
7278 /* destroy cursor, collection, session before the client they came from */
7279 if (cursor) {
7280 mongoc_cursor_destroy (cursor);
7281 }
7282 if (collection) {
7283 mongoc_collection_destroy (collection);
7284 }
7285 if (client_session) {
7286 mongoc_client_session_destroy (client_session);
7287 }
7288 if (uri) {
7289 mongoc_uri_destroy (uri);
7290 }
7291 if (client) {
7292 mongoc_client_destroy (client);
7293 }
7294
7295 mongoc_cleanup ();
7296
7297 return exit_code;
7298 }
7299
7300
7301 mongoc_client_session_with_transaction_cb_t
7302 Synopsis
7303 typedef bool (*mongoc_client_session_with_transaction_cb_t) (
7304 mongoc_client_session_t *session,
7305 void *ctx,
7306 bson_t **reply,
7307 bson_error_t *error);
7308
7309 Provide this callback to mongoc_client_session_with_transaction. The
7310 callback should run a sequence of operations meant to be contained
7311 within a transaction. The callback should not attempt to start or com‐
7312 mit transactions.
7313
7314 Parameters
7315 • session: A mongoc_client_session_t.
7316
7317 • ctx: A void* set to the the user-provided ctx passed to mon‐
7318 goc_client_session_with_transaction.
7319
7320 • reply: An optional location for a bson_t or NULL. The callback should
7321 set this if it runs any operations against the server and receives
7322 replies.
7323
7324 • error: A bson_error_t. The callback should set this if it receives
7325 any errors while running operations against the server.
7326
7327 Return
7328 Returns true for success and false on failure. If cb returns false then
7329 it should also set error.
7330
7331 SEE ALSO:
7332 mongoc_client_session_with_transaction
7333
7334
7335 mongoc_client_t
7336 A single-threaded MongoDB connection. See connection-pooling.
7337
7338 Synopsis
7339 typedef struct _mongoc_client_t mongoc_client_t;
7340
7341 typedef mongoc_stream_t *(*mongoc_stream_initiator_t) (
7342 const mongoc_uri_t *uri,
7343 const mongoc_host_list_t *host,
7344 void *user_data,
7345 bson_error_t *error);
7346
7347 mongoc_client_t is an opaque type that provides access to a MongoDB
7348 server, replica set, or sharded cluster. It maintains management of un‐
7349 derlying sockets and routing to individual nodes based on mon‐
7350 goc_read_prefs_t or mongoc_write_concern_t.
7351
7352 Streams
7353 The underlying transport for a given client can be customized, wrapped
7354 or replaced by any implementation that fulfills mongoc_stream_t. A cus‐
7355 tom transport can be set with mongoc_client_set_stream_initiator().
7356
7357 Thread Safety
7358 mongoc_client_t is NOT thread-safe and should only be used from one
7359 thread at a time. When used in multi-threaded scenarios, it is recom‐
7360 mended that you use the thread-safe mongoc_client_pool_t to retrieve a
7361 mongoc_client_t for your thread.
7362
7363 Example
7364 example-client.c
7365
7366 /* gcc example-client.c -o example-client $(pkg-config --cflags --libs
7367 * libmongoc-1.0) */
7368
7369 /* ./example-client [CONNECTION_STRING [COLLECTION_NAME]] */
7370
7371 #include <mongoc/mongoc.h>
7372 #include <stdio.h>
7373 #include <stdlib.h>
7374
7375 int
7376 main (int argc, char *argv[])
7377 {
7378 mongoc_client_t *client;
7379 mongoc_collection_t *collection;
7380 mongoc_cursor_t *cursor;
7381 bson_error_t error;
7382 const bson_t *doc;
7383 const char *collection_name = "test";
7384 bson_t query;
7385 char *str;
7386 const char *uri_string = "mongodb://127.0.0.1/?appname=client-example";
7387 mongoc_uri_t *uri;
7388
7389 mongoc_init ();
7390 if (argc > 1) {
7391 uri_string = argv[1];
7392 }
7393
7394 if (argc > 2) {
7395 collection_name = argv[2];
7396 }
7397
7398 uri = mongoc_uri_new_with_error (uri_string, &error);
7399 if (!uri) {
7400 fprintf (stderr,
7401 "failed to parse URI: %s\n"
7402 "error message: %s\n",
7403 uri_string,
7404 error.message);
7405 return EXIT_FAILURE;
7406 }
7407
7408 client = mongoc_client_new_from_uri (uri);
7409 if (!client) {
7410 return EXIT_FAILURE;
7411 }
7412
7413 mongoc_client_set_error_api (client, 2);
7414
7415 bson_init (&query);
7416 collection = mongoc_client_get_collection (client, "test", collection_name);
7417 cursor = mongoc_collection_find_with_opts (
7418 collection,
7419 &query,
7420 NULL, /* additional options */
7421 NULL); /* read prefs, NULL for default */
7422
7423 while (mongoc_cursor_next (cursor, &doc)) {
7424 str = bson_as_canonical_extended_json (doc, NULL);
7425 fprintf (stdout, "%s\n", str);
7426 bson_free (str);
7427 }
7428
7429 if (mongoc_cursor_error (cursor, &error)) {
7430 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7431 return EXIT_FAILURE;
7432 }
7433
7434 bson_destroy (&query);
7435 mongoc_cursor_destroy (cursor);
7436 mongoc_collection_destroy (collection);
7437 mongoc_uri_destroy (uri);
7438 mongoc_client_destroy (client);
7439 mongoc_cleanup ();
7440
7441 return EXIT_SUCCESS;
7442 }
7443
7444
7445 mongoc_collection_t
7446 Synopsis
7447 typedef struct _mongoc_collection_t mongoc_collection_t;
7448
7449 mongoc_collection_t provides access to a MongoDB collection. This han‐
7450 dle is useful for actions for most CRUD operations, I.e. insert, up‐
7451 date, delete, find, etc.
7452
7453 Read Preferences and Write Concerns
7454 Read preferences and write concerns are inherited from the parent
7455 client. They can be overridden by set_* commands if so desired.
7456
7457 mongoc_cursor_t
7458 Client-side cursor abstraction
7459
7460 Synopsis
7461 typedef struct _mongoc_cursor_t mongoc_cursor_t;
7462
7463 mongoc_cursor_t provides access to a MongoDB query cursor. It wraps up
7464 the wire protocol negotiation required to initiate a query and retrieve
7465 an unknown number of documents.
7466
7467 Common cursor operations include:
7468
7469 • Determine which host we've connected to with mongoc_cur‐
7470 sor_get_host().
7471
7472 • Retrieve more records with repeated calls to mongoc_cursor_next().
7473
7474 • Clone a query to repeat execution at a later point with mongoc_cur‐
7475 sor_clone().
7476
7477 • Test for errors with mongoc_cursor_error().
7478
7479 Cursors are lazy, meaning that no connection is established and no net‐
7480 work traffic occurs until the first call to mongoc_cursor_next().
7481
7482 Thread Safety
7483 mongoc_cursor_t is NOT thread safe. It may only be used from within the
7484 thread in which it was created.
7485
7486 Example
7487 Query MongoDB and iterate results
7488
7489 /* gcc example-client.c -o example-client $(pkg-config --cflags --libs
7490 * libmongoc-1.0) */
7491
7492 /* ./example-client [CONNECTION_STRING [COLLECTION_NAME]] */
7493
7494 #include <mongoc/mongoc.h>
7495 #include <stdio.h>
7496 #include <stdlib.h>
7497
7498 int
7499 main (int argc, char *argv[])
7500 {
7501 mongoc_client_t *client;
7502 mongoc_collection_t *collection;
7503 mongoc_cursor_t *cursor;
7504 bson_error_t error;
7505 const bson_t *doc;
7506 const char *collection_name = "test";
7507 bson_t query;
7508 char *str;
7509 const char *uri_string = "mongodb://127.0.0.1/?appname=client-example";
7510 mongoc_uri_t *uri;
7511
7512 mongoc_init ();
7513 if (argc > 1) {
7514 uri_string = argv[1];
7515 }
7516
7517 if (argc > 2) {
7518 collection_name = argv[2];
7519 }
7520
7521 uri = mongoc_uri_new_with_error (uri_string, &error);
7522 if (!uri) {
7523 fprintf (stderr,
7524 "failed to parse URI: %s\n"
7525 "error message: %s\n",
7526 uri_string,
7527 error.message);
7528 return EXIT_FAILURE;
7529 }
7530
7531 client = mongoc_client_new_from_uri (uri);
7532 if (!client) {
7533 return EXIT_FAILURE;
7534 }
7535
7536 mongoc_client_set_error_api (client, 2);
7537
7538 bson_init (&query);
7539 collection = mongoc_client_get_collection (client, "test", collection_name);
7540 cursor = mongoc_collection_find_with_opts (
7541 collection,
7542 &query,
7543 NULL, /* additional options */
7544 NULL); /* read prefs, NULL for default */
7545
7546 while (mongoc_cursor_next (cursor, &doc)) {
7547 str = bson_as_canonical_extended_json (doc, NULL);
7548 fprintf (stdout, "%s\n", str);
7549 bson_free (str);
7550 }
7551
7552 if (mongoc_cursor_error (cursor, &error)) {
7553 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7554 return EXIT_FAILURE;
7555 }
7556
7557 bson_destroy (&query);
7558 mongoc_cursor_destroy (cursor);
7559 mongoc_collection_destroy (collection);
7560 mongoc_uri_destroy (uri);
7561 mongoc_client_destroy (client);
7562 mongoc_cleanup ();
7563
7564 return EXIT_SUCCESS;
7565 }
7566
7567
7568 mongoc_database_t
7569 MongoDB Database Abstraction
7570
7571 Synopsis
7572 typedef struct _mongoc_database_t mongoc_database_t;
7573
7574 mongoc_database_t provides access to a MongoDB database. This handle is
7575 useful for actions a particular database object. It is not a container
7576 for mongoc_collection_t structures.
7577
7578 Read preferences and write concerns are inherited from the parent
7579 client. They can be overridden with mongoc_database_set_read_prefs()
7580 and mongoc_database_set_write_concern().
7581
7582 Examples
7583 #include <mongoc/mongoc.h>
7584
7585 int
7586 main (int argc, char *argv[])
7587 {
7588 mongoc_database_t *database;
7589 mongoc_client_t *client;
7590
7591 mongoc_init ();
7592
7593 client = mongoc_client_new ("mongodb://localhost/");
7594 database = mongoc_client_get_database (client, "test");
7595
7596 mongoc_database_destroy (database);
7597 mongoc_client_destroy (client);
7598
7599 mongoc_cleanup ();
7600
7601 return 0;
7602 }
7603
7604 mongoc_delete_flags_t
7605 Flags for deletion operations
7606
7607 Synopsis
7608 typedef enum {
7609 MONGOC_DELETE_NONE = 0,
7610 MONGOC_DELETE_SINGLE_REMOVE = 1 << 0,
7611 } mongoc_delete_flags_t;
7612
7613 Deprecated
7614 WARNING:
7615 These flags are deprecated and should not be used in new code.
7616
7617 Please use mongoc_collection_delete_one() or mongoc_collec‐
7618 tion_delete_many() instead.
7619
7620 mongoc_find_and_modify_opts_t
7621 find_and_modify abstraction
7622
7623 Synopsis
7624 mongoc_find_and_modify_opts_t is a builder interface to construct a
7625 find_and_modify command.
7626
7627 It was created to be able to accommodate new arguments to the MongoDB
7628 find_and_modify command.
7629
7630 As of MongoDB 3.2, the mongoc_write_concern_t specified on the mon‐
7631 goc_collection_t will be used, if any.
7632
7633 Example
7634 flags.c
7635
7636 void
7637 fam_flags (mongoc_collection_t *collection)
7638 {
7639 mongoc_find_and_modify_opts_t *opts;
7640 bson_t reply;
7641 bson_error_t error;
7642 bson_t query = BSON_INITIALIZER;
7643 bson_t *update;
7644 bool success;
7645
7646
7647 /* Find Zlatan Ibrahimovic, the striker */
7648 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7649 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7650 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7651 BSON_APPEND_INT32 (&query, "age", 34);
7652 BSON_APPEND_INT32 (
7653 &query, "goals", (16 + 35 + 23 + 57 + 16 + 14 + 28 + 84) + (1 + 6 + 62));
7654
7655 /* Add his football position */
7656 update = BCON_NEW ("$set", "{", "position", BCON_UTF8 ("striker"), "}");
7657
7658 opts = mongoc_find_and_modify_opts_new ();
7659
7660 mongoc_find_and_modify_opts_set_update (opts, update);
7661
7662 /* Create the document if it didn't exist, and return the updated document */
7663 mongoc_find_and_modify_opts_set_flags (
7664 opts, MONGOC_FIND_AND_MODIFY_UPSERT | MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7665
7666 success = mongoc_collection_find_and_modify_with_opts (
7667 collection, &query, opts, &reply, &error);
7668
7669 if (success) {
7670 char *str;
7671
7672 str = bson_as_canonical_extended_json (&reply, NULL);
7673 printf ("%s\n", str);
7674 bson_free (str);
7675 } else {
7676 fprintf (
7677 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7678 }
7679
7680 bson_destroy (&reply);
7681 bson_destroy (update);
7682 bson_destroy (&query);
7683 mongoc_find_and_modify_opts_destroy (opts);
7684 }
7685
7686
7687 bypass.c
7688
7689 void
7690 fam_bypass (mongoc_collection_t *collection)
7691 {
7692 mongoc_find_and_modify_opts_t *opts;
7693 bson_t reply;
7694 bson_t *update;
7695 bson_error_t error;
7696 bson_t query = BSON_INITIALIZER;
7697 bool success;
7698
7699
7700 /* Find Zlatan Ibrahimovic, the striker */
7701 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7702 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7703 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7704
7705 /* Bump his age */
7706 update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}");
7707
7708 opts = mongoc_find_and_modify_opts_new ();
7709 mongoc_find_and_modify_opts_set_update (opts, update);
7710 /* He can still play, even though he is pretty old. */
7711 mongoc_find_and_modify_opts_set_bypass_document_validation (opts, true);
7712
7713 success = mongoc_collection_find_and_modify_with_opts (
7714 collection, &query, opts, &reply, &error);
7715
7716 if (success) {
7717 char *str;
7718
7719 str = bson_as_canonical_extended_json (&reply, NULL);
7720 printf ("%s\n", str);
7721 bson_free (str);
7722 } else {
7723 fprintf (
7724 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7725 }
7726
7727 bson_destroy (&reply);
7728 bson_destroy (update);
7729 bson_destroy (&query);
7730 mongoc_find_and_modify_opts_destroy (opts);
7731 }
7732
7733
7734 update.c
7735
7736 void
7737 fam_update (mongoc_collection_t *collection)
7738 {
7739 mongoc_find_and_modify_opts_t *opts;
7740 bson_t *update;
7741 bson_t reply;
7742 bson_error_t error;
7743 bson_t query = BSON_INITIALIZER;
7744 bool success;
7745
7746
7747 /* Find Zlatan Ibrahimovic */
7748 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7749 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7750
7751 /* Make him a book author */
7752 update = BCON_NEW ("$set", "{", "author", BCON_BOOL (true), "}");
7753
7754 opts = mongoc_find_and_modify_opts_new ();
7755 /* Note that the document returned is the _previous_ version of the document
7756 * To fetch the modified new version, use
7757 * mongoc_find_and_modify_opts_set_flags (opts,
7758 * MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7759 */
7760 mongoc_find_and_modify_opts_set_update (opts, update);
7761
7762 success = mongoc_collection_find_and_modify_with_opts (
7763 collection, &query, opts, &reply, &error);
7764
7765 if (success) {
7766 char *str;
7767
7768 str = bson_as_canonical_extended_json (&reply, NULL);
7769 printf ("%s\n", str);
7770 bson_free (str);
7771 } else {
7772 fprintf (
7773 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7774 }
7775
7776 bson_destroy (&reply);
7777 bson_destroy (update);
7778 bson_destroy (&query);
7779 mongoc_find_and_modify_opts_destroy (opts);
7780 }
7781
7782
7783 fields.c
7784
7785 void
7786 fam_fields (mongoc_collection_t *collection)
7787 {
7788 mongoc_find_and_modify_opts_t *opts;
7789 bson_t fields = BSON_INITIALIZER;
7790 bson_t *update;
7791 bson_t reply;
7792 bson_error_t error;
7793 bson_t query = BSON_INITIALIZER;
7794 bool success;
7795
7796
7797 /* Find Zlatan Ibrahimovic */
7798 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7799 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7800
7801 /* Return his goal tally */
7802 BSON_APPEND_INT32 (&fields, "goals", 1);
7803
7804 /* Bump his goal tally */
7805 update = BCON_NEW ("$inc", "{", "goals", BCON_INT32 (1), "}");
7806
7807 opts = mongoc_find_and_modify_opts_new ();
7808 mongoc_find_and_modify_opts_set_update (opts, update);
7809 mongoc_find_and_modify_opts_set_fields (opts, &fields);
7810 /* Return the new tally */
7811 mongoc_find_and_modify_opts_set_flags (opts,
7812 MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7813
7814 success = mongoc_collection_find_and_modify_with_opts (
7815 collection, &query, opts, &reply, &error);
7816
7817 if (success) {
7818 char *str;
7819
7820 str = bson_as_canonical_extended_json (&reply, NULL);
7821 printf ("%s\n", str);
7822 bson_free (str);
7823 } else {
7824 fprintf (
7825 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7826 }
7827
7828 bson_destroy (&reply);
7829 bson_destroy (update);
7830 bson_destroy (&fields);
7831 bson_destroy (&query);
7832 mongoc_find_and_modify_opts_destroy (opts);
7833 }
7834
7835
7836 sort.c
7837
7838 void
7839 fam_sort (mongoc_collection_t *collection)
7840 {
7841 mongoc_find_and_modify_opts_t *opts;
7842 bson_t *update;
7843 bson_t sort = BSON_INITIALIZER;
7844 bson_t reply;
7845 bson_error_t error;
7846 bson_t query = BSON_INITIALIZER;
7847 bool success;
7848
7849
7850 /* Find all users with the lastname Ibrahimovic */
7851 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7852
7853 /* Sort by age (descending) */
7854 BSON_APPEND_INT32 (&sort, "age", -1);
7855
7856 /* Bump his goal tally */
7857 update = BCON_NEW ("$set", "{", "oldest", BCON_BOOL (true), "}");
7858
7859 opts = mongoc_find_and_modify_opts_new ();
7860 mongoc_find_and_modify_opts_set_update (opts, update);
7861 mongoc_find_and_modify_opts_set_sort (opts, &sort);
7862
7863 success = mongoc_collection_find_and_modify_with_opts (
7864 collection, &query, opts, &reply, &error);
7865
7866 if (success) {
7867 char *str;
7868
7869 str = bson_as_canonical_extended_json (&reply, NULL);
7870 printf ("%s\n", str);
7871 bson_free (str);
7872 } else {
7873 fprintf (
7874 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7875 }
7876
7877 bson_destroy (&reply);
7878 bson_destroy (update);
7879 bson_destroy (&sort);
7880 bson_destroy (&query);
7881 mongoc_find_and_modify_opts_destroy (opts);
7882 }
7883
7884
7885 opts.c
7886
7887 void
7888 fam_opts (mongoc_collection_t *collection)
7889 {
7890 mongoc_find_and_modify_opts_t *opts;
7891 bson_t reply;
7892 bson_t *update;
7893 bson_error_t error;
7894 bson_t query = BSON_INITIALIZER;
7895 mongoc_write_concern_t *wc;
7896 bson_t extra = BSON_INITIALIZER;
7897 bool success;
7898
7899
7900 /* Find Zlatan Ibrahimovic, the striker */
7901 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7902 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7903 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7904
7905 /* Bump his age */
7906 update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}");
7907
7908 opts = mongoc_find_and_modify_opts_new ();
7909 mongoc_find_and_modify_opts_set_update (opts, update);
7910
7911 /* Abort if the operation takes too long. */
7912 mongoc_find_and_modify_opts_set_max_time_ms (opts, 100);
7913
7914 /* Set write concern w: 2 */
7915 wc = mongoc_write_concern_new ();
7916 mongoc_write_concern_set_w (wc, 2);
7917 mongoc_write_concern_append (wc, &extra);
7918
7919 /* Some future findAndModify option the driver doesn't support conveniently
7920 */
7921 BSON_APPEND_INT32 (&extra, "futureOption", 42);
7922 mongoc_find_and_modify_opts_append (opts, &extra);
7923
7924 success = mongoc_collection_find_and_modify_with_opts (
7925 collection, &query, opts, &reply, &error);
7926
7927 if (success) {
7928 char *str;
7929
7930 str = bson_as_canonical_extended_json (&reply, NULL);
7931 printf ("%s\n", str);
7932 bson_free (str);
7933 } else {
7934 fprintf (
7935 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7936 }
7937
7938 bson_destroy (&reply);
7939 bson_destroy (&extra);
7940 bson_destroy (update);
7941 bson_destroy (&query);
7942 mongoc_write_concern_destroy (wc);
7943 mongoc_find_and_modify_opts_destroy (opts);
7944 }
7945
7946
7947 fam.c
7948
7949 int
7950 main (void)
7951 {
7952 mongoc_collection_t *collection;
7953 mongoc_database_t *database;
7954 mongoc_client_t *client;
7955 const char *uri_string =
7956 "mongodb://localhost:27017/admin?appname=find-and-modify-opts-example";
7957 mongoc_uri_t *uri;
7958 bson_error_t error;
7959 bson_t *options;
7960
7961 mongoc_init ();
7962
7963 uri = mongoc_uri_new_with_error (uri_string, &error);
7964 if (!uri) {
7965 fprintf (stderr,
7966 "failed to parse URI: %s\n"
7967 "error message: %s\n",
7968 uri_string,
7969 error.message);
7970 return EXIT_FAILURE;
7971 }
7972
7973 client = mongoc_client_new_from_uri (uri);
7974 if (!client) {
7975 return EXIT_FAILURE;
7976 }
7977
7978 mongoc_client_set_error_api (client, 2);
7979 database = mongoc_client_get_database (client, "databaseName");
7980
7981 options = BCON_NEW ("validator",
7982 "{",
7983 "age",
7984 "{",
7985 "$lte",
7986 BCON_INT32 (34),
7987 "}",
7988 "}",
7989 "validationAction",
7990 BCON_UTF8 ("error"),
7991 "validationLevel",
7992 BCON_UTF8 ("moderate"));
7993
7994 collection = mongoc_database_create_collection (
7995 database, "collectionName", options, &error);
7996 if (!collection) {
7997 fprintf (
7998 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7999 return EXIT_FAILURE;
8000 }
8001
8002 fam_flags (collection);
8003 fam_bypass (collection);
8004 fam_update (collection);
8005 fam_fields (collection);
8006 fam_opts (collection);
8007 fam_sort (collection);
8008
8009 mongoc_collection_drop (collection, NULL);
8010 bson_destroy (options);
8011 mongoc_uri_destroy (uri);
8012 mongoc_database_destroy (database);
8013 mongoc_collection_destroy (collection);
8014 mongoc_client_destroy (client);
8015
8016 mongoc_cleanup ();
8017 return EXIT_SUCCESS;
8018 }
8019
8020
8021 Outputs:
8022
8023 {
8024 "lastErrorObject": {
8025 "updatedExisting": false,
8026 "n": 1,
8027 "upserted": {
8028 "$oid": "56562a99d13e6d86239c7b00"
8029 }
8030 },
8031 "value": {
8032 "_id": {
8033 "$oid": "56562a99d13e6d86239c7b00"
8034 },
8035 "age": 34,
8036 "firstname": "Zlatan",
8037 "goals": 342,
8038 "lastname": "Ibrahimovic",
8039 "profession": "Football player",
8040 "position": "striker"
8041 },
8042 "ok": 1
8043 }
8044 {
8045 "lastErrorObject": {
8046 "updatedExisting": true,
8047 "n": 1
8048 },
8049 "value": {
8050 "_id": {
8051 "$oid": "56562a99d13e6d86239c7b00"
8052 },
8053 "age": 34,
8054 "firstname": "Zlatan",
8055 "goals": 342,
8056 "lastname": "Ibrahimovic",
8057 "profession": "Football player",
8058 "position": "striker"
8059 },
8060 "ok": 1
8061 }
8062 {
8063 "lastErrorObject": {
8064 "updatedExisting": true,
8065 "n": 1
8066 },
8067 "value": {
8068 "_id": {
8069 "$oid": "56562a99d13e6d86239c7b00"
8070 },
8071 "age": 35,
8072 "firstname": "Zlatan",
8073 "goals": 342,
8074 "lastname": "Ibrahimovic",
8075 "profession": "Football player",
8076 "position": "striker"
8077 },
8078 "ok": 1
8079 }
8080 {
8081 "lastErrorObject": {
8082 "updatedExisting": true,
8083 "n": 1
8084 },
8085 "value": {
8086 "_id": {
8087 "$oid": "56562a99d13e6d86239c7b00"
8088 },
8089 "goals": 343
8090 },
8091 "ok": 1
8092 }
8093 {
8094 "lastErrorObject": {
8095 "updatedExisting": true,
8096 "n": 1
8097 },
8098 "value": {
8099 "_id": {
8100 "$oid": "56562a99d13e6d86239c7b00"
8101 },
8102 "age": 35,
8103 "firstname": "Zlatan",
8104 "goals": 343,
8105 "lastname": "Ibrahimovic",
8106 "profession": "Football player",
8107 "position": "striker",
8108 "author": true
8109 },
8110 "ok": 1
8111 }
8112
8113 mongoc_gridfs_file_list_t
8114 Synopsis
8115 #include <mongoc/mongoc.h>
8116
8117 typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t;
8118
8119 Description
8120 mongoc_gridfs_file_list_t provides a gridfs file list abstraction. It
8121 provides iteration and basic marshalling on top of a regular mon‐
8122 goc_collection_find_with_opts() style query. In interface, it's styled
8123 after mongoc_cursor_t.
8124
8125 Example
8126 mongoc_gridfs_file_list_t *list;
8127 mongoc_gridfs_file_t *file;
8128
8129 list = mongoc_gridfs_find (gridfs, query);
8130
8131 while ((file = mongoc_gridfs_file_list_next (list))) {
8132 do_something (file);
8133
8134 mongoc_gridfs_file_destroy (file);
8135 }
8136
8137 mongoc_gridfs_file_list_destroy (list);
8138
8139 mongoc_gridfs_file_opt_t
8140 Synopsis
8141 typedef struct {
8142 const char *md5;
8143 const char *filename;
8144 const char *content_type;
8145 const bson_t *aliases;
8146 const bson_t *metadata;
8147 uint32_t chunk_size;
8148 } mongoc_gridfs_file_opt_t;
8149
8150 Description
8151 This structure contains options that can be set on a mon‐
8152 goc_gridfs_file_t. It can be used by various functions when creating a
8153 new gridfs file.
8154
8155 mongoc_gridfs_file_t
8156 Synopsis
8157 typedef struct _mongoc_gridfs_file_t mongoc_gridfs_file_t;
8158
8159 Description
8160 This structure provides a MongoDB GridFS file abstraction. It provides
8161 several APIs.
8162
8163 • readv, writev, seek, and tell.
8164
8165 • General file metadata such as filename and length.
8166
8167 • GridFS metadata such as md5, filename, content_type, aliases, meta‐
8168 data, chunk_size, and upload_date.
8169
8170 Thread Safety
8171 This structure is NOT thread-safe and should only be used from one
8172 thread at a time.
8173
8174 Related
8175 • mongoc_client_t
8176
8177 • mongoc_gridfs_t
8178
8179 • mongoc_gridfs_file_list_t
8180
8181 • mongoc_gridfs_file_opt_t
8182
8183 mongoc_gridfs_bucket_t
8184 Synopsis
8185 #include <mongoc/mongoc.h>
8186
8187 typedef struct _mongoc_gridfs_bucket_t mongoc_gridfs_bucket_t;
8188
8189 Description
8190 mongoc_gridfs_bucket_t provides a spec-compliant MongoDB GridFS imple‐
8191 mentation, superseding mongoc_gridfs_t. See the GridFS MongoDB documen‐
8192 tation.
8193
8194 Thread Safety
8195 mongoc_gridfs_bucket_t is NOT thread-safe and should only be used in
8196 the same thread as the owning mongoc_client_t.
8197
8198 Lifecycle
8199 It is an error to free a mongoc_gridfs_bucket_t before freeing all de‐
8200 rived instances of mongoc_stream_t. The owning mongoc_client_t must
8201 outlive the mongoc_gridfs_bucket_t.
8202
8203 Example
8204 example-gridfs-bucket.c
8205
8206 #include <stdio.h>
8207 #include <stdlib.h>
8208
8209 #include <mongoc/mongoc.h>
8210
8211 int
8212 main (int argc, char *argv[])
8213 {
8214 const char *uri_string =
8215 "mongodb://localhost:27017/?appname=new-gridfs-example";
8216 mongoc_client_t *client;
8217 mongoc_database_t *db;
8218 mongoc_stream_t *file_stream;
8219 mongoc_gridfs_bucket_t *bucket;
8220 mongoc_cursor_t *cursor;
8221 bson_t filter;
8222 bool res;
8223 bson_value_t file_id;
8224 bson_error_t error;
8225 const bson_t *doc;
8226 char *str;
8227 mongoc_init ();
8228
8229 if (argc != 3) {
8230 fprintf (stderr, "usage: %s SOURCE_FILE_PATH FILE_COPY_PATH\n", argv[0]);
8231 return EXIT_FAILURE;
8232 }
8233
8234 /* 1. Make a bucket. */
8235 client = mongoc_client_new (uri_string);
8236 db = mongoc_client_get_database (client, "test");
8237 bucket = mongoc_gridfs_bucket_new (db, NULL, NULL, &error);
8238 if (!bucket) {
8239 printf ("Error creating gridfs bucket: %s\n", error.message);
8240 return EXIT_FAILURE;
8241 }
8242
8243 /* 2. Insert a file. */
8244 file_stream = mongoc_stream_file_new_for_path (argv[1], O_RDONLY, 0);
8245 res = mongoc_gridfs_bucket_upload_from_stream (
8246 bucket, "my-file", file_stream, NULL, &file_id, &error);
8247 if (!res) {
8248 printf ("Error uploading file: %s\n", error.message);
8249 return EXIT_FAILURE;
8250 }
8251
8252 mongoc_stream_close (file_stream);
8253 mongoc_stream_destroy (file_stream);
8254
8255 /* 3. Download the file in GridFS to a local file. */
8256 file_stream = mongoc_stream_file_new_for_path (argv[2], O_CREAT | O_RDWR, 0);
8257 if (!file_stream) {
8258 perror ("Error opening file stream");
8259 return EXIT_FAILURE;
8260 }
8261
8262 res = mongoc_gridfs_bucket_download_to_stream (
8263 bucket, &file_id, file_stream, &error);
8264 if (!res) {
8265 printf ("Error downloading file to stream: %s\n", error.message);
8266 return EXIT_FAILURE;
8267 }
8268 mongoc_stream_close (file_stream);
8269 mongoc_stream_destroy (file_stream);
8270
8271 /* 4. List what files are available in GridFS. */
8272 bson_init (&filter);
8273 cursor = mongoc_gridfs_bucket_find (bucket, &filter, NULL);
8274
8275 while (mongoc_cursor_next (cursor, &doc)) {
8276 str = bson_as_canonical_extended_json (doc, NULL);
8277 printf ("%s\n", str);
8278 bson_free (str);
8279 }
8280
8281 /* 5. Delete the file that we added. */
8282 res = mongoc_gridfs_bucket_delete_by_id (bucket, &file_id, &error);
8283 if (!res) {
8284 printf ("Error deleting the file: %s\n", error.message);
8285 return EXIT_FAILURE;
8286 }
8287
8288 /* 6. Cleanup. */
8289 mongoc_stream_close (file_stream);
8290 mongoc_stream_destroy (file_stream);
8291 mongoc_cursor_destroy (cursor);
8292 bson_destroy (&filter);
8293 mongoc_gridfs_bucket_destroy (bucket);
8294 mongoc_database_destroy (db);
8295 mongoc_client_destroy (client);
8296 mongoc_cleanup ();
8297
8298 return EXIT_SUCCESS;
8299 }
8300
8301
8302 SEE ALSO:
8303 The MongoDB GridFS specification.
8304
8305 The non spec-compliant mongoc_gridfs_t.
8306
8307
8308 mongoc_gridfs_t
8309 WARNING:
8310 This GridFS implementation does not conform to the MongoDB GridFS
8311 specification. For a spec compliant implementation, use mon‐
8312 goc_gridfs_bucket_t.
8313
8314 Synopsis
8315 #include <mongoc/mongoc.h>
8316
8317 typedef struct _mongoc_gridfs_t mongoc_gridfs_t;
8318
8319 Description
8320 mongoc_gridfs_t provides a MongoDB gridfs implementation. The system as
8321 a whole is made up of gridfs objects, which contain gridfs_files and
8322 gridfs_file_lists. Essentially, a basic file system API.
8323
8324 There are extensive caveats about the kind of use cases gridfs is prac‐
8325 tical for. In particular, any writing after initial file creation is
8326 likely to both break any concurrent readers and be quite expensive.
8327 That said, this implementation does allow for arbitrary writes to ex‐
8328 isting gridfs object, just use them with caution.
8329
8330 mongoc_gridfs also integrates tightly with the mongoc_stream_t abstrac‐
8331 tion, which provides some convenient wrapping for file creation and
8332 reading/writing. It can be used without, but its worth looking to see
8333 if your problem can fit that model.
8334
8335 WARNING:
8336 mongoc_gridfs_t does not support read preferences. In a replica set,
8337 GridFS queries are always routed to the primary.
8338
8339 Thread Safety
8340 mongoc_gridfs_t is NOT thread-safe and should only be used in the same
8341 thread as the owning mongoc_client_t.
8342
8343 Lifecycle
8344 It is an error to free a mongoc_gridfs_t before freeing all related in‐
8345 stances of mongoc_gridfs_file_t and mongoc_gridfs_file_list_t.
8346
8347 Example
8348 example-gridfs.c
8349
8350 #include <assert.h>
8351 #include <mongoc/mongoc.h>
8352 #include <stdio.h>
8353 #include <stdlib.h>
8354 #include <fcntl.h>
8355
8356 int
8357 main (int argc, char *argv[])
8358 {
8359 mongoc_gridfs_t *gridfs;
8360 mongoc_gridfs_file_t *file;
8361 mongoc_gridfs_file_list_t *list;
8362 mongoc_gridfs_file_opt_t opt = {0};
8363 mongoc_client_t *client;
8364 const char *uri_string = "mongodb://127.0.0.1:27017/?appname=gridfs-example";
8365 mongoc_uri_t *uri;
8366 mongoc_stream_t *stream;
8367 bson_t filter;
8368 bson_t opts;
8369 bson_t child;
8370 bson_error_t error;
8371 ssize_t r;
8372 char buf[4096];
8373 mongoc_iovec_t iov;
8374 const char *filename;
8375 const char *command;
8376 bson_value_t id;
8377
8378 if (argc < 2) {
8379 fprintf (stderr, "usage - %s command ...\n", argv[0]);
8380 return EXIT_FAILURE;
8381 }
8382
8383 mongoc_init ();
8384
8385 iov.iov_base = (void *) buf;
8386 iov.iov_len = sizeof buf;
8387
8388 /* connect to localhost client */
8389 uri = mongoc_uri_new_with_error (uri_string, &error);
8390 if (!uri) {
8391 fprintf (stderr,
8392 "failed to parse URI: %s\n"
8393 "error message: %s\n",
8394 uri_string,
8395 error.message);
8396 return EXIT_FAILURE;
8397 }
8398
8399 client = mongoc_client_new_from_uri (uri);
8400 assert (client);
8401 mongoc_client_set_error_api (client, 2);
8402
8403 /* grab a gridfs handle in test prefixed by fs */
8404 gridfs = mongoc_client_get_gridfs (client, "test", "fs", &error);
8405 assert (gridfs);
8406
8407 command = argv[1];
8408 filename = argv[2];
8409
8410 if (strcmp (command, "read") == 0) {
8411 if (argc != 3) {
8412 fprintf (stderr, "usage - %s read filename\n", argv[0]);
8413 return EXIT_FAILURE;
8414 }
8415 file = mongoc_gridfs_find_one_by_filename (gridfs, filename, &error);
8416 assert (file);
8417
8418 stream = mongoc_stream_gridfs_new (file);
8419 assert (stream);
8420
8421 for (;;) {
8422 r = mongoc_stream_readv (stream, &iov, 1, -1, 0);
8423
8424 assert (r >= 0);
8425
8426 if (r == 0) {
8427 break;
8428 }
8429
8430 if (fwrite (iov.iov_base, 1, r, stdout) != r) {
8431 MONGOC_ERROR ("Failed to write to stdout. Exiting.\n");
8432 exit (1);
8433 }
8434 }
8435
8436 mongoc_stream_destroy (stream);
8437 mongoc_gridfs_file_destroy (file);
8438 } else if (strcmp (command, "list") == 0) {
8439 bson_init (&filter);
8440
8441 bson_init (&opts);
8442 bson_append_document_begin (&opts, "sort", -1, &child);
8443 BSON_APPEND_INT32 (&child, "filename", 1);
8444 bson_append_document_end (&opts, &child);
8445
8446 list = mongoc_gridfs_find_with_opts (gridfs, &filter, &opts);
8447
8448 bson_destroy (&filter);
8449 bson_destroy (&opts);
8450
8451 while ((file = mongoc_gridfs_file_list_next (list))) {
8452 const char *name = mongoc_gridfs_file_get_filename (file);
8453 printf ("%s\n", name ? name : "?");
8454
8455 mongoc_gridfs_file_destroy (file);
8456 }
8457
8458 mongoc_gridfs_file_list_destroy (list);
8459 } else if (strcmp (command, "write") == 0) {
8460 if (argc != 4) {
8461 fprintf (stderr, "usage - %s write filename input_file\n", argv[0]);
8462 return EXIT_FAILURE;
8463 }
8464
8465 stream = mongoc_stream_file_new_for_path (argv[3], O_RDONLY, 0);
8466 assert (stream);
8467
8468 opt.filename = filename;
8469
8470 /* the driver generates a file_id for you */
8471 file = mongoc_gridfs_create_file_from_stream (gridfs, stream, &opt);
8472 assert (file);
8473
8474 id.value_type = BSON_TYPE_INT32;
8475 id.value.v_int32 = 1;
8476
8477 /* optional: the following method specifies a file_id of any
8478 BSON type */
8479 if (!mongoc_gridfs_file_set_id (file, &id, &error)) {
8480 fprintf (stderr, "%s\n", error.message);
8481 return EXIT_FAILURE;
8482 }
8483
8484 if (!mongoc_gridfs_file_save (file)) {
8485 mongoc_gridfs_file_error (file, &error);
8486 fprintf (stderr, "Could not save: %s\n", error.message);
8487 return EXIT_FAILURE;
8488 }
8489
8490 mongoc_gridfs_file_destroy (file);
8491 } else {
8492 fprintf (stderr, "Unknown command");
8493 return EXIT_FAILURE;
8494 }
8495
8496 mongoc_gridfs_destroy (gridfs);
8497 mongoc_uri_destroy (uri);
8498 mongoc_client_destroy (client);
8499
8500 mongoc_cleanup ();
8501
8502 return EXIT_SUCCESS;
8503 }
8504
8505
8506 SEE ALSO:
8507 The MongoDB GridFS specification.
8508
8509 The spec-compliant mongoc_gridfs_bucket_t.
8510
8511
8512 mongoc_host_list_t
8513 Synopsis
8514 typedef struct {
8515 mongoc_host_list_t *next;
8516 char host[BSON_HOST_NAME_MAX + 1];
8517 char host_and_port[BSON_HOST_NAME_MAX + 7];
8518 uint16_t port;
8519 int family;
8520 void *padding[4];
8521 } mongoc_host_list_t;
8522
8523 Description
8524 The host and port of a MongoDB server. Can be part of a linked list:
8525 for example the return value of mongoc_uri_get_hosts when multiple
8526 hosts are provided in the MongoDB URI.
8527
8528 SEE ALSO:
8529 mongoc_uri_get_hosts and mongoc_cursor_get_host.
8530
8531
8532 mongoc_index_opt_geo_t
8533 Synopsis
8534 #include <mongoc/mongoc.h>
8535
8536 typedef struct {
8537 uint8_t twod_sphere_version;
8538 uint8_t twod_bits_precision;
8539 double twod_location_min;
8540 double twod_location_max;
8541 double haystack_bucket_size;
8542 uint8_t *padding[32];
8543 } mongoc_index_opt_geo_t;
8544
8545 Description
8546 This structure contains the options that may be used for tuning a GEO
8547 index.
8548
8549 SEE ALSO:
8550 mongoc_index_opt_t
8551
8552 mongoc_index_opt_wt_t
8553
8554
8555 mongoc_index_opt_t
8556 Synopsis
8557 #include <mongoc/mongoc.h>
8558
8559 typedef struct {
8560 bool is_initialized;
8561 bool background;
8562 bool unique;
8563 const char *name;
8564 bool drop_dups;
8565 bool sparse;
8566 int32_t expire_after_seconds;
8567 int32_t v;
8568 const bson_t *weights;
8569 const char *default_language;
8570 const char *language_override;
8571 mongoc_index_opt_geo_t *geo_options;
8572 mongoc_index_opt_storage_t *storage_options;
8573 const bson_t *partial_filter_expression;
8574 const bson_t *collation;
8575 void *padding[4];
8576 } mongoc_index_opt_t;
8577
8578 Deprecated
8579 This structure is deprecated and should not be used in new code. See
8580 create-indexes.
8581
8582 Description
8583 This structure contains the options that may be used for tuning a spe‐
8584 cific index.
8585
8586 See the createIndexes documentations in the MongoDB manual for descrip‐
8587 tions of individual options.
8588
8589 NOTE:
8590 dropDups is deprecated as of MongoDB version 3.0.0. This option is
8591 silently ignored by the server and unique index builds using this
8592 option will fail if a duplicate value is detected.
8593
8594 Example
8595 {
8596 bson_t keys;
8597 bson_error_t error;
8598 mongoc_index_opt_t opt;
8599 mongoc_index_opt_geo_t geo_opt;
8600
8601 mongoc_index_opt_init (&opt);
8602 mongoc_index_opt_geo_init (&geo_opt);
8603
8604 bson_init (&keys);
8605 BSON_APPEND_UTF8 (&keys, "location", "2d");
8606
8607 geo_opt.twod_location_min = -123;
8608 geo_opt.twod_location_max = +123;
8609 geo_opt.twod_bits_precision = 30;
8610 opt.geo_options = &geo_opt;
8611
8612 collection = mongoc_client_get_collection (client, "test", "geo_test");
8613 if (mongoc_collection_create_index (collection, &keys, &opt, &error)) {
8614 /* Successfully created the geo index */
8615 }
8616 bson_destroy (&keys);
8617 mongoc_collection_destroy (&collection);
8618 }
8619
8620 SEE ALSO:
8621 mongoc_index_opt_geo_t
8622
8623 mongoc_index_opt_wt_t
8624
8625
8626 mongoc_index_opt_wt_t
8627 Synopsis
8628 #include <mongoc/mongoc.h>
8629
8630 typedef struct {
8631 mongoc_index_opt_storage_t base;
8632 const char *config_str;
8633 void *padding[8];
8634 } mongoc_index_opt_wt_t;
8635
8636 Description
8637 This structure contains the options that may be used for tuning a
8638 WiredTiger specific index.
8639
8640 SEE ALSO:
8641 mongoc_index_opt_t
8642
8643 mongoc_index_opt_geo_t
8644
8645
8646 mongoc_insert_flags_t
8647 Flags for insert operations
8648
8649 Synopsis
8650 typedef enum {
8651 MONGOC_INSERT_NONE = 0,
8652 MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0,
8653 } mongoc_insert_flags_t;
8654
8655 #define MONGOC_INSERT_NO_VALIDATE (1U << 31)
8656
8657 Description
8658 These flags correspond to the MongoDB wire protocol. They may be bit‐
8659 wise or'd together. They may modify how an insert happens on the Mon‐
8660 goDB server.
8661
8662 Flag Values
8663 ┌──────────────────────────┬────────────────────────────┐
8664 │MONGOC_INSERT_NONE │ Specify no insert flags. │
8665 ├──────────────────────────┼────────────────────────────┤
8666 │MONGOC_INSERT_CON‐ │ Continue inserting docu‐ │
8667 │TINUE_ON_ERROR │ ments from the insertion │
8668 │ │ set even if one insert │
8669 │ │ fails. │
8670 └──────────────────────────┴────────────────────────────┘
8671
8672
8673
8674
8675 │MONGOC_INSERT_NO_VALIDATE │ Do not validate insertion │
8676 │ │ documents before perform‐ │
8677 │ │ ing an insert. Validation │
8678 │ │ can be expensive, so this │
8679 │ │ can save some time if you │
8680 │ │ know your documents are │
8681 │ │ already valid. │
8682 └──────────────────────────┴────────────────────────────┘
8683
8684 mongoc_iovec_t
8685 Synopsis
8686 Synopsis
8687 #include <mongoc/mongoc.h>
8688
8689 #ifdef _WIN32
8690 typedef struct {
8691 u_long iov_len;
8692 char *iov_base;
8693 } mongoc_iovec_t;
8694 #else
8695 typedef struct iovec mongoc_iovec_t;
8696 #endif
8697
8698 The mongoc_iovec_t structure is a portability abstraction for consumers
8699 of the mongoc_stream_t interfaces. It allows for scatter/gather I/O
8700 through the socket subsystem.
8701
8702 WARNING:
8703 When writing portable code, beware of the ordering of iov_len and
8704 iov_base as they are different on various platforms. Therefore, you
8705 should not use C initializers for initialization.
8706
8707 mongoc_matcher_t
8708 Client-side document matching abstraction
8709
8710 Synopsis
8711 typedef struct _mongoc_matcher_t mongoc_matcher_t;
8712
8713 mongoc_matcher_t provides a reduced-interface for client-side matching
8714 of BSON documents.
8715
8716 It can perform the basics such as $in, $nin, $eq, $neq, $gt, $gte, $lt,
8717 and $lte.
8718
8719 WARNING:
8720 mongoc_matcher_t does not currently support the full spectrum of
8721 query operations that the MongoDB server supports.
8722
8723 Deprecated
8724 WARNING:
8725 mongoc_matcher_t is deprecated and will be removed in version 2.0.
8726
8727 Example
8728 Filter a sequence of BSON documents from STDIN based on a query
8729
8730 #include <bson/bson.h>
8731 #include <mongoc/mongoc.h>
8732 #include <stdio.h>
8733
8734 int
8735 main (int argc, char *argv[])
8736 {
8737 mongoc_matcher_t *matcher;
8738 bson_reader_t *reader;
8739 const bson_t *bson;
8740 bson_t *spec;
8741 char *str;
8742 int fd;
8743
8744 mongoc_init ();
8745
8746 #ifdef _WIN32
8747 fd = fileno (stdin);
8748 #else
8749 fd = STDIN_FILENO;
8750 #endif
8751
8752 reader = bson_reader_new_from_fd (fd, false);
8753
8754 spec = BCON_NEW ("hello", "world");
8755 matcher = mongoc_matcher_new (spec, NULL);
8756
8757 while ((bson = bson_reader_read (reader, NULL))) {
8758 if (mongoc_matcher_match (matcher, bson)) {
8759 str = bson_as_canonical_extended_json (bson, NULL);
8760 printf ("%s\n", str);
8761 bson_free (str);
8762 }
8763 }
8764
8765 bson_reader_destroy (reader);
8766 bson_destroy (spec);
8767
8768 mongoc_cleanup ();
8769
8770 return 0;
8771 }
8772
8773 mongoc_optional_t
8774 A struct to store optional boolean values.
8775
8776 Synopsis
8777 Used to specify optional boolean flags, which may remain unset.
8778
8779 This is used within mongoc_server_api_t to track whether a flag was ex‐
8780 plicitly set.
8781
8782 mongoc_query_flags_t
8783 Flags for query operations
8784
8785 Synopsis
8786 typedef enum {
8787 MONGOC_QUERY_NONE = 0,
8788 MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1,
8789 MONGOC_QUERY_SECONDARY_OK = 1 << 2,
8790 MONGOC_QUERY_OPLOG_REPLAY = 1 << 3,
8791 MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4,
8792 MONGOC_QUERY_AWAIT_DATA = 1 << 5,
8793 MONGOC_QUERY_EXHAUST = 1 << 6,
8794 MONGOC_QUERY_PARTIAL = 1 << 7,
8795 } mongoc_query_flags_t;
8796
8797 Description
8798 These flags correspond to the MongoDB wire protocol. They may be bit‐
8799 wise or'd together. They may modify how a query is performed in the
8800 MongoDB server.
8801
8802 Flag Values
8803 ┌───────────────────────────┬────────────────────────────┐
8804 │MONGOC_QUERY_NONE │ Specify no query flags. │
8805 ├───────────────────────────┼────────────────────────────┤
8806 │MONGOC_QUERY_TAILABLE_CUR‐ │ Cursor will not be closed │
8807 │SOR │ when the last data is re‐ │
8808 │ │ trieved. You can resume │
8809 │ │ this cursor later. │
8810 ├───────────────────────────┼────────────────────────────┤
8811 │MONGOC_QUERY_SECONDARY_OK │ Allow query of replica set │
8812 │ │ secondaries. │
8813 ├───────────────────────────┼────────────────────────────┤
8814 │MONGOC_QUERY_OPLOG_REPLAY │ Used internally by Mon‐ │
8815 │ │ goDB. │
8816 ├───────────────────────────┼────────────────────────────┤
8817 │MONGOC_QUERY_NO_CUR‐ │ The server normally times │
8818 │SOR_TIMEOUT │ out an idle cursor after │
8819 │ │ an inactivity period (10 │
8820 │ │ minutes). This prevents │
8821 │ │ that. │
8822 └───────────────────────────┴────────────────────────────┘
8823
8824
8825
8826
8827
8828
8829 │MONGOC_QUERY_AWAIT_DATA │ Use with MON‐ │
8830 │ │ GOC_QUERY_TAILABLE_CURSOR. │
8831 │ │ Block rather than return‐ │
8832 │ │ ing no data. After a pe‐ │
8833 │ │ riod, time out. │
8834 ├───────────────────────────┼────────────────────────────┤
8835 │MONGOC_QUERY_EXHAUST │ Stream the data down full │
8836 │ │ blast in multiple "reply" │
8837 │ │ packets. Faster when you │
8838 │ │ are pulling down a lot of │
8839 │ │ data and you know you want │
8840 │ │ to retrieve it all. Only │
8841 │ │ applies to cursors created │
8842 │ │ from a find operation │
8843 │ │ (i.e. mongoc_collec‐ │
8844 │ │ tion_find()). │
8845 ├───────────────────────────┼────────────────────────────┤
8846 │MONGOC_QUERY_PARTIAL │ Get partial results from │
8847 │ │ mongos if some shards are │
8848 │ │ down (instead of throwing │
8849 │ │ an error). │
8850 └───────────────────────────┴────────────────────────────┘
8851
8852 mongoc_rand
8853 MongoDB Random Number Generator
8854
8855 Synopsis
8856 void
8857 mongoc_rand_add (const void *buf, int num, double entropy);
8858
8859 void
8860 mongoc_rand_seed (const void *buf, int num);
8861
8862 int
8863 mongoc_rand_status (void);
8864
8865 Description
8866 The mongoc_rand family of functions provide access to the low level
8867 randomness primitives used by the MongoDB C Driver. In particular,
8868 they control the creation of cryptographically strong pseudo-random
8869 bytes required by some security mechanisms.
8870
8871 While we can usually pull enough entropy from the environment, you may
8872 be required to seed the PRNG manually depending on your OS, hardware
8873 and other entropy consumers running on the same system.
8874
8875 Entropy
8876 mongoc_rand_add and mongoc_rand_seed allow the user to directly provide
8877 entropy. They differ insofar as mongoc_rand_seed requires that each
8878 bit provided is fully random. mongoc_rand_add allows the user to spec‐
8879 ify the degree of randomness in the provided bytes as well.
8880
8881 Status
8882 The mongoc_rand_status function allows the user to check the status of
8883 the mongoc PRNG. This can be used to guarantee sufficient entropy at
8884 program startup, rather than waiting for runtime errors to occur.
8885
8886 mongoc_read_concern_t
8887 Read Concern abstraction
8888
8889 Synopsis
8890 New in MongoDB 3.2.
8891
8892 The mongoc_read_concern_t allows clients to choose a level of isolation
8893 for their reads. The default, MONGOC_READ_CONCERN_LEVEL_LOCAL, is right
8894 for the great majority of applications.
8895
8896 You can specify a read concern on connection objects, database objects,
8897 or collection objects.
8898
8899 See readConcern on the MongoDB website for more information.
8900
8901 Read Concern is only sent to MongoDB when it has explicitly been set by
8902 mongoc_read_concern_set_level to anything other than NULL.
8903
8904 Read Concern Levels
8905 ──────────────────────────────────────────────────────────────────
8906 Macro Description First MongoDB ver‐
8907 sion
8908 ──────────────────────────────────────────────────────────────────
8909 MONGOC_READ_CON‐ Level "local", the 3.2
8910 CERN_LEVEL_LOCAL default.
8911 ──────────────────────────────────────────────────────────────────
8912 MONGOC_READ_CON‐ Level "majority". 3.2
8913 CERN_LEVEL_MAJORITY
8914 ──────────────────────────────────────────────────────────────────
8915 MONGOC_READ_CON‐ Level "lineariz‐ 3.4
8916 CERN_LEVEL_LIN‐ able".
8917 EARIZABLE
8918 ──────────────────────────────────────────────────────────────────
8919 MONGOC_READ_CON‐ Level "available". 3.6
8920 CERN_LEVEL_AVAIL‐
8921 ABLE
8922 ──────────────────────────────────────────────────────────────────
8923 MONGOC_READ_CON‐ Level "snapshot". 4.0
8924 CERN_LEVEL_SNAPSHOT
8925 ┌────────────────────┬─────────────────────┬─────────────────────┐
8926 │ │ │ │
8927 For│ the sake of comp│atibility with future │versions of MongoDB, m│on‐
8928 goc│_read_concern_set_lev│el allows any string, │not just this list │of
8929 kno│wn read concern level│s. │ │
8930 │ │ │ │
8931 See│ Read Concern Leve│ls in the MongoDB ma│nual for more informat│ion
8932 abo│ut the individual rea│d concern levels. │ │
8933 │ │ │ │
8934 mongoc_│read_mode_t │ │ │
8935 Rea│d Preference Modes │ │ │
8936 │ │ │ │
8937 Synopsi│s │ │ │
8938 │typedef enum { │ │ │
8939 │ MONGOC_READ_PRIMAR│Y = (1 << 0), │ │
8940 │ MONGOC_READ_SECOND│ARY = (1 << 1), │ │
8941 │ MONGOC_READ_PRIMAR│Y_PREFERRED = (1 << 2)│| MONGOC_READ_PRIMARY│,
8942 │ MONGOC_READ_SECOND│ARY_PREFERRED = (1 << │2) | MONGOC_READ_SECON│DARY,
8943 │ MONGOC_READ_NEARES│T = (1 << 3) | MONGOC_│READ_SECONDARY, │
8944 │} mongoc_read_mode_t;│ │ │
8945 │ │ │ │
8946 Descrip│tion │ │ │
8947 Thi│s enum describes how │reads should be dispat│ched. The default is M│ON‐
8948 GOC│_READ_PRIMARY. │ │ │
8949 │ │ │ │
8950 Ple│ase see the MongoDB w│ebsite for a descripti│on of Read Preferences│.
8951 │ │ │ │
8952 mongoc_│read_prefs_t │ │ │
8953 A r│ead preference abstra│ction │ │
8954 │ │ │ │
8955 Synopsi│s │ │ │
8956 mon│goc_read_prefs_t pro│vides an abstraction o│n top of the MongoDB c│on‐
8957 nec│tion read preferences│. It allows for hintin│g to the driver wh│ich
8958 nod│es in a replica set s│hould be accessed firs│t and how. │
8959 │ │ │ │
8960 You│ can specify a read │preference mode on con│nection objects, datab│ase
8961 obj│ects, collection obje│cts, or per-operation.│ Generally, it makes │the
8962 mos│t sense to stick wit│h the global default m│ode, MONGOC_READ_PRIMA│RY.
8963 All│of the other modes c│ome with caveats that │won't be covered in gr│eat
8964 det│ail here. │ │ │
8965 │ │ │ │
8966 Read Mo│des │ │ │
8967 │ ┌────────────────┼──────────┬──────────┼─────────────────┐ │
8968 │ │MONGOC_READ_PRIM│ARY │ Default │mode. All opera‐ │ │
8969 │ │ │ │ tions rea│d from the cur‐ │ │
8970 │ │ │ │ rent repl│ica set primary. │ │
8971 │ ├────────────────┼──────────┼──────────┼─────────────────┤ │
8972 │ │MONGOC_READ_SECO│NDARY │ All oper│ations read from │ │
8973 │ │ │ │ among th│e nearest sec‐ │ │
8974 │ │ │ │ ondary │members of the │ │
8975 │ │ │ │ replica s│et. │ │
8976 │ ├────────────────┼──────────┼──────────┼─────────────────┤ │
8977 │ │MONGOC_READ_PRIM│ARY_PRE‐ │ In most s│ituations, opera‐ │ │
8978 │ │FERRED │ │ tions rea│d from the pri‐ │ │
8979 │ │ │ │ mary but │if it is unavail‐ │ │
8980 │ │ │ │ able, ope│rations read from │ │
8981 │ │ │ │ secondary│members. │ │
8982 │ └────────────────┼──────────┴──────────┼─────────────────┘ │
8983 │ │ │ │
8984 │ │ │ │
8985
8986 │MONGOC_READ_SECONDARY_PRE‐ │ In most situations, opera‐ │
8987 │FERRED │ tions read from among the │
8988 │ │ nearest secondary members, │
8989 │ │ but if no secondaries are │
8990 │ │ available, operations read │
8991 │ │ from the primary. │
8992 ├───────────────────────────┼────────────────────────────┤
8993 │MONGOC_READ_NEAREST │ Operations read from among │
8994 │ │ the nearest members of the │
8995 │ │ replica set, irrespective │
8996 │ │ of the member's type. │
8997 └───────────────────────────┴────────────────────────────┘
8998
8999 Tag Sets
9000 Tag sets allow you to specify custom read preferences and write con‐
9001 cerns so that your application can target operations to specific mem‐
9002 bers.
9003
9004 Custom read preferences and write concerns evaluate tags sets in dif‐
9005 ferent ways: read preferences consider the value of a tag when select‐
9006 ing a member to read from, while write concerns ignore the value of a
9007 tag when selecting a member, except to consider whether or not the
9008 value is unique.
9009
9010 You can specify tag sets with the following read preference modes:
9011
9012 • primaryPreferred
9013
9014 • secondary
9015
9016 • secondaryPreferred
9017
9018 • nearest
9019
9020 Tags are not compatible with MONGOC_READ_PRIMARY and, in general, only
9021 apply when selecting a secondary member of a set for a read operation.
9022 However, the nearest read mode, when combined with a tag set, will se‐
9023 lect the nearest member that matches the specified tag set, which may
9024 be a primary or secondary.
9025
9026 Tag sets are represented as a comma-separated list of colon-separated
9027 key-value pairs when provided as a connection string, e.g.
9028 dc:ny,rack:1.
9029
9030 To specify a list of tag sets, using multiple readPreferenceTags, e.g.
9031
9032 readPreferenceTags=dc:ny,rack:1;readPreferenceTags=dc:ny;readPreferenceTags=
9033
9034 Note the empty value for the last one, which means "match any secondary
9035 as a last resort".
9036
9037 Order matters when using multiple readPreferenceTags.
9038
9039 Tag Sets can also be configured using mongoc_read_prefs_set_tags.
9040
9041 All interfaces use the same member selection logic to choose the member
9042 to which to direct read operations, basing the choice on read prefer‐
9043 ence mode and tag sets.
9044
9045 Max Staleness
9046 When connected to replica set running MongoDB 3.4 or later, the driver
9047 estimates the staleness of each secondary based on lastWriteDate values
9048 provided in server hello responses.
9049
9050 Max Staleness is the maximum replication lag in seconds (wall clock
9051 time) that a secondary can suffer and still be eligible for reads. The
9052 default is MONGOC_NO_MAX_STALENESS, which disables staleness checks.
9053 Otherwise, it must be a positive integer at least MONGOC_SMALL‐
9054 EST_MAX_STALENESS_SECONDS (90 seconds).
9055
9056 Max Staleness is also supported by sharded clusters of replica sets if
9057 all servers run MongoDB 3.4 or later.
9058
9059 Hedged Reads
9060 When connecting to a sharded cluster running MongoDB 4.4 or later,
9061 reads can be sent in parallel to the two "best" hosts. Once one result
9062 returns, any other outstanding operations that were part of the hedged
9063 read are cancelled.
9064
9065 When the read preference mode is MONGOC_READ_NEAREST and the sharded
9066 cluster is running MongoDB 4.4 or later, hedged reads are enabled by
9067 default. Additionally, hedged reads may be explicitly enabled or dis‐
9068 abled by calling mongoc_read_prefs_set_hedge with a BSON document, e.g.
9069
9070 {
9071 enabled: true
9072 }
9073
9074 Appropriate values for the enabled key are true or false.
9075
9076 mongoc_remove_flags_t
9077 Flags for deletion operations
9078
9079 Synopsis
9080 typedef enum {
9081 MONGOC_REMOVE_NONE = 0,
9082 MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0,
9083 } mongoc_remove_flags_t;
9084
9085 Description
9086 These flags correspond to the MongoDB wire protocol. They may be bit‐
9087 wise or'd together. They may change the number of documents that are
9088 removed during a remove command.
9089
9090 Flag Values
9091 ┌─────────────────────────┬────────────────────────────┐
9092 │MONGOC_REMOVE_NONE │ Specify no removal flags. │
9093 │ │ All matching documents │
9094 │ │ will be removed. │
9095 ├─────────────────────────┼────────────────────────────┤
9096 │MONGOC_REMOVE_SINGLE_RE‐ │ Only remove the first │
9097 │MOVE │ matching document from the │
9098 │ │ selector. │
9099 └─────────────────────────┴────────────────────────────┘
9100
9101 mongoc_reply_flags_t
9102 Flags from server replies
9103
9104 Synopsis
9105 typedef enum {
9106 MONGOC_REPLY_NONE = 0,
9107 MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0,
9108 MONGOC_REPLY_QUERY_FAILURE = 1 << 1,
9109 MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2,
9110 MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3,
9111 } mongoc_reply_flags_t;
9112
9113 Description
9114 These flags correspond to the wire protocol. They may be bitwise or'd
9115 together.
9116
9117 Flag Values
9118 ┌───────────────────────────┬────────────────────────────┐
9119 │MONGOC_REPLY_NONE │ No flags set. │
9120 ├───────────────────────────┼────────────────────────────┤
9121 │MONGOC_REPLY_CUR‐ │ No matching cursor was │
9122 │SOR_NOT_FOUND │ found on the server. │
9123 ├───────────────────────────┼────────────────────────────┤
9124 │MONGOC_REPLY_QUERY_FAILURE │ The query failed or was │
9125 │ │ invalid. Error document │
9126 │ │ has been provided. │
9127 ├───────────────────────────┼────────────────────────────┤
9128 │MONGOC_REPLY_SHARD_CON‐ │ Shard config is stale. │
9129 │FIG_STALE │ │
9130 ├───────────────────────────┼────────────────────────────┤
9131 │MONGOC_REPLY_AWAIT_CAPABLE │ If the returned cursor is │
9132 │ │ capable of MON‐ │
9133 │ │ GOC_QUERY_AWAIT_DATA. │
9134 └───────────────────────────┴────────────────────────────┘
9135
9136 mongoc_server_api_t
9137 A versioned API to use for connections.
9138
9139 Synopsis
9140 Used to specify which version of the MongoDB server's API to use for
9141 driver connections.
9142
9143 The server API type takes a mongoc_server_api_version_t. It can option‐
9144 ally be strict about the list of allowed commands in that API version,
9145 and can also optionally provide errors for deprecated commands in that
9146 API version.
9147
9148 A mongoc_server_api_t can be set on a client, and will then be sent to
9149 MongoDB for most commands run using that client.
9150
9151 mongoc_server_api_version_t
9152 A representation of server API version numbers.
9153
9154 Synopsis
9155 Used to specify which version of the MongoDB server's API to use for
9156 driver connections.
9157
9158 Supported API Versions
9159 The driver currently supports the following MongoDB API versions:
9160
9161 ┌─────────────────────┬────────────────────────┐
9162 │Enum value │ MongoDB version string │
9163 ├─────────────────────┼────────────────────────┤
9164 │MONGOC_SERVER_API_V1 │ "1" │
9165 └─────────────────────┴────────────────────────┘
9166
9167 mongoc_server_description_t
9168 Server description
9169
9170 Synopsis
9171 #include <mongoc/mongoc.h>
9172 typedef struct _mongoc_server_description_t mongoc_server_description_t
9173
9174 mongoc_server_description_t holds information about a mongod or mongos
9175 the driver is connected to.
9176
9177 Lifecycle
9178 Clean up a mongoc_server_description_t with mongoc_server_descrip‐
9179 tion_destroy() when necessary.
9180
9181 Applications receive a temporary reference to a mongoc_server_descrip‐
9182 tion_t as a parameter to an SDAM Monitoring callback that must not be
9183 destroyed. See Introduction to Application Performance Monitoring.
9184
9185 SEE ALSO:
9186 mongoc_client_get_server_descriptions().
9187
9188
9189 mongoc_session_opt_t
9190 #include <mongoc/mongoc.h>
9191
9192 typedef struct _mongoc_session_opt_t mongoc_session_opt_t;
9193
9194 Synopsis
9195 Start a session with mongoc_client_start_session, use the session for a
9196 sequence of operations and multi-document transactions, then free it
9197 with mongoc_client_session_destroy(). Any mongoc_cursor_t or mon‐
9198 goc_change_stream_t using a session must be destroyed before the ses‐
9199 sion, and a session must be destroyed before the mongoc_client_t it
9200 came from.
9201
9202 By default, sessions are causally consistent. To disable causal consis‐
9203 tency, before starting a session create a mongoc_session_opt_t with
9204 mongoc_session_opts_new() and call mongoc_session_opts_set_causal_con‐
9205 sistency(), then free the struct with mongoc_session_opts_destroy.
9206
9207 Unacknowledged writes are prohibited with sessions.
9208
9209 A mongoc_client_session_t must be used by only one thread at a time.
9210 Due to session pooling, mongoc_client_start_session may return a ses‐
9211 sion that has been idle for some time and is about to be closed after
9212 its idle timeout. Use the session within one minute of acquiring it to
9213 refresh the session and avoid a timeout.
9214
9215 See the example code for mongoc_session_opts_set_causal_consistency.
9216
9217 mongoc_socket_t
9218 Portable socket abstraction
9219
9220 Synopsis
9221 #include <mongoc/mongoc.h>
9222
9223 typedef struct _mongoc_socket_t mongoc_socket_t
9224
9225 Synopsis
9226 This structure provides a socket abstraction that is friendlier for
9227 portability than BSD sockets directly. Inconsistencies between Linux,
9228 various BSDs, Solaris, and Windows are handled here.
9229
9230 mongoc_ssl_opt_t
9231 Synopsis
9232 typedef struct {
9233 const char *pem_file;
9234 const char *pem_pwd;
9235 const char *ca_file;
9236 const char *ca_dir;
9237 const char *crl_file;
9238 bool weak_cert_validation;
9239 bool allow_invalid_hostname;
9240 void *internal;
9241 void *padding[6];
9242 } mongoc_ssl_opt_t;
9243
9244 Description
9245 This structure is used to set the TLS options for a mongoc_client_t or
9246 mongoc_client_pool_t.
9247
9248 Beginning in version 1.2.0, once a pool or client has any TLS options
9249 set, all connections use TLS, even if ssl=true is omitted from the Mon‐
9250 goDB URI. Before, TLS options were ignored unless tls=true was included
9251 in the URI.
9252
9253 As of 1.4.0, the mongoc_client_pool_set_ssl_opts and mon‐
9254 goc_client_set_ssl_opts will not only shallow copy the struct, but will
9255 also copy the const char*. It is therefore no longer needed to make
9256 sure the values remain valid after setting them.
9257
9258 SEE ALSO:
9259 configuring_tls
9260
9261 mongoc_client_set_ssl_opts
9262
9263 mongoc_client_pool_set_ssl_opts
9264
9265
9266 mongoc_stream_buffered_t
9267 Synopsis
9268 typedef struct _mongoc_stream_buffered_t mongoc_stream_buffered_t;
9269
9270 Description
9271 mongoc_stream_buffered_t should be considered a subclass of mon‐
9272 goc_stream_t. It performs buffering on an underlying stream.
9273
9274 SEE ALSO:
9275 mongoc_stream_buffered_new()
9276
9277 mongoc_stream_destroy()
9278
9279
9280 mongoc_stream_file_t
9281 Synopsis
9282 typedef struct _mongoc_stream_file_t mongoc_stream_file_t
9283
9284 mongoc_stream_file_t is a mongoc_stream_t subclass for working with
9285 standard UNIX style file-descriptors.
9286
9287 mongoc_stream_socket_t
9288 Synopsis
9289 typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t
9290
9291 mongoc_stream_socket_t should be considered a subclass of mon‐
9292 goc_stream_t that works upon socket streams.
9293
9294 mongoc_stream_t
9295 Synopsis
9296 typedef struct _mongoc_stream_t mongoc_stream_t
9297
9298 mongoc_stream_t provides a generic streaming IO abstraction based on a
9299 struct of pointers interface. The idea is to allow wrappers, perhaps
9300 other language drivers, to easily shim their IO system on top of mon‐
9301 goc_stream_t.
9302
9303 The API for the stream abstraction is currently private and non-exten‐
9304 sible.
9305
9306 Stream Types
9307 There are a number of built in stream types that come with mongoc. The
9308 default configuration is a buffered unix stream. If TLS is in use, that
9309 in turn is wrapped in a tls stream.
9310
9311 SEE ALSO:
9312 mongoc_stream_buffered_t
9313
9314 mongoc_stream_file_t
9315
9316 mongoc_stream_socket_t
9317
9318 mongoc_stream_tls_t
9319
9320
9321 mongoc_stream_tls_t
9322 Synopsis
9323 typedef struct _mongoc_stream_tls_t mongoc_stream_tls_t
9324
9325 mongoc_stream_tls_t is a mongoc_stream_t subclass for working with TLS
9326 streams.
9327
9328 mongoc_topology_description_t
9329 Status of MongoDB Servers
9330
9331 Synopsis
9332 typedef struct _mongoc_topology_description_t mongoc_topology_description_t;
9333
9334 mongoc_topology_description_t is an opaque type representing the
9335 driver's knowledge of the MongoDB server or servers it is connected to.
9336 Its API conforms to the SDAM Monitoring Specification.
9337
9338 Applications receive a temporary reference to a mongoc_topology_de‐
9339 scription_t as a parameter to an SDAM Monitoring callback that must not
9340 be destroyed. See Introduction to Application Performance Monitoring.
9341
9342 mongoc_transaction_opt_t
9343 #include <mongoc/mongoc.h>
9344
9345 typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t;
9346
9347 Synopsis
9348 Options for starting a multi-document transaction.
9349
9350 When a session is first created with mongoc_client_start_session, it
9351 inherits from the client the read concern, write concern, and read
9352 preference with which to start transactions. Each of these fields can
9353 be overridden independently. Create a mongoc_transaction_opt_t with
9354 mongoc_transaction_opts_new, and pass a non-NULL option to any of the
9355 mongoc_transaction_opt_t setter functions:
9356
9357 • mongoc_transaction_opts_set_read_concern
9358
9359 • mongoc_transaction_opts_set_write_concern
9360
9361 • mongoc_transaction_opts_set_read_prefs
9362
9363 Pass the resulting transaction options to mongoc_client_ses‐
9364 sion_start_transaction. Each field set in the transaction options over‐
9365 rides the inherited client configuration.
9366
9367 Example
9368 example-transaction.c
9369
9370 /* gcc example-transaction.c -o example-transaction \
9371 * $(pkg-config --cflags --libs libmongoc-1.0) */
9372
9373 /* ./example-transaction [CONNECTION_STRING] */
9374
9375 #include <stdio.h>
9376 #include <mongoc/mongoc.h>
9377
9378
9379 int
9380 main (int argc, char *argv[])
9381 {
9382 int exit_code = EXIT_FAILURE;
9383
9384 mongoc_client_t *client = NULL;
9385 mongoc_database_t *database = NULL;
9386 mongoc_collection_t *collection = NULL;
9387 mongoc_client_session_t *session = NULL;
9388 mongoc_session_opt_t *session_opts = NULL;
9389 mongoc_transaction_opt_t *default_txn_opts = NULL;
9390 mongoc_transaction_opt_t *txn_opts = NULL;
9391 mongoc_read_concern_t *read_concern = NULL;
9392 mongoc_write_concern_t *write_concern = NULL;
9393 const char *uri_string = "mongodb://127.0.0.1/?appname=transaction-example";
9394 mongoc_uri_t *uri;
9395 bson_error_t error;
9396 bson_t *doc = NULL;
9397 bson_t *insert_opts = NULL;
9398 int32_t i;
9399 int64_t start;
9400 bson_t reply = BSON_INITIALIZER;
9401 char *reply_json;
9402 bool r;
9403
9404 mongoc_init ();
9405
9406 if (argc > 1) {
9407 uri_string = argv[1];
9408 }
9409
9410 uri = mongoc_uri_new_with_error (uri_string, &error);
9411 if (!uri) {
9412 MONGOC_ERROR ("failed to parse URI: %s\n"
9413 "error message: %s\n",
9414 uri_string,
9415 error.message);
9416 goto done;
9417 }
9418
9419 client = mongoc_client_new_from_uri (uri);
9420 if (!client) {
9421 goto done;
9422 }
9423
9424 mongoc_client_set_error_api (client, 2);
9425 database = mongoc_client_get_database (client, "example-transaction");
9426
9427 /* inserting into a nonexistent collection normally creates it, but a
9428 * collection can't be created in a transaction; create it now */
9429 collection =
9430 mongoc_database_create_collection (database, "collection", NULL, &error);
9431
9432 if (!collection) {
9433 /* code 48 is NamespaceExists, see error_codes.err in mongodb source */
9434 if (error.code == 48) {
9435 collection = mongoc_database_get_collection (database, "collection");
9436 } else {
9437 MONGOC_ERROR ("Failed to create collection: %s", error.message);
9438 goto done;
9439 }
9440 }
9441
9442 /* a transaction's read preferences, read concern, and write concern can be
9443 * set on the client, on the default transaction options, or when starting
9444 * the transaction. for the sake of this example, set read concern on the
9445 * default transaction options. */
9446 default_txn_opts = mongoc_transaction_opts_new ();
9447 read_concern = mongoc_read_concern_new ();
9448 mongoc_read_concern_set_level (read_concern, "snapshot");
9449 mongoc_transaction_opts_set_read_concern (default_txn_opts, read_concern);
9450 session_opts = mongoc_session_opts_new ();
9451 mongoc_session_opts_set_default_transaction_opts (session_opts,
9452 default_txn_opts);
9453
9454 session = mongoc_client_start_session (client, session_opts, &error);
9455 if (!session) {
9456 MONGOC_ERROR ("Failed to start session: %s", error.message);
9457 goto done;
9458 }
9459
9460 /* in this example, set write concern when starting the transaction */
9461 txn_opts = mongoc_transaction_opts_new ();
9462 write_concern = mongoc_write_concern_new ();
9463 mongoc_write_concern_set_wmajority (write_concern, 1000 /* wtimeout */);
9464 mongoc_transaction_opts_set_write_concern (txn_opts, write_concern);
9465
9466 insert_opts = bson_new ();
9467 if (!mongoc_client_session_append (session, insert_opts, &error)) {
9468 MONGOC_ERROR ("Could not add session to opts: %s", error.message);
9469 goto done;
9470 }
9471
9472 retry_transaction:
9473 r = mongoc_client_session_start_transaction (session, txn_opts, &error);
9474 if (!r) {
9475 MONGOC_ERROR ("Failed to start transaction: %s", error.message);
9476 goto done;
9477 }
9478
9479 /* insert two documents - on error, retry the whole transaction */
9480 for (i = 0; i < 2; i++) {
9481 doc = BCON_NEW ("_id", BCON_INT32 (i));
9482 bson_destroy (&reply);
9483 r = mongoc_collection_insert_one (
9484 collection, doc, insert_opts, &reply, &error);
9485
9486 bson_destroy (doc);
9487
9488 if (!r) {
9489 MONGOC_ERROR ("Insert failed: %s", error.message);
9490 mongoc_client_session_abort_transaction (session, NULL);
9491
9492 /* a network error, primary failover, or other temporary error in a
9493 * transaction includes {"errorLabels": ["TransientTransactionError"]},
9494 * meaning that trying the entire transaction again may succeed
9495 */
9496 if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
9497 goto retry_transaction;
9498 }
9499
9500 goto done;
9501 }
9502
9503 reply_json = bson_as_json (&reply, NULL);
9504 printf ("%s\n", reply_json);
9505 bson_free (reply_json);
9506 }
9507
9508 /* in case of transient errors, retry for 5 seconds to commit transaction */
9509 start = bson_get_monotonic_time ();
9510 while (bson_get_monotonic_time () - start < 5 * 1000 * 1000) {
9511 bson_destroy (&reply);
9512 r = mongoc_client_session_commit_transaction (session, &reply, &error);
9513 if (r) {
9514 /* success */
9515 break;
9516 } else {
9517 MONGOC_ERROR ("Warning: commit failed: %s", error.message);
9518 if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
9519 goto retry_transaction;
9520 } else if (mongoc_error_has_label (&reply,
9521 "UnknownTransactionCommitResult")) {
9522 /* try again to commit */
9523 continue;
9524 }
9525
9526 /* unrecoverable error trying to commit */
9527 break;
9528 }
9529 }
9530
9531 exit_code = EXIT_SUCCESS;
9532
9533 done:
9534 bson_destroy (&reply);
9535 bson_destroy (insert_opts);
9536 mongoc_write_concern_destroy (write_concern);
9537 mongoc_read_concern_destroy (read_concern);
9538 mongoc_transaction_opts_destroy (txn_opts);
9539 mongoc_transaction_opts_destroy (default_txn_opts);
9540 mongoc_client_session_destroy (session);
9541 mongoc_collection_destroy (collection);
9542 mongoc_database_destroy (database);
9543 mongoc_uri_destroy (uri);
9544 mongoc_client_destroy (client);
9545
9546 mongoc_cleanup ();
9547
9548 return exit_code;
9549 }
9550
9551
9552 mongoc_transaction_state_t
9553 Constants for transaction states
9554
9555 Synopsis
9556 typedef enum {
9557 MONGOC_TRANSACTION_NONE = 0,
9558 MONGOC_TRANSACTION_STARTING = 1,
9559 MONGOC_TRANSACTION_IN_PROGRESS = 2,
9560 MONGOC_TRANSACTION_COMMITTED = 3,
9561 MONGOC_TRANSACTION_ABORTED = 4,
9562 } mongoc_transaction_state_t;
9563
9564 Description
9565 These constants describe the current transaction state of a session.
9566
9567 Flag Values
9568 ┌───────────────────────────┬────────────────────────────┐
9569 │MONGOC_TRANSACTION_NONE │ There is no transaction in │
9570 │ │ progress. │
9571 ├───────────────────────────┼────────────────────────────┤
9572 │MONGOC_TRANSACTION_START‐ │ A transaction has been │
9573 │ING │ started, but no operation │
9574 │ │ has been sent to the │
9575 │ │ server. │
9576 ├───────────────────────────┼────────────────────────────┤
9577 │MONGOC_TRANSAC‐ │ A transaction is in │
9578 │TION_IN_PROGRESS │ progress. │
9579 ├───────────────────────────┼────────────────────────────┤
9580 │MONGOC_TRANSACTION_COMMIT‐ │ The transaction was com‐ │
9581 │TED │ mitted. │
9582 ├───────────────────────────┼────────────────────────────┤
9583 │MONGOC_TRANSACTION_ABORTED │ The transaction was │
9584 │ │ aborted. │
9585 └───────────────────────────┴────────────────────────────┘
9586
9587 mongoc_update_flags_t
9588 Flags for update operations
9589
9590 Synopsis
9591 typedef enum {
9592 MONGOC_UPDATE_NONE = 0,
9593 MONGOC_UPDATE_UPSERT = 1 << 0,
9594 MONGOC_UPDATE_MULTI_UPDATE = 1 << 1,
9595 } mongoc_update_flags_t;
9596
9597 #define MONGOC_UPDATE_NO_VALIDATE (1U << 31)
9598
9599 Description
9600 These flags correspond to the MongoDB wire protocol. They may be bit‐
9601 wise or'd together. The allow for modifying the way an update is per‐
9602 formed in the MongoDB server.
9603
9604 Flag Values
9605 ┌───────────────────────────┬────────────────────────────┐
9606 │MONGOC_UPDATE_NONE │ No update flags set. │
9607 └───────────────────────────┴────────────────────────────┘
9608
9609
9610 │MONGOC_UPDATE_UPSERT │ If an upsert should be │
9611 │ │ performed. │
9612 ├───────────────────────────┼────────────────────────────┤
9613 │MONGOC_UPDATE_MULTI_UPDATE │ If more than a single │
9614 │ │ matching document should │
9615 │ │ be updated. By default │
9616 │ │ only the first document is │
9617 │ │ updated. │
9618 ├───────────────────────────┼────────────────────────────┤
9619 │MONGOC_UPDATE_NO_VALIDATE │ Do not perform client side │
9620 │ │ BSON validations when per‐ │
9621 │ │ forming an update. This is │
9622 │ │ useful if you already know │
9623 │ │ your BSON documents are │
9624 │ │ valid. │
9625 └───────────────────────────┴────────────────────────────┘
9626
9627 mongoc_uri_t
9628 Synopsis
9629 typedef struct _mongoc_uri_t mongoc_uri_t;
9630
9631 Description
9632 mongoc_uri_t provides an abstraction on top of the MongoDB connection
9633 URI format. It provides standardized parsing as well as convenience
9634 methods for extracting useful information such as replica hosts or au‐
9635 thorization information.
9636
9637 See Connection String URI Reference on the MongoDB website for more in‐
9638 formation.
9639
9640 Format
9641 mongodb[+srv]:// <1>
9642 [username:password@] <2>
9643 host1 <3>
9644 [:port1] <4>
9645 [,host2[:port2],...[,hostN[:portN]]] <5>
9646 [/[database] <6>
9647 [?options]] <7>
9648
9649 1. "mongodb" is the specifier of the MongoDB protocol. Use "mon‐
9650 godb+srv" with a single service name in place of "host1" to specify
9651 the initial list of servers with an SRV record.
9652
9653 2. An optional username and password.
9654
9655 3. The only required part of the uri. This specifies either a host‐
9656 name, IPv4 address, IPv6 address enclosed in "[" and "]", or UNIX
9657 domain socket.
9658
9659 4. An optional port number. Defaults to :27017.
9660
9661 5. Extra optional hosts and ports. You would specify multiple hosts,
9662 for example, for connections to replica sets.
9663
9664 6. The name of the database to authenticate if the connection string
9665 includes authentication credentials. If /database is not specified
9666 and the connection string includes credentials, defaults to the 'ad‐
9667 min' database.
9668
9669 7. Connection specific options.
9670
9671 NOTE:
9672 Option names are case-insensitive. Do not repeat the same option
9673 (e.g. "mongodb://localhost/db?opt=value1&OPT=value2") since this may
9674 have unexpected results.
9675
9676 The MongoDB C Driver exposes constants for each supported connection
9677 option. These constants make it easier to discover connection options,
9678 but their string values can be used as well.
9679
9680 For example, the following calls are equal.
9681
9682 uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_APPNAME "=applicationName");
9683 uri = mongoc_uri_new ("mongodb://localhost/?appname=applicationName");
9684 uri = mongoc_uri_new ("mongodb://localhost/?appName=applicationName");
9685
9686 Replica Set Example
9687 To describe a connection to a replica set named 'test' with the follow‐
9688 ing mongod hosts:
9689
9690 • db1.example.com on port 27017
9691
9692 • db2.example.com on port 2500
9693
9694 You would use a connection string that resembles the following.
9695
9696 mongodb://db1.example.com,db2.example.com:2500/?replicaSet=test
9697
9698 SRV Example
9699 If you have configured an SRV record with a name like "_mon‐
9700 godb._tcp.server.example.com" whose records are a list of one or more
9701 MongoDB server hostnames, use a connection string like this:
9702
9703 uri = mongoc_uri_new ("mongodb+srv://server.example.com/?replicaSet=rs&appName=applicationName");
9704
9705 The driver prefixes the service name with "_mongodb._tcp.", then per‐
9706 forms a DNS SRV query to resolve the service name to one or more host‐
9707 names. If this query succeeds, the driver performs a DNS TXT query on
9708 the service name (without the "_mongodb._tcp" prefix) for additional
9709 URI options configured as TXT records.
9710
9711 On Unix, the MongoDB C Driver relies on libresolv to look up SRV and
9712 TXT records. If libresolv is unavailable, then using a "mongodb+srv"
9713 URI will cause an error. If your libresolv lacks res_nsearch then the
9714 driver will fall back to res_search, which is not thread-safe.
9715
9716 IPv4 and IPv6
9717 If connecting to a hostname that has both IPv4 and IPv6 DNS records,
9718 the behavior follows RFC-6555. A connection to the IPv6 address is at‐
9719 tempted first. If IPv6 fails, then a connection is attempted to the
9720 IPv4 address. If the connection attempt to IPv6 does not complete
9721 within 250ms, then IPv4 is tried in parallel. Whichever succeeds con‐
9722 nection first cancels the other. The successful DNS result is cached
9723 for 10 minutes.
9724
9725 As a consequence, attempts to connect to a mongod only listening on
9726 IPv4 may be delayed if there are both A (IPv4) and AAAA (IPv6) DNS
9727 records associated with the host.
9728
9729 To avoid a delay, configure hostnames to match the MongoDB configura‐
9730 tion. That is, only create an A record if the mongod is only listening
9731 on IPv4.
9732
9733 Connection Options
9734┌───────────────────┬──────────────────┬──────────────────┬────────────────────────────────┐
9735│Constant │ Key │ Default │ Description │
9736├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9737│MON‐ │ retryreads │ true │ If "true" and │
9738│GOC_URI_RETRYREADS │ │ │ the server is a │
9739│ │ │ │ MongoDB 3.6+ │
9740│ │ │ │ standalone, │
9741│ │ │ │ replica set, or │
9742│ │ │ │ sharded cluster, │
9743│ │ │ │ the driver │
9744│ │ │ │ safely retries a │
9745│ │ │ │ read that failed │
9746│ │ │ │ due to a network │
9747│ │ │ │ error or replica │
9748│ │ │ │ set failover. │
9749└───────────────────┴──────────────────┴──────────────────┴────────────────────────────────┘
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768│MONGOC_URI_RETRY‐ │ retrywrites │ true if driver │ If "true" and │
9769│WRITES │ │ built w/ TLS │ the server is a │
9770│ │ │ │ MongoDB 3.6+ │
9771│ │ │ │ replica set or │
9772│ │ │ │ sharded cluster, │
9773│ │ │ │ the driver │
9774│ │ │ │ safely retries a │
9775│ │ │ │ write that │
9776│ │ │ │ failed due to a │
9777│ │ │ │ network error or │
9778│ │ │ │ replica set │
9779│ │ │ │ failover. Only │
9780│ │ │ │ inserts, updates │
9781│ │ │ │ of single docu‐ │
9782│ │ │ │ ments, or │
9783│ │ │ │ deletes of sin‐ │
9784│ │ │ │ gle documents │
9785│ │ │ │ are retried. │
9786├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9787│MONGOC_URI_APPNAME │ appname │ Empty (no app‐ │ The client ap‐ │
9788│ │ │ name) │ plication name. │
9789│ │ │ │ This value is │
9790│ │ │ │ used by MongoDB │
9791│ │ │ │ when it logs │
9792│ │ │ │ connection in‐ │
9793│ │ │ │ formation and │
9794│ │ │ │ profile informa‐ │
9795│ │ │ │ tion, such as │
9796│ │ │ │ slow queries. │
9797├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9798│MONGOC_URI_TLS │ tls │ Empty (not set, │ {true|false}, │
9799│ │ │ same as false) │ indicating if │
9800│ │ │ │ TLS must be │
9801│ │ │ │ used. (See also │
9802│ │ │ │ mon‐ │
9803│ │ │ │ goc_client_set_ssl_opts │
9804│ │ │ │ and mon‐ │
9805│ │ │ │ goc_client_pool_set_ssl_opts.) │
9806├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9807│MONGOC_URI_COM‐ │ compressors │ Empty (no com‐ │ Comma separated list of com‐ │
9808│PRESSORS │ │ pressors) │ pressors, if any, to use to │
9809│ │ │ │ compress the wire protocol │
9810│ │ │ │ messages. Snappy, zlib, and │
9811│ │ │ │ zstd are optional build time │
9812│ │ │ │ dependencies, and enable the │
9813│ │ │ │ "snappy", "zlib", and "zstd" │
9814│ │ │ │ values respectively. │
9815├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9816│MONGOC_URI_CON‐ │ connecttimeoutms │ 10,000 ms (10 │ This setting applies to new │
9817│NECTTIMEOUTMS │ │ seconds) │ server connections. It is also │
9818│ │ │ │ used as the socket timeout for │
9819│ │ │ │ server discovery and monitor‐ │
9820│ │ │ │ ing operations. │
9821├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9822│MONGOC_URI_SOCKET‐ │ sockettimeoutms │ 300,000 ms (5 │ The time in milliseconds to │
9823│TIMEOUTMS │ │ minutes) │ attempt to send or receive on │
9824│ │ │ │ a socket before the attempt │
9825│ │ │ │ times out. │
9826├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9827│MONGOC_URI_REPLI‐ │ replicaset │ Empty (no repli‐ │ The name of the Replica Set │
9828│CASET │ │ caset) │ that the driver should connect │
9829│ │ │ │ to. │
9830├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9831│MONGOC_URI_ZLIB‐ │ zlibcompression‐ │ -1 │ When the MONGOC_URI_COMPRES‐ │
9832│COMPRESSIONLEVEL │ level │ │ SORS includes "zlib" this op‐ │
9833│ │ │ │ tions configures the zlib com‐ │
9834│ │ │ │ pression level, when the zlib │
9835│ │ │ │ compressor is used to compress │
9836│ │ │ │ client data. │
9837├───────────────────┼──────────────────┼──────────────────┼────────────────────────────────┤
9838│MONGOC_URI_LOAD‐ │ loadbalanced │ false │ If true, this indicates the │
9839│BALANCED │ │ │ driver is connecting to a Mon‐ │
9840│ │ │ │ goDB cluster behind a load │
9841│ │ │ │ balancer. │
9842└───────────────────┴──────────────────┴──────────────────┴────────────────────────────────┘
9843
9844 Setting any of the *timeoutMS options above to 0 will be interpreted as
9845 "use the default value".
9846
9847 Authentication Options
9848 ┌────────────────────┬────────────────────┬─────────────────────┐
9849 │Constant │ Key │ Description │
9850 ├────────────────────┼────────────────────┼─────────────────────┤
9851 │MONGOC_URI_AUTH‐ │ authmechanism │ Specifies the mech‐ │
9852 │MECHANISM │ │ anism to use when │
9853 │ │ │ authenticating as │
9854 │ │ │ the provided user. │
9855 │ │ │ See Authentication │
9856 │ │ │ for supported val‐ │
9857 │ │ │ ues. │
9858 ├────────────────────┼────────────────────┼─────────────────────┤
9859 │MONGOC_URI_AUTH‐ │ authmechanismprop‐ │ Certain authentica‐ │
9860 │MECHANISMPROPERTIES │ erties │ tion mechanisms │
9861 │ │ │ have additional op‐ │
9862 │ │ │ tions that can be │
9863 │ │ │ configured. These │
9864 │ │ │ options should be │
9865 │ │ │ provided as comma │
9866 │ │ │ separated op‐ │
9867 │ │ │ tion_key:op‐ │
9868 │ │ │ tion_value pair and │
9869 │ │ │ provided as auth‐ │
9870 │ │ │ MechanismProper‐ │
9871 │ │ │ ties. │
9872 ├────────────────────┼────────────────────┼─────────────────────┤
9873 │MONGOC_URI_AUTH‐ │ authsource │ The authSource de‐ │
9874 │SOURCE │ │ fines the database │
9875 │ │ │ that should be used │
9876 │ │ │ to authenticate to. │
9877 │ │ │ It is unnecessary │
9878 │ │ │ to provide this op‐ │
9879 │ │ │ tion the database │
9880 │ │ │ name is the same as │
9881 │ │ │ the database used │
9882 │ │ │ in the URI. │
9883 └────────────────────┴────────────────────┴─────────────────────┘
9884
9885 Mechanism Properties
9886 ┌────────────────────┬───────────────────┬─────────────────────┐
9887 │Constant │ Key │ Description │
9888 ├────────────────────┼───────────────────┼─────────────────────┤
9889 │MONGOC_URI_CANONI‐ │ canonicalizehost‐ │ Use the canonical │
9890 │CALIZEHOSTNAME │ name │ hostname of the │
9891 │ │ │ service, rather │
9892 │ │ │ than its configured │
9893 │ │ │ alias, when authen‐ │
9894 │ │ │ ticating with │
9895 │ │ │ Cyrus-SASL Ker‐ │
9896 │ │ │ beros. │
9897 ├────────────────────┼───────────────────┼─────────────────────┤
9898 │MONGOC_URI_GSSAPIS‐ │ gssapiservicename │ Use alternative │
9899 │ERVICENAME │ │ service name. The │
9900 │ │ │ default is mongodb. │
9901 └────────────────────┴───────────────────┴─────────────────────┘
9902
9903 TLS Options
9904 ┌────────────────────┬─────────────────────┬─────────────────────┐
9905 │Constant │ Key │ Description │
9906 ├────────────────────┼─────────────────────┼─────────────────────┤
9907 │MONGOC_URI_TLS │ tls │ {true|false}, indi‐ │
9908 │ │ │ cating if TLS must │
9909 │ │ │ be used. │
9910 ├────────────────────┼─────────────────────┼─────────────────────┤
9911 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ Path to PEM format‐ │
9912 │TIFICATEKEYFILE │ file │ ted Private Key, │
9913 │ │ │ with its Public │
9914 │ │ │ Certificate con‐ │
9915 │ │ │ catenated at the │
9916 │ │ │ end. │
9917 ├────────────────────┼─────────────────────┼─────────────────────┤
9918 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ The password, if │
9919 │TIFICATEKEY‐ │ password │ any, to use to un‐ │
9920 │FILEPASSWORD │ │ lock encrypted Pri‐ │
9921 │ │ │ vate Key. │
9922 └────────────────────┴─────────────────────┴─────────────────────┘
9923
9924
9925
9926 │MON‐ │ tlscafile │ One, or a bundle │
9927 │GOC_URI_TLSCAFILE │ │ of, Certificate Au‐ │
9928 │ │ │ thorities whom │
9929 │ │ │ should be consid‐ │
9930 │ │ │ ered to be trusted. │
9931 ├────────────────────┼─────────────────────┼─────────────────────┤
9932 │MONGOC_URI_TLSAL‐ │ tlsallowinvalidcer‐ │ Accept and ignore │
9933 │LOWINVALIDCERTIFI‐ │ tificates │ certificate verifi‐ │
9934 │CATES │ │ cation errors (e.g. │
9935 │ │ │ untrusted issuer, │
9936 │ │ │ expired, etc.) │
9937 ├────────────────────┼─────────────────────┼─────────────────────┤
9938 │MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │ Ignore hostname │
9939 │LOWINVALIDHOSTNAMES │ hostnames │ verification of the │
9940 │ │ │ certificate (e.g. │
9941 │ │ │ Man In The Middle, │
9942 │ │ │ using valid cer‐ │
9943 │ │ │ tificate, but is‐ │
9944 │ │ │ sued for another │
9945 │ │ │ hostname) │
9946 ├────────────────────┼─────────────────────┼─────────────────────┤
9947 │MONGOC_URI_TLSINSE‐ │ tlsinsecure │ {true|false}, indi‐ │
9948 │CURE │ │ cating if insecure │
9949 │ │ │ TLS options should │
9950 │ │ │ be used. Currently │
9951 │ │ │ this implies MON‐ │
9952 │ │ │ GOC_URI_TLSALLOWIN‐ │
9953 │ │ │ VALIDCERTIFICATES │
9954 │ │ │ and MONGOC_URI_TL‐ │
9955 │ │ │ SALLOWINVALIDHOST‐ │
9956 │ │ │ NAMES. │
9957 ├────────────────────┼─────────────────────┼─────────────────────┤
9958 │MONGOC_URI_TLSDIS‐ │ tlsdisablecertifi‐ │ {true|false}, indi‐ │
9959 │ABLECERTIFICATERE‐ │ caterevocationcheck │ cates if revocation │
9960 │VOCATIONCHECK │ │ checking (CRL / │
9961 │ │ │ OCSP) should be │
9962 │ │ │ disabled. │
9963 ├────────────────────┼─────────────────────┼─────────────────────┤
9964 │MONGOC_URI_TLSDIS‐ │ tlsdisableocspend‐ │ {true|false}, indi‐ │
9965 │ABLEOCSPEND‐ │ pointcheck │ cates if OCSP re‐ │
9966 │POINTCHECK │ │ sponder endpoints │
9967 │ │ │ should not be re‐ │
9968 │ │ │ quested when an │
9969 │ │ │ OCSP response is │
9970 │ │ │ not stapled. │
9971 └────────────────────┴─────────────────────┴─────────────────────┘
9972
9973 See configuring_tls for details about these options and about building
9974 libmongoc with TLS support.
9975
9976 Deprecated SSL Options
9977 The following options have been deprecated and may be removed from fu‐
9978 ture releases of libmongoc.
9979
9980 ┌──────────────────────┬──────────────────┬───────────────────┬──────────────────┐
9981 │Constant │ Key │ Deprecated For │ Key │
9982 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9983 │MONGOC_URI_SSL │ ssl │ MONGOC_URI_TLS │ tls │
9984 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9985 │MON‐ │ sslclientcer‐ │ MON‐ │ tlscertifi‐ │
9986 │GOC_URI_SSLCLIENTCER‐ │ tificatekeyfile │ GOC_URI_TLSCER‐ │ catekeyfile │
9987 │TIFICATEKEYFILE │ │ TIFICATEKEYFILE │ │
9988 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9989 │MON‐ │ sslclientcer‐ │ MON‐ │ tlscertifi‐ │
9990 │GOC_URI_SSLCLIENTCER‐ │ tificatekeypass‐ │ GOC_URI_TLSCER‐ │ catekeypassword │
9991 │TIFICATEKEYPASSWORD │ word │ TIFICATEKEY‐ │ │
9992 │ │ │ FILEPASSWORD │ │
9993 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9994 │MONGOC_URI_SSLCER‐ │ sslcertifi‐ │ MON‐ │ tlscafile │
9995 │TIFICATEAUTHORITYFILE │ cateauthority‐ │ GOC_URI_TLSCAFILE │ │
9996 │ │ file │ │ │
9997 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9998 │MONGOC_URI_SSLALLOW‐ │ sslallowinvalid‐ │ MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │
9999 │INVALIDCERTIFICATES │ certificates │ LOWINVALIDCER‐ │ certificates │
10000 │ │ │ TIFICATES │ │
10001 └──────────────────────┴──────────────────┴───────────────────┴──────────────────┘
10002
10003
10004
10005 │MONGOC_URI_SSLALLOW‐ │ sslallowinvalid‐ │ MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │
10006 │INVALIDHOSTNAMES │ hostnames │ LOWINVALIDHOST‐ │ hostnames │
10007 │ │ │ NAMES │ │
10008 └──────────────────────┴──────────────────┴───────────────────┴──────────────────┘
10009
10010 Server Discovery, Monitoring, and Selection Options
10011 Clients in a mongoc_client_pool_t share a topology scanner that runs on
10012 a background thread. The thread wakes every heartbeatFrequencyMS (de‐
10013 fault 10 seconds) to scan all MongoDB servers in parallel. Whenever an
10014 application operation requires a server that is not known--for example,
10015 if there is no known primary and your application attempts an in‐
10016 sert--the thread rescans all servers every half-second. In this situa‐
10017 tion the pooled client waits up to serverSelectionTimeoutMS (default 30
10018 seconds) for the thread to find a server suitable for the operation,
10019 then returns an error with domain MONGOC_ERROR_SERVER_SELECTION.
10020
10021 Technically, the total time an operation may wait while a pooled client
10022 scans the topology is controlled both by serverSelectionTimeoutMS and
10023 connectTimeoutMS. The longest wait occurs if the last scan begins just
10024 at the end of the selection timeout, and a slow or down server requires
10025 the full connection timeout before the client gives up.
10026
10027 A non-pooled client is single-threaded. Every heartbeatFrequencyMS, it
10028 blocks the next application operation while it does a parallel scan.
10029 This scan takes as long as needed to check the slowest server: roughly
10030 connectTimeoutMS. Therefore the default heartbeatFrequencyMS for sin‐
10031 gle-threaded clients is greater than for pooled clients: 60 seconds.
10032
10033 By default, single-threaded (non-pooled) clients scan only once when an
10034 operation requires a server that is not known. If you attempt an insert
10035 and there is no known primary, the client checks all servers once try‐
10036 ing to find it, then succeeds or returns an error with domain MON‐
10037 GOC_ERROR_SERVER_SELECTION. But if you set serverSelectionTryOnce to
10038 "false", the single-threaded client loops, checking all servers every
10039 half-second, until serverSelectionTimeoutMS.
10040
10041 The total time an operation may wait for a single-threaded client to
10042 scan the topology is determined by connectTimeoutMS in the try-once
10043 case, or serverSelectionTimeoutMS and connectTimeoutMS if serverSelec‐
10044 tionTryOnce is set "false".
10045
10046 ┌────────────────────┬─────────────────────┬─────────────────────┐
10047 │Constant │ Key │ Description │
10048 ├────────────────────┼─────────────────────┼─────────────────────┤
10049 │MONGOC_URI_HEART‐ │ heartbeatfrequen‐ │ The interval be‐ │
10050 │BEATFREQUENCYMS │ cyms │ tween server moni‐ │
10051 │ │ │ toring checks. De‐ │
10052 │ │ │ faults to 10,000ms │
10053 │ │ │ (10 seconds) in │
10054 │ │ │ pooled │
10055 │ │ │ (multi-threaded) │
10056 │ │ │ mode, 60,000ms (60 │
10057 │ │ │ seconds) in │
10058 │ │ │ non-pooled mode │
10059 │ │ │ (single-threaded). │
10060 ├────────────────────┼─────────────────────┼─────────────────────┤
10061 │MONGOC_URI_SERVERS‐ │ serverselection‐ │ A timeout in mil‐ │
10062 │ELECTIONTIMEOUTMS │ timeoutms │ liseconds to block │
10063 │ │ │ for server selec‐ │
10064 │ │ │ tion before throw‐ │
10065 │ │ │ ing an exception. │
10066 │ │ │ The default is │
10067 │ │ │ 30,0000ms (30 sec‐ │
10068 │ │ │ onds). │
10069 └────────────────────┴─────────────────────┴─────────────────────┘
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084 │MONGOC_URI_SERVERS‐ │ serverselectiontry‐ │ If "true", the │
10085 │ELECTIONTRYONCE │ once │ driver scans the │
10086 │ │ │ topology exactly │
10087 │ │ │ once after server │
10088 │ │ │ selection fails, │
10089 │ │ │ then either selects │
10090 │ │ │ a server or returns │
10091 │ │ │ an error. If it is │
10092 │ │ │ false, then the │
10093 │ │ │ driver repeatedly │
10094 │ │ │ searches for a │
10095 │ │ │ suitable server for │
10096 │ │ │ up to serverSelec‐ │
10097 │ │ │ tionTimeoutMS mil‐ │
10098 │ │ │ liseconds (pausing │
10099 │ │ │ a half second be‐ │
10100 │ │ │ tween attempts). │
10101 │ │ │ The default for │
10102 │ │ │ serverSelectionTry‐ │
10103 │ │ │ Once is "false" for │
10104 │ │ │ pooled clients, │
10105 │ │ │ otherwise "true". │
10106 │ │ │ Pooled clients ig‐ │
10107 │ │ │ nore serverSelec‐ │
10108 │ │ │ tionTryOnce; they │
10109 │ │ │ signal the thread │
10110 │ │ │ to rescan the │
10111 │ │ │ topology every │
10112 │ │ │ half-second until │
10113 │ │ │ serverSelection‐ │
10114 │ │ │ TimeoutMS expires. │
10115 ├────────────────────┼─────────────────────┼─────────────────────┤
10116 │MONGOC_URI_SOCK‐ │ socketcheckinter‐ │ Only applies to │
10117 │ETCHECKINTERVALMS │ valms │ single threaded │
10118 │ │ │ clients. If a │
10119 │ │ │ socket has not been │
10120 │ │ │ used within this │
10121 │ │ │ time, its connec‐ │
10122 │ │ │ tion is checked │
10123 │ │ │ with a quick │
10124 │ │ │ "hello" call before │
10125 │ │ │ it is used again. │
10126 │ │ │ Defaults to 5,000ms │
10127 │ │ │ (5 seconds). │
10128 ├────────────────────┼─────────────────────┼─────────────────────┤
10129 │MONGOC_URI_DIRECT‐ │ directconnection │ If "true", the │
10130 │CONNECTION │ │ driver connects to │
10131 │ │ │ a single server di‐ │
10132 │ │ │ rectly and will not │
10133 │ │ │ monitor additional │
10134 │ │ │ servers. If │
10135 │ │ │ "false", the driver │
10136 │ │ │ connects based on │
10137 │ │ │ the presence and │
10138 │ │ │ value of the repli‐ │
10139 │ │ │ caSet option. │
10140 └────────────────────┴─────────────────────┴─────────────────────┘
10141
10142 Setting any of the *TimeoutMS options above to 0 will be interpreted as
10143 "use the default value".
10144
10145 Connection Pool Options
10146 These options govern the behavior of a mongoc_client_pool_t. They are
10147 ignored by a non-pooled mongoc_client_t.
10148
10149 ┌────────────────────┬────────────────────┬─────────────────────┐
10150 │Constant │ Key │ Description │
10151 └────────────────────┴────────────────────┴─────────────────────┘
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163 │MONGOC_URI_MAXPOOL‐ │ maxpoolsize │ The maximum number │
10164 │SIZE │ │ of clients created │
10165 │ │ │ by a mon‐ │
10166 │ │ │ goc_client_pool_t │
10167 │ │ │ total (both in the │
10168 │ │ │ pool and checked │
10169 │ │ │ out). The default │
10170 │ │ │ value is 100. Once │
10171 │ │ │ it is reached, mon‐ │
10172 │ │ │ goc_client_pool_pop │
10173 │ │ │ blocks until an‐ │
10174 │ │ │ other thread pushes │
10175 │ │ │ a client. │
10176 ├────────────────────┼────────────────────┼─────────────────────┤
10177 │MONGOC_URI_MINPOOL‐ │ minpoolsize │ Deprecated. This │
10178 │SIZE │ │ option's behavior │
10179 │ │ │ does not match its │
10180 │ │ │ name, and its ac‐ │
10181 │ │ │ tual behavior will │
10182 │ │ │ likely hurt perfor‐ │
10183 │ │ │ mance. │
10184 ├────────────────────┼────────────────────┼─────────────────────┤
10185 │MONGOC_URI_MAXIDLE‐ │ maxidletimems │ Not implemented. │
10186 │TIMEMS │ │ │
10187 ├────────────────────┼────────────────────┼─────────────────────┤
10188 │MONGOC_URI_WAIT‐ │ waitqueuemultiple │ Not implemented. │
10189 │QUEUEMULTIPLE │ │ │
10190 ├────────────────────┼────────────────────┼─────────────────────┤
10191 │MONGOC_URI_WAIT‐ │ waitqueuetimeoutms │ The maximum time to │
10192 │QUEUETIMEOUTMS │ │ wait for a client │
10193 │ │ │ to become available │
10194 │ │ │ from the pool. │
10195 └────────────────────┴────────────────────┴─────────────────────┘
10196
10197 Write Concern Options
10198 ┌───────────────────┬────────────┬─────────────────────┐
10199 │Constant │ Key │ Description │
10200 └───────────────────┴────────────┴─────────────────────┘
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242 MONGOC_URI_W w Determines the
10243 write concern
10244 (guarantee). Valid
10245 values:
10246
10247 • 0 = The
10248 driver
10249 will not
10250 acknowl‐
10251 edge write
10252 operations
10253 but will
10254 pass or
10255 handle any
10256 network
10257 and socket
10258 errors
10259 that it
10260 receives
10261 to the
10262 client. If
10263 you dis‐
10264 able write
10265 concern
10266 but enable
10267 the get‐
10268 LastError
10269 command’s
10270 w option,
10271 w over‐
10272 rides the
10273 w option.
10274
10275 • 1 = Pro‐
10276 vides ba‐
10277 sic ac‐
10278 knowledge‐
10279 ment of
10280 write op‐
10281 erations.
10282 By speci‐
10283 fying 1,
10284 you re‐
10285 quire that
10286 a stand‐
10287 alone mon‐
10288 god in‐
10289 stance, or
10290 the pri‐
10291 mary for
10292 replica
10293 sets, ac‐
10294 knowledge
10295 all write
10296 opera‐
10297 tions. For
10298 drivers
10299 released
10300 after the
10301 default
10302 write con‐
10303 cern
10304 change,
10305 this is
10306 the de‐
10307 fault
10308 write con‐
10309 cern set‐
10310 ting.
10311
10312 • majority =
10313 For
10314 replica
10315 sets, if
10316 you spec‐
10317 ify the
10318 special
10319 majority
10320 value to w
10321 option,
10322 write op‐
10323 erations
10324 will only
10325 return
10326 success‐
10327 fully af‐
10328 ter a ma‐
10329 jority of
10330 the con‐
10331 figured
10332 replica
10333 set mem‐
10334 bers have
10335 acknowl‐
10336 edged the
10337 write op‐
10338 eration.
10339
10340 • n = For
10341 replica
10342 sets, if
10343 you spec‐
10344 ify a num‐
10345 ber n
10346 greater
10347 than 1,
10348 operations
10349 with this
10350 write con‐
10351 cern re‐
10352 turn only
10353 after n
10354 members of
10355 the set
10356 have ac‐
10357 knowledged
10358 the write.
10359 If you set
10360 n to a
10361 number
10362 that is
10363 greater
10364 than the
10365 number of
10366 available
10367 set mem‐
10368 bers or
10369 members
10370 that hold
10371 data, Mon‐
10372 goDB will
10373 wait, po‐
10374 tentially
10375 indefi‐
10376 nitely,
10377 for these
10378 members to
10379 become
10380 available.
10381
10382 • tags = For
10383 replica
10384 sets, you
10385 can spec‐
10386 ify a tag
10387 set to re‐
10388 quire that
10389 all mem‐
10390 bers of
10391 the set
10392 that have
10393 these tags
10394 configured
10395 return
10396 confirma‐
10397 tion of
10398 the write
10399 operation.
10400 ├───────────────────┼────────────┼─────────────────────┤
10401 │MONGOC_URI_WTIME‐ │ wtimeoutms │ The time in mil‐ │
10402 │OUTMS │ │ liseconds to wait │
10403 │ │ │ for replication to │
10404 │ │ │ succeed, as speci‐ │
10405 │ │ │ fied in the w op‐ │
10406 │ │ │ tion, before timing │
10407 │ │ │ out. When wtime‐ │
10408 │ │ │ outMS is 0, write │
10409 │ │ │ operations will │
10410 │ │ │ never time out. │
10411 ├───────────────────┼────────────┼─────────────────────┤
10412 │MONGOC_URI_JOURNAL │ journal │ Controls whether │
10413 │ │ │ write operations │
10414 │ │ │ will wait until the │
10415 │ │ │ mongod acknowledges │
10416 │ │ │ the write opera‐ │
10417 │ │ │ tions and commits │
10418 │ │ │ the data to the on │
10419 │ │ │ disk journal. │
10420 │ │ │ │
10421 │ │ │ • true = │
10422 │ │ │ Enables │
10423 │ │ │ journal │
10424 │ │ │ commit ac‐ │
10425 │ │ │ knowledge‐ │
10426 │ │ │ ment write │
10427 │ │ │ concern. │
10428 │ │ │ Equivalent │
10429 │ │ │ to speci‐ │
10430 │ │ │ fying the │
10431 │ │ │ getLastEr‐ │
10432 │ │ │ ror com‐ │
10433 │ │ │ mand with │
10434 │ │ │ the j op‐ │
10435 │ │ │ tion en‐ │
10436 │ │ │ abled. │
10437 │ │ │ │
10438 │ │ │ • false = │
10439 │ │ │ Does not │
10440 │ │ │ require │
10441 │ │ │ that mon‐ │
10442 │ │ │ god commit │
10443 │ │ │ write op‐ │
10444 │ │ │ erations │
10445 │ │ │ to the │
10446 │ │ │ journal │
10447 │ │ │ before ac‐ │
10448 │ │ │ knowledg‐ │
10449 │ │ │ ing the │
10450 │ │ │ write op‐ │
10451 │ │ │ eration. │
10452 │ │ │ This is │
10453 │ │ │ the de‐ │
10454 │ │ │ fault op‐ │
10455 │ │ │ tion for │
10456 │ │ │ the jour‐ │
10457 │ │ │ nal param‐ │
10458 │ │ │ eter. │
10459 └───────────────────┴────────────┴─────────────────────┘
10460
10461 Read Concern Options
10462 ┌────────────────────┬──────────────────┬─────────────────────┐
10463 │Constant │ Key │ Description │
10464 ├────────────────────┼──────────────────┼─────────────────────┤
10465 │MONGOC_URI_READCON‐ │ readconcernlevel │ The level of isola‐ │
10466 │CERNLEVEL │ │ tion for read oper‐ │
10467 │ │ │ ations. If the │
10468 │ │ │ level is left un‐ │
10469 │ │ │ specified, the │
10470 │ │ │ server default will │
10471 │ │ │ be used. See │
10472 │ │ │ readConcern in the │
10473 │ │ │ MongoDB Manual for │
10474 │ │ │ details. │
10475 └────────────────────┴──────────────────┴─────────────────────┘
10476
10477 Read Preference Options
10478 When connected to a replica set, the driver chooses which member to
10479 query using the read preference:
10480
10481 1. Choose members whose type matches "readPreference".
10482
10483 2. From these, if there are any tags sets configured, choose members
10484 matching the first tag set. If there are none, fall back to the next
10485 tag set and so on, until some members are chosen or the tag sets are
10486 exhausted.
10487
10488 3. From the chosen servers, distribute queries randomly among the
10489 server with the fastest round-trip times. These include the server
10490 with the fastest time and any whose round-trip time is no more than
10491 "localThresholdMS" slower.
10492
10493 ┌────────────────────┬─────────────────────┬──────────────────────────┐
10494 │Constant │ Key │ Description │
10495 ├────────────────────┼─────────────────────┼──────────────────────────┤
10496 │MONGOC_URI_READ‐ │ readpreference │ Specifies the │
10497 │PREFERENCE │ │ replica set read │
10498 │ │ │ preference for this │
10499 │ │ │ connection. This │
10500 │ │ │ setting overrides │
10501 │ │ │ any secondaryOk │
10502 │ │ │ value. The read │
10503 │ │ │ preference values │
10504 │ │ │ are the following: │
10505 │ │ │ │
10506 │ │ │ • primary │
10507 │ │ │ (default) │
10508 │ │ │ │
10509 │ │ │ • prima‐ │
10510 │ │ │ ryPre‐ │
10511 │ │ │ ferred │
10512 │ │ │ │
10513 │ │ │ • secondary │
10514 │ │ │ │
10515 │ │ │ • sec‐ │
10516 │ │ │ ondaryPre‐ │
10517 │ │ │ ferred │
10518 │ │ │ │
10519 │ │ │ • nearest │
10520 ├────────────────────┼─────────────────────┼──────────────────────────┤
10521 │MONGOC_URI_READ‐ │ readpreferencetags │ A representation of │
10522 │PREFERENCETAGS │ │ a tag set. See also │
10523 │ │ │ mon‐ │
10524 │ │ │ goc-read-prefs-tag-sets. │
10525 ├────────────────────┼─────────────────────┼──────────────────────────┤
10526 │MONGOC_URI_LO‐ │ localthresholdms │ How far to distribute │
10527 │CALTHRESHOLDMS │ │ queries, beyond the │
10528 │ │ │ server with the fastest │
10529 │ │ │ round-trip time. By de‐ │
10530 │ │ │ fault, only servers │
10531 │ │ │ within 15ms of the │
10532 │ │ │ fastest round-trip time │
10533 │ │ │ receive queries. │
10534 ├────────────────────┼─────────────────────┼──────────────────────────┤
10535 │MONGOC_URI_MAXSTAL‐ │ maxstalenessseconds │ The maximum replication │
10536 │ENESSSECONDS │ │ lag, in wall clock time, │
10537 │ │ │ that a secondary can │
10538 │ │ │ suffer and still be eli‐ │
10539 │ │ │ gible. The smallest al‐ │
10540 │ │ │ lowed value for maxStal‐ │
10541 │ │ │ enessSeconds is 90 sec‐ │
10542 │ │ │ onds. │
10543 └────────────────────┴─────────────────────┴──────────────────────────┘
10544
10545 NOTE:
10546 When connecting to more than one mongos, libmongoc's localThresh‐
10547 oldMS applies only to the selection of mongos servers. The threshold
10548 for selecting among replica set members in shards is controlled by
10549 the mongos's localThreshold command line option.
10550
10551 Legacy Options
10552 For historical reasons, the following options are available. They
10553 should however not be used.
10554
10555 ┌────────────────┬──────┬─────────────────────┐
10556 │Constant │ Key │ Description │
10557 └────────────────┴──────┴─────────────────────┘
10558
10559
10560 │MONGOC_URI_SAFE │ safe │ {true|false} Same │
10561 │ │ │ as w={1|0} │
10562 └────────────────┴──────┴─────────────────────┘
10563
10564 Version Checks
10565 Conditional compilation based on mongoc version
10566
10567 Description
10568 The following preprocessor macros can be used to perform various checks
10569 based on the version of the library you are compiling against. This
10570 may be useful if you only want to enable a feature on a certain version
10571 of the library.
10572
10573 #include <mongoc/mongoc.h>
10574
10575 #define MONGOC_MAJOR_VERSION (x)
10576 #define MONGOC_MINOR_VERSION (y)
10577 #define MONGOC_MICRO_VERSION (z)
10578 #define MONGOC_VERSION_S "x.y.z"
10579 #define MONGOC_VERSION_HEX ((1 << 24) | (0 << 16) | (0 << 8) | 0)
10580 #define MONGOC_CHECK_VERSION(major, minor, micro)
10581
10582 Only compile a block on MongoDB C Driver 1.1.0 and newer.
10583
10584 #if MONGOC_CHECK_VERSION(1, 1, 0)
10585 static void
10586 do_something (void)
10587 {
10588 }
10589 #endif
10590
10591 mongoc_write_concern_t
10592 Write Concern abstraction
10593
10594 Synopsis
10595 mongoc_write_concern_t tells the driver what level of acknowledgement
10596 to await from the server. The default, MONGOC_WRITE_CONCERN_W_DEFAULT,
10597 is right for the great majority of applications.
10598
10599 You can specify a write concern on connection objects, database ob‐
10600 jects, collection objects, or per-operation. Data-modifying operations
10601 typically use the write concern of the object they operate on, and
10602 check the server response for a write concern error or write concern
10603 timeout. For example, mongoc_collection_drop_index uses the collec‐
10604 tion's write concern, and a write concern error or timeout in the re‐
10605 sponse is considered a failure.
10606
10607 Exceptions to this principle are the generic command functions:
10608
10609 • mongoc_client_command
10610
10611 • mongoc_client_command_simple
10612
10613 • mongoc_database_command
10614
10615 • mongoc_database_command_simple
10616
10617 • mongoc_collection_command
10618
10619 • mongoc_collection_command_simple
10620
10621 These generic command functions do not automatically apply a write con‐
10622 cern, and they do not check the server response for a write concern er‐
10623 ror or write concern timeout.
10624
10625 See Write Concern on the MongoDB website for more information.
10626
10627 Write Concern Levels
10628 Set the write concern level with mongoc_write_concern_set_w.
10629
10630 ┌───────────────────────────┬────────────────────────────┐
10631 │MONGOC_WRITE_CONCERN_W_DE‐ │ By default, writes block │
10632 │FAULT (1) │ awaiting acknowledgement │
10633 │ │ from MongoDB. Acknowledged │
10634 │ │ write concern allows │
10635 │ │ clients to catch network, │
10636 │ │ duplicate key, and other │
10637 │ │ errors. │
10638 └───────────────────────────┴────────────────────────────┘
10639
10640 │MONGOC_WRITE_CONCERN_W_UN‐ │ With this write concern, │
10641 │ACKNOWLEDGED (0) │ MongoDB does not acknowl‐ │
10642 │ │ edge the receipt of write │
10643 │ │ operation. Unacknowledged │
10644 │ │ is similar to errors ig‐ │
10645 │ │ nored; however, mongoc at‐ │
10646 │ │ tempts to receive and han‐ │
10647 │ │ dle network errors when │
10648 │ │ possible. │
10649 ├───────────────────────────┼────────────────────────────┤
10650 │MONGOC_WRITE_CONCERN_W_MA‐ │ Block until a write has │
10651 │JORITY (majority) │ been propagated to a ma‐ │
10652 │ │ jority of the nodes in the │
10653 │ │ replica set. │
10654 ├───────────────────────────┼────────────────────────────┤
10655 │n │ Block until a write has │
10656 │ │ been propagated to at │
10657 │ │ least n nodes in the │
10658 │ │ replica set. │
10659 └───────────────────────────┴────────────────────────────┘
10660
10661 Deprecations
10662 The write concern MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED (value -1) is a
10663 deprecated synonym for MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED (value 0),
10664 and will be removed in the next major release.
10665
10666 mongoc_write_concern_set_fsync is deprecated.
10667
10668 Application Performance Monitoring (APM)
10669 The MongoDB C Driver allows you to monitor all the MongoDB operations
10670 the driver executes. This event-notification system conforms to two
10671 MongoDB driver specs:
10672
10673 • Command Monitoring: events related to all application operations.
10674
10675 • SDAM Monitoring: events related to the driver's Server Discovery And
10676 Monitoring logic.
10677
10678 To receive notifications, create a mongoc_apm_callbacks_t with mon‐
10679 goc_apm_callbacks_new, set callbacks on it, then pass it to mon‐
10680 goc_client_set_apm_callbacks or mongoc_client_pool_set_apm_callbacks.
10681
10682 Command-Monitoring Example
10683 example-command-monitoring.c
10684
10685 /* gcc example-command-monitoring.c -o example-command-monitoring \
10686 * $(pkg-config --cflags --libs libmongoc-1.0) */
10687
10688 /* ./example-command-monitoring [CONNECTION_STRING] */
10689
10690 #include <mongoc/mongoc.h>
10691 #include <stdio.h>
10692
10693
10694 typedef struct {
10695 int started;
10696 int succeeded;
10697 int failed;
10698 } stats_t;
10699
10700
10701 void
10702 command_started (const mongoc_apm_command_started_t *event)
10703 {
10704 char *s;
10705
10706 s = bson_as_relaxed_extended_json (
10707 mongoc_apm_command_started_get_command (event), NULL);
10708 printf ("Command %s started on %s:\n%s\n\n",
10709 mongoc_apm_command_started_get_command_name (event),
10710 mongoc_apm_command_started_get_host (event)->host,
10711 s);
10712
10713 ((stats_t *) mongoc_apm_command_started_get_context (event))->started++;
10714
10715 bson_free (s);
10716 }
10717
10718
10719 void
10720 command_succeeded (const mongoc_apm_command_succeeded_t *event)
10721 {
10722 char *s;
10723
10724 s = bson_as_relaxed_extended_json (
10725 mongoc_apm_command_succeeded_get_reply (event), NULL);
10726 printf ("Command %s succeeded:\n%s\n\n",
10727 mongoc_apm_command_succeeded_get_command_name (event),
10728 s);
10729
10730 ((stats_t *) mongoc_apm_command_succeeded_get_context (event))->succeeded++;
10731
10732 bson_free (s);
10733 }
10734
10735
10736 void
10737 command_failed (const mongoc_apm_command_failed_t *event)
10738 {
10739 bson_error_t error;
10740
10741 mongoc_apm_command_failed_get_error (event, &error);
10742 printf ("Command %s failed:\n\"%s\"\n\n",
10743 mongoc_apm_command_failed_get_command_name (event),
10744 error.message);
10745
10746 ((stats_t *) mongoc_apm_command_failed_get_context (event))->failed++;
10747 }
10748
10749
10750 int
10751 main (int argc, char *argv[])
10752 {
10753 mongoc_client_t *client;
10754 mongoc_apm_callbacks_t *callbacks;
10755 stats_t stats = {0};
10756 mongoc_collection_t *collection;
10757 bson_error_t error;
10758 const char *uri_string =
10759 "mongodb://127.0.0.1/?appname=cmd-monitoring-example";
10760 mongoc_uri_t *uri;
10761 const char *collection_name = "test";
10762 bson_t *docs[2];
10763
10764 mongoc_init ();
10765
10766 if (argc > 1) {
10767 uri_string = argv[1];
10768 }
10769
10770 uri = mongoc_uri_new_with_error (uri_string, &error);
10771 if (!uri) {
10772 fprintf (stderr,
10773 "failed to parse URI: %s\n"
10774 "error message: %s\n",
10775 uri_string,
10776 error.message);
10777 return EXIT_FAILURE;
10778 }
10779
10780 client = mongoc_client_new_from_uri (uri);
10781 if (!client) {
10782 return EXIT_FAILURE;
10783 }
10784
10785 mongoc_client_set_error_api (client, 2);
10786 callbacks = mongoc_apm_callbacks_new ();
10787 mongoc_apm_set_command_started_cb (callbacks, command_started);
10788 mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded);
10789 mongoc_apm_set_command_failed_cb (callbacks, command_failed);
10790 mongoc_client_set_apm_callbacks (
10791 client, callbacks, (void *) &stats /* context pointer */);
10792
10793 collection = mongoc_client_get_collection (client, "test", collection_name);
10794 mongoc_collection_drop (collection, NULL);
10795
10796 docs[0] = BCON_NEW ("_id", BCON_INT32 (0));
10797 docs[1] = BCON_NEW ("_id", BCON_INT32 (1));
10798 mongoc_collection_insert_many (
10799 collection, (const bson_t **) docs, 2, NULL, NULL, NULL);
10800
10801 /* duplicate key error on the second insert */
10802 mongoc_collection_insert_one (collection, docs[0], NULL, NULL, NULL);
10803
10804 mongoc_collection_destroy (collection);
10805 mongoc_apm_callbacks_destroy (callbacks);
10806 mongoc_uri_destroy (uri);
10807 mongoc_client_destroy (client);
10808
10809 printf ("started: %d\nsucceeded: %d\nfailed: %d\n",
10810 stats.started,
10811 stats.succeeded,
10812 stats.failed);
10813
10814 bson_destroy (docs[0]);
10815 bson_destroy (docs[1]);
10816
10817 mongoc_cleanup ();
10818
10819 return EXIT_SUCCESS;
10820 }
10821
10822
10823 This example program prints:
10824
10825 Command drop started on 127.0.0.1:
10826 { "drop" : "test" }
10827
10828 Command drop succeeded:
10829 { "ns" : "test.test", "nIndexesWas" : 1, "ok" : 1.0 }
10830
10831 Command insert started on 127.0.0.1:
10832 {
10833 "insert" : "test",
10834 "ordered" : true,
10835 "documents" : [
10836 { "_id" : 0 }, { "_id" : 1 }
10837 ]
10838 }
10839
10840 Command insert succeeded:
10841 { "n" : 2, "ok" : 1.0 }
10842
10843 Command insert started on 127.0.0.1:
10844 {
10845 "insert" : "test",
10846 "ordered" : true,
10847 "documents" : [
10848 { "_id" : 0 }
10849 ]
10850 }
10851
10852 Command insert succeeded:
10853 {
10854 "n" : 0,
10855 "writeErrors" : [
10856 { "index" : 0, "code" : 11000, "errmsg" : "duplicate key" }
10857 ],
10858 "ok" : 1.0
10859 }
10860
10861 started: 3
10862 succeeded: 3
10863 failed: 0
10864
10865 The output has been edited and formatted for clarity. Depending on your
10866 server configuration, messages may include metadata like database name,
10867 logical session ids, or cluster times that are not shown here.
10868
10869 The final "insert" command is considered successful, despite the
10870 writeError, because the server replied to the overall command with
10871 "ok": 1.
10872
10873 SDAM Monitoring Example
10874 example-sdam-monitoring.c
10875
10876 /* gcc example-sdam-monitoring.c -o example-sdam-monitoring \
10877 * $(pkg-config --cflags --libs libmongoc-1.0) */
10878
10879 /* ./example-sdam-monitoring [CONNECTION_STRING] */
10880
10881 #include <mongoc/mongoc.h>
10882 #include <stdio.h>
10883
10884
10885 typedef struct {
10886 int server_changed_events;
10887 int server_opening_events;
10888 int server_closed_events;
10889 int topology_changed_events;
10890 int topology_opening_events;
10891 int topology_closed_events;
10892 int heartbeat_started_events;
10893 int heartbeat_succeeded_events;
10894 int heartbeat_failed_events;
10895 } stats_t;
10896
10897
10898 static void
10899 server_changed (const mongoc_apm_server_changed_t *event)
10900 {
10901 stats_t *context;
10902 const mongoc_server_description_t *prev_sd, *new_sd;
10903
10904 context = (stats_t *) mongoc_apm_server_changed_get_context (event);
10905 context->server_changed_events++;
10906
10907 prev_sd = mongoc_apm_server_changed_get_previous_description (event);
10908 new_sd = mongoc_apm_server_changed_get_new_description (event);
10909
10910 printf ("server changed: %s %s -> %s\n",
10911 mongoc_apm_server_changed_get_host (event)->host_and_port,
10912 mongoc_server_description_type (prev_sd),
10913 mongoc_server_description_type (new_sd));
10914 }
10915
10916
10917 static void
10918 server_opening (const mongoc_apm_server_opening_t *event)
10919 {
10920 stats_t *context;
10921
10922 context = (stats_t *) mongoc_apm_server_opening_get_context (event);
10923 context->server_opening_events++;
10924
10925 printf ("server opening: %s\n",
10926 mongoc_apm_server_opening_get_host (event)->host_and_port);
10927 }
10928
10929
10930 static void
10931 server_closed (const mongoc_apm_server_closed_t *event)
10932 {
10933 stats_t *context;
10934
10935 context = (stats_t *) mongoc_apm_server_closed_get_context (event);
10936 context->server_closed_events++;
10937
10938 printf ("server closed: %s\n",
10939 mongoc_apm_server_closed_get_host (event)->host_and_port);
10940 }
10941
10942
10943 static void
10944 topology_changed (const mongoc_apm_topology_changed_t *event)
10945 {
10946 stats_t *context;
10947 const mongoc_topology_description_t *prev_td;
10948 const mongoc_topology_description_t *new_td;
10949 mongoc_server_description_t **prev_sds;
10950 size_t n_prev_sds;
10951 mongoc_server_description_t **new_sds;
10952 size_t n_new_sds;
10953 size_t i;
10954 mongoc_read_prefs_t *prefs;
10955
10956 context = (stats_t *) mongoc_apm_topology_changed_get_context (event);
10957 context->topology_changed_events++;
10958
10959 prev_td = mongoc_apm_topology_changed_get_previous_description (event);
10960 prev_sds = mongoc_topology_description_get_servers (prev_td, &n_prev_sds);
10961 new_td = mongoc_apm_topology_changed_get_new_description (event);
10962 new_sds = mongoc_topology_description_get_servers (new_td, &n_new_sds);
10963
10964 printf ("topology changed: %s -> %s\n",
10965 mongoc_topology_description_type (prev_td),
10966 mongoc_topology_description_type (new_td));
10967
10968 if (n_prev_sds) {
10969 printf (" previous servers:\n");
10970 for (i = 0; i < n_prev_sds; i++) {
10971 printf (" %s %s\n",
10972 mongoc_server_description_type (prev_sds[i]),
10973 mongoc_server_description_host (prev_sds[i])->host_and_port);
10974 }
10975 }
10976
10977 if (n_new_sds) {
10978 printf (" new servers:\n");
10979 for (i = 0; i < n_new_sds; i++) {
10980 printf (" %s %s\n",
10981 mongoc_server_description_type (new_sds[i]),
10982 mongoc_server_description_host (new_sds[i])->host_and_port);
10983 }
10984 }
10985
10986 prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
10987
10988 /* it is safe, and unfortunately necessary, to cast away const here */
10989 if (mongoc_topology_description_has_readable_server (
10990 (mongoc_topology_description_t *) new_td, prefs)) {
10991 printf (" secondary AVAILABLE\n");
10992 } else {
10993 printf (" secondary UNAVAILABLE\n");
10994 }
10995
10996 if (mongoc_topology_description_has_writable_server (
10997 (mongoc_topology_description_t *) new_td)) {
10998 printf (" primary AVAILABLE\n");
10999 } else {
11000 printf (" primary UNAVAILABLE\n");
11001 }
11002
11003 mongoc_read_prefs_destroy (prefs);
11004 mongoc_server_descriptions_destroy_all (prev_sds, n_prev_sds);
11005 mongoc_server_descriptions_destroy_all (new_sds, n_new_sds);
11006 }
11007
11008
11009 static void
11010 topology_opening (const mongoc_apm_topology_opening_t *event)
11011 {
11012 stats_t *context;
11013
11014 context = (stats_t *) mongoc_apm_topology_opening_get_context (event);
11015 context->topology_opening_events++;
11016
11017 printf ("topology opening\n");
11018 }
11019
11020
11021 static void
11022 topology_closed (const mongoc_apm_topology_closed_t *event)
11023 {
11024 stats_t *context;
11025
11026 context = (stats_t *) mongoc_apm_topology_closed_get_context (event);
11027 context->topology_closed_events++;
11028
11029 printf ("topology closed\n");
11030 }
11031
11032
11033 static void
11034 server_heartbeat_started (const mongoc_apm_server_heartbeat_started_t *event)
11035 {
11036 stats_t *context;
11037
11038 context =
11039 (stats_t *) mongoc_apm_server_heartbeat_started_get_context (event);
11040 context->heartbeat_started_events++;
11041
11042 printf ("%s heartbeat started\n",
11043 mongoc_apm_server_heartbeat_started_get_host (event)->host_and_port);
11044 }
11045
11046
11047 static void
11048 server_heartbeat_succeeded (
11049 const mongoc_apm_server_heartbeat_succeeded_t *event)
11050 {
11051 stats_t *context;
11052 char *reply;
11053
11054 context =
11055 (stats_t *) mongoc_apm_server_heartbeat_succeeded_get_context (event);
11056 context->heartbeat_succeeded_events++;
11057
11058 reply = bson_as_canonical_extended_json (
11059 mongoc_apm_server_heartbeat_succeeded_get_reply (event), NULL);
11060
11061 printf (
11062 "%s heartbeat succeeded: %s\n",
11063 mongoc_apm_server_heartbeat_succeeded_get_host (event)->host_and_port,
11064 reply);
11065
11066 bson_free (reply);
11067 }
11068
11069
11070 static void
11071 server_heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event)
11072 {
11073 stats_t *context;
11074 bson_error_t error;
11075
11076 context = (stats_t *) mongoc_apm_server_heartbeat_failed_get_context (event);
11077 context->heartbeat_failed_events++;
11078 mongoc_apm_server_heartbeat_failed_get_error (event, &error);
11079
11080 printf ("%s heartbeat failed: %s\n",
11081 mongoc_apm_server_heartbeat_failed_get_host (event)->host_and_port,
11082 error.message);
11083 }
11084
11085
11086 int
11087 main (int argc, char *argv[])
11088 {
11089 mongoc_client_t *client;
11090 mongoc_apm_callbacks_t *cbs;
11091 stats_t stats = {0};
11092 const char *uri_string =
11093 "mongodb://127.0.0.1/?appname=sdam-monitoring-example";
11094 mongoc_uri_t *uri;
11095 bson_t cmd = BSON_INITIALIZER;
11096 bson_t reply;
11097 bson_error_t error;
11098
11099 mongoc_init ();
11100
11101 if (argc > 1) {
11102 uri_string = argv[1];
11103 }
11104
11105 uri = mongoc_uri_new_with_error (uri_string, &error);
11106 if (!uri) {
11107 fprintf (stderr,
11108 "failed to parse URI: %s\n"
11109 "error message: %s\n",
11110 uri_string,
11111 error.message);
11112 return EXIT_FAILURE;
11113 }
11114
11115 client = mongoc_client_new_from_uri (uri);
11116 if (!client) {
11117 return EXIT_FAILURE;
11118 }
11119
11120 mongoc_client_set_error_api (client, 2);
11121 cbs = mongoc_apm_callbacks_new ();
11122 mongoc_apm_set_server_changed_cb (cbs, server_changed);
11123 mongoc_apm_set_server_opening_cb (cbs, server_opening);
11124 mongoc_apm_set_server_closed_cb (cbs, server_closed);
11125 mongoc_apm_set_topology_changed_cb (cbs, topology_changed);
11126 mongoc_apm_set_topology_opening_cb (cbs, topology_opening);
11127 mongoc_apm_set_topology_closed_cb (cbs, topology_closed);
11128 mongoc_apm_set_server_heartbeat_started_cb (cbs, server_heartbeat_started);
11129 mongoc_apm_set_server_heartbeat_succeeded_cb (cbs,
11130 server_heartbeat_succeeded);
11131 mongoc_apm_set_server_heartbeat_failed_cb (cbs, server_heartbeat_failed);
11132 mongoc_client_set_apm_callbacks (
11133 client, cbs, (void *) &stats /* context pointer */);
11134
11135 /* the driver connects on demand to perform first operation */
11136 BSON_APPEND_INT32 (&cmd, "buildinfo", 1);
11137 mongoc_client_command_simple (client, "admin", &cmd, NULL, &reply, &error);
11138 mongoc_uri_destroy (uri);
11139 mongoc_client_destroy (client);
11140
11141 printf ("Events:\n"
11142 " server changed: %d\n"
11143 " server opening: %d\n"
11144 " server closed: %d\n"
11145 " topology changed: %d\n"
11146 " topology opening: %d\n"
11147 " topology closed: %d\n"
11148 " heartbeat started: %d\n"
11149 " heartbeat succeeded: %d\n"
11150 " heartbeat failed: %d\n",
11151 stats.server_changed_events,
11152 stats.server_opening_events,
11153 stats.server_closed_events,
11154 stats.topology_changed_events,
11155 stats.topology_opening_events,
11156 stats.topology_closed_events,
11157 stats.heartbeat_started_events,
11158 stats.heartbeat_succeeded_events,
11159 stats.heartbeat_failed_events);
11160
11161 bson_destroy (&cmd);
11162 bson_destroy (&reply);
11163 mongoc_apm_callbacks_destroy (cbs);
11164
11165 mongoc_cleanup ();
11166
11167 return EXIT_SUCCESS;
11168 }
11169
11170
11171 Start a 3-node replica set on localhost with set name "rs" and start
11172 the program:
11173
11174 ./example-sdam-monitoring "mongodb://localhost:27017,localhost:27018/?replicaSet=rs"
11175
11176 This example program prints something like:
11177
11178 topology opening
11179 topology changed: Unknown -> ReplicaSetNoPrimary
11180 secondary UNAVAILABLE
11181 primary UNAVAILABLE
11182 server opening: localhost:27017
11183 server opening: localhost:27018
11184 localhost:27017 heartbeat started
11185 localhost:27018 heartbeat started
11186 localhost:27017 heartbeat succeeded: { ... reply ... }
11187 server changed: localhost:27017 Unknown -> RSPrimary
11188 server opening: localhost:27019
11189 topology changed: ReplicaSetNoPrimary -> ReplicaSetWithPrimary
11190 new servers:
11191 RSPrimary localhost:27017
11192 secondary UNAVAILABLE
11193 primary AVAILABLE
11194 localhost:27019 heartbeat started
11195 localhost:27018 heartbeat succeeded: { ... reply ... }
11196 server changed: localhost:27018 Unknown -> RSSecondary
11197 topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
11198 previous servers:
11199 RSPrimary localhost:27017
11200 new servers:
11201 RSPrimary localhost:27017
11202 RSSecondary localhost:27018
11203 secondary AVAILABLE
11204 primary AVAILABLE
11205 localhost:27019 heartbeat succeeded: { ... reply ... }
11206 server changed: localhost:27019 Unknown -> RSSecondary
11207 topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
11208 previous servers:
11209 RSPrimary localhost:27017
11210 RSSecondary localhost:27018
11211 new servers:
11212 RSPrimary localhost:27017
11213 RSSecondary localhost:27018
11214 RSSecondary localhost:27019
11215 secondary AVAILABLE
11216 primary AVAILABLE
11217 topology closed
11218
11219 Events:
11220 server changed: 3
11221 server opening: 3
11222 server closed: 0
11223 topology changed: 4
11224 topology opening: 1
11225 topology closed: 1
11226 heartbeat started: 3
11227 heartbeat succeeded: 3
11228 heartbeat failed: 0
11229
11230 The driver connects to the mongods on ports 27017 and 27018, which were
11231 specified in the URI, and determines which is primary. It also discov‐
11232 ers the third member, "localhost:27019", and adds it to the topology.
11233
11235 MongoDB, Inc
11236
11238 2017-present, MongoDB, Inc
11239
11240
11241
11242
112431.20.0 Nov 18, 2021 MONGOC_REFERENCE(3)