diff --git a/src/Makefile b/src/Makefile index 0a69b8c..5708eed 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,6 @@ #This is the makefile -USEPOSTGRESQL=1 +USEPOSTGRESQL=0 +USEDBIXX=1 USESTDOUT=0 BASE_LIBS=-lgcrypt @@ -18,6 +19,12 @@ ifeq ($(USEPOSTGRESQL),1) BASE_CFLAGS+= -DUSEPOSTGRESQL=1 endif +ifeq ($(USEDBIXX),1) + BASE_LIBS+= -ldbixx + O_FILES+= build/db2dbixx.o + BASE_CFLAGS+= -DUSEDBIXX=1 +endif + build/oastat: $(O_FILES) g++ -O -o build/oastat $(O_FILES) $(BASE_LIBS) @@ -34,6 +41,11 @@ build/db2postgresql.o: db/Db2PostgreSQL.cpp db/Db2PostgreSQL.h db/database.hpp g++ $(BASE_CFLAGS) db/Db2PostgreSQL.cpp -o build/db2postgresql.o endif +ifeq ($(USEDBIXX),1) +build/db2dbixx.o: db/Db2DbiXX.cpp db/Db2DbiXX.hpp db/database.hpp + g++ $(BASE_CFLAGS) db/Db2DbiXX.cpp -o build/db2dbixx.o +endif + build/oastatstruct.o: oastatstruct.cpp oastatstruct.h g++ $(BASE_CFLAGS) oastatstruct.cpp -o build/oastatstruct.o diff --git a/src/db/Db2DbiXX.cpp b/src/db/Db2DbiXX.cpp new file mode 100644 index 0000000..1713ccf --- /dev/null +++ b/src/db/Db2DbiXX.cpp @@ -0,0 +1,161 @@ +/* + * File: Db2DbiXX.cpp + * Author: poul + * + * Created on 11. oktober 2010, 20:59 + */ + +#include "Db2DbiXX.hpp" + +#define GETNEXTGAMENUMBER "SELECT nextval('oastat_games_gamenumber_seq')" + +#define STARTGAME "INSERT INTO oastat_games(gamenumber,gametype, mapname, basegame) VALUES (?,?,?,?)" +#define PLAYERSINSERT "INSERT INTO oastat_players(guid,nickname,lastseen,isBot, model, headmodel) VALUES (?,?,now(),?,?,?)" +#define PLAYERSUPDATE "UPDATE oastat_players SET nickname = ?,lastseen = now(),isBot = ?, model = ?, headmodel = ? WHERE guid = ?" +#define USERINFOINSERT "INSERT INTO oastat_userinfo(gamenumber,second,guid,team,model,skill) VALUES (?,?,?,?,?,?)" +#define ENDGAME "UPDATE oastat_games SET second=?,time = now() where gamenumber = ?" +#define KILL "INSERT INTO oastat_kills(gamenumber,second,attacker,target,modtype) VALUES(?,?,?,?,?)" +#define CAPTURE "INSERT INTO oastat_captures(gamenumber,second,player,team) VALUES (?,?,?,?)" +#define AWARD "INSERT INTO oastat_awards(gamenumber,second,player,award) VALUES (?,?,?,?)" + +static char* booltext[2] = {"false","true"}; + +Db2DbiXX::Db2DbiXX() { + sql = new session("pgsql"); + sql->param("dbname","oastat"); + sql->connect(); + commitlock = new transaction(*sql); + debug = true; +} + +Db2DbiXX::Db2DbiXX(string dbargs) +{ + stringstream stream(stringstream::in | stringstream::out); + stream << dbargs; + string holder; + stream >> holder; + sql = new session(holder); + while(!stream.eof()) { + stream >> holder; + if(!stream.eof()) { + string param; + stream >> param; + sql->param(holder,param); + } + } + sql->connect(); + commitlock = new transaction(*sql); + debug = true; + //sql(dbargs); +} + +Db2DbiXX::Db2DbiXX(const Db2DbiXX& orig) { + throw "May not make copy of Db2DbiXX"; +} + +Db2DbiXX::~Db2DbiXX() { + delete commitlock; + delete sql; +} + +void Db2DbiXX::createTables() { + +} + +void Db2DbiXX::startGame(int gametype, string mapname, string basegame) { + Rollback(); //in case there was some garbage that could be comitted (like warmup or an unfinished game) + SetOk(true); + gamenumber = getNextGameNumber(); + *sql << STARTGAME,gamenumber,gametype,mapname,basegame,exec(); + DebugMessage("startGame"); +} + +/* + endGame is called then we finnish the game. This also means that it is safe to commit + */ +void Db2DbiXX::endGame(int second) { + *sql << ENDGAME,second,gamenumber,exec(); + Commit(); //Game have ended, transaction is in a stable state + DebugMessage("endgame"); +} + +int Db2DbiXX::getGameNumber() { + return gamenumber; +} + +void Db2DbiXX::setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill) { + if(team>-1) + { + try{ + *sql << "SAVEPOINT SETPLAYER",exec(); + *sql << PLAYERSINSERT,guid,nickname,booltext[isBot],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 << PLAYERSUPDATE,nickname,booltext[isBot],model,headmodel,guid,exec(); + } + *sql << USERINFOINSERT,gamenumber,second,guid,team,model,skill,exec(); + DebugMessage("setPlayerInfo for "+nickname+" with GUID: "+guid); +} + +void Db2DbiXX::addKill(int second, string attackerID, string targetID, int type) { + *sql<< KILL,gamenumber,second,attackerID,targetID,type,exec(); + DebugMessage("addKill"); +} + +void Db2DbiXX::addCapture(int second, string player, int team) { + *sql<< CAPTURE,gamenumber,second,player,team,exec(); + DebugMessage("addCapture"); +} + +void Db2DbiXX::addAward(int second, string player, int award) { + *sql << AWARD,gamenumber,second,player,award,exec(); + DebugMessage("addAward"); +} + +int Db2DbiXX::getNextGameNumber() { + int result = -1; + row r; + *sql<< GETNEXTGAMENUMBER; + DebugMessage("Gettings next game number"); + if(sql->single(r)) { + r>> result; + return result; + } + else { + throw "Could not get next gamenumber"; + } +} + +/* + This is a helper function so we never forget to start a new transaction after a commit. + */ +void Db2DbiXX::Commit() { + 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::DebugMessage(string msg) { + if(debug) { + cout << "oastat: " << msg << endl; + } +} diff --git a/src/db/Db2DbiXX.hpp b/src/db/Db2DbiXX.hpp new file mode 100644 index 0000000..fa01380 --- /dev/null +++ b/src/db/Db2DbiXX.hpp @@ -0,0 +1,49 @@ +/* + * File: Db2DbiXX.hpp + * Author: poul + * + * Created on 11. oktober 2010, 20:59 + */ + +#ifndef _DB2DBIXX_HPP +#define _DB2DBIXX_HPP + +#include "database.hpp" + +#include +#include +#include + +using namespace std; +using namespace dbixx; + +class Db2DbiXX : public Database { +public: + Db2DbiXX(); + Db2DbiXX(string dbargs); + Db2DbiXX(const Db2DbiXX& orig); + virtual ~Db2DbiXX(); + void createTables(); + void startGame(int gametype, string mapname, string basegame); + void endGame(int second); + int getGameNumber(); + void setPlayerInfo(string guid, string nickname, bool isBot, int second, int team, string model, string headmodel, int skill); + void addKill(int second, string attackerID, string targetID, int type); + void addCapture(int second, string player, int team); + void addAward(int second, string player, int award); +private: + session *sql; + transaction *commitlock; + bool isok; + bool debug; + int gamenumber; + int getNextGameNumber(); + void Commit(); + void Rollback(); + bool Ok(); + void SetOk(bool ok); + void DebugMessage(string msg); +}; + +#endif /* _DB2DBIXX_HPP */ + diff --git a/src/db/Db2PostgreSQL.cpp b/src/db/Db2PostgreSQL.cpp index ee5ce6a..99b1bab 100644 --- a/src/db/Db2PostgreSQL.cpp +++ b/src/db/Db2PostgreSQL.cpp @@ -129,6 +129,7 @@ void Db2PostgreSQL::createTables() void Db2PostgreSQL::startGame(int gametype, string mapname, string basegame) { + simpleQuery("ROLLBACK"); //In case we have just completed warmup or simpleQuery("BEGIN"); //simpleQuery("LOCK TABLE OASTAT_GAMES IN SHARE ROW EXCLUSIVE"); //Hold a lock until we have selected the just inserted line gamenumber = -1; //Prevent any following sql commands from completing until this is set! diff --git a/src/oastat.cpp b/src/oastat.cpp index 0d50654..dde6357 100644 --- a/src/oastat.cpp +++ b/src/oastat.cpp @@ -36,6 +36,9 @@ using namespace std; #ifdef USEPOSTGRESQL #include "db/Db2PostgreSQL.h" #endif +#ifdef USEDBIXX +#include "db/Db2DbiXX.hpp" +#endif #include "oastatstruct.h" #include "oss2db/struct2db.h" #include "local.h" @@ -48,7 +51,7 @@ using namespace std; string clientIdMap[MAX_ID]; -static void processStdIn(); +static int processStdIn(); Database *db; @@ -90,11 +93,20 @@ int main (int argc, const char* argv[]) db = new DB2stdout(); #endif - #if USEPOSTGRESQL + /*#if USEPOSTGRESQL + cout << "Using postgreSQL" << endl; if(dbargs.length()<1) db = new Db2PostgreSQL(); else db = new Db2PostgreSQL(dbargs); + #endif*/ + + #if USEDBIXX + cout << "Using DBI" << endl; + if(dbargs.length()<1) + db = new Db2DbiXX(); + else + db = new Db2DbiXX(dbargs); #endif addCommands(); @@ -103,12 +115,13 @@ int main (int argc, const char* argv[]) }catch (const char *s) { cout << "Crashed: " << s << endl; + return -1; } return 0; //Rest of file is for testing - string line = " 3:33 Kill: 2 5 6: aaargh!!!!!!!!!!!!!! killed RALV by MOD_ROCKET"; + /*string line = " 3:33 Kill: 2 5 6: aaargh!!!!!!!!!!!!!! killed RALV by MOD_ROCKET"; OaStatStruct oss; oss.parseLine(line); @@ -128,18 +141,38 @@ int main (int argc, const char* argv[]) db->addKill(10, "DSAGOJSAOGFJWA55555555AGA", "AHFDSHDFBSDTRHSJYFDSGFA", 3); - return 0; + return 0;*/ } -static void processStdIn() { +static int processStdIn() { string line; + OaStatStruct oss; + bool done = true; + try{ while( getline(cin,line) ) { - OaStatStruct oss; + oss.clear(); oss.parseLine(line); for(int i=0;iprocess(oss); + } catch (exception &e) { + cerr << "oastat: Sql_error at line: \"" << line << "\"" << endl << + "oastat: Error is: " << e.what() << + "oastat: Last error will be ignored" << endl; + } } } + } catch (exception &e2) { + /* + If there is an error write it in the log and try again continue + */ + cerr << "oastat: Crashed at line: \"" << line << "\"" << endl << + "oastat: Error is: " << e2.what(); + done = false; + } + if (!done) + return processStdIn(); + return 0; } /** diff --git a/src/oastatstruct.cpp b/src/oastatstruct.cpp index f80d920..91025a5 100644 --- a/src/oastatstruct.cpp +++ b/src/oastatstruct.cpp @@ -29,7 +29,7 @@ using namespace std; OaStatStruct::OaStatStruct() { second = 0; command = ""; - parameters.empty(); + parameters.clear(); restOfLine = ""; } @@ -43,6 +43,13 @@ OaStatStruct::OaStatStruct(const OaStatStruct& orig) { OaStatStruct::~OaStatStruct() { } +void OaStatStruct::clear() { + second=0; + command = ""; + parameters.clear(); + restOfLine = ""; +} + void OaStatStruct::parseLine(string line) { //Parse time //cout << line << endl; diff --git a/src/oastatstruct.h b/src/oastatstruct.h index 919d835..5263b6d 100644 --- a/src/oastatstruct.h +++ b/src/oastatstruct.h @@ -45,6 +45,7 @@ public: string restOfLine; void parseLine(string line); + void clear(); /* *Parses the rest of the line to an info string