diff --git a/README.md b/README.md index 8126177..a488b1e 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,6 @@ On earlier versions CppDb must be installed manually. CppDb can be disabled from the build by adding the line: USECPPDB=0 to src/Makefile.local (file must be created) -libdbi-dev can be used instead by adding: -USEDBIXX=1 to src/Makefile.local (file must be created) - Go to ./src and type "make" The executable will be in the same folder. @@ -53,7 +50,7 @@ Reading from stdin: This will generate XML-files in the choosen output dir in this case *~/oastat* ### Writing to database -The recommended backend is CppDb. Writing to a MySQL server is done like this: +The database backend is called CppDb. Writing to a MySQL server is done like this: `oastat --backend "CppDb" --dbarg "mysql:database=oastat;user=;password="` diff --git a/src/Makefile b/src/Makefile index a0f4fe1..87e84e6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,3 @@ -ifndef USEDBIXX -USEDBIXX=0 -endif ifndef USECPPDB USECPPDB=1 endif @@ -18,16 +15,6 @@ BASE_CFLAGS=-c -g -O1 -Wall -std=c++11 O_FILES=oastat.o oastatstruct.o oss2db/kill2db.o oss2db/init2db.o oss2db/shutdown2db.o oss2db/userinfo2db.o oss2db/Disconnect2Db.o oss2db/Award2Db.o oss2db/Ctf2Db.o oss2db/Point2Db.o oss2db/Ctf1f2Db.o oss2db/Elimination2Db.o oss2db/CtfElimination2Db.o oss2db/Harvester2Db.o oss2db/Challenge2Db.o oss2db/Warmup2Db.o oss2db/Accuracy2Db.o -ifeq ($(USEDBIXX),1) -ifeq ($(wildcard /usr/local/lib/libdbixx.so),) - BASE_LIBS+= -ldbixx -else - BASE_LIBS+= /usr/local/lib/libdbixx.so # -ldbixx -endif - O_FILES+= db/Db2DbiXX.o - BASE_CFLAGS+= -DUSEDBIXX=1 -endif - ifeq ($(USECPPDB),1) BASE_LIBS+= -lcppdb O_FILES+= db/Db2CppDb.o diff --git a/src/db/Db2DbiXX.cpp b/src/db/Db2DbiXX.cpp deleted file mode 100644 index 5fbe6d6..0000000 --- a/src/db/Db2DbiXX.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* -=========================================================================== -oastat - a program for parsing log files and write the result to a database -Copyright (C) 2012 Poul Sander - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see http://www.gnu.org/licenses/ - -Source information and contacts persons can be found at -https://github.com/sago007/oastat/ -=========================================================================== -*/ - -#include - -#include "Db2DbiXX.hpp" - - -using namespace dbixx; - -void Db2DbiXX::InitStrings(const string &backend) -{ - last_value = false; - if (backend == "pgsql") { - last_value = true; //Now also use last for PostgreSQL - } - if (backend == "mysql") { - last_value = true; - } - sql_backend = backend; -} - -void Db2DbiXX::ReadConfigFromDb() -{ - result res; - row r; - string value; - *sql<<"SELECT thekey FROM oastat_config_uservars2save",res; - while (res.next(r)) { - r >> value; - uservars2save.insert(value); - } - *sql<< "SELECT cvar FROM oastat_config_gamevars2save",res; - while (res.next(r)) { - r >> value; - cvars2save.insert(value); - } -} - -bool Db2DbiXX::IsDuplicate(const string &servername,const tm &thetime) -{ - result res; - *sql << "SELECT 'X' FROM oastat_games WHERE servername = ? AND time = ?",servername,thetime,res; - if (res.rows()) { - return true; - } else { - return false; - } -} - -Db2DbiXX::Db2DbiXX() -{ - sql = new session("pgsql"); - InitStrings("pgsql"); - sql->param("dbname","oastat"); - sql->connect(); - ReadConfigFromDb(); - commitlock = new transaction(*sql); - debug = false; -} - -Db2DbiXX::Db2DbiXX(const string &dbargs) -{ - stringstream stream(stringstream::in | stringstream::out); - stream << dbargs; - string holder; - stream >> holder; - sql = new session(holder); - InitStrings(holder); - while (!stream.eof()) { - stream >> holder; - if (!stream.eof()) { - string param; - stream >> param; - sql->param(holder,param); - } - } - sql->connect(); - ReadConfigFromDb(); - commitlock = new transaction(*sql); - debug = false; - //sql(dbargs); -} - -Db2DbiXX::Db2DbiXX(const Db2DbiXX& orig) -{ - throw runtime_error("May not make copy of Db2DbiXX"); -} - -Db2DbiXX::~Db2DbiXX() -{ - delete commitlock; - delete sql; -} - -void Db2DbiXX::createTables() -{ - -} - -void Db2DbiXX::startGame(int gametype, const string &mapname, const string &basegame, const string &servername, const OaStatStruct &oss) -{ - sql->reconnect(); - Rollback(); //in case there was some garbage that could be comitted (like warmup or an unfinished game) - SetOk(true); - timestamp = oss.getDateTime(); - if (oss.restOfLine.find("\\isWarmup\\1") != string::npos) { - SetOk(false); - cout << "Warmup: " << servername << ", " << oss.getTimeStamp() << endl; - return; - } - if (IsDuplicate(servername,timestamp)) { - SetOk(false); - cout << "Duplicate:" << servername << ", " << oss.getTimeStamp() << endl; - return; - } - if (last_value) { - *sql << "INSERT INTO oastat_games(gametype, mapname, basegame,servername,time) VALUES (?,LOWER(?),?,?,?)",gametype,mapname,basegame,servername,timestamp,exec(); - gamenumber = getLastGameNumber(); - if (gamenumber < 1) { - SetOk(false); - cout << "Must FAIL!" << endl; - } - } else { - gamenumber = getNextGameNumber(); - *sql << "INSERT INTO oastat_games(gamenumber,gametype, mapname, basegame,servername,time) VALUES (?,?,LOWER(?),?,?,?)", - gamenumber,gametype,mapname,basegame,servername,timestamp,exec(); - } - DebugMessage("startGame"); -} - -void Db2DbiXX::addGameCvar(const std::string &cvar, const std::string &value) -{ - if (!isok) { - return; - } - if (cvars2save.find(cvar) == cvars2save.end()) { - return; //not to be saved - } - *sql << "INSERT INTO oastat_gamecvars(gamenumber,cvar,value,numericvalue) VALUES (?,LOWER(?),?,?)",gamenumber,cvar,value,0,exec(); - DebugMessage("addCvar"); -} - -/* - endGame is called then we finnish the game. This also means that it is safe to commit - */ -void Db2DbiXX::endGame(int second) -{ - if (!isok) { - return; - } - *sql << "UPDATE oastat_games SET second=? WHERE gamenumber = ?",second,gamenumber,exec(); - Commit(); //Game have ended, transaction is in a stable state - DebugMessage("endgame"); -} - -int Db2DbiXX::getGameNumber() -{ - return gamenumber; -} - -void Db2DbiXX::setPlayerInfo(const std::string &guid, const std::string &nickname, bool isBot, int second, int team, const std::string &model, const std::string &headmodel, int skill) -{ - if (!isok) { - return; - } - if (team>-1) { - try { - *sql << "SAVEPOINT SETPLAYER",exec(); - *sql << "INSERT INTO oastat_players(guid,nickname,lastseen,isBot, model, headmodel) VALUES (?,?,?,?,?,?)",guid,nickname,timestamp,(isBot? "y":"n"),model,headmodel,exec(); - *sql << "RELEASE SAVEPOINT SETPLAYER",exec(); //Needed by postgresql - } catch (dbixx_error &e) { - DebugMessage("Already inserted? "+(string)e.what()); - *sql << "ROLLBACK TO SAVEPOINT SETPLAYER",exec(); - } - *sql << "UPDATE oastat_players SET nickname = ?,lastseen = ?,isBot = ?, model = ?, headmodel = ? WHERE guid = ? AND lastseen < ?",nickname,timestamp,(isBot? "y":"n"),model,headmodel,guid,timestamp,exec(); - } - try { - *sql << "SAVEPOINT SETUSERINFO",exec(); - *sql << "INSERT INTO oastat_userinfo(gamenumber,second,player,team,model,skill) VALUES (?,?,?,?,?,?)",gamenumber,second,getPlayerId(guid),team,model,skill,exec(); - *sql << "RELEASE SAVEPOINT SETUSERINFO",exec(); //Needed by postgresql - } catch (dbixx_error &e) { - *sql << "ROLLBACK TO SAVEPOINT SETUSERINFO",exec(); - *sql << "UPDATE oastat_userinfo SET team = ?, model = ?, skill = ? WHERE gamenumber = ? AND second = ? AND player = ?",team,model,skill,gamenumber,second,getPlayerId(guid),exec(); - } - DebugMessage("setPlayerInfo for "+nickname+" with GUID: "+guid); -} - -void Db2DbiXX::addKill(int second, const std::string &attackerID, const std::string &targetID, int type) -{ - if (!isok) { - return; - } - *sql<< "INSERT INTO oastat_kills(gamenumber,second,attacker,target,modtype) VALUES(?,?,?,?,?)",gamenumber,second,getPlayerId(attackerID),getPlayerId(targetID),type,exec(); - DebugMessage("addKill"); -} - -void Db2DbiXX::addAward(int second, const std::string &player, int award) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_awards(gamenumber,second,player,award) VALUES (?,?,?,?)",gamenumber,second,getPlayerId(player),award,exec(); - DebugMessage("addAward"); -} - -void Db2DbiXX::addScoreInfo(int second, const std::string &player, int score) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_points(gamenumber,second,player,score) VALUES (?,?,?,?)",gamenumber,second,getPlayerId(player),score,exec(); - DebugMessage("addScoreInfo"); -} - -void Db2DbiXX::addCtf(int second, const std::string &player, int team, int event) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,player,gametype,eventtype) VALUES (?,?,?,?,'ctf',?)",gamenumber,second,team,getPlayerId(player),event,exec(); - DebugMessage("addCtf"); -} - -void Db2DbiXX::addCtf1f(int second, const std::string &player, int team, int event) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,player,gametype,eventtype) VALUES (?,?,?,?,'1fctf',?)",gamenumber,second,team,getPlayerId(player),event,exec(); - DebugMessage("addCtf1f"); -} - -void Db2DbiXX::addElimination(int second, int roundnumber, int team, int event) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,eventtype,generic1,gametype) VALUES (?,?,?,?,?,'elimination')", - gamenumber,second,team,event,roundnumber,exec(); - DebugMessage("addElimination"); -} - -void Db2DbiXX::addCtfElimination(int second, int roundnumber, const std::string &player, int team, int event) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,player,eventtype,generic1,gametype) VALUES (?,?,?,?,?,?,'ctfelim')",gamenumber,second,team,getPlayerId(player),event,roundnumber,exec(); - DebugMessage("addCtfElimination"); -} - -void Db2DbiXX::addHarvester(int second, const std::string &player1, const std::string &player2, int team, int event, int score) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,player,player2,eventtype,amount,gametype) VALUES (?,?,?,?,?,?,?,'harvester')", - gamenumber,second,team,getPlayerId(player1),getPlayerId(player2),event,score,exec(); - DebugMessage("addHarvester"); -} - -void Db2DbiXX::addGenericTeamEvent(int second, int team, int amount, const std::string &gametype, const std::string &player1, const std::string &player2, int event, int generic1) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_team_events(gamenumber,second,team,player,player2,eventtype,amount,generic1,gametype) VALUES (?,?,?,?,?,?,?,?,?)", - gamenumber,second,team,getPlayerId(player1),getPlayerId(player2),event,amount,generic1, gametype,exec(); - DebugMessage("addGenericTeamEvent"); -} - -void Db2DbiXX::addChallenge(int second, const std::string &player, int challenge, int amount) -{ - if (!isok) { - return; - } - *sql << "INSERT INTO oastat_challenges(gamenumber,player,challenge,amount) VALUES (?,?,?,?)",gamenumber,getPlayerId(player),challenge,amount,exec(); - DebugMessage("addChallenge"); -} - -void Db2DbiXX::addAccuracy(int second, const std::string &player, int type, int shotsFired, int shotsHit) -{ - if (!isok) { - return; - } - try { - *sql << "SAVEPOINT SETACCURACY",exec(); - *sql << "INSERT INTO oastat_accuracy(gamenumber,player,shotsfired,shotshit,modtype) VALUES (?,?,?,?,?)",gamenumber,getPlayerId(player),shotsFired,shotsHit,type,exec(); - *sql << "RELEASE SAVEPOINT SETACCURACY",exec(); //Needed by postgresql - } catch (dbixx_error &e) { - *sql << "ROLLBACK TO SAVEPOINT SETACCURACY",exec(); - *sql << "UPDATE oastat_accuracy SET shotsfired = ?, shotshit = ?, modtype = ? WHERE player = ? AND gamenumber = ?",shotsFired,shotsHit,type,getPlayerId(player),gamenumber,exec(); - } -} - -int Db2DbiXX::getNextGameNumber() -{ - int result = -1; - row r; - *sql<< "SELECT nextval('oastat_games_gamenumber_seq')"; - DebugMessage("Gettings next game number"); - if (sql->single(r)) { - r>> result; - return result; - } else { - throw runtime_error("Could not get next gamenumber"); - } -} - -int Db2DbiXX::getLastGameNumber() -{ - int result = -1; - row r; - if (sql_backend == "mysql") { - *sql << "SELECT LAST_INSERT_ID() FROM DUAL"; - } else { - *sql<< "SELECT currval('oastat_games_gamenumber_seq')"; - } - DebugMessage("Gettings last game number"); - if (sql->single(r)) { - r>> result; - cout << "Game number: " << result << endl; - return result; - } else { - throw runtime_error("Could not get last gamenumber"); - } -} - - -/* - This is a helper function so we never forget to start a new transaction after a commit. - */ -void Db2DbiXX::Commit() -{ - if (!isok) { - Rollback(); - return; - } - commitlock->commit(); - delete commitlock; - commitlock = new transaction(*sql); - DebugMessage("Commited"); -} - -void Db2DbiXX::Rollback() -{ - commitlock->rollback(); - delete commitlock; - commitlock = new transaction(*sql); - DebugMessage("Rollback"); -} - -bool Db2DbiXX::Ok() -{ - return isok; -} - -void Db2DbiXX::SetOk(bool ok) -{ - isok = ok; -} - -void Db2DbiXX::doNotCommit() -{ - SetOk(false); -} - -void Db2DbiXX::DebugMessage(const string &msg) -{ - if (debug) { - cout << "oastat: " << msg << endl; - } -} - -int Db2DbiXX::getPlayerId(const string& guid) -{ - int ret = 0; - if (playerids.count(guid)) { - ret = playerids[guid]; - } else { - row r; - *sql << "SELECT playerid FROM oastat_players WHERE guid = ?",guid; - if (sql->single(r)) { - r >> ret; - playerids[guid] = ret; - } - } - return ret; -} diff --git a/src/db/Db2DbiXX.hpp b/src/db/Db2DbiXX.hpp deleted file mode 100644 index 81d8dfd..0000000 --- a/src/db/Db2DbiXX.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -=========================================================================== -oastat - a program for parsing log files and write the result to a database -Copyright (C) 2012 Poul Sander - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see http://www.gnu.org/licenses/ - -Source information and contacts persons can be found at -https://github.com/sago007/oastat/ -=========================================================================== -*/ - -#ifndef DB2DBIXX_HPP -#define DB2DBIXX_HPP - -#include "database.hpp" - -#include -#include -#include -#include - -class Db2DbiXX : public Database -{ -public: - Db2DbiXX(); - Db2DbiXX(const string &dbargs); - Db2DbiXX(const Db2DbiXX& orig); - virtual ~Db2DbiXX(); - void createTables() override; - void startGame(int gametype, const std::string &mapname, const std::string &basegame, const std::string &servername, const OaStatStruct &oss) override; - void addGameCvar(const std::string &cvar, const std::string &value) override; - void endGame(int second) override; - int getGameNumber() override; - void setPlayerInfo(const std::string &guid, const std::string &nickname, bool isBot, int second, int team, const std::string &model, const std::string &headmodel, int skill) override; - void addKill(int second, const std::string &attackerID, const std::string &targetID, int type) override; - //void addCapture(int second, string player, int team); - void addAward(int second, const std::string &player, int award) override; - void addScoreInfo(int second, const std::string &player, int score) override; - void addCtf(int second, const std::string &player, int team, int event) override; - void addCtf1f(int second, const std::string &player, int team, int event) override; - void addElimination(int second, int roundnumber, int team, int event) override; - void addCtfElimination(int second, int roundnumber, const std::string &player, int team, int event) override; - void addHarvester(int second, const std::string &player1, const std::string &player2, int team, int event, int score) override; - void addChallenge(int second, const std::string &player, int challenge, int amount) override; - void addAccuracy(int second, const std::string &player, int type, int shotsFired, int shotsHit) override; - void addGenericTeamEvent(int second, int team, int amount, const std::string &gametype, const std::string &player1, const std::string &player2, int event, int generic1) override; - void doNotCommit() override; -private: - dbixx::session *sql; - dbixx::transaction *commitlock; - bool isok; - bool debug; - int gamenumber; /** Gamenumber we are currently working on */ - tm timestamp; /** Start time of the game we are currently working on */ - int getNextGameNumber(); - int getLastGameNumber(); - void Commit(); - void Rollback(); - bool Ok(); - void SetOk(bool ok); - void DebugMessage(const std::string &msg); - void InitStrings(const std::string &backend); - void ReadConfigFromDb(); - bool IsDuplicate(const std::string &servername, const tm &thetime); - int getPlayerId(const std::string &guid); - std::map playerids; - std::string sql_backend; - bool last_value; - std::set cvars2save; - std::set uservars2save; -}; - -#endif /* DB2DBIXX_HPP */ - diff --git a/src/oastat.cpp b/src/oastat.cpp index aadd1a3..ec3e994 100644 --- a/src/oastat.cpp +++ b/src/oastat.cpp @@ -36,9 +36,6 @@ https://github.com/sago007/oastat/ #include #include "db/database.hpp" -#ifdef USEDBIXX -#include "db/Db2DbiXX.hpp" -#endif #ifdef USECPPDB #include "db/Db2CppDb.hpp" #endif @@ -219,8 +216,8 @@ int main (int argc, const char* argv[]) if (vm.count("help")) { std::cout << desc << "n"; std::cout << "Examples: \n"; - std::cout << argv[0] << " -f \"~/.openarena/baseoa/games.log\" --backend \"DbiXX\" --dbarg \"mysql dbname oastat username openarena\"\n"; - std::cout << argv[0] << " -f \"~/.openarena/baseoa/games.log\" --backend \"DbiXX\" --dbarg \"pgsql dbname oastat username openarena\"\n"; + std::cout << argv[0] << " -f \"~/.openarena/baseoa/games.log\" --backend \"Cppdb\" --dbarg \"mysql:database=oastat;username=openarena\"\n"; + std::cout << argv[0] << " -f \"~/.openarena/baseoa/games.log\" --backend \"CppDb\" --dbarg \"pgsql:database=oastat;username=openarena\"\n"; std::cout << argv[0] << " -f %APPDATA%/OpenArena/baseoa/games.log --backend \"CppDb\" --dbarg \"sqlite3:db=defoastat.db3\"\n"; std::cout << "tail -f \"~/.openarena/baseoa/games.log\" | "<< argv[0] << " -f \"\" --backend \"Xml\" --dbarg \"outputdir ~/oastat\"\n"; std::cout << "\n"; @@ -244,16 +241,6 @@ int main (int argc, const char* argv[]) } std::shared_ptr db; -#if USEDBIXX - if (backend == "DbiXX") { - cout << "Using DBI" << endl; - if (dbargs.length()<1) { - db = std::shared_ptr(new Db2DbiXX() ); - } else { - db = std::shared_ptr(new Db2DbiXX(dbargs) ); - } - } -#endif #if USECPPDB if (backend == "CppDb") { std::cout << "Using CppDb\n";