1BSON_TUTORIAL(3)                    libbson                   BSON_TUTORIAL(3)
2
3
4

NAME

6       bson_tutorial - Tutorial
7

USING LIBBSON IN YOUR C PROGRAM

9   Include bson.h
10       All  libbson's  functions  and  types are available in one header file.
11       Simply include bson.h:
12
13       hello_bson.c
14
15          #include <stdio.h>
16          #include <bson/bson.h>
17
18          int
19          main (int argc, const char **argv)
20          {
21             bson_t *b;
22             char *j;
23
24             b = BCON_NEW ("hello", BCON_UTF8 ("bson!"));
25             j = bson_as_canonical_extended_json (b, NULL);
26             printf ("%s\n", j);
27
28             bson_free (j);
29             bson_destroy (b);
30
31             return 0;
32          }
33
34
35   CMake
36       The libbson installation includes a CMake config-file package,  so  you
37       can  use  CMake's find_package command to import libbson's CMake target
38       and link to libbson (as a shared library):
39
40       CMakeLists.txt
41
42          # Specify the minimum version you require.
43          find_package (bson-1.0 1.7 REQUIRED)
44
45          # The "hello_bson.c" sample program is shared among four tests.
46          add_executable (hello_bson ../../hello_bson.c)
47          target_link_libraries (hello_bson PRIVATE mongo::bson_shared)
48
49
50       You can  also  use  libbson  as  a  static  library  instead:  Use  the
51       mongo::bson_static CMake target:
52
53          # Specify the minimum version you require.
54          find_package (bson-1.0 1.7 REQUIRED)
55
56          # The "hello_bson.c" sample program is shared among four tests.
57          add_executable (hello_bson ../../hello_bson.c)
58          target_link_libraries (hello_bson PRIVATE mongo::bson_static)
59
60
61   pkg-config
62       If  you're  not  using CMake, use pkg-config on the command line to set
63       header and library paths:
64
65          gcc -o hello_bson hello_bson.c $(pkg-config --libs --cflags libbson-1.0)
66
67
68       Or to statically link to libbson:
69
70          gcc -o hello_bson hello_bson.c $(pkg-config --libs --cflags libbson-static-1.0)
71
72

CREATING A BSON DOCUMENT

74   The bson_t structure
75       BSON documents are created using the bson_t structure.  This  structure
76       encapsulates the necessary logic for encoding using the BSON Specifica‐
77       tion. At the core, bson_t is a buffer manager and set of encoding  rou‐
78       tines.
79
80       TIP:
81          BSON  documents  can live on the stack or the heap based on the per‐
82          formance needs or preference of the consumer.
83
84       Let's start by creating a new BSON  document  on  the  stack.  Whenever
85       using libbson, make sure you #include <bson/bson.h>.
86
87          bson_t b;
88
89          bson_init (&b);
90
91       This creates an empty document. In JSON, this would be the same as {}.
92
93       We  can  now proceed to adding items to the BSON document. A variety of
94       functions prefixed with bson_append_ can be used based on the  type  of
95       field you want to append. Let's append a UTF-8 encoded string.
96
97          bson_append_utf8 (&b, "key", -1, "value", -1);
98
99       Notice  the  two  -1 parameters. The first indicates that the length of
100       key in bytes should be  determined  with  strlen().  Alternatively,  we
101       could  have  passed  the number 3. The same goes for the second -1, but
102       for value.
103
104       Libbson provides macros to make this less  tedious  when  using  string
105       literals. The following two appends are identical.
106
107          bson_append_utf8 (&b, "key", -1, "value", -1);
108          BSON_APPEND_UTF8 (&b, "key", "value");
109
110       Now  let's  take  a  look at an example that adds a few different field
111       types to a BSON document.
112
113          bson_t b = BSON_INITIALIZER;
114
115          BSON_APPEND_INT32 (&b, "a", 1);
116          BSON_APPEND_UTF8 (&b, "hello", "world");
117          BSON_APPEND_BOOL (&b, "bool", true);
118
119       Notice that we omitted the call to bson_init(). By specifying BSON_INI‐
120       TIALIZER  we  can remove the need to initialize the structure to a base
121       state.
122
123   Sub-Documents and Sub-Arrays
124       To simplify the creation of sub-documents and arrays, bson_append_docu‐
125       ment_begin()  and bson_append_array_begin() exist. These can be used to
126       build a sub-document using the parent documents memory  region  as  the
127       destination buffer.
128
129          bson_t parent;
130          bson_t child;
131          char *str;
132
133          bson_init (&parent);
134          bson_append_document_begin (&parent, "foo", 3, &child);
135          bson_append_int32 (&child, "baz", 3, 1);
136          bson_append_document_end (&parent, &child);
137
138          str = bson_as_canonical_extended_json (&parent, NULL);
139          printf ("%s\n", str);
140          bson_free (str);
141
142          bson_destroy (&parent);
143
144          { "foo" : { "baz" : 1 } }
145
146   Simplified BSON C Object Notation
147       Creating  BSON  documents  by  hand  can be tedious and time consuming.
148       BCON, or BSON C Object Notation, was added to allow for the creation of
149       BSON documents in a format that looks closer to the destination format.
150
151       The  following  example  shows  the use of BCON. Notice that values for
152       fields are wrapped in the BCON_* macros. These  are  required  for  the
153       variadic processor to determine the parameter type.
154
155          bson_t *doc;
156
157          doc = BCON_NEW ("foo",
158                          "{",
159                          "int",
160                          BCON_INT32 (1),
161                          "array",
162                          "[",
163                          BCON_INT32 (100),
164                          "{",
165                          "sub",
166                          BCON_UTF8 ("value"),
167                          "}",
168                          "]",
169                          "}");
170
171       Creates the following document
172
173          { "foo" : { "int" : 1, "array" : [ 100, { "sub" : "value" } ] } }
174

