From cfa6a1df535f7dd90b5722e98cb22e966657353f Mon Sep 17 00:00:00 2001 From: adrido Date: Sun, 23 Dec 2018 12:25:09 +0100 Subject: [PATCH] Add Sqlite support for players --- Minetestmapper/PlayerAttributes.cpp | 73 +++++++++++++++++++++-------- Minetestmapper/PlayerAttributes.h | 5 ++ 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/Minetestmapper/PlayerAttributes.cpp b/Minetestmapper/PlayerAttributes.cpp index 67a3a4d..ace632d 100644 --- a/Minetestmapper/PlayerAttributes.cpp +++ b/Minetestmapper/PlayerAttributes.cpp @@ -13,6 +13,7 @@ namespace fs = std::filesystem; #include #include +#include #include #include "PlayerAttributes.h" @@ -23,36 +24,68 @@ PlayerAttributes::PlayerAttributes(const std::string &sourceDirectory) { const string playersPath = sourceDirectory + "players"; + // if players.sqlite, could not be opened, then process the playerfiles + if (!extractPlayersSqlite(playersPath)) { #ifdef HAVE_FILESYSTEM - for (const auto &dirEntry : fs::directory_iterator(playersPath)) { - cout << dirEntry << std::endl; - //dirEntry.path().filename(); + for (const auto &dirEntry : fs::directory_iterator(playersPath)) { + cout << dirEntry << std::endl; + //dirEntry.path().filename(); - extractPlayer(dirEntry.path().string()); - } + extractPlayer(dirEntry.path().string()); + } #else - DIR *dir; - dir = opendir(playersPath.c_str()); - if (dir == NULL) { - return; - } - - struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - if (ent->d_name[0] == '.') { - continue; + DIR *dir; + dir = opendir(playersPath.c_str()); + if (dir == NULL) { + return; } - const string path = playersPath + '/' + ent->d_name; + struct dirent *ent; + while ((ent = readdir(dir)) != NULL) { + if (ent->d_name[0] == '.') { + continue; + } - extractPlayer(path); - } - closedir(dir); + const string path = playersPath + '/' + ent->d_name; + + extractPlayer(path); + } + closedir(dir); #endif // HAVE_FILESYSTEM - + } } +bool PlayerAttributes::extractPlayersSqlite(const std::string &playersPath) +{ + const string playersDB = playersPath + ".sqlite"; + const string statement = "SELECT name, posX, posY, posZ FROM player"; + + int sqlite_state = sqlite3_open_v2(playersDB.c_str(), &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_PRIVATECACHE, nullptr); + if (sqlite_state == SQLITE_CANTOPEN) { + return false; + } + + if (sqlite_state != SQLITE_OK) { + throw std::runtime_error(std::string(sqlite3_errmsg(db)) + ", Database file: " + playersDB); + } + if (SQLITE_OK != sqlite3_prepare_v2(db, statement.c_str(), -1, &preparedStatement, nullptr)) { + throw std::runtime_error("Failed to prepare SQL statement (dataVersionStatement)"); + } + + while (sqlite3_step(preparedStatement) == SQLITE_ROW) { + Player player; + player.name = reinterpret_cast(sqlite3_column_text(preparedStatement, 0)); + player.x = sqlite3_column_double(preparedStatement, 1); + player.y = sqlite3_column_double(preparedStatement, 2); + player.z = sqlite3_column_double(preparedStatement, 3); + m_players.push_back(player); + }; + sqlite3_finalize(preparedStatement); + sqlite3_close(db); + return true; +} + void PlayerAttributes::extractPlayer(const std::string &path) { ifstream in; diff --git a/Minetestmapper/PlayerAttributes.h b/Minetestmapper/PlayerAttributes.h index e1d16da..ee0fd4f 100644 --- a/Minetestmapper/PlayerAttributes.h +++ b/Minetestmapper/PlayerAttributes.h @@ -2,6 +2,7 @@ #include #include +#include struct Player { @@ -24,5 +25,9 @@ public: private: Players m_players; void extractPlayer(const std::string &path); + + bool extractPlayersSqlite(const std::string &playersPath); //returns false if database could not found + sqlite3_stmt *preparedStatement = nullptr; + sqlite3 *db = nullptr; };