3.5 sqlite3的封装

引用库文件

先编译生成静态库 然后复制库文件 和 sqlite3.h 头文件

3.5 sqlite3的封装_第1张图片

需要项目配置一致

3.5 sqlite3的封装_第2张图片
在这里插入图片描述
在这里插入图片描述

就配置好了 为什么不需要 sqlite3ext.h 是只有dll的情况 没有lib

进行封装

有二种一种是偏向于API 容易移植 ,一种是偏向业务,
这个封装是是偏向于API的

封装API

sqlite.h

#pragma once
#include 
#include 
#include 
#include "sqlite3.h"
#pragma comment(lib,"Sqlite.lib")
#ifdef _UNICODE
typedef  std::wstring tstring;
#define SqliteOpen sqlite3_open16
#else
typedef  std::string tstring;
#define SqliteOpen sqlite3_open
#endif // _UNICODE

class Sqlite
{
public:
	Sqlite(const tstring& dbPath);
	~Sqlite();
	int Query(
		const std::string& sql,
		std::vector<std::vector<std::string>>& results,
		std::vector<std::string>& cloumns,
		std::string& strMsg);//查询
	int QueryContainBlob(
		const std::string& sql,
		std::vector<std::vector<std::string>>& results,
		std::vector<std::string>& cloumns,
		std::string& strMsg);//查询
	int Exec(const std::string& sql, std::string& strMsg);
protected:
	static int SelectCallBackEntry(void* thiz, int argc, char* argv[], char* names[]);
	int SelectCallBack(int argc, char* argv[], char* names[]);
	int ClearResult();
private:
	//不能复制构造 对象只有一个
	Sqlite(const Sqlite& db) = delete;
	Sqlite& operator=(const Sqlite& db) = delete;
private:
	sqlite3* m_db;
	sqlite3_stmt* m_stmt;
	std::list<std::vector<std::string>*> m_result;
	std::vector<std::string>			 m_cloumn;

};

sqlite.cpp

#include "Sqlite.h"

Sqlite::Sqlite(const tstring& dbPath)
{
	m_stmt = NULL;
	int ret= SqliteOpen(dbPath.c_str(), &m_db);
	if (ret != 0)
	{
		throw ret;
	}
}

Sqlite::~Sqlite()
{
	ClearResult();
	sqlite3* db = m_db;
	m_db = NULL;
	sqlite3_close(db);
}

int Sqlite::Query(
	const std::string& sql,
	std::vector<std::vector<std::string>>&results,
	std::vector<std::string>& cloumns,
	std::string&strMsg)
{
	ClearResult();

	char* errmsg = NULL;
	int ret = sqlite3_exec(m_db, sql.c_str(), &Sqlite::SelectCallBackEntry, this, &errmsg);//只支持多字节 
	if (ret != SQLITE_OK)
	{
		strMsg = errmsg;
		sqlite3_free(errmsg);
		return ret;
	}
	results.resize(m_result.size());
	if(m_result.size() > 0)
	{
		std::list<std::vector<std::string>*>::iterator it = m_result.begin();
		for (size_t i = 0; (i < m_result.size())&& (it!=m_result.end()); i++,it++)
		{
			results[i].resize((*it)->size());
			for (size_t j = 0; j < (*it)->size(); j++)
			{
				results[i][j] = (**it)[j];
			}
		}
	}
	cloumns.resize(m_cloumn.size());
	for (size_t i = 0; i < m_cloumn.size(); i++)
	{
		cloumns[i] = m_cloumn[i];
	}
	return ret;
}

