Our first task will be to build a BSON document, which we can later insert into MongoDB. For this example, we want something more complex than a simple "Hello World"-style object, so we can showcase all the interesting functions of the BSON API.
Lets build a document that would look like this, if we were writing JSON:
{
author: "Gergely Nagy",
pages: [
{
title: "BSON tutorial",
content: "...",
importance: 1
},
{
title: "Some other thing",
content: "...",
importance: 0
}
],
inline: true
}
First we start by including the main libmongo-client header. It's convenient to include the whole lot instead of including the used headers one by one, unless one's embedding only parts of the library.
#include <mongo.h>
#include <string.h>
#include <stdio.h>
int
main (void)
{
We'll be building the same BSON object in various different ways, so we declare a few more variables than we'd normally need.
bson *b_new, *b_builder, *b_builder_full;
bson *page1, *page2, *pages;
Next, we create the two pages:
gboolean bson_append_string(bson *b, const gchar *name, const gchar *val, gint32 length)
Append a string to a BSON object.
Definition bson.c:626
gboolean bson_append_int32(bson *b, const gchar *name, gint32 i)
Append a 32-bit integer to a BSON object.
Definition bson.c:761
bson * bson_new(void)
Create a new BSON object.
Definition bson.c:252
gboolean bson_finish(bson *b)
Finish a BSON object.
Definition bson.c:521
Then we construct the "pages" array. Do note how we set the key to "1" and "2", and how pages is just a document! This is because in BSON, an array is a document that has a special type, and where keys are numbers.
gboolean bson_append_document(bson *b, const gchar *name, const bson *doc)
Append a BSON document to a BSON object.
Definition bson.c:633
Finally, now that we have all the subdocuments ready, we build up our main object:
gboolean bson_append_array(bson *b, const gchar *name, const bson *array)
Append a BSON array to a BSON object.
Definition bson.c:639
gboolean bson_append_boolean(bson *b, const gchar *name, gboolean value)
Append a boolean to a BSON object.
Definition bson.c:675
And that's about it! But surely, there is an easier way to do this... And indeed, there is, using bson_build():
bson * bson_build(bson_type type, const gchar *name,...)
Build a BSON object in one go.
Definition bson.c:448
@ BSON_TYPE_ARRAY
4byte length + NULL terminated document
Definition bson.h:69
@ BSON_TYPE_STRING
4byte length + NULL terminated string
Definition bson.h:67
@ BSON_TYPE_NONE
Only used for errors.
Definition bson.h:65
@ BSON_TYPE_BOOLEAN
1byte boolean value
Definition bson.h:73
Much cleaner, but still, we had to create the pages array in three steps beforehand. Couldn't we do it in one gigantic function call instead?
bson * bson_build_full(bson_type type, const gchar *name, gboolean free_after,...)
Build a BSON object in one go, with full control.
Definition bson.c:484
@ BSON_TYPE_DOCUMENT
4byte length + NULL terminated document
Definition bson.h:68
@ BSON_TYPE_INT32
4byte integer
Definition bson.h:84
Wonderful! We have three BSON objects created now, in three different ways! But are they the same? That's really easy to figure out. As a quick check, we can compare their sizes: if they do not match, we can bail out fast:
{
fprintf (stderr, "There's something fishy: the three BSON objects have different sizes");
return 1;
}
gint32 bson_size(const bson *b)
Return the size of a finished BSON object.
Definition bson.c:542
Or, we can do a more expensive comparsion, and compare the data:
{
fprintf (stderr, "The BSON objects do not match. Something smells.");
return 1;
}
const guint8 * bson_data(const bson *b)
Return the raw bytestream form of the BSON object.
Definition bson.c:554
And now that we are done, we free up the resources we allocated.
void bson_free(bson *b)
Free the memory associated with a BSON object.
Definition bson.c:579