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