BlueRoseNote/02-Note/读书笔记/深入应用C++11代码优化与工程级应用/深入应用c++11代码优化与工程级应用第十三章.md
2023-06-29 11:55:02 +08:00

5.9 KiB
Raw Blame History

使用c++11封装sqlite库

13.1 sqlite基本用法

对于带参数的sql语句
其中sqlite3_perpare_v2用于解析sql文本并且保存到sqlite_stmt对象中sqlite3_stmt将作为后面一些函数的入参sqlite3_bind_XXX用于绑定sql文本中的参数

#include <sqlite3.h>
#include <string>
bool test()
{
	sqlite3* dbHandle = nullptr;
	int result = sqlite3_open("test.db", &dbHandle);
	if (result != SQLITE_OK)
	{
		sqlite3_close(dbHandle);
		return false;
	}
	const char* sqlcreat = "CREATE TABLE if not exists PersonTable(ID INTEGER NOT NULL, Name Text,Address BLOB);";
	result = sqlite3_exec(dbHandle, sqlcreat, nullptr, nullptr, nullptr);
	//插入数据
	sqlite3_stmt* stmt = NULL;
	const char* sqlinsert = "INSERT INTO PersonTable(ID,Name,Adress)  VALUE(?,?,?);";
	//解析并且保存sql脚本
	sqlite3_prepare_v2(dbHandle, sqlinsert, strlen(sqlinsert), &stmt, nullptr);

	int id = 2;
	const char* name = "peter";
	for (int i=0;i<10;++i)
	{
		sqlite3_bind_int(stmt, 1, id);
		sqlite3_bind_text(stmt, 2, name, strlen(name), SQLITE_TRANSIENT);
		sqlite3_bind_null(stmt, 3);

		if (sqlite3_step(stmt) != SQLITE_DONE)
		{
			sqlite3_finalize(stmt);
			sqlite3_close(dbHandle);
		}
		//重新初始化stmt对象下次再用
		sqlite3_reset(stmt);
	}
	//使用完需要释放,不然会内存泄露
	sqlite3_finalize(stmt);

	sqlite3_close(dbHandle);
	return result = SQLITE_OK;
}

最后通过 sqlite3_colume_xxx(sqlite3_stmt*,int iCol)取得结果

int colCount=sqlite3_column_count(stmt);
while(true)
{
    int r=sqlite3_step(stmt);
    if(r==SQLITE_DONE)
    {
        break;//数据行都已经获取,跳出循环
    }
    if(r==SQLITE_ROW)
    {
        break;//获得某一行数据失败,跳出循环
    }
    
    //获得每一列数据
    for(int i=0;i<colCount;++i)
    {
        int coltype=sqlite3_column_type(stmt,i);
        if(coltype==SQLITE_INTEGER)
        {
            int val=sqlite3_column_int(stmt,i);
        }else if(coltype==SQLITE_FLOAT)
        {
            double val=sqlite3_column_double(stmt,i);
        }else if(coltype==SQLITE_TEXT)
        {
            const char* val=(const char*)sqlite3_column_text(stmt,i);
        }else if(coltype==SQLITE_NULL)
        {
            
        }
    }
}
sqlite3_finalize(stmt);

事务

sqlite3_exec(dbHandle,"BEGIN");

sqlite3_exec(dbHandle,"ROLLBACK");

sqlite3_exec(dbHandle,"COMMIT");

sqlite3_exec(dbHandle,"END");
/**
	* 不带占位符。执行sql不带返回结果, 如insert,update,delete等
	* @param[in] query: sql语句, 不带占位符
	* @return bool, 成功返回true否则返回false
	*/
	bool Excecute(const string& sqlStr)
	{
		m_code = sqlite3_exec(m_dbHandle, sqlStr.data(), nullptr, nullptr, nullptr);
		return SQLITE_OK == m_code;
	}

	/**
	* 带占位符。执行sql不带返回结果, 如insert,update,delete等
	* @param[in] query: sql语句, 可能带占位符"?"
	* @param[in] args: 参数列表,用来填充占位符
	* @return bool, 成功返回true否则返回false
	*/
	template <typename... Args>
	bool Excecute(const string& sqlStr, Args && ... args)
	{
		if (!Prepare(sqlStr))
		{
			return false;
		}

		return ExcecuteArgs(std::forward<Args>(args)...);
	}

	/**
	* 批量操作之前准备sql接口必须和ExcecuteBulk一起调用准备批量操作的sql可能带占位符
	* @param[in] query: sql语句, 带占位符"?"
	* @return bool, 成功返回true否则返回false
	*/
	bool Prepare(const string& sqlStr)
	{
		m_code = sqlite3_prepare_v2(m_dbHandle, sqlStr.data(), -1, &m_statement, nullptr);
		if (m_code != SQLITE_OK)
		{
			return false;
		}

		return true;
	}

	/**
	* 批量操作接口必须先调用Prepare接口
	* @param[in] args: 参数列表
	* @return bool, 成功返回true否则返回false
	*/
	template <typename... Args>
	bool ExcecuteArgs(Args && ... args)
	{
		if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward<Args>(args)...))
		{
			return false;
		}

		m_code = sqlite3_step(m_statement);

		sqlite3_reset(m_statement);
		return m_code == SQLITE_DONE;
	}

	template<typename Tuple>
	bool ExcecuteTuple(const string& sqlStr, Tuple&& t)
	{
		if (!Prepare(sqlStr))
		{
			return false;
		}

		m_code = detail::ExcecuteTuple(m_statement, detail::MakeIndexes<std::tuple_size<Tuple>::value>::type(), std::forward<Tuple>(t));
		return m_code == SQLITE_DONE;
	}

	bool ExcecuteJson(const string& sqlStr, const char* json)
	{
		rapidjson::Document doc;
		doc.Parse<0>(json);
		if (doc.HasParseError())
		{
			cout << doc.GetParseError() << endl;
			return false;
		}

		if (!Prepare(sqlStr))
		{
			return false;
		}

		return JsonTransaction(doc);
	}

	/**
	* 执行sql返回函数执行的一个值, 执行简单的汇聚函数如select count(*), select max(*)等
	* 返回结果可能有多种类型返回Value类型在外面通过get函数去取
	* @param[in] query: sql语句, 可能带占位符"?"
	* @param[in] args: 参数列表,用来填充占位符
	* @return int: 返回结果值,失败则返回-1
	*/
	template < typename R = sqlite_int64, typename... Args>
	R ExecuteScalar(const string& sqlStr, Args&&... args)
	{
		if (!Prepare(sqlStr))
			return GetErrorVal<R>();

		if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward<Args>(args)...))
		{
			return GetErrorVal<R>();
		}

		m_code = sqlite3_step(m_statement);

		if (m_code != SQLITE_ROW)
			return GetErrorVal<R>();

		SqliteValue val = GetValue(m_statement, 0);
		R result = val.Get<R>();// get<R>(val);
		sqlite3_reset(m_statement);
		return result;
	}

	template <typename... Args>
	std::shared_ptr<rapidjson::Document> Query(const string& query, Args&&... args)
	{
		if (!PrepareStatement(query, std::forward<Args>(args)...))
			nullptr;

		auto doc = std::make_shared<rapidjson::Document>();

		m_buf.Clear();
		m_jsonHelper.BuildJsonObject(m_statement);

		doc->Parse<0>(m_buf.GetString());

		return doc;
	}

详细代码见 https://github.com/qicosmos/SmartDB1.03/blob/master/SmartDB.hpp