前言
 
做了document组装试验, 也能显示组装后的document内容.  但是, 向mongodb中插入数据时, 才发现数组中的数据要指定下标.  否则报错: document to insert contains invalid keys  如果只是显示document的json内容, 看不出来的.  插入(add)数据, 使用mongoc_collection_insert, 参数为组装好的document.
 
记录
 
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <cstddef>
#include 
"MongoDbEx.h"
#include 
"BusinessLogic.h"
int testcase_mongoc_example_command_simple(int argc, char* argv[]);
int testcase_mongoc_example_document_add(int argc, char* argv[]);
int main(int argc, char* argv[])
{
    printf(
"============================================================\n");
    printf(
">> testcase v1.0.0.5\n");
    printf(
"============================================================\n");
    testcase_mongoc_example_document_add(argc, argv);
    // testcase_mongoc_example_command_simple(argc, argv);
    printf(
"============================================================\n");
    printf(
"END\n");
    printf(
"============================================================\n");
    
return 0;
}
int testcase_mongoc_example_document_add(int argc, char* argv[])
{
    bool bRc = 
false;
    TAG_PERSON_INFO person;
    bson_t* document = NULL;
    mongoc_client_t* client = NULL;
    mongoc_database_t* database = NULL;
    mongoc_collection_t* collection = NULL;
    bson_error_t 
error;
    bool retval = 
false;
    
do {
        memset(&person, sizeof(person), 
0);
        mongoc_init();
        client = mongoc_client_new(
"mongodb://localhost:27017");
        mongoc_client_set_appname(client, 
"CRUD-Add");
        database = mongoc_client_get_database(client, 
"db_ls");
        collection = mongoc_client_get_collection(client, 
"db_ls", 
"coll_ls");
        // cmd :  ping
        retval = DbOptExec_command_simple(client, 
"admin", 
"ping", &
error);
        
if (!retval) {
            ShowErrMsg(
"ping", &
error);
            
break;
        }
        person.birthday.tm_year = 
1973 - 
1900; // base 
1900
        person.birthday.tm_mon = 
4;
        person.birthday.tm_mday = 
1;
        person.name.first = 
"lostspeed";
        person.name.last = 
"cn";
        person.skillAry[
0] = 
"C";
        person.skillAry[
1] = 
"C++";
        person.skillAry[
2] = 
"MASM";
        person.skillAry[
3] = 
"RE";
        person.skillAry[
4] = NULL; // !
        person.degreeAry[
0].degree = 
"graduates";
        person.degreeAry[
0].school = 
"zhongnian";
        person.degreeAry[
1].degree = 
"graduates";
        person.degreeAry[
1].school = 
"cr";
        person.degreeAry[
2].degree = NULL; // !
        person.degreeAry[
2].school = NULL; // !
        document = bson_new();
        fill_TAG_PERSON_INFO(document, &person);
        // use document ...
        ShowDocument(
"person", document);
        /**
        // 这个ok
        [person] { 
            
"name" : { 
                
"first" : 
"lostspeed", 
                
"last" : 
"cn" }, 
            
"birthday" : { 
"$date" : 
1404690916000 } }
        // 这个ok
        [person] { 
            
"name" : { 
                
"first" : 
"lostspeed", 
                
"last" : 
"cn" }, 
            
"birthday" : { 
"$date" : -
1211776988000 }, 
            
"skill" : [ 
"C", 
"C++", 
"MASM", 
"RE" ] 
            }
        // ok
        [person] { 
            
"name" : { 
"first" : 
"lostspeed", 
"last" : 
"cn" }, 
            
"birthday" : { 
"$date" : 
2234350468000 }, 
            
"skill" : [ 
"C", 
"C++", 
"MASM", 
"RE" ], 
            
"degrees" : [ 
                { 
"school" : 
"zhongnian", 
"degree" : 
"graduates" }, 
                { 
"school" : 
"cr", 
"degree" : 
"graduates" } ] }
        // 下面这个格式有问题
        // 虽然从json内容看不出来, 但是报错原因为degrees下的复合数据要加标号
        // 数组的数据必须加数组下标
        [person] {
            
"name" : { 
"first" : 
"lostspeed", 
"last" : 
"cn" },
            
"birthday" : { 
"$date" : 
105087610000 },
            
"skill" : [ 
"C", 
"C++", 
"MASM", 
"RE" ],
            
"degrees" : [
                { 
"school" : 
"zhongnian", 
"degree" : 
"graduates" },
                { 
"school" : 
"cr", 
"degree" : 
"graduates" } ]
                }
        */
        bRc = DbOptAddDocument(collection, document, &
error);
        
if (bRc) {
            printf(
"CURD-add ok\n");
        } 
else {
            ShowErrMsg(
"CURD-add", &
error);
        }
    } 
while (
0);
    
if (NULL != document) {
        bson_destroy(document);
    }
    
if (NULL != collection) {
        mongoc_collection_destroy(collection);
    }
    
if (NULL != database) {
        mongoc_database_destroy(database);
    }
    
if (NULL != client) {
        mongoc_client_destroy(client);
    }
    
return 0;
}
int testcase_mongoc_example_command_simple(int argc, char* argv[])
{
    mongoc_client_t* client = NULL;
    mongoc_database_t* database = NULL;
    mongoc_collection_t* collection = NULL;
    bson_t* insert = NULL;
    bson_error_t 
error;
    bool retval = 
false;
    mongoc_init();
    client = mongoc_client_new(
"mongodb://localhost:27017");
    /*
     * Register the application name so we can track it 
in the profile logs
     * on the server. This can also be done from the URI (see other examples).
     */
    mongoc_client_set_appname(client, 
"connect-example");
    database = mongoc_client_get_database(client, 
"db_name");
    collection = mongoc_client_get_collection(client, 
"db_name", 
"coll_name");
    // cmd :  ping
    retval = DbOptExec_command_simple(client, 
"admin", 
"ping", &
error);
    
if (!retval) {
        ShowErrMsg(
"ping", &
error);
        
return EXIT_FAILURE;
    }
    /**
    [ping] { 
"ok" : 
1.0 }
    */
    insert = BCON_NEW(
"hello", BCON_UTF8(
"world"));
    
if (!mongoc_collection_insert(
                collection, MONGOC_INSERT_NONE, insert, NULL, &
error)) {
        ShowErrMsg(
"mongoc_collection_insert", &
error);
    }
    // cmd : buildinfo
    bson_destroy(insert);
    retval = DbOptExec_command_simple(client, 
"admin", 
"buildinfo", &
error);
    
if (!retval) {
        ShowErrMsg(
"buildinfo", &
error);
    }
    /**
    [buildinfo] {
        
"version" : 
"2.6.10",
        
"gitVersion" : 
"5901dbfb49d16eaef6f2c2c50fba534d23ac7f6c",
        
"OpenSSLVersion" : 
"",
        
"sysInfo" : 
"Linux build18.nj1.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49",
        
"loaderFlags" : 
"-fPIC -pthread -Wl,-z,now -rdynamic",
        
"compilerFlags" : 
"-Wnon-virtual-dtor -Woverloaded-virtual -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -pipe -Werror -O3 -Wno-unused-function -Wno-deprecated-declarations -fno-builtin-memcmp",
        
"allocator" : 
"tcmalloc",
        
"versionArray" : [ 
2, 
6, 
10, 
0 ],
        
"javascriptEngine" : 
"V8",
        
"bits" : 
64,
        
"debug" : 
false,
        
"maxBsonObjectSize" : 
16777216,
        
"ok" : 
1.0 }
    */
    // cmd : serverStatus
    retval = DbOptExec_command_simple(client, 
"admin", 
"serverStatus", &
error);
    
if (!retval) {
        ShowErrMsg(
"serverStatus", &
error);
    }
    /**
    [serverStatus]
    {
    
"host" : 
"debian",
    
"version" : 
"2.6.10",
    
"process" : 
"mongod",
    
"pid" : 
3243,
    
"uptime" : 
21899.0,
    
"uptimeMillis" : 
21897854,
    
"uptimeEstimate" : 
19920.0,
    
"localTime" : { 
"$date" : 
1491227764737 },
    
"asserts" : { 
"regular" : 
0, 
"warning" : 
0, 
"msg" : 
0, 
"user" : 
0, 
"rollovers" : 
0 },
    
"backgroundFlushing" : { 
"flushes" : 
364, 
"total_ms" : 
54, 
"average_ms" : 
0.14835164835164835195, 
"last_ms" : 
0, 
"last_finished" : { 
"$date" : 
1491227708337 } },
    
"connections" : { 
"current" : 
1, 
"available" : 
818, 
"totalCreated" : 
9 },
    
"cursors" : { 
"note" : 
"deprecated, use server status metrics", 
"clientCursors_size" : 
0, 
"totalOpen" : 
0, 
"pinned" : 
0, 
"totalNoTimeout" : 
0, 
"timedOut" : 
0 },
    
"dur" : { 
"commits" : 
29, 
"journaledMB" : 
0.0, 
"writeToDataFilesMB" : 
0.0, 
"compression" : 
0.0, 
"commitsInWriteLock" : 
0, 
"earlyCommits" : 
0,
    
"timeMs" : { 
"dt" : 
3044, 
"prepLogBuffer" : 
0, 
"writeToJournal" : 
0, 
"writeToDataFiles" : 
0, 
"remapPrivateView" : 
0 } },
    
"extra_info" : { 
"note" : 
"fields vary by platform", 
"heap_usage_bytes" : 
62725408, 
"page_faults" : 
98 },
    
"globalLock" : { 
"totalTime" : 
21897856000, 
"lockTime" : 
5334268,
    
"currentQueue" : { 
"total" : 
0, 
"readers" : 
0, 
"writers" : 
0 },
    
"activeClients" : { 
"total" : 
0, 
"readers" : 
0, 
"writers" : 
0 } },
    
"indexCounters" : { 
"accesses" : 
19, 
"hits" : 
19, 
"misses" : 
0, 
"resets" : 
0, 
"missRatio" : 
0.0 },
    
"locks" : { 
"." : {
    
"timeLockedMicros" : { 
"R" : 
435761, 
"W" : 
5334268 },
    
"timeAcquiringMicros" : { 
"R" : 
4899977, 
"W" : 
2994540 } },
    
"admin" : { 
"timeLockedMicros" : { 
"r" : 
151982, 
"w" : 
0 },
    
"timeAcquiringMicros" : { 
"r" : 
369253, 
"w" : 
0 } },
    
"local" : { 
"timeLockedMicros" : { 
"r" : 
128739, 
"w" : 
83 }, 
"timeAcquiringMicros" : { 
"r" : 
54838, 
"w" : 
1 } },
    
"testdb" : { 
"timeLockedMicros" : { 
"r" : 
2081468, 
"w" : 
130 }, 
"timeAcquiringMicros" : { 
"r" : 
19698, 
"w" : 
3 } },
    
"mongodb" : { 
"timeLockedMicros" : { 
"r" : 
191151, 
"w" : 
128 }, 
"timeAcquiringMicros" : { 
"r" : 
30413, 
"w" : 
4 } },
    
"db_name" : { 
"timeLockedMicros" : { 
"r" : 
375654, 
"w" : 
908 }, 
"timeAcquiringMicros" : { 
"r" : 
14419, 
"w" : 
40 } },
    
"Barca" : { 
"timeLockedMicros" : { 
"r" : 
158307, 
"w" : 
134 }, 
"timeAcquiringMicros" : { 
"r" : 
19699, 
"w" : 
3 } },
    
"dbs" : { 
"timeLockedMicros" : { 
"r" : 
610389, 
"w" : 
224 }, 
"timeAcquiringMicros" : { 
"r" : 
17663, 
"w" : 
6 } },
    
"test1" : { 
"timeLockedMicros" : { 
"r" : 
829203, 
"w" : 
28 }, 
"timeAcquiringMicros" : { 
"r" : 
15951, 
"w" : 
2 } },
    
"yekai" : { 
"timeLockedMicros" : { 
"r" : 
2065973, 
"w" : 
269 }, 
"timeAcquiringMicros" : { 
"r" : 
61179, 
"w" : 
4 } },
    
"tutorial" : { 
"timeLockedMicros" : { 
"r" : 
1491259, 
"w" : 
157 }, 
"timeAcquiringMicros" : { 
"r" : 
28555, 
"w" : 
3 } } },
    
"network" : { 
"bytesIn" : 
5730, 
"bytesOut" : 
13310, 
"numRequests" : 
44 },
    
"opcounters" : { 
"insert" : 
9, 
"query" : 
3641, 
"update" : 
0, 
"delete" : 
0, 
"getmore" : 
0, 
"command" : 
38 },
    
"opcountersRepl" : { 
"insert" : 
0, 
"query" : 
0, 
"update" : 
0, 
"delete" : 
0, 
"getmore" : 
0, 
"command" : 
0 },
    
"recordStats" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0,
    
"Barca" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"admin" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"db_name" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"dbs" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"local" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"mongodb" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"test1" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"testdb" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"tutorial" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 },
    
"yekai" : { 
"accessesNotInMemory" : 
0, 
"pageFaultExceptionsThrown" : 
0 } },
    
"writeBacksQueued" : 
false,
    
"mem" : { 
"bits" : 
64, 
"resident" : 
158, 
"virtual" : 
62683, 
"supported" : 
true, 
"mapped" : 
31251, 
"mappedWithJournal" : 
62502 },
    
"metrics" : { 
"cursor" : { 
"timedOut" : 
0, 
"open" : { 
"noTimeout" : 
0, 
"pinned" : 
0, 
"total" : 
0 } },
    
"document" : { 
"deleted" : 
0, 
"inserted" : 
9, 
"returned" : 
0, 
"updated" : 
0 },
    
"getLastError" : { 
"wtime" : { 
"num" : 
0, 
"totalMillis" : 
0 }, 
"wtimeouts" : 
0 },
    
"operation" : { 
"fastmod" : 
0, 
"idhack" : 
0, 
"scanAndOrder" : 
0 },
    
"queryExecutor" : { 
"scanned" : 
0, 
"scannedObjects" : 
0 },
    
"record" : { 
"moves" : 
0 },
    
"repl" : {
    
"apply" : { 
"batches" : { 
"num" : 
0, 
"totalMillis" : 
0 }, 
"ops" : 
0 },
    
"buffer" : { 
"count" : 
0, 
"maxSizeBytes" : 
268435456, 
"sizeBytes" : 
0 },
    
"network" : { 
"bytes" : 
0, 
"getmores" : { 
"num" : 
0, 
"totalMillis" : 
0 }, 
"ops" : 
0, 
"readersCreated" : 
0 },
    
"preload" : { 
"docs" : { 
"num" : 
0, 
"totalMillis" : 
0 }, 
"indexes" : { 
"num" : 
0, 
"totalMillis" : 
0 } } },
    
"storage" : { 
"freelist" : { 
"search" : { 
"bucketExhausted" : 
0, 
"requests" : 
8, 
"scanned" : 
16 } } },
    
"ttl" : { 
"deletedDocuments" : 
0, 
"passes" : 
364 } },
    
"ok" : 
1.0 }
    */
    // cmd : ismaster
    retval = DbOptExec_command_simple(client, 
"admin", 
"ismaster", &
error);
    
if (!retval) {
        ShowErrMsg(
"ismaster", &
error);
    }
    /**
    [ismaster] {
        
"ismaster" : 
true,
        
"maxBsonObjectSize" : 
16777216,
        
"maxMessageSizeBytes" : 
48000000,
        
"maxWriteBatchSize" : 
1000,
        
"localTime" : { 
"$date" : 
1491230240360 },
        
"maxWireVersion" : 
2,
        
"minWireVersion" : 
0,
        
"ok" : 
1.0
        }
    */
    // cmd : getlasterror
    retval = DbOptExec_command_simple(client, 
"admin", 
"getlasterror", &
error);
    
if (!retval) {
        ShowErrMsg(
"getlasterror", &
error);
    }
    /**
    [getlasterror] {
        
"connectionId" : 
11,
        
"n" : 
0,
        
"syncMillis" : 
0,
        
"writtenTo" : null,
        
"err" : null,
        
"ok" : 
1.0
        }
    */
    // cmd : foo
    retval = DbOptExec_command_simple(client, 
"admin", 
"foo", &
error);
    
if (!retval) {
        ShowErrMsg(
"foo", &
error);
    }
    /**
    [foo] 
error : no such cmd: foo
    */
    // cmd : empty
    // 空命令会报错的
    //     retval = DbOptExec_command_simple(client, 
"admin", 
"{}", &
error);
    //
    //     
