C++封装 C mongodb

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Oyj1020/article/details/85044579

封装类

#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 ([email protected])
#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);
}

猜你喜欢

转载自blog.csdn.net/Oyj1020/article/details/85044579
今日推荐