对sqlite3二次封装——提供更人性化的接口

先看一段使用方法:

另外,关于代码中的字符串动态加密,可使用x2lib中的MixPool类

SqliteDB.h


#ifndef _20266D69_1291_4C2A_8708_56BE03DB0B74
#define _20266D69_1291_4C2A_8708_56BE03DB0B74

#include "depends/incfile.h"
#include "../../../sqlite3xx/include/sqlite3xx.h"
#include "xCores.h"

 数据库操作失败重试次数
//#define DBVALUENUBER        10
//
回调函数指针
//#define  DB_Password     _T("J5A4M6E819840917");

namespace x2lib
{
	/*==============================================================================
	 * 描述:数据库操作简易封装类
	 =============================================================================*/
	class SqliteDB
	{
	public:
		SqliteDB();
		virtual ~SqliteDB(void);

		/*------------------------------------------------------------------------------
			* 描  述:初始化数据库
			* 参  数:[in] pszFile 数据库文件名,全路径,若为nullptr则创建内存数据库
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool Init(const char* pszFile, const char* pszPwd = nullptr);

		/*------------------------------------------------------------------------------
			* 描  述:反初始化数据库
			* 参  数:
			* 返回值:无
			*----------------------------------------------------------------------------*/
		void UnInit();

		/*------------------------------------------------------------------------------
			* 描  述:获取数据库文件
			* 参  数:
			* 返回值:返回nullptr表示为内存数据库
			*----------------------------------------------------------------------------*/
		const char* GetFile();

		/*------------------------------------------------------------------------------
			* 描  述:删除数据库表
			* 参  数:[in] szTableName 数据库表名
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool DropTable(const char* pszTable);

		/*------------------------------------------------------------------------------
			* 描  述:清空数据库表
			* 参  数:[in] szTableName 数据库表名
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool CleanTable(const char* pszTable);

		/*------------------------------------------------------------------------------
			* 描  述:判断数据库表是否存在
			* 参  数:[in] szTableName 数据库表名
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool IsTableExist(const char* szTable);

		/*------------------------------------------------------------------------------
			* 描  述:判断数据库表指定字段是否存在
			* 参  数:[in] szTableName 数据库表名
			* 参  数:[in] szFiledName 数据库表字段名
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool IsFiledExist(const char* pszTable, char* pszFiled);

		/*------------------------------------------------------------------------------
			* 描  述:增加数据库表字段
			* 参  数:[in] szTableName 数据库表名
			* 参  数:[in] szFiledName 数据库表字段名
			* 参  数:[in] szKeyType 数据库表字段类型
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool AppendFiled(const char* pszTable, const char* pszFiled, const char* pszKeyType);

		/*------------------------------------------------------------------------------
			* 描  述:执行一条sql语句
			* 参  数:[in] szSql 语句
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool ExecuteSql(const char* pszSql, int(*callback)(void*, int, char**, char**) = nullptr, void* p = nullptr);

		bool ExecuteSql(int(*callback)(void*, int, char**, char**), const char* pszSqlFmt, ...);

		/*------------------------------------------------------------------------------
			* 描  述:插入一条数据
			* 参  数:[in] pszTable 目标表名
			* 参  数:[in] ... 键值对序列,【键名】格式必须为“I:aaa”“F:bbb”“S:ccc”,
			**					其中IFS固定,分别代表字段数据类型,aaa,bbb,ccc为任意字段名;
			**					【键值】紧跟键名;最后一个参数必须为nullptr,即可变参为奇数个
			**				如:InsertItem("UserInfo", "S:userName","小王", "I:age",18, nullptr)
			* 返回值:TRUE/FALSE 是否执行成功
			*----------------------------------------------------------------------------*/
		bool InsertItem(const char *pszTable, ...);
        bool insertItem(const char *pszTable, va_list va);

        //准备废弃,推荐使用ExecuteSql(szCreateSql)创建
		//bool CreateTable(const char* pszTable, ...);