HANDLING ERRORS

176   Description
177       Many  libbson functions report errors by returning NULL or -1 and fill‐
178       ing out a bson_error_t structure with an error domain, error code,  and
179       message.
180
181       · error.domain names the subsystem that generated the error.
182
183       · error.code is a domain-specific error type.
184
185       · error.message describes the error.
186
187       Some  error codes overlap with others; always check both the domain and
188       code to determine the type of error.
189
190
191
192
193
194
195
196
197
198
199┌──────────────────┬────────────────────────────────────┬────────────────────────────────┐
200BSON_ERROR_JSON   BSON_JSON_ERROR_READ_COR‐          bson_json_reader_t             
201│                  │ RUPT_JS                            │ tried    to   parse            │
202│                  │ BSON_JSON_ERROR_READ_INVALID_PARAM │ invalid     MongoDB            │
203│                  │ BSON_JSON_ERROR_READ_CB_FAIL‐      │ Extended      JSON.            │
204│                  │ URE                                │ Tried  to  parse  a            │
205│                  │                                    │ valid JSON document            │
206│                  │                                    │ that is invalid  as            │
207│                  │                                    │ MongoDBExtended                │
208│                  │                                    │ JSON.  An  internal            │
209│                  │                                    │ callback    failure            │
210│                  │                                    │ during  JSON  pars‐            │
211│                  │                                    │ ing.                           │
212├──────────────────┼────────────────────────────────────┼────────────────────────────────┤
213BSON_ERROR_READER BSON_ERROR_READER_BADFD            bson_json_reader_new_from_file 
214│                  │                                    │ could not open  the            │
215│                  │                                    │ file.                          │
216└──────────────────┴────────────────────────────────────┴────────────────────────────────┘
217

OBJECTIDS

219       Libbson  provides a simple way to generate ObjectIDs. It can be used in
220       a single-threaded or multi-threaded manner depending on  your  require‐
221       ments.
222
223       The  bson_oid_t  structure  represents  an ObjectID in MongoDB. It is a
224       96-bit identifier.
225
226   Composition
227       · 4 bytes : The UNIX timestamp in big-endian format.
228
229       · 5 bytes : A random number.
230
231       · 3 bytes : A 24-bit monotonic  counter  incrementing  from  rand()  in
232         big-endian.
233
234   Sorting ObjectIDs
235       The  typical way to sort in C is using qsort(). Therefore, Libbson pro‐
236       vides a qsort() compatible callback function named  bson_oid_compare().
237       It  returns less than 1, greater than 1, or 0 depending on the equality
238       of two bson_oid_t structures.
239
240   Comparing Object IDs
241       If you simply want to compare two bson_oid_t structures  for  equality,
242       use bson_oid_equal().
243
244   Generating
245       To generate a bson_oid_t, you may use the following.
246
247          bson_oid_t oid;
248
249          bson_oid_init (&oid, NULL);
250
251   Parsing ObjectID Strings
252       You  can  also parse a string containing a bson_oid_t. The input string
253       MUST be 24 characters or more in length.
254
255          bson_oid_t oid;
256
257          bson_oid_init_from_string (&oid, "123456789012345678901234");
258
259          bson_oid_t oid;
260
261          bson_oid_init_from_string_unsafe (&oid, "123456789012345678901234");
262
263   Hashing ObjectIDs
264       If you need to store items in a hashtable, you  may  want  to  use  the
265       bson_oid_t  as  the key. Libbson provides a hash function for just this
266       purpose. It is based on DJB hash.
267
268          unsigned hash;
269
270          hash = bson_oid_hash (oid);
271
272   Fetching ObjectID Creation Time
273       You can easily fetch the time that a  bson_oid_t  was  generated  using
274       bson_oid_get_time_t().
275
276          time_t t;
277
278          t = bson_oid_get_time_t (oid);
279          printf ("The OID was generated at %u\n", (unsigned) t);
280

PARSING AND ITERATING BSON DOCUMENTS