if (!retval) {
    //         ShowErrMsg(
"{}", &
error);
    //     }
    // cmd : empty
    retval = DbOptExec_command_simple(client, 
"admin", 
"", &
error);
    
if (!retval) {
        ShowErrMsg(
"", &
error);
    }
    /**
    [] 
error : no such cmd:
    */
    // cmd : db
    retval = DbOptExec_command_simple(client, 
"admin", 
"db", &
error);
    
if (!retval) {
        ShowErrMsg(
"db", &
error);
    }
    /**
    [db] 
error : no such cmd: db
    */
    /**
    MongoDB shell version: 
2.6.10
    connecting to: test
    > show dbs
    Barca      
0.078GB
    admin      
0.078GB
    db_name    
0.078GB
    
local      0.078GB
    mongodb    
0.078GB
    test1      
0.078GB
    testdb     
0.078GB
    tutorial   
0.078GB
    yekai      
7.950GB
    >
      > use test1
      switched to db test1
      > show collections
      system.indexes
      test1
      >
    */
    // cmd : 
"{'drop': '%s'}"
    retval = DbOptExec_command_simple(client, 
"admin", 
"use", 
"test1", &
error);
    
if (!retval) {
        ShowErrMsg(
"use test1", &
error);
    }
    /**
    [use test1] 
error : no such cmd: use
    */
    retval = DbOptExec_command_simple(client, 
"test1", 
"drop", 
"test1", &
error);
    