        // callback可以为nullptr
        // coMethod = true 表示或, false表示与
        int SelectItems(const char* pszTable, bool coMethod, int(*callback)(void*, int, char**, char**), ...);
        int selectItems(const char* pszTable, bool coMethod, int(*callback)(void*, int, char**, char**), va_list va);

		static bool Convert2(sqlite3xx::sqlite3db* pMemDB, const char* pszFile, bool toFile);

	private:
		char			m_szFile[1024];		// 数据库文件名称( 路径)
        sqlite3xx::sqlite3db *		m_pDB;
		xCores::Mutex	m_mutex;
	};
}

SqliteDB.cpp


// sqlite3.3.1后貌似是线程安全的

#include "SqliteDB.h"

using namespace sqlite3xx;

namespace x2lib
{

	SqliteDB::SqliteDB()
	{
		m_pDB = nullptr;
		memset(m_szFile, 0, sizeof(m_szFile));
	}

	SqliteDB::~SqliteDB(void)
	{
	}

	bool SqliteDB::Init(const char* pszFile, const char* pszPwd)
	{
		if (m_pDB && (!pszFile || 0 == strcmp(m_szFile, pszFile)))
		{
			return true;
		}

		if (m_pDB)
		{
			sqlite3xx_close(m_pDB);
		}

		if (pszFile)
		{
			strcpy(m_szFile, pszFile);
		}
		else
		{
			strcpy(m_szFile, ":memory:");
		}

		int nRet = 0;
		if (SQLITE_OK != sqlite3xx_open(m_szFile, &m_pDB))
		{
			m_pDB = nullptr;
			return false;
		}

#if 0 // 仅供SqlCipher使用
		if (pszPwd && pszPwd[0] && SQLITE_OK != sqlite3xx_key(m_pDB, pszPwd, strlen(pszPwd)))
		{
			sqlite3xx_close(m_pDB);
			m_pDB = nullptr;
			return false;
		}
#endif

		return true;
	}

	void SqliteDB::UnInit()
	{
		if (m_pDB)
		{
			sqlite3xx_close(m_pDB);
			m_pDB = nullptr;
		}
	}

	const char* SqliteDB::GetFile()
	{
		return m_szFile[0] ? m_szFile : nullptr;
	}

	bool SqliteDB::InsertItem(const char *pszTable, ...)
	{
		va_list body;
		va_start(body, pszTable);
        bool isSucc = InsertItem(pszTable, body);
		va_end(body);
		return isSucc;
	}

    bool SqliteDB::insertItem(const char *pszTable, va_list va)
    {
        char szKeys[1024] = { 0 };
        char* pszValues = (char*)calloc(1, 1024 * 8);

        for (int i = 0;; ++i)
        {
            char* pkv = va_arg(va, char*);
            if (pkv == nullptr) { break; }
            sprintf(szKeys, "%s,%s", szKeys, &pkv[2]);
            if (pkv[0] == 'I' || pkv[0] == 'B')
            {
                sprintf(pszValues, "%s,%d", pszValues, va_arg(va, int));
            }
            else if (pkv[0] == 'F')
            {
                sprintf(pszValues, "%s,%f", pszValues, va_arg(va, double));
            }
            else if (pkv[0] == 'S')
            {
                sprintf(pszValues, "%s,'%s'", pszValues, va_arg(va, char*));
            }
        }

        char* pszSql = (char*)calloc(1, 1024 * 10);
        if (pszValues[0] && szKeys[0])
        {
            sprintf(pszSql, "INSERT INTO %s (%s) VALUES (%s);", pszTable, &szKeys[1], &pszValues[1]);
        }
        else
        {
            sprintf(pszSql, "INSERT INTO %s DEFAULT VALUES;", pszTable);
        }
        bool isSucc = ExecuteSql(pszSql);
        free(pszValues);
        free(pszSql);
        return isSucc;
    }

	//bool SqliteDB::CreateTable(const char* pszTable, ...)
	//{
	//	char szCols[1024] = { 0 };

