From: Maxim Mamontov Date: Fri, 26 Jul 2013 18:53:47 +0000 (+0300) Subject: Merge branch 'master' into full-month-stats X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/9a834ba2e0caea6edffec5c1db403cf9832ea96e?ds=inline;hp=-c Merge branch 'master' into full-month-stats Conflicts: projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp --- 9a834ba2e0caea6edffec5c1db403cf9832ea96e diff --combined projects/stargazer/plugins/store/postgresql/postgresql_store.h index 654de146,72a2c22c..4585bbdf --- a/projects/stargazer/plugins/store/postgresql/postgresql_store.h +++ b/projects/stargazer/plugins/store/postgresql/postgresql_store.h @@@ -33,17 -33,14 +33,14 @@@ #include #include - #include #include "stg/store.h" #include "stg/logger.h" -// Minimal DB version is 5 -// Recommended DB version is 6 (support FreeMb logging on disconnects) -#define DB_MIN_VERSION 5 +// Minimal DB version is 7 +// Recommended DB version is 7 (support full month stats) +#define DB_MIN_VERSION 7 - extern "C" STORE * GetStore(); - class POSTGRESQL_STORE : public STORE { public: POSTGRESQL_STORE(); @@@ -97,7 -94,7 +94,7 @@@ // Tariffs int GetTariffsList(std::vector * tariffsList) const; int AddTariff(const std::string & name) const; - int DelTariff(const string & name) const; + int DelTariff(const std::string & name) const; int SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const; int RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const; @@@ -116,11 -113,11 +113,11 @@@ int DelService(const std::string & name) const; // Settings - inline void SetSettings(const MODULE_SETTINGS & s) { settings = s; }; + inline void SetSettings(const MODULE_SETTINGS & s) { settings = s; } int ParseSettings(); - inline const string & GetStrError() const { return strError; }; - inline const string & GetVersion() const { return versionString; }; + inline const std::string & GetStrError() const { return strError; } + inline const std::string & GetVersion() const { return versionString; } private: POSTGRESQL_STORE(const POSTGRESQL_STORE & rvalue); POSTGRESQL_STORE & operator=(const POSTGRESQL_STORE & rvalue); @@@ -131,8 -128,8 +128,8 @@@ int EscapeString(std::string & value) const; - std::string Int2TS(uint32_t value) const; - uint32_t TS2Int(const std::string & value) const; + std::string Int2TS(time_t value) const; + time_t TS2Int(const std::string & value) const; int SaveStat(const USER_STAT & stat, const std::string & login, int year = 0, int month = 0) const; @@@ -163,6 -160,4 +160,4 @@@ PLUGIN_LOGGER logger; }; - extern const volatile time_t stgTime; - #endif //POSTGRESQL_STORE_H diff --combined projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp index df802eea,0722cc4c..f8eba5c1 --- a/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp +++ b/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp @@@ -39,7 -39,7 +39,7 @@@ #include "postgresql_store.h" //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::GetUsersList(vector * usersList) const + int POSTGRESQL_STORE::GetUsersList(std::vector * usersList) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -95,7 -95,7 +95,7 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::AddUser(const string & name) const + int POSTGRESQL_STORE::AddUser(const std::string & name) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -130,7 -130,7 +130,7 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; + std::ostringstream query; query << "SELECT sp_add_user('" << elogin << "')"; result = PQexec(connection, query.str().c_str()); @@@ -159,7 -159,7 +159,7 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::DelUser(const string & login) const + int POSTGRESQL_STORE::DelUser(const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -194,7 -194,7 +194,7 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; + std::ostringstream query; query << "DELETE FROM tb_users WHERE name = '" << elogin << "'"; result = PQexec(connection, query.str().c_str()); @@@ -223,24 -223,34 +223,24 @@@ return 0 } //----------------------------------------------------------------------------- int POSTGRESQL_STORE::SaveUserStat(const USER_STAT & stat, - const string & login) const + const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -return SaveStat(stat, login); -} -//----------------------------------------------------------------------------- -int POSTGRESQL_STORE::SaveStat(const USER_STAT & stat, - const std::string & login, - int year, - int month) const -{ if (PQstatus(connection) != CONNECTION_OK) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str()); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str()); if (Reset()) { strError = "Connection lost"; - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str()); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str()); return -1; } } -PGresult * result; - if (StartTransaction()) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to start transaction'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to start transaction'\n"); return -1; } @@@ -248,15 -258,15 +248,15 @@@ std::string elogin = login if (EscapeString(elogin)) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to escape login'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to escape login'\n"); if (RollbackTransaction()) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n"); } return -1; } - std::stringstream query; + std::ostringstream query; query << "UPDATE tb_users SET " "cash = " << stat.cash << ", " "free_mb = " << stat.freeMb << ", " @@@ -266,27 -276,32 +266,27 @@@ "passive_time = " << stat.passiveTime << " " "WHERE name = '" << elogin << "'"; -result = PQexec(connection, query.str().c_str()); +PGresult * result = PQexec(connection, query.str().c_str()); if (PQresultStatus(result) != PGRES_COMMAND_OK) { strError = PQresultErrorMessage(result); PQclear(result); - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str()); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str()); if (RollbackTransaction()) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n"); } return -1; } PQclear(result); -std::string date; - -MakeDate(date, year, month); - for (int dir = 0; dir < DIR_NUM; ++dir) { query.str(""); query << "SELECT sp_add_stats_traffic (" "'" << elogin << "', " - "CAST('" << date << "' AS DATE), " "CAST(" << dir << " AS SMALLINT), " "CAST(" << stat.up[dir] << " AS BIGINT), " "CAST(" << stat.down[dir] << " AS BIGINT))"; @@@ -297,10 -312,10 +297,10 @@@ { strError = PQresultErrorMessage(result); PQclear(result); - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str()); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str()); if (RollbackTransaction()) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n"); } return -1; } @@@ -310,7 -325,7 +310,7 @@@ if (CommitTransaction()) { - printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to commit transaction'\n"); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to commit transaction'\n"); return -1; } @@@ -319,7 -334,7 +319,7 @@@ return 0 //----------------------------------------------------------------------------- int POSTGRESQL_STORE::SaveUserConf(const USER_CONF & conf, - const string & login) const + const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -354,7 -369,7 +354,7 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; + std::ostringstream query; query << "SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'"; result = PQexec(connection, query.str().c_str()); @@@ -385,14 -400,16 +385,16 @@@ if (tuples != 1 return -1; } - std::stringstream tuple; - tuple << PQgetvalue(result, 0, 0); + uint32_t uid; - PQclear(result); + { + std::stringstream tuple; + tuple << PQgetvalue(result, 0, 0); - uint32_t uid; + PQclear(result); - tuple >> uid; + tuple >> uid; + } std::string eaddress = conf.address; std::string eemail = conf.email; @@@ -588,7 -605,7 +590,7 @@@ return 0 //----------------------------------------------------------------------------- int POSTGRESQL_STORE::RestoreUserStat(USER_STAT * stat, - const string & login) const + const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -623,14 -640,16 +625,16 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; - query << "SELECT pk_user, cash, free_mb, " - "last_activity_time, last_cash_add, " - "last_cash_add_time, passive_time " - "FROM tb_users " - "WHERE name = '" << elogin << "'"; + { + std::ostringstream query; - query << "SELECT cash, free_mb, " ++ query << "SELECT pk_user, cash, free_mb, " + "last_activity_time, last_cash_add, " + "last_cash_add_time, passive_time " + "FROM tb_users " + "WHERE name = '" << elogin << "'"; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -658,32 -677,32 +662,35 @@@ if (tuples != 1 return -1; } - std::stringstream tuple; - tuple << PQgetvalue(result, 0, 0) << " "; - tuple << PQgetvalue(result, 0, 1) << " "; - tuple << PQgetvalue(result, 0, 2) << " "; - stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 3)); - tuple << PQgetvalue(result, 0, 4) << " "; - stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 5)); - tuple << PQgetvalue(result, 0, 6); - - PQclear(result); - +uint32_t uid; + - tuple >> uid - >> stat->cash - >> stat->freeMb - >> stat->lastCashAdd - >> stat->passiveTime; + { + std::stringstream tuple; + tuple << PQgetvalue(result, 0, 0) << " "; + tuple << PQgetvalue(result, 0, 1) << " "; - stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 2)); - tuple << PQgetvalue(result, 0, 3) << " "; - stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 4)); - tuple << PQgetvalue(result, 0, 5) << " "; ++ tuple << PQgetvalue(result, 0, 2) << " "; ++ stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 3)); ++ tuple << PQgetvalue(result, 0, 4) << " "; ++ stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 5)); ++ tuple << PQgetvalue(result, 0, 6) << " "; - query.str(""); + PQclear(result); - query << "SELECT dir_num, upload, download " - "FROM tb_stats_traffic " - "WHERE fk_user = " << uid; - tuple >> stat->cash ++ tuple >> uid ++ >> stat->cash + >> stat->freeMb + >> stat->lastCashAdd + >> stat->passiveTime; + } - result = PQexec(connection, query.str().c_str()); + { + std::ostringstream query; + query << "SELECT dir_num, upload, download " + "FROM tb_stats_traffic " - "WHERE fk_user IN (SELECT pk_user FROM tb_users WHERE name = '" << elogin << "') AND " - "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP))"; ++ "WHERE fk_user = " << uid; + + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -726,7 -745,7 +733,7 @@@ return 0 //----------------------------------------------------------------------------- int POSTGRESQL_STORE::RestoreUserConf(USER_CONF * conf, - const string & login) const + const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -761,21 -780,23 +768,23 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; - query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, " - "tb_users.credit, tb_users.credit_expire, tb_users.disabled, " - "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, " - "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, " - "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name " - "FROM tb_users LEFT JOIN tb_tariffs AS tf1 " - "ON tf1.pk_tariff = tb_users.fk_tariff " - "LEFT JOIN tb_tariffs AS tf2 " - "ON tf2.pk_tariff = tb_users.fk_tariff_change " - "LEFT JOIN tb_corporations " - "ON tb_corporations.pk_corporation = tb_users.fk_corporation " - "WHERE tb_users.name = '" << elogin << "'"; + { + std::ostringstream query; + query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, " + "tb_users.credit, tb_users.credit_expire, tb_users.disabled, " + "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, " + "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, " + "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name " + "FROM tb_users LEFT JOIN tb_tariffs AS tf1 " + "ON tf1.pk_tariff = tb_users.fk_tariff " + "LEFT JOIN tb_tariffs AS tf2 " + "ON tf2.pk_tariff = tb_users.fk_tariff_change " + "LEFT JOIN tb_corporations " + "ON tb_corporations.pk_corporation = tb_users.fk_corporation " + "WHERE tb_users.name = '" << elogin << "'"; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -805,43 -826,46 +814,46 @@@ if (tuples != 1 uint32_t uid; - std::stringstream tuple; - - tuple << PQgetvalue(result, 0, 0) << " "; // uid - conf->address = PQgetvalue(result, 0, 1); // address - conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1); - tuple << PQgetvalue(result, 0, 3) << " "; // credit - conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4)); // creditExpire - conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1); - conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1); - conf->email = PQgetvalue(result, 0, 7); // email - conf->group = PQgetvalue(result, 0, 8); // group - conf->note = PQgetvalue(result, 0, 9); // note - conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1); - conf->password = PQgetvalue(result, 0, 11); // password - conf->phone = PQgetvalue(result, 0, 12); // phone - conf->realName = PQgetvalue(result, 0, 13); // realName - conf->tariffName = PQgetvalue(result, 0, 14); // tariffName - conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff - conf->corp = PQgetvalue(result, 0, 16); // corp + { + std::stringstream tuple; + tuple << PQgetvalue(result, 0, 0) << " "; // uid + conf->address = PQgetvalue(result, 0, 1); // address + conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1); + tuple << PQgetvalue(result, 0, 3) << " "; // credit + conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4)); // creditExpire + conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1); + conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1); + conf->email = PQgetvalue(result, 0, 7); // email + conf->group = PQgetvalue(result, 0, 8); // group + conf->note = PQgetvalue(result, 0, 9); // note + conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1); + conf->password = PQgetvalue(result, 0, 11); // password + conf->phone = PQgetvalue(result, 0, 12); // phone + conf->realName = PQgetvalue(result, 0, 13); // realName + conf->tariffName = PQgetvalue(result, 0, 14); // tariffName + conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff + conf->corp = PQgetvalue(result, 0, 16); // corp - PQclear(result); + PQclear(result); - if (conf->tariffName == "") - conf->tariffName = NO_TARIFF_NAME; - if (conf->corp == "") - conf->corp = NO_CORP_NAME; + if (conf->tariffName == "") + conf->tariffName = NO_TARIFF_NAME; + if (conf->corp == "") + conf->corp = NO_CORP_NAME; - tuple >> uid - >> conf->credit; + tuple >> uid + >> conf->credit; + } - query.str(""); - query << "SELECT name FROM tb_services " - "WHERE pk_service IN (SELECT fk_service " - "FROM tb_users_services " - "WHERE fk_user = " << uid << ")"; + { + std::ostringstream query; + query << "SELECT name FROM tb_services " + "WHERE pk_service IN (SELECT fk_service " + "FROM tb_users_services " + "WHERE fk_user = " << uid << ")"; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -864,12 -888,14 +876,14 @@@ for (int i = 0; i < tuples; ++i PQclear(result); - query.str(""); - query << "SELECT num, data " - "FROM tb_users_data " - "WHERE fk_user = " << uid; + { + std::ostringstream query; + query << "SELECT num, data " + "FROM tb_users_data " + "WHERE fk_user = " << uid; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -904,12 -930,14 +918,14 @@@ for (int i = 0; i < tuples; ++i PQclear(result); - query.str(""); - query << "SELECT host(ip), masklen(ip) " - "FROM tb_allowed_ip " - "WHERE fk_user = " << uid; + { + std::ostringstream query; + query << "SELECT host(ip), masklen(ip) " + "FROM tb_allowed_ip " + "WHERE fk_user = " << uid; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -958,13 -986,13 +974,13 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::WriteUserChgLog(const string & login, - const string & admLogin, + int POSTGRESQL_STORE::WriteUserChgLog(const std::string & login, + const std::string & admLogin, uint32_t admIP, - const string & paramName, - const string & oldValue, - const string & newValue, - const string & message = "") const + const std::string & paramName, + const std::string & oldValue, + const std::string & newValue, + const std::string & message = "") const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -1044,7 -1072,7 +1060,7 @@@ if (EscapeString(enew) return -1; } - std::stringstream query; + std::ostringstream query; query << "SELECT sp_add_param_log_entry(" "'" << elogin << "', " "'" << eadminLogin << "', CAST('" @@@ -1081,7 -1109,7 +1097,7 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::WriteUserConnect(const string & login, uint32_t ip) const + int POSTGRESQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -1116,7 -1144,7 +1132,7 @@@ if (EscapeString(elogin) return -1; } - std::stringstream query; + std::ostringstream query; if (version < 6) { query << "SELECT sp_add_session_log_entry(" @@@ -1160,7 -1188,7 +1176,7 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::WriteUserDisconnect(const string & login, + int POSTGRESQL_STORE::WriteUserDisconnect(const std::string & login, const DIR_TRAFF & up, const DIR_TRAFF & down, const DIR_TRAFF & sessionUp, @@@ -1214,26 -1242,28 +1230,28 @@@ if (EscapeString(ereason) return -1; } - std::stringstream query; - if (version < 6) { - // Old database version - no freeMb logging support - query << "SELECT sp_add_session_log_entry(" - "'" << elogin << "', " - "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), " - "'d', CAST('0.0.0.0/0' AS INET), " - << cash << ")"; - } - else - { - query << "SELECT sp_add_session_log_entry(" - "'" << elogin << "', " - "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), " - "'d', CAST('0.0.0.0/0' AS INET), " - << cash << ", " << freeMb << ", '" << ereason << "')"; - } + std::ostringstream query; + if (version < 6) + { + // Old database version - no freeMb logging support + query << "SELECT sp_add_session_log_entry(" + "'" << elogin << "', " + "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), " + "'d', CAST('0.0.0.0/0' AS INET), " + << cash << ")"; + } + else + { + query << "SELECT sp_add_session_log_entry(" + "'" << elogin << "', " + "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), " + "'d', CAST('0.0.0.0/0' AS INET), " + << cash << ", " << freeMb << ", '" << ereason << "')"; + } - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_TUPLES_OK) { @@@ -1279,7 -1309,7 +1297,7 @@@ PQclear(result) for (int i = 0; i < DIR_NUM; ++i) { - std::stringstream query; + std::ostringstream query; query << "INSERT INTO tb_sessions_data " "(fk_session_log, " "dir_num, " @@@ -1322,9 -1352,9 +1340,9 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::WriteDetailedStat(const map & statTree, + int POSTGRESQL_STORE::WriteDetailedStat(const std::map & statTree, time_t lastStat, - const string & login) const + const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); @@@ -1359,12 -1389,12 +1377,12 @@@ if (EscapeString(elogin) return -1; } - map::const_iterator it; + std::map::const_iterator it; time_t currTime = time(NULL); for (it = statTree.begin(); it != statTree.end(); ++it) { - std::stringstream query; + std::ostringstream query; query << "INSERT INTO tb_detail_stats " "(till_time, from_time, fk_user, " "dir_num, ip, download, upload, cost) " @@@ -1405,131 -1435,11 +1423,131 @@@ return 0 } //----------------------------------------------------------------------------- - int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const + int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const { STG_LOCKER lock(&mutex, __FILE__, __LINE__); -return SaveStat(stat, login, year, month); +if (PQstatus(connection) != CONNECTION_OK) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str()); + if (Reset()) + { + strError = "Connection lost"; + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str()); + return -1; + } + } + +if (StartTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to start transaction'\n"); + return -1; + } + +std::string elogin = login; + +if (EscapeString(elogin)) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to escape login'\n"); + if (RollbackTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n"); + } + return -1; + } + +std::string date; + +MakeDate(date, year, month); + +std::stringstream query; +query << "SELECT sp_add_month_stats(" + "'" << elogin << "'," + "CAST('" << date << "' AS DATE), " + "CAST(" << stat.cash << " AS dm_money), " + "CAST(" << stat.freeMb << " AS dm_money), " + "CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), " + "CAST(" << stat.lastCashAdd << " AS dm_money), " + "CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), " + "CAST(" << stat.passiveTime << " AS INTEGER))"; + +PGresult * result = PQexec(connection, query.str().c_str()); + +if (PQresultStatus(result) != PGRES_TUPLES_OK) + { + strError = PQresultErrorMessage(result); + PQclear(result); + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str()); + if (RollbackTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n"); + } + return -1; + } + +int tuples = PQntuples(result); + +if (tuples != 1) + { + strError = "Failed to fetch month stat's ID"; + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples); + PQclear(result); + if (RollbackTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n"); + } + return -1; + } + +uint32_t sid; + +if (str2x(PQgetvalue(result, 0, 0), sid)) + { + strError = "Failed to convert string to int"; + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str()); + PQclear(result); + if (RollbackTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n"); + } + return -1; + } + +PQclear(result); + +for (int dir = 0; dir < DIR_NUM; ++dir) + { + query.str(""); + query << "SELECT sp_add_month_stats_traffic (" + << sid << ", " + "CAST(" << dir << " AS SMALLINT), " + "CAST(" << stat.up[dir] << " AS BIGINT), " + "CAST(" << stat.down[dir] << " AS BIGINT))"; + + result = PQexec(connection, query.str().c_str()); + + if (PQresultStatus(result) != PGRES_TUPLES_OK) + { + strError = PQresultErrorMessage(result); + PQclear(result); + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str()); + if (RollbackTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n"); + } + return -1; + } + + PQclear(result); + } + +if (CommitTransaction()) + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to commit transaction'\n"); + return -1; + } + +return 0; } //----------------------------------------------------------------------------- @@@ -1538,21 -1448,23 +1556,23 @@@ int POSTGRESQL_STORE::SaveUserServices( { PGresult * result; - std::stringstream query; - query << "DELETE FROM tb_users_services WHERE fk_user = " << uid; + { + std::ostringstream query; + query << "DELETE FROM tb_users_services WHERE fk_user = " << uid; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + + if (PQresultStatus(result) != PGRES_COMMAND_OK) + { + strError = PQresultErrorMessage(result); + PQclear(result); + printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str()); + return -1; + } - if (PQresultStatus(result) != PGRES_COMMAND_OK) - { - strError = PQresultErrorMessage(result); PQclear(result); - printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str()); - return -1; } - PQclear(result); - std::vector::const_iterator it; for (it = services.begin(); it != services.end(); ++it) @@@ -1565,7 -1477,7 +1585,7 @@@ return -1; } - std::stringstream query; + std::ostringstream query; query << "INSERT INTO tb_users_services " "(fk_user, fk_service) " "VALUES " @@@ -1596,10 -1508,12 +1616,12 @@@ int POSTGRESQL_STORE::SaveUserIPs(uint3 { PGresult * result; - std::stringstream query; - query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid; + { + std::ostringstream query; + query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid; - result = PQexec(connection, query.str().c_str()); + result = PQexec(connection, query.str().c_str()); + } if (PQresultStatus(result) != PGRES_COMMAND_OK) { @@@ -1611,9 -1525,9 +1633,9 @@@ PQclear(result); - for (int i = 0; i < ips.Count(); ++i) + for (size_t i = 0; i < ips.Count(); ++i) { - std::stringstream query; + std::ostringstream query; query << "INSERT INTO tb_allowed_ip " "(fk_user, ip) " "VALUES " @@@ -1653,7 -1567,7 +1675,7 @@@ for (unsigned i = 0; i < data.size(); + PGresult * result; - std::stringstream query; + std::ostringstream query; query << "SELECT sp_set_user_data(" << uid << ", " << "CAST(" << i << " AS SMALLINT), "