if (!retval) {
        ShowErrMsg(
"drop test1", &
error);
    }
    /**
    [drop] { 
"ns" : 
"test1.test1", 
"nIndexesWas" : 
1, 
"ok" : 
1.0 }
    */
    /** mongo console
    > use test1
    switched to db test1
    > show collections
    system.indexes
    >
    */
    // cmd : getCmdLineOpts
    retval = DbOptExec_command_simple(client, 
"admin", 
"getCmdLineOpts", &
error);
    
if (!retval) {
        ShowErrMsg(
"getCmdLineOpts", &
error);
    }
    /**
    [getCmdLineOpts] {
        
"argv" : [ 
"\/usr\/local\/mongodb\/bin\/mongod", 
"--config", 
"\/usr\/local\/mongodb\/bin\/mongodb.conf" ],
        
"parsed" : {
            
"config" : 
"\/usr\/local\/mongodb\/bin\/mongodb.conf",
            
"net" : { 
"http" : { 
"enabled" : 
false }, 
"port" : 
27017 },
            
"processManagement" : { 
"fork" : 
true },
            
"storage" : { 
"dbPath" : 
"\/usr\/local\/mongodb\/db" },
            
"systemLog" : { 
"destination" : 
"file", 
"path" : 
"\/usr\/local\/mongodb\/logs\/mongodb.log" }
            },
        
"ok" : 
1.0
        }
    */
    mongoc_collection_destroy(collection);
    mongoc_database_destroy(database);
    mongoc_client_destroy(client);
    mongoc_cleanup();
    