	//	va_list body;
	//	va_start(body, pszTable);
	//	for (int i = 0;; ++i)
	//	{
	//		char* pkv = va_arg(body, char*);
	//		if (pkv == nullptr) { break; }
	//		if (pkv[0] == 'I' || pkv[0] == 'B')
	//		{
	//			sprintf(szCols, "%s INT", szCols, &pkv[2]);
	//		}
	//		else if (pkv[0] == 'F')
	//		{
	//			sprintf(szCols, "%s REAL", szCols, &pkv[2]);
	//		}
	//		else if (pkv[0] == 'S')
	//		{
	//			sprintf(szCols, "%s TEXT", szCols, &pkv[2]);
	//		}
	//	}
	//	va_end(body);

	//	char szSql[1024] = { 0 };
	//	sprintf(szSql, "CREATE TABLE %s(%s);", pszTable, szCols);
	//	return ExecuteSql(szSql);
	//}

	int SqliteDB::SelectItems(const char* pszTable, bool coMethod, int(*callback)(void*, int, char**, char**), ...)
	{
        va_list va;
        va_start(va, callback);
        int nCount = SelectItems(pszTable, coMethod, callback, va);
        va_end(va);

        return nCount;
	}

    int SqliteDB::selectItems(const char* pszTable, bool coMethod, int(*callback)(void*, int, char**, char**), va_list va)
    {
        int nCount = 0;

        if (!m_pDB) { return 0; }

        const char* pszCoMethod = nullptr;
        if (coMethod) { pszCoMethod = "OR "; }
        else { pszCoMethod = "AND "; }

        va_list body;
        va_start(body, callback);
        char* pszWhere = (char*)calloc(1, 1024 * 8);
        for (int i = 0;; ++i)
        {
            char* pkv = va_arg(va, char*);
            if (pkv == nullptr) { break; }
            if (pkv[0] == 'I' || pkv[0] == 'B')
            {
                sprintf(pszWhere, "%s%s=%d ", pszWhere, &pkv[2], va_arg(va, int));
            }
            else if (pkv[0] == 'F')
            {
                sprintf(pszWhere, "%s%s=%f ", pszWhere, &pkv[2], va_arg(va, double));
            }
            else if (pkv[0] == 'S')
            {
                sprintf(pszWhere, "%s%s='%s' ", pszWhere, &pkv[2], va_arg(va, char*));
            }

            strcat(pszWhere, pszCoMethod);
        }
        va_end(body);

        pszWhere[strlen(pszCoMethod) - strlen(pszCoMethod) + 1] = 0;

        char szSql[1024] = { 0 };
        sprintf(szSql, "SELECT COUNT(*) FROM %s WHERE %s;", pszTable, pszWhere);
        m_mutex.Lock();
        sqlite3xx_exec(m_pDB, szSql, [](void* pVoid, int, char**, char**)->int {
            ++(*(int*)pVoid);
            return 0;
        }, &nCount, nullptr);
        m_mutex.Unlock();

        if (callback)
        {
            sprintf(szSql, "SELECT * FROM %s WHERE %s;", pszTable, pszWhere);
            char *pszErr = nullptr;
            m_mutex.Lock();
            sqlite3xx_exec(m_pDB, szSql, callback, 0, &pszErr);
            if (pszErr) { sqlite3xx_free(pszErr); }
            m_mutex.Unlock();
        }

        return nCount;
    }

	bool SqliteDB::IsTableExist(const char* szTable)
	{
		char *pErrmsg = nullptr;
		char szSql[512] = { 0 };
		int  nRow = 0;
		int nColumn = 0;
		char **pDBResult = nullptr;

		sprintf(szSql, "SELECT * FROM sqlite_master WHERE type='table' AND name = '%s';", szTable);
		m_mutex.Lock();
		int nRet = sqlite3xx_get_table(m_pDB, szSql, &pDBResult, &nRow, &nColumn, &pErrmsg);
		if (pDBResult) { sqlite3xx_free_table(pDBResult); }
		if (pErrmsg) { sqlite3xx_free(pErrmsg); }
		m_mutex.Unlock();

	    return (nRet == SQLITE_OK && nRow > 0);
	}

