本地缓存(key-value)

目前在做本地缓存时常用的方式是用sqlite作为本地缓存数据库,缓存使用的场景很多,每次都设计表就变成一件很麻烦的事情,而且很多场景就只是用来记录一些配置信息,所以采用key-value这种接口去封装sqlite就是一种很好的方式。

接口:

#include <string>

class LocalStorage
{
public:
	SINGLETON_DEFINE(LocalStorage);
	LocalStorage();
	~LocalStorage();

public:
	bool Load(std::string sBusiness, std::string key, __int32& value);
	bool Load(std::string sBusiness, std::string key, __int64& value);
	bool Load(std::string sBusiness, std::string key, std::string& value);
	bool Load(std::string sBusiness, std::vector<std::pair<std::string, std::string>>& keyValue);

	bool Save(std::string sBusiness, std::string key, __int32 value);
	bool Save(std::string sBusiness, std::string key, __int64 value);
	bool Save(std::string sBusiness, std::string key, std::string value);

	bool Remove(std::string sBusiness, std::string key);
	bool Remove(std::string sBusiness);
};

load方法共有4个重载方法1,2这两个数值型底层调用的还是第三个string型的方法,后面只是将string转为了数值型。

load的第四个方法是将整个业务的所有key-value取出。

Save共三个方法,1,2的数值型接口底层也是调用的第三个string型的。

Remove两个方法,第一个将对应key的key-value记录删除,第二个删除整个业务缓存。

第一个参数业务内部对应的是一张表,key-value对应表中的记录。每一条记录都是固定的key-value格式。

实现:

#include "localstorage.h"
#include "db/db_sqlite3.h"
#include "base/sqllite/db_sqlite3.h"
#include <ShlObj.h>
#include <Shlwapi.h>

namespace{
	ndb::SQLiteDB   db_;
	bool OpenDB()
	{
		char szPath[MAX_PATH] = { 0 };
		::SHGetSpecialFolderPathA(nullptr, szPath, CSIDL_LOCAL_APPDATA, FALSE);
		::PathAppendA(szPath, "localstorage.db");
		bool result = db_.Open(szPath,
			"",
			ndb::SQLiteDB::modeReadWrite | ndb::SQLiteDB::modeCreate | ndb::SQLiteDB::modeSerialized
			);
		return result;
	}
	bool CloseDB()
	{
		return db_.Close();
	}

	bool CreateTable(std::string sBusiness)
	{
		std::string sSqlCreate = "CREATE TABLE IF NOT EXISTS ";
		sSqlCreate += sBusiness;
		sSqlCreate += "(key TEXT PRIMARY KEY, value TEXT)";

		int dbresult = SQLITE_OK;
		dbresult |= db_.Query(sSqlCreate.c_str());
		bool no_error = dbresult == SQLITE_OK;
		return no_error;
	}
}


LocalStorage::LocalStorage()
{
	OpenDB();
}


LocalStorage::~LocalStorage()
{
	CloseDB();
}

bool LocalStorage::Load(std::string sBusiness, std::string key, __int32& value)
{
	std::string sValue;
	if (Load(sBusiness, key, sValue))
	{
		value = std::stoi(sValue);
	}
	return true;
}

bool LocalStorage::Load(std::string sBusiness, std::string key, __int64& value)
{
	std::string sValue;
	if (Load(sBusiness, key, sValue))
	{
		value = std::stoll(sValue);
	}
	return true;
}

bool LocalStorage::Load(std::string sBusiness, std::string key, std::string& value)
{
	ndb::SQLiteStatement stmt;
	std::string sSqlSelect = "SELECT * FROM ";
	sSqlSelect += sBusiness;
	sSqlSelect += " WHERE key=?;";
	db_.Query(stmt, sSqlSelect.c_str());
	stmt.BindText(1, key.c_str(), key.size());
	int32_t result = stmt.NextRow();
	if (result == SQLITE_ROW)
	{
		value = stmt.GetTextField(1);
		return true;
	}
	return false;
}

bool LocalStorage::Load(std::string sBusiness, std::vector<std::pair<std::string, std::string>>& keyValue)
{
	ndb::SQLiteStatement stmt;
	std::string sSqlSelect = "SELECT * FROM ";
	sSqlSelect += sBusiness;
	sSqlSelect += ";";
	int result = SQLITE_OK;
	result |= db_.Query(stmt, sSqlSelect.c_str());

	if (SQLITE_OK == result)
	{
		result = stmt.NextRow();
		while (result == SQLITE_ROW)
		{
			const char* sKey = stmt.GetTextField(0);
			const char* sValue = stmt.GetTextField(1);
			if (nullptr != sKey && nullptr != sValue)
			{
				keyValue.push_back(std::make_pair(sKey, sValue));
			}
			result = stmt.NextRow();
		}
		return true;
	}
	return false;
}

bool LocalStorage::Save(std::string sBusiness, std::string key, __int32 value)
{
	std::string sValue = std::to_string(value);
	return Save(sBusiness, key, sValue);
}

bool LocalStorage::Save(std::string sBusiness, std::string key, __int64 value)
{
	std::string sValue = std::to_string(value);
	return Save(sBusiness, key, sValue);
}

bool LocalStorage::Save(std::string sBusiness, std::string key, std::string value)
{
	if (CreateTable(sBusiness))
	{
		std::string sSqlInsert = "INSERT OR REPLACE into ";
		sSqlInsert += sBusiness;
		sSqlInsert += " (key,value) values (?,?);";
		ndb::SQLiteStatement stmt;
		db_.Query(stmt, sSqlInsert.c_str());
		stmt.BindText(1, key.c_str(), key.size());
		stmt.BindText(2, value.c_str(), value.size());
		int32_t result = stmt.NextRow();
		bool no_error = result == SQLITE_OK || result == SQLITE_ROW || result == SQLITE_DONE;
		if (no_error)
		{
			return true;
		}
	}

	return false;
}

bool LocalStorage::Remove(std::string sBusiness, std::string key)
{
	std::string sSqlDeleteRecord = "DELETE FROM ";
	sSqlDeleteRecord += sBusiness;
	sSqlDeleteRecord += " WHERE key=?;";
	ndb::SQLiteStatement stmt;
	int dbresult = SQLITE_OK;
	dbresult |= db_.Query(stmt, sSqlDeleteRecord.c_str());
	stmt.BindText(1, key.c_str());
	int32_t result = stmt.NextRow();
	return (result == SQLITE_OK || result == SQLITE_ROW || result == SQLITE_DONE);
}

bool LocalStorage::Remove(std::string sBusiness)
{
	std::string sSqlDropTable = "DROP TABLE ";
	sSqlDropTable += sBusiness;
	sSqlDropTable += ";";

	int dbresult = SQLITE_OK;
	dbresult |= db_.Query(sSqlDropTable.c_str());
	return dbresult == SQLITE_OK;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章