return 0;
}
 
#if !defined(AFX_BUSINESSLOGIC_H__91436BA7_97DD_495E_A750_A141145804E1__INCLUDED_)
#define AFX_BUSINESSLOGIC_H__91436BA7_97DD_495E_A750_A141145804E1__INCLUDED_
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
#ifndef BOOL
typedef 
bool BOOL;
#define TRUE 1
#define FALSE 0
#endif // #ifndef BOOL
typedef 
struct _tag_name {
    
const char* first;
    
const char* last;
} TAG_NAME;
typedef 
struct _tag_degress {
    
const char* school;
    
const char* degree;
} TAG_DEGRESS;
typedef 
struct _tag_person_info {
    TAG_NAME name;
    
struct tm birthday;
    
const char* skillAry[
10];
    TAG_DEGRESS degreeAry[
10];
} TAG_PERSON_INFO;
void fill_TAG_PERSON_INFO(bson_t* document, TAG_PERSON_INFO* person);
#endif // !defined(AFX_BUSINESSLOGIC_H__91436BA7_97DD_495E_A750_A141145804E1__INCLUDED_)
 
#include "BusinessLogic.h"
void fill_TAG_PERSON_INFO(bson_t* document, TAG_PERSON_INFO* person)
{
    
int i = 
0;
    
int iArySize = 
0;
    bson_t child;
    bson_t child2;
    
const char* key = NULL;
    size_t keylen = 
0;
    
char buf[
32] = {
'\0'};
    
if ((NULL == document) || (NULL == person)) {
        
return;
    }
    bson_append_document_begin(document, 
"name", -
1, &child);
    BSON_APPEND_UTF8(&child, 
"first", person->name.first);
    BSON_APPEND_UTF8(&child, 
"last", person->name.last);
    bson_append_document_end(document, &child);
    BSON_APPEND_DATE_TIME(document, 
"birthday", mktime(&person->birthday) * 
1000);
    bson_append_array_begin(document, 
"skill", -
1, &child);
    iArySize = 
sizeof(person->skillAry) / 
sizeof(
char*);
    
for (i = 
0; i < iArySize; i++) {
        
if (NULL == person->skillAry[i]) {
            
break;
        }
        keylen = bson_uint32_to_string(i + 
1, &key, buf, 
sizeof buf);
        bson_append_utf8(&child, key, (
int) keylen, person->skillAry[i], -
1);
    }
    bson_append_array_end(document, &child);
    bson_append_array_begin(document, 
"degrees", -
1, &child);
    iArySize = 
sizeof(person->degreeAry) / 
sizeof(TAG_DEGRESS);
    
for (i = 
0; i < iArySize; i++) {
        
if ((NULL == person->degreeAry[i].degree) || (NULL == person->degreeAry[i].school)) {
            
break;
        }
        
        
        
        
        keylen = bson_uint32_to_string (i, &key, buf, 
sizeof buf);
        bson_append_document_begin(&child, key, keylen, &child2);
        bson_append_utf8(&child2, 
"school", -
1, person->degreeAry[i].school, -
1);
        bson_append_utf8(&child2, 
"degree", -
1, person->degreeAry[i].degree, -
1);
        bson_append_document_end(&child, &child2);
    }
    bson_append_array_end(document, &child);
} 
#ifndef __MONGODB_EX__
#define __MONGODB_EX__
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
#ifndef BOOL
typedef 
bool BOOL;
#define TRUE 1
#define FALSE 0
#endif // #ifndef BOOL
BOOL DbOptInit();
BOOL DbOptUnInit();
mongoc_client_t* DbOptOpenConect(
const char* pConnectUrl);
void DbOptCloseConect(mongoc_client_t*& pDbConnect);
mongoc_database_t* DbOptOpenDb(mongoc_client_t* pDbConnect, 
const char* pDbName);
void DbOptCloseDb(mongoc_database_t*& pDb);
mongoc_collection_t* DbOptOpenTbl(mongoc_database_t* pDb, 
const char* pTblName);
void DbOptCloseTbl(mongoc_collection_t*& pTbl);
bool DbOptExec_command_simple(
    mongoc_client_t* pClient,
    
const char* pcDbName,
    
const char* pcCommand,
    bson_error_t* pError);
