封装类
#pragma once
#include <bson.h>
#include <bson/bson.h>
#include <mongoc.h>
#include <string>
#include <vector>
class mongoClient
{
public:
mongoClient();
bool Connect(std::string& dbAddr,std::string& dbName);
bool CreateCollections(std::string& dbName, std::string& colName, std::string& command);
bool UpdateCollections(std::string& dbName, std::string& colName, std::string& oldItem, std::string& newItem);
bool InsertCollections(std::string& dbName, std::string& colName, std::string& command);
bool DelCollections(std::string& dbName, std::string& colName, std::string& command);
bool DelCollectionsAll(std::string& dbName, std::string& colName, std::string& command);
bool QueryCollections(std::string& dbName, std::string& colName, std::string& queryCondition,std::vector<std::string>& queryResult);
int ExampleInsert();
int ExampleFind();
int Example3();
~mongoClient();
private:
bool _bConnect=false;
mongoc_client_t *_client;
mongoc_database_t *_database;
};
//Authors Yongjiu,Ou (964358093@qq.com)
#include "mongoClient.h"
#include "logging.h"
#include <iconv.h>
#include <locale.h>
using namespace std;
static int gbk2utf8(char *inbuf, size_t inlen, char *outbuf, size_t outlen);
static void gbk2utf8(std::string& gbk, std::string& utf8);
mongoClient::mongoClient()
{
}
bool mongoClient::Connect(std::string& dbAddr, std::string& dbName)
{
bson_t *command, reply;
bson_error_t err;
bool retval;
if (_bConnect)return true;
mongoc_init();
_client = mongoc_client_new(dbAddr.c_str());
if (!_client){
mongoc_cleanup();
return false;
}
_database = mongoc_client_get_database(_client, dbName.c_str());
if (!_database){
mongoc_client_destroy(_client);
mongoc_cleanup();
return false;
}
command = BCON_NEW("ping", BCON_INT32(1));
retval = mongoc_client_command_simple(_client, dbName.c_str(), command, NULL, &reply, &err);
bson_destroy(command);
if (!retval){
mongoc_database_destroy(_database);
mongoc_client_destroy(_client);
mongoc_cleanup();
return false;
}
_bConnect = true;
}
bool mongoClient::CreateCollections(std::string& dbName,std::string& colName, std::string& command)
{
if (!_bConnect)return false;
return true;
}
bool mongoClient::UpdateCollections(std::string& dbName, std::string& colName, std::string& oldItem, std::string& newItem)
{
if (!_bConnect)return false;
mongoc_collection_t *collection = mongoc_client_get_collection(_client, dbName.c_str(), colName.c_str());
if (!collection){
error("Insert opt. Get col error\n");
return false;
}
string utf8value;
gbk2utf8(oldItem, utf8value);
bson_error_t err;
bson_t *doc = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!doc){
error("query cmd %s\n", oldItem.c_str());
error("query err %s\n", err.message);
mongoc_collection_destroy(collection);
return false;
}
utf8value.clear();
gbk2utf8(newItem, utf8value);
bson_t *newdoc = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!newdoc){
error("query cmd %s\n", newItem.c_str());
error("query err %s\n", err.message);
bson_destroy(doc);
mongoc_collection_destroy(collection);
return false;
}
int b=mongoc_collection_update(collection, MONGOC_UPDATE_MULTI_UPDATE, doc, newdoc, NULL, &err);
bool bret=true;
if (!b){ error("%s\n", err.message); bret = false; }
mongoc_collection_destroy(collection);
bson_destroy(doc);
bson_destroy(newdoc);
return bret;
}
bool mongoClient::InsertCollections(std::string& dbName, std::string& colName, std::string& command)
{
if (!_bConnect)return false;
mongoc_collection_t *collection= mongoc_client_get_collection(_client, dbName.c_str(), colName.c_str());
if (!collection){
error("Insert opt. Get col error\n");
return false;
}
string utf8value;
gbk2utf8(command, utf8value);
bson_error_t err;
bson_t *doc = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!doc){
error("query cmd %s\n", command.c_str());
error("query err %s\n", err.message);
mongoc_collection_destroy(collection);
return false;
}
int b = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, doc, NULL, &err);
bool bret = true;
if (!b){ bret = false; error("%s\n", err.message); }
mongoc_collection_destroy(collection);
bson_destroy(doc);
return bret;
}
bool mongoClient::DelCollections(std::string& dbName, std::string& colName, std::string& command)
{
if (!_bConnect)return false;
mongoc_collection_t *collection = mongoc_client_get_collection(_client, dbName.c_str(), colName.c_str());
if (!collection){
error("Del opt. get col error\n");
return false;
}
string utf8value;
gbk2utf8(command, utf8value);
bson_error_t err;
bson_t *doc = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!doc){
error("query cmd %s\n", command.c_str());
error("query err %s\n", err.message);
mongoc_collection_destroy(collection);
return false;
}
int b=mongoc_collection_remove(collection, MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &err);
bool bret = true;
if (!b){
bret = false;
error("Delete failed: %s\n", err.message);
}
bson_destroy(doc);
mongoc_collection_destroy(collection);
return bret;
}
bool mongoClient::DelCollectionsAll(std::string& dbName, std::string& colName, std::string& command)
{
if (!_bConnect)return false;
mongoc_collection_t *collection = mongoc_client_get_collection(_client, dbName.c_str(), colName.c_str());
if (!collection){ return false; }
string utf8value;
gbk2utf8(command, utf8value);
bson_error_t err;
bson_t *query = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!query){
error("query cmd %s\n", command.c_str());
error("query err %s\n", err.message);
mongoc_collection_destroy(collection);
return false;
}
mongoc_cursor_t *cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
if (!cursor){
error("find collection falied\n");
mongoc_collection_destroy(collection);
bson_destroy(query);
return false;
}
const bson_t *doc;
while (mongoc_cursor_next(cursor, &doc)) {
if (!mongoc_collection_remove(collection, MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &err)) {
break;
}
}
mongoc_cursor_destroy(cursor);
bson_destroy(query);
mongoc_collection_destroy(collection);
return true;
}
bool mongoClient::QueryCollections(std::string& dbName, std::string& colName, std::string& queryCondition, vector<std::string>& queryResult)
{
if (!_bConnect)return false;
mongoc_collection_t *collection= mongoc_client_get_collection(_client, dbName.c_str(), colName.c_str());
if (!collection){return false;}
string utf8value;
gbk2utf8(queryCondition, utf8value);
bson_error_t err;
bson_t *query;
if (queryCondition.empty())
query=bson_new();
else
query = bson_new_from_json((const uint8_t*)utf8value.c_str(), utf8value.length(), &err);
if (!query){
error("query cmd %s\n", queryCondition.c_str());
error("query err %s\n", err.message);
mongoc_collection_destroy(collection);
return false;
}
mongoc_cursor_t *cursor= mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
if (!cursor){
bson_destroy(query);
mongoc_collection_destroy(collection);
return false;
}
const bson_t *bson;
char *str;
while (mongoc_cursor_next(cursor,&bson)) {
str = bson_as_json(bson, NULL);
//trace("%s %s\n %s", dbName.c_str(), colName.c_str(),str);
if (str){
queryResult.push_back(string(str));
bson_free(str);
}
}
mongoc_cursor_destroy(cursor);
bson_destroy(query);
mongoc_collection_destroy(collection);
return true;
}
int mongoClient::ExampleFind()
{
mongoc_client_t *client;
mongoc_collection_t *collection;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
char *str;
mongoc_init();
client = mongoc_client_new("mongodb://localhost:27017/");
collection = mongoc_client_get_collection(client, "runoob", "col");
// query是一个空的BSON文档,用于做查询说明符的时候匹配所有文档。
//query = BCON_NEW("hello", BCON_UTF8("菜鸟教程"));;
query = bson_new();
//query=BCON_NEW("hello", "菜鸟教程");
//BSON_APPEND_UTF8(query, "hello", "菜鸟教程");
// 执行查询操作
cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
while (mongoc_cursor_next(cursor, &doc)) {
str = bson_as_json(doc, NULL);
printf("%s\n", str);
bson_free(str);
}
bson_destroy(query);
mongoc_cursor_destroy(cursor);
mongoc_collection_destroy(collection);
mongoc_client_destroy(client);
mongoc_cleanup();
return 0;
}
void gbk2utf8(std::string& gbk, std::string& utf8)
{
char dst[1024] = {0};
size_t dstlen = 1024;
if (gbk.length() > dstlen)return;
gbk2utf8((char*)gbk.c_str(), gbk.length(), dst, dstlen);
utf8.append(dst, strlen(dst));
}
int gbk2utf8(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open("UTF-8", "GB2312");
if (cd == 0)return -1;
memset(outbuf, 0, outlen);
iconv(cd, pin, (size_t*)&inlen, pout, (size_t*)&outlen);
iconv_close(cd);
return 0;
}
int mongoClient::Example3()
{
return 0;
}
int mongoClient::ExampleInsert()
{
mongoc_client_t *client;
mongoc_database_t *database;
mongoc_collection_t *collection;
bson_t *command,
reply,
*insert;
bson_error_t error;
char *str;
bool retval;
/*
* 初始化libmongoc's
*/
mongoc_init();
/*
* 创建一个新的client实例
*/
client = mongoc_client_new("mongodb://192.168.1.106:27017");
/*
* 获取数据库"db_name"和集合"coll_name"的句柄
*/
database = mongoc_client_get_database(client, "runoob");
collection = mongoc_client_get_collection(client, "runoob", "col");
/*
* 执行操作。此处以执行ping数据库,以json格式打印结果。并执行一个插入操作。
*/
// 执行命令操作(ping)
command = BCON_NEW("ping", BCON_INT32(1));
retval = mongoc_client_command_simple(client, "runoob", command, NULL, &reply, &error);
if (!retval) {
fprintf(stderr, "%s\n", error.message);
return EXIT_FAILURE;
}
// 获取json形式的结果
str = bson_as_json(&reply, NULL);
printf("%s\n", str); // 打印输出
char dst[4096];
size_t srclen = 4096;
size_t dstlen = 4096;
char* src = "小鸟";
int ret = gbk2utf8(src, strlen(src), dst, dstlen);
insert = BCON_NEW("hello", dst);
if (!mongoc_collection_insert(collection, MONGOC_INSERT_NONE, insert, NULL, &error)) {
fprintf(stderr, "%s\n", error.message);
}
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
query = bson_new();
memset(dst, 0, 4096);
char* src2 = "MongoDB 教程";
gbk2utf8(src2, strlen(src2), dst, dstlen);
query = BCON_NEW("title", dst);
//BSON_APPEND_UTF8(query, "hello", "菜鸟教程");
// 执行查询操作
cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
char *str2;
while (mongoc_cursor_next(cursor, &doc)) {
str2 = bson_as_json(doc, NULL);
printf("%s\n", str2);
bson_free(str2);
}
// 释放资源
bson_destroy(insert);
bson_destroy(&reply);
bson_destroy(command);
bson_free(str);
/*
* 释放拥有的句柄并清理libmongoc
*/
mongoc_collection_destroy(collection);
mongoc_database_destroy(database);
mongoc_client_destroy(client);
mongoc_cleanup();
}
mongoClient::~mongoClient()
{
if (_bConnect){
mongoc_database_destroy(_database);
mongoc_client_destroy(_client);
mongoc_cleanup();
}
_bConnect = false;
}
测试用例
#define UNIT_TEST
#ifdef UNIT_TEST
#include <limits.h>
#include <string>
#include <gtest/gtest.h>
#include <json/json.h>
#include "mongoClient.h"
#include <iostream>
using namespace std;
TEST(mongonDB, connectDb) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
std::string colName = "col";
bool bConn = mgl.Connect(dbAddr, dbName);
//mgl.ExampleFind();
EXPECT_TRUE(bConn);
if (bConn){
std::vector<std::string> queryResult;
string queryCondition;
bool bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
}
}
#if 1
TEST(mongonDB, insert) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
bool bConn = mgl.Connect(dbAddr, dbName);
EXPECT_TRUE(bConn);
std::string colName = "col";
std::string insert = "{\"k\": \"大鸟\"}";
bool bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
insert = "{\"k\": \"大鸟\"";
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_FALSE(bInsert);
}
TEST(mongonDB, dbQuery) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
bool bConn = mgl.Connect(dbAddr, dbName);
EXPECT_TRUE(bConn);
std::string colName = "col";
std::string queryCondition = "{\"k\": \"大鸟\"}";
//插入数据以便查询
std::string insert = "{\"k\": \"大鸟\"}";
bool bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
//查询数据
std::vector<std::string> queryResult;
bool bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
EXPECT_TRUE(bQuery);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
//输入错误的查询数据
queryResult.clear();
queryCondition = "{\"mydate\":\"2012-11-02T07:58:51Z\"}";
bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
EXPECT_TRUE(bQuery);
}
TEST(mongonDB, dbDelAll) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
bool bConn = mgl.Connect(dbAddr, dbName);
EXPECT_TRUE(bConn);
std::string colName = "col";
std::string insert = "{\"k\": \"大鸟\"}";
bool bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
std::vector<std::string> queryResult;
std::string queryCondition = insert;
bool bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
EXPECT_TRUE(bQuery);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
insert = "{\"k\": \"大鸟\"}";
bool bDel = mgl.DelCollectionsAll(dbName, colName, insert);
EXPECT_TRUE(bDel);
bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
EXPECT_TRUE(bQuery);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
}
TEST(mongonDB, Dbdel) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
bool bConn = mgl.Connect(dbAddr, dbName);
EXPECT_TRUE(bConn);
std::string colName = "col";
std::string insert = "{\"k\": \"大鸟\"}";
bool bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
insert = "{\"k\": \"大鸟\"}";
bool bDel = mgl.DelCollections(dbName, colName, insert);
EXPECT_TRUE(bDel);
std::string queryCondition = insert;
std::vector<std::string> queryResult;
bool bQuery = mgl.QueryCollections(dbName, colName, queryCondition, queryResult);
EXPECT_TRUE(bQuery);
for (int i = 0; i < queryResult.size(); i++)
{
cout << queryResult[i] << endl;
}
bDel = mgl.DelCollections(dbName, colName, insert);
EXPECT_TRUE(bDel);
bDel = mgl.DelCollections(dbName, colName, insert);
EXPECT_TRUE(bDel);
}
TEST(mongonDB, DbUpdate) {
mongoClient mgl;
std::string dbAddr = "mongodb://192.168.1.88:27017";
std::string dbName = "runoob";
bool bConn = mgl.Connect(dbAddr, dbName);
EXPECT_TRUE(bConn);
std::string colName = "col";
std::string insert = "{\"k\": \"1\"}";
bool bInsert = mgl.InsertCollections(dbName, colName, insert);
EXPECT_TRUE(bInsert);
//测试old json错误格式
std::string old = "{\"k\", \"1\"}";
std::string newItem = "{\"$set\":{\"k\": \"小鸟\"}}";
bInsert = mgl.UpdateCollections(dbName, colName, old,newItem);
EXPECT_FALSE(bInsert);
//测试old json正确格式
old = "{\"k\": \"小鸟\"}";
newItem = "{\"$set\":{\"k\": \"大鸟\"}}";
bInsert = mgl.UpdateCollections(dbName, colName, old, newItem);
EXPECT_TRUE(bInsert);
//测试newItem json错误格式
old = "{\"k\": \"小鸟\"}";
newItem = "{\"$set\":{\"k\", \"大鸟\"}}";
bInsert = mgl.UpdateCollections(dbName, colName, old, newItem);
EXPECT_FALSE(bInsert);
//测试newItem json正确格式
old = "{\"k\": \"1\"}";
newItem = "{\"$set\":{\"k\": \"大鸟\"}}";
bInsert = mgl.UpdateCollections(dbName, colName, old, newItem);
EXPECT_TRUE(bInsert);
}