282   Parsing
283       BSON  documents are lazily parsed as necessary. To begin parsing a BSON
284       document, use one of the provided Libbson functions  to  create  a  new
285       bson_t  from existing data such as bson_new_from_data(). This will make
286       a copy of the data so that additional mutations may occur to  the  BSON
287       document.
288
289       TIP:
290          If you only want to parse a BSON document and have no need to mutate
291          it, you may use bson_init_static() to avoid making  a  copy  of  the
292          data.
293
294          bson_t *b;
295
296          b = bson_new_from_data (my_data, my_data_len);
297          if (!b) {
298             fprintf (stderr, "The specified length embedded in <my_data> did not match "
299                              "<my_data_len>\n");
300             return;
301          }
302
303          bson_destroy (b);
304
305       Only two checks are performed when creating a new bson_t from an exist‐
306       ing buffer. First, the document must  begin  with  the  buffer  length,
307       matching what was expected by the caller. Second, the document must end
308       with the expected trailing \0 byte.
309
310       To parse the document further we use a bson_iter_t to iterate the  ele‐
311       ments  within  the  document. Let's print all of the field names in the
312       document.
313
314          bson_t *b;
315          bson_iter_t iter;
316
317          if ((b = bson_new_from_data (my_data, my_data_len))) {
318             if (bson_iter_init (&iter, b)) {
319                while (bson_iter_next (&iter)) {
320                   printf ("Found element key: \"%s\"\n", bson_iter_key (&iter));
321                }
322             }
323             bson_destroy (b);
324          }
325
326       Converting a document to JSON uses a bson_iter_t and bson_visitor_t  to
327       iterate  all fields of a BSON document recursively and generate a UTF-8
328       encoded JSON string.
329
330          bson_t *b;
331          char *json;
332
333          if ((b = bson_new_from_data (my_data, my_data_len))) {
334             if ((json = bson_as_canonical_extended_json (b, NULL))) {
335                printf ("%s\n", json);
336                bson_free (json);
337             }
338             bson_destroy (b);
339          }
340
341   Recursing into Sub-Documents
342       Libbson provides convenient sub-iterators to dive down into a sub-docu‐
343       ment  or sub-array. Below is an example that will dive into a sub-docu‐
344       ment named "foo" and print it's field names.
345
346          bson_iter_t iter;
347          bson_iter_t child;
348          char *json;
349
350          if (bson_iter_init_find (&iter, doc, "foo") &&
351              BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) {
352             while (bson_iter_next (&child)) {
353                printf ("Found sub-key of \"foo\" named \"%s\"\n",
354                        bson_iter_key (&child));
355             }
356          }
357
358   Finding Fields using Dot Notation
359       Using   the    bson_iter_recurse()    function    exemplified    above,
360       bson_iter_find_descendant()  can find a field for you using the MongoDB
361       style path notation such as "foo.bar.0.baz".
362
363       Let's create a document like {"foo": {"bar": [{"baz: 1}]}}  and  locate
364       the "baz" field.
365
366          bson_t *b;
367          bson_iter_t iter;
368          bson_iter_t baz;
369
370          b =
371             BCON_NEW ("foo", "{", "bar", "[", "{", "baz", BCON_INT32 (1), "}", "]", "}");
372
373          if (bson_iter_init (&iter, b) &&
374              bson_iter_find_descendant (&iter, "foo.bar.0.baz", &baz) &&
375              BSON_ITER_HOLDS_INT32 (&baz)) {
376             printf ("baz = %d\n", bson_iter_int32 (&baz));
377          }
378
379          bson_destroy (b);
380
381   Validating a BSON Document
382       If  all  you  want to do is validate that a BSON document is valid, you
383       can use bson_validate().
384
385          size_t err_offset;
386
387          if (!bson_validate (doc, BSON_VALIDATE_NONE, &err_offset)) {
388             fprintf (stderr,
389                      "The document failed to validate at offset: %u\n",
390                      (unsigned) err_offset);
391          }
392
393       See the bson_validate() documentation for more  information  and  exam‐
394       ples.
395

UTF-8

397   Encoding
398       Libbson  expects  that  you are always working with UTF-8 encoded text.
399       Anything else is invalid API use.
400
401       If you should need to walk through UTF-8 sequences,  you  can  use  the
402       various UTF-8 helper functions distributed with Libbson.
403
404   Validating a UTF-8 Sequence
405       To  validate  the string contained in my_string, use the following. You
406       may pass -1 for the string length if you know the string is NULL-termi‐
407       nated.
408
409          if (!bson_utf8_validate (my_string, -1, false)) {
410             printf ("Validation failed.\n");
411          }
412
413       If  my_string  has  NULL  bytes within the string, you must provide the
414       string length. Use the following format. Notice the  true  at  the  end
415       indicating \0 is allowed.
416
417          if (!bson_utf8_validate (my_string, my_string_len, true)) {
418             printf ("Validation failed.\n");
419          }
420
421       For more information see the API reference for bson_utf8_validate().
422

AUTHOR

424       MongoDB, Inc
425
427       2017-present, MongoDB, Inc
428
429
430
431
4321.17.4                           Feb 04, 2021                 BSON_TUTORIAL(3)
Impressum