Mongo数据库(C驱动),将一条查询记录按脚本格式输出至std::string中

由于工作需要将一条Mongo数据库的查询记录,输出成脚本格式。现记录关键代码,方便使用。Mongo数据库 C语言驱动的基础使用不做介绍。


用例数据:

    /* Create a rich document like this one:
     *
     * { _id: ObjectId("4d95ea712b752328eb2fc2cc"),
     *   user_id: ObjectId("4d95ea712b752328eb2fc2cd"),
     *
     *   items: [
     *     { sku: "col-123",
     *       name: "John Coltrane: Impressions",
     *       price: 1099,
     *     },
     *
     *     { sku: "young-456",
     *       name: "Larry Young: Unity",
     *       price: 1199
     *     }
     *   ],
     *
     *   address: {
     *     street: "59 18th St.",
     *     zip: 10010
     *   },
     *
     *   total: 2298
     * }
     */

    bson_init( &b );
    bson_append_new_oid( &b, "_id" );
    bson_append_new_oid( &b, "user_id" );

    bson_append_start_array( &b, "items" );
    bson_append_start_object( &b, "book0" );
    bson_append_string( &b, "sku", "col-123" );
    bson_append_string( &b, "name", "John Coltrane: Impressions" );
    bson_append_int( &b, "price", 1099 );
    bson_append_finish_object( &b );

    bson_append_start_object( &b, "book1" );
    bson_append_string( &b, "sku", "young-456" );
    bson_append_string( &b, "name", "Larry Young: Unity" );
    bson_append_int( &b, "price", 1199 );
    bson_append_finish_object( &b );
    bson_append_finish_object( &b );

    bson_append_start_object( &b, "address" );
    bson_append_string( &b, "street", "59 18th St." );
    bson_append_int( &b, "zip", 10010 );
    bson_append_finish_object( &b );

    bson_append_int( &b, "total", 2298 );
    bson_finish( &b );

格式输出函数借鉴的Mongo C驱动源码如下:

MONGO_EXPORT void bson_print_raw( const char *data , int depth ) {
    bson_iterator i;
    const char *key;
    int temp;
    bson_timestamp_t ts;
    char oidhex[25];
    bson scope;
    bson_iterator_from_buffer( &i, data );

    while ( bson_iterator_next( &i ) ) {
        bson_type t = bson_iterator_type( &i );
        if ( t == 0 )
            break;
        key = bson_iterator_key( &i );

        for ( temp=0; temp<=depth; temp++ )
            bson_printf( "\t" );
        bson_printf( "%s : %d \t " , key , t );
        switch ( t ) {
        case BSON_DOUBLE:
            bson_printf( "%f" , bson_iterator_double( &i ) );
            break;
        case BSON_STRING:
            bson_printf( "%s" , bson_iterator_string( &i ) );
            break;
        case BSON_SYMBOL:
            bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
            break;
        case BSON_OID:
            bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
            bson_printf( "%s" , oidhex );
            break;
        case BSON_BOOL:
            bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
            break;
        case BSON_DATE:
            bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) );
            break;
        case BSON_BINDATA:
            bson_printf( "BSON_BINDATA" );
            break;
        case BSON_UNDEFINED:
            bson_printf( "BSON_UNDEFINED" );
            break;
        case BSON_NULL:
            bson_printf( "BSON_NULL" );
            break;
        case BSON_REGEX:
            bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
            break;
        case BSON_CODE:
            bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
            break;
        case BSON_CODEWSCOPE:
            bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
            /* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */
            bson_iterator_code_scope( &i, &scope );
            bson_printf( "\n\t SCOPE: " );
            bson_print( &scope );
            /* bson_destroy( &scope ); */ /* review - causes free error */
            break;
        case BSON_INT:
            bson_printf( "%d" , bson_iterator_int( &i ) );
            break;
        case BSON_LONG:
            bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) );
            break;
        case BSON_TIMESTAMP:
            ts = bson_iterator_timestamp( &i );
            bson_printf( "i: %d, t: %d", ts.i, ts.t );
            break;
        case BSON_OBJECT:
        case BSON_ARRAY:
            bson_printf( "\n" );
            bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
            break;
        default:
            bson_errprintf( "can't print type : %d\n" , t );
        }
        bson_printf( "\n" );
    }
}

修改之后的接口:

void bson_print_raw_to_string( const char *data , const string& strPrefix, string& strOutput ) {
    bson_iterator i;
    const char *key;
    bson_timestamp_t ts;
    char oidhex[25];
    const int nOutputSize = 1024;
    char szOutput[nOutputSize] = {0};
    bson scope;
    bson_iterator_from_buffer( &i, data );

    while ( bson_iterator_next( &i ) ) {
        bson_type t = bson_iterator_type( &i );
        if ( t == 0 )
            break;
        key = bson_iterator_key( &i );

        switch ( t ) {
        case BSON_DOUBLE:
            sprintf_s( szOutput, nOutputSize, "%f" , bson_iterator_double( &i ) );
            break;
        case BSON_STRING:
            sprintf_s( szOutput, nOutputSize, "%s" , bson_iterator_string( &i ) );
            break;
        case BSON_SYMBOL:
            sprintf_s( szOutput, nOutputSize, "%s" , bson_iterator_string( &i ) );
            break;
        case BSON_OID:
            bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
            sprintf_s( szOutput, nOutputSize, "%s" , oidhex );
            break;
        case BSON_BOOL:
            sprintf_s( szOutput, nOutputSize, "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
            break;
        case BSON_DATE:
            sprintf_s( szOutput, nOutputSize, "%ld" , ( long int )bson_iterator_date( &i ) );
            break;
        case BSON_INT:
            sprintf_s( szOutput, nOutputSize, "%d" , bson_iterator_int( &i ) );
            break;
        case BSON_LONG:
            sprintf_s( szOutput, nOutputSize, "%lld" , ( uint64_t )bson_iterator_long( &i ) );
            break;
        case BSON_TIMESTAMP:
            ts = bson_iterator_timestamp( &i );
            sprintf_s( szOutput, nOutputSize, "i: %d, t: %d", ts.i, ts.t );
            break;
        case BSON_OBJECT:
        case BSON_ARRAY:
            if (!strPrefix.empty())
            {
                bson_print_raw_to_string( bson_iterator_value( &i ) , strPrefix+"."+string(key), strOutput );
            }
            else
            {
                bson_print_raw_to_string( bson_iterator_value( &i ) , string(key), strOutput );
            }
            
            break;
        default:
            break;
        }
        
        string strValue(szOutput);
        if (!strValue.empty())
        {
            if (!strPrefix.empty())
            {
                strOutput += strPrefix + "." + string(key) + ":=\"" + strValue + "\";\n";
            }
            else
            {
                strOutput += string(key) + ":=\"" + strValue + "\";\n";
            }
        }

        memset(szOutput, 0, nOutputSize);
    }
}

上面只处理了我需要使用的Mongo字段参数类型,其它字段可参照驱动源码自行添加。将上方的用例调用修改后的接口查询输出后,显示如下:

_id:="5560c19b4278000000000000";
user_id:="5560c19b4278000000000001";
items.book0.sku:="col-123";
items.book0.name:="John Coltrane: Impressions";
items.book0.price:="1099";
items.book1.sku:="young-456";
items.book1.name:="Larry Young: Unity";
items.book1.price:="1199";
address.street:="59 18th St.";
address.zip:="10010";
total:="2298";


至此能够满足基本使用要求。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值