Implement sqlite repository, fix link against sqlite3.

This commit is contained in:
Christian Speckner 2019-04-29 00:46:27 +02:00
parent f9554ee3df
commit b1f485e2bd
3 changed files with 99 additions and 3 deletions

1
configure vendored
View File

@ -876,6 +876,7 @@ if test "$_build_sqlite" = yes; then
DEFINES="$DEFINES -DSQLITE_SUPPORT" DEFINES="$DEFINES -DSQLITE_SUPPORT"
MODULES="$MODULES $SQLITE" MODULES="$MODULES $SQLITE"
INCLUDES="$INCLUDES -I$SQLITE" INCLUDES="$INCLUDES -I$SQLITE"
LIBS="$LIBS -lsqlite3"
fi fi
if test "$_build_zip" = yes ; then if test "$_build_zip" = yes ; then

View File

@ -16,28 +16,109 @@
//============================================================================ //============================================================================
#include <sqlite3.h> #include <sqlite3.h>
#include <cstdio>
#include "KeyValueRepositorySqlite.hxx" #include "KeyValueRepositorySqlite.hxx"
#include "bspf.hxx"
#ifdef BSPF_WINDOWS
#define SEPARATOR "\"
#else
#define SEPARATOR "/"
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValueRepositorySqlite::KeyValueRepositorySqlite( KeyValueRepositorySqlite::KeyValueRepositorySqlite(
const string& databaseDirectory, const string& databaseDirectory,
const string& databaseName const string& databaseName
) ) : myDatabaseFile(databaseDirectory + SEPARATOR + databaseName + ".sqlite3"),
myDbHandle(nullptr),
myDbInitialized(false)
{} {}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValueRepositorySqlite::~KeyValueRepositorySqlite() KeyValueRepositorySqlite::~KeyValueRepositorySqlite()
{} {
if (myDbHandle) sqlite3_close(myDbHandle);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::map<string, Variant> KeyValueRepositorySqlite::load() std::map<string, Variant> KeyValueRepositorySqlite::load()
{ {
std::map<string, Variant> values; std::map<string, Variant> values;
initializeDb();
if (!myDbInitialized) {
cout << "Unable to load from sqlite DB " << myDatabaseFile << endl;
return values;
}
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(
myDbHandle,
"SELECT `key`, `VALUE` FROM `values`",
-1, &stmt, nullptr
) != SQLITE_OK) return values;
while (sqlite3_step(stmt) == SQLITE_ROW)
values[reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0))] =
reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
sqlite3_finalize(stmt);
return values; return values;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void KeyValueRepositorySqlite::save(const std::map<string, Variant>& values) void KeyValueRepositorySqlite::save(const std::map<string, Variant>& values)
{} {
initializeDb();
if (!myDbInitialized) {
cout << "Unable to save to sqlite DB " << myDatabaseFile << endl;
return;
}
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(
myDbHandle,
"INSERT OR REPLACE INTO `values` VALUES (?, ?)",
-1, &stmt, nullptr
) != SQLITE_OK) return;
for (const auto& pair: values) {
sqlite3_bind_text(stmt, 1, pair.first.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, pair.second.toCString(), -1, SQLITE_STATIC);
sqlite3_step(stmt);
if (sqlite3_reset(stmt) != SQLITE_OK) break;
}
sqlite3_finalize(stmt);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void KeyValueRepositorySqlite::initializeDb()
{
if (myDbHandle) return;
for (int tries = 1; tries < 3 && !myDbInitialized; tries++) {
myDbInitialized = (sqlite3_open(myDatabaseFile.c_str(), &myDbHandle) == SQLITE_OK);
myDbInitialized = myDbInitialized && (sqlite3_exec(
myDbHandle,
"CREATE TABLE IF NOT EXISTS `values` (`key` TEXT PRIMARY KEY, `value` TEXT) WITHOUT ROWID",
nullptr, nullptr, nullptr
) == SQLITE_OK);
if (!myDbInitialized && tries == 1) {
cout << "sqlite DB " << myDatabaseFile << " seems to be corrupt, removing and retrying..." << endl;
remove(myDatabaseFile.c_str());
}
}
if (!myDbInitialized)
cout << "unable to initialize sqlite DB " << myDatabaseFile << endl;
}

View File

@ -18,6 +18,8 @@
#ifndef KEY_VALUE_REPOSITORY_SQLITE_HXX #ifndef KEY_VALUE_REPOSITORY_SQLITE_HXX
#define KEY_VALUE_REPOSITORY_SQLITE_HXX #define KEY_VALUE_REPOSITORY_SQLITE_HXX
#include <sqlite3.h>
#include "repository/KeyValueRepository.hxx" #include "repository/KeyValueRepository.hxx"
class KeyValueRepositorySqlite : public KeyValueRepository class KeyValueRepositorySqlite : public KeyValueRepository
@ -31,6 +33,18 @@ class KeyValueRepositorySqlite : public KeyValueRepository
virtual std::map<string, Variant> load(); virtual std::map<string, Variant> load();
virtual void save(const std::map<string, Variant>& values); virtual void save(const std::map<string, Variant>& values);
private:
void initializeDb();
private:
string myDatabaseFile;
sqlite3* myDbHandle;
bool myDbInitialized;
}; };
#endif // KEY_VALUE_REPOSITORY_SQLITE_HXX #endif // KEY_VALUE_REPOSITORY_SQLITE_HXX