	//表字段是否存在
	bool SqliteDB::IsFiledExist(const char* pszTable, char* pszFiled)
	{
		char*	pErrmsg = nullptr;
		char	szSql[1024] = { 0 };
		int		nRow = 0;
		int nColumn = 0;
		char **pDBResult = nullptr;

		sprintf(szSql, "SELECT sql FROM sqlite_master WHERE tbl_name='%s' and type='table';", pszTable);
		m_mutex.Lock();
		int nRet = sqlite3xx_get_table(m_pDB, szSql, &pDBResult, &nRow, &nColumn, &pErrmsg);
		if (pErrmsg) { sqlite3xx_free(pErrmsg); }
		m_mutex.Unlock();

		bool bFind = false;
		do
		{
			if (nRet != SQLITE_OK || nRow <= 0 || pDBResult == nullptr)
				break;

			char* pColumValue = pDBResult[1];
			if (pColumValue == nullptr)
				break;

			if (nullptr == strstr(pColumValue, pszFiled))
				break;

			bFind = true;
		} while (0);
		sqlite3xx_free_table(pDBResult);
		return bFind;
	}

	bool SqliteDB::AppendFiled(const char* pszTable, const char* pszFiled, const char* pszKeyType)
	{
		char	szSql[1024] = { 0 };
		sprintf(szSql, "ALTER TABLE '%s' ADD '%s' %s;", pszTable, pszFiled, pszKeyType);
		return ExecuteSql(szSql);
	}

	bool SqliteDB::DropTable(const char* pszTable)     //删除表
	{
		char	szSql[1024] = { 0 };
		sprintf(szSql, "DROP TABLE '%s';", pszTable);
		return ExecuteSql(szSql);
	}

	bool SqliteDB::CleanTable(const char* pszTable)    //清空表
	{
		char	szSql[1024] = { 0 };
		sprintf(szSql, "DELETE FROM '%s';", pszTable);
		return ExecuteSql(szSql);
	}

	bool SqliteDB::ExecuteSql(const char* szSql, int(*callback)(void*, int, char**, char**), void* p)
	{
		char * pErrmsg = nullptr;
		m_mutex.Lock();
		int  iRet = sqlite3xx_exec(m_pDB, szSql, callback, p, &pErrmsg);
		if (pErrmsg) { sqlite3xx_free(pErrmsg); }
		m_mutex.Unlock();
		return (iRet == SQLITE_OK);
	}

	bool SqliteDB::ExecuteSql(int(*callback)(void*, int, char**, char**), const char* pszSqlFmt, ...)
	{
		char* pszSql = (char*)calloc(1, 1024 * 10);
		va_list body;
		va_start(body, pszSqlFmt);
		vsprintf(pszSql, pszSqlFmt, body);
		va_end(body);
		bool isSucc = ExecuteSql(pszSql, callback);
		free(pszSql);
		return isSucc;
	}

	bool SqliteDB::Convert2(sqlite3db* pMemDB, const char* pszFile, bool toFile)
	{
        sqlite3db *pFileDB = nullptr;
		if (SQLITE_OK == sqlite3xx_open(pszFile, &pFileDB))
		{
            sqlite3db *pFrom = (toFile ? pMemDB : pFileDB);
            sqlite3db *pTo = (toFile ? pFileDB : pMemDB);

			sqlite3xx_backup *pBackup = sqlite3xx_backup_init(pTo, "main", pFrom, "main");
			if (pBackup)
			{
				sqlite3xx_backup_step(pBackup, -1);
                sqlite3xx_backup_finish(pBackup);
			}

			bool isSucc = (SQLITE_OK == sqlite3xx_errcode(pFileDB));
			sqlite3xx_close(pFileDB);
			return isSucc;
		}
		return false;
	}

}

猜你喜欢

转载自blog.csdn.net/xk641018299/article/details/121220839
今日推荐