bool DbOptExec_command_simple(
    mongoc_client_t* pClient,
    
const char* pcDbName,
    
const char* pcCommand,
    
const char* pcValue,
    bson_error_t* pError);
bool DbOptAddDocument(mongoc_collection_t*& pTbl, bson_t* document, bson_error_t* error);
void ShowErrMsg(
const char* pTip, bson_error_t* error);
void ShowReply(
const char* pTip, bson_t* reply);
void ShowDocument(
const char* pTip, bson_t* document);
bson_t* new_formatv_bson(
const char* json, ...);
char* single_quotes_to_double(
const char* str);
#endif // #ifndef __MONGODB_EX__ 
#include "MongoDbEx.h"
BOOL DbOptInit()
{
    mongoc_init();
}
BOOL DbOptUnInit()
{
    mongoc_cleanup();
}
mongoc_client_t* DbOptOpenConect(
const char* pConnectUrl)
{
    mongoc_client_t* pDbClient = 
NULL;
    
if (
NULL != pConnectUrl) {
        pDbClient = mongoc_client_new(pConnectUrl);
    }
    
return pDbClient;
}
void DbOptCloseConect(mongoc_client_t*& pDbConnect)
{
    
if (
NULL != pDbConnect) {
        mongoc_client_destroy(pDbConnect);
        pDbConnect = 
NULL;
    }
}
mongoc_database_t* DbOptOpenDb(mongoc_client_t* pDbConnect, 
const char* pDbName)
{
    mongoc_database_t* pDb = 
NULL;
    
if (
NULL != pDbConnect) {
        pDb = mongoc_client_get_database(pDbConnect, pDbName);
    }
    
return pDb;
}
void DbOptCloseDb(mongoc_database_t*& pDb)
{
    
if (
NULL != pDb) {
        mongoc_database_destroy(pDb);
        pDb = 
NULL;
    }
}
mongoc_collection_t* DbOptOpenTbl(mongoc_database_t* pDb, 
const char* pTblName)
{
    mongoc_collection_t* pTbl = 
NULL;
    pTbl = mongoc_database_get_collection(pDb, pTblName);
    
return pTbl;
}
void DbOptCloseTbl(mongoc_collection_t*& pTbl)
{
    
if (
NULL != pTbl) {
        mongoc_collection_destroy(pTbl);
        pTbl = 
NULL;
    }
}
bool DbOptExec_command_simple(
    mongoc_client_t* pClient,
    
const char* pcDbName,
    
const char* pcCommand,
    bson_error_t* pError)
{
    
bool retval = 
false;
    bson_t* command = 
NULL;
    bson_t reply;
    
do {
        command = BCON_NEW(pcCommand, BCON_INT32(
1));
        
        retval = mongoc_client_command_simple(pClient, pcDbName, command, 
NULL, &reply, pError);
        
if (!retval) {
            
break;
        } 
else {
            ShowReply(pcCommand, &reply);
        }
    } 
while (
0);
    bson_destroy(&reply);
    bson_destroy(command);
    
return retval;
}
bool DbOptExec_command_simple(
    mongoc_client_t* pClient,
    
const char* pcDbName,
    
const char* pcCommand,
    
const char* pcValue,
    bson_error_t* pError)
{
    
bool retval = 
false;
    bson_t reply;
    bson_t* doc = 
NULL;
    
char* sz_cmd = 
NULL;
    
do {
        
        sz_cmd = bson_strdup_printf(
"{'%s': '%s'}", pcCommand, pcValue);
        doc = new_formatv_bson(
"%s", sz_cmd);
        retval = mongoc_client_command_simple(pClient, pcDbName, doc, 
NULL, &reply, pError);
        bson_free(sz_cmd);
        
if (!retval) {
            
break;
        } 
else {
            ShowReply(pcCommand, &reply);
        }
    } 
while (
0);
    bson_destroy(&reply);
    bson_destroy(doc);
    
return retval;
}
bool DbOptAddDocument(mongoc_collection_t*& pTbl, bson_t* document, bson_error_t* error)
{
    
bool bRc = 
false;
    
do {
        
if ((
NULL == pTbl) || (
NULL == document) || (
NULL == error)) {
            
break;
        }
        bRc = mongoc_collection_insert(pTbl, MONGOC_INSERT_NONE, document, 
NULL, error);
    } 
while (
0);
    
return bRc;
}
void ShowErrMsg(
const char* pTip, bson_error_t* error)
{
    
if (
NULL != error) {
        fprintf(stderr, 
"[%s] error : %s\n\n", (
NULL != pTip) ? pTip : 
"", error->message);
    }
}
void ShowReply(
const char* pTip, bson_t* reply)
{
    
char* str = 
NULL;
    
if (
NULL != reply) {
        str = bson_as_json(reply, 
NULL);
        
if (
NULL != str) {
            printf(
"[%s] %s\n\n", (
NULL != pTip) ? pTip : 
"", str);
            bson_free(str);
        }
    }
}
void ShowDocument(
const char* pTip, bson_t* document)
{
    
char* str = 
NULL;
    
if (
NULL != document) {
        str = bson_as_json(document, 
NULL);
        
if (
NULL != str) {
            printf(
"[%s] %s\n\n", (
NULL != pTip) ? pTip : 
"", str);
            bson_free(str);
        }
    }
}
bson_t* new_formatv_bson(
const char* json, ...)
{
    va_list args;
    bson_error_t error;
    
char* formatted;
    
char* double_quoted;
    bson_t* doc;
    
if (json) {
        va_start(args, json);
        formatted = bson_strdupv_printf(json, args);
        va_end(args);
        double_quoted = single_quotes_to_double(formatted);
        doc = bson_new_from_json((
const uint8_t*) double_quoted, -
1, &error);
        
if (!doc) {
            fprintf(stderr, 
"%s\n", error
.message);
            abort();
        }
        bson_free(formatted);
        bson_free(double_quoted);
    } 
else {
        doc = bson_new();
    }
    
return doc;
}
char* single_quotes_to_double(
const char* str)
{
    
char* result = bson_strdup(str);
    
char* p;
    
for (p = result; *p; p++) {
        
if (*p == 
'\'') {
            *p = 
'"';
        }
    }
    
return result;
}
 