int Sqlite::QueryContainBlob(const std::string& sql,
	std::vector<std::vector<std::string>>& results,
	std::vector<std::string>& cloumns,
	std::string& strMsg)
{
	cloumns.clear();
	ClearResult();
	int ret=sqlite3_prepare(m_db, sql.c_str(),sql.size(), &m_stmt, NULL);//二进制处理
	if (ret != SQLITE_OK)
	{
		strMsg = sqlite3_errmsg(m_db);
		return ret;
	}
	while (sqlite3_step(m_stmt)==SQLITE_ROW)
	{
		int count = sqlite3_column_count(m_stmt);
		if (count > 0 && cloumns.size() <= 0)
		{
			cloumns.resize(count);
			for (size_t i = 0; i < count; i++)
			{
				cloumns[i]=sqlite3_column_name(m_stmt, i);
			}
		}
		if (count > 0)
		{
			std::vector<std::string>* presult = new std::vector<std::string>;
			presult->resize(count);
			for (int i = 0; i < count; i++)
			{
				int type=sqlite3_column_type(m_stmt, i);
				if ((type == SQLITE_BLOB))
				{
					(*presult)[i].resize(sqlite3_column_bytes(m_stmt, i));
					memcpy((char*)(*presult)[i].c_str(), sqlite3_column_blob(m_stmt, i), (*presult)[i].size());
				}
				else
				{
					switch (type)
					{
					case SQLITE_INTEGER :
						(*presult)[i] = std::to_string(sqlite3_column_int(m_stmt, i));
						break;
					case SQLITE_FLOAT:
						(*presult)[i] =std::to_string(sqlite3_column_double(m_stmt, i));
						break;
					case SQLITE_NULL:
						(*presult)[i] = "NULL";
						break;
					case  SQLITE_TEXT:
						(*presult)[i] = (char*)sqlite3_column_text(m_stmt, i);
						break;
					}
				}
			}
			m_result.push_back(presult);
		}
	}

	results.resize(m_result.size());
	if (m_result.size() > 0)
	{
		std::list<std::vector<std::string>*>::iterator it = m_result.begin();
		for (size_t i = 0; (i < m_result.size()) && (it != m_result.end()); i++, it++)
		{
			results[i].resize((*it)->size());
			for (size_t j = 0; j < (*it)->size(); j++)
			{
				results[i][j] = (**it)[j];
			}
		}
	}
	

	sqlite3_finalize(m_stmt);
	m_stmt = NULL;
	return ret;
}

int Sqlite::Exec(const std::string& sql, std::string& strMsg)
{
	char* errmsg = NULL;
	int ret = sqlite3_exec(m_db, sql.c_str(), NULL, this, &errmsg);//只支持多字节 
	if (ret != SQLITE_OK)
	{
		strMsg = errmsg;
		sqlite3_free(errmsg);
		return ret;
	}
	return ret;
}

int Sqlite::SelectCallBackEntry(void* thiz, int argc, char* argv[], char* names[])
{
	return ((Sqlite*)thiz)->SelectCallBack(argc, argv, names);
}

int Sqlite::SelectCallBack(int argc, char* argv[], char* names[])
{
	if ((m_cloumn.size() == 0)&&(argc>0))
	{
		m_cloumn.resize(argc);
		for (int i = 0; i < argc; i++)
		{
			m_cloumn[i] = names[i];
		}
	}
	if (argc > 0)
	{
		std::vector<std::string>* presult = new std::vector<std::string>;
		presult->resize(argc);
		for (int i = 0; i < argc; i++)
		{
			(*presult)[i] = argv[i];
		}
		m_result.push_back(presult);//为了避免 拷贝问题 
	}
	return 0;
}

int Sqlite::ClearResult()
{
	while (m_result.size()>0)
	{
		std::vector<std::string>* presult = m_result.front();
		m_result.pop_front();
		if (presult)
		{
			presult->clear();
			delete presult;
		}
	}
	m_cloumn.clear();
	return 0;
}

主函数

#include "Sqlite.h"
#include 
#include 
using namespace std;
const char* createtable = "CREATE TABLE  TianChen("  \
						  "ID INT      PRIMARY KEY NOT NULL," \
						  "NAME TEXT   NOT NULL );";
const char* inset = "INSERT INTO TianChen (ID,NAME)VALUES(1,\"tianchen1\");";
const char* inset2 = "INSERT INTO TianChen (ID,NAME)VALUES(2,\"tianchen2\");";
const char* droptable = "DROP TABLE TianChen;";
const char* query = "SELECT * FROM TianChen;";

int main()
{
	Sqlite sqlite(_T("test.db"));
	std::string msg;
	int ret = sqlite.Exec(createtable, msg);
	if (ret != 0)
	{
		std::cout << msg << std::endl;
		return -1;
	}
	 ret = sqlite.Exec(inset, msg);
	if (ret != 0)
	{
		std::cout << msg << std::endl;
		return -1;
	}
	 ret = sqlite.Exec(inset2, msg);
	if (ret != 0)
	{
		std::cout << msg << std::endl;
		return -1;
	}

	std::vector<std::vector<std::string>>result;
	std::vector<std::string>cloumns;
	//ret = sqlite.Query(query,result,cloumns,msg);
	ret = sqlite.QueryContainBlob(query,result,cloumns,msg);
	if (ret != 0)
	{
		std::cout << msg << std::endl;
		return -1;
	}
	for (size_t i = 0; i < result.size(); i++)
	{
		for (size_t j = 0; j < result[i].size(); j++)
		{
			std::cout << cloumns[j] << "==" << result[i][j] << std::endl;
		}
	}
	 ret = sqlite.Exec(droptable, msg);
	if (ret != 0)
	{
		std::cout << msg << std::endl;
		return -1;
	}



}

你可能感兴趣的:(大型聊天项目,sqlite,数据库,封装,装饰器模式,VS2022)