# testcase by lostspeed
# first build do : chmod 777 *
# build cmd is : ./Makefile
clear
rm ./testcase
rm ./*.o
# MongoDbEx.cpp
g++ -c MongoDbEx.cpp -o MongoDbEx.o \
-
I/usr/local/mongo_c162_driver/include/libmongoc-1.0 \
-
I/usr/local/mongo_c162_driver/include/libbson-1.0 \
-
L/usr/local/lib \
-
L/usr/local/mongo_c162_driver/lib \
-
lpthread \
-
lmongoc-1.0 \
-
lbson-1.0
# BusinessLogic.cpp
g++ -c BusinessLogic.cpp -o BusinessLogic.o \
-
I/usr/local/mongo_c162_driver/include/libmongoc-1.0 \
-
I/usr/local/mongo_c162_driver/include/libbson-1.0 \
-
L/usr/local/lib \
-
L/usr/local/mongo_c162_driver/lib \
-
lpthread \
-
lmongoc-1.0 \
-
lbson-1.0
# testcase_main.cpp
g++ testcase_main.cpp BusinessLogic.o MongoDbEx.o -o testcase \
-
I/usr/local/mongo_c162_driver/include/libmongoc-1.0 \
-
I/usr/local/mongo_c162_driver/include/libbson-1.0 \
-
L/usr/local/lib \
-
L/usr/local/mongo_c162_driver/lib \
-
lpthread \
-
lmongoc-1.0 \
-
lbson-1.0
ls
./testcase