1 #include "mysql_store.h"
3 #include "stg/common.h"
4 #include "stg/user_ips.h"
5 #include "stg/user_conf.h"
6 #include "stg/user_stat.h"
7 #include "stg/admin_conf.h"
8 #include "stg/tariff_conf.h"
9 #include "stg/blowfish.h"
10 #include "stg/logger.h"
18 #include <mysql/errmsg.h>
20 #define adm_enc_passwd "cjeifY8m3"
26 const int pt_mega = 1024 * 1024;
27 const std::string badSyms = "'`";
28 const char repSym = '\"';
29 const int RepitTimes = 3;
32 int GetInt(const std::string & str, T * val, T defaultVal = T())
36 *val = static_cast<T>(strtoll(str.c_str(), &res, 10));
40 *val = defaultVal; //Error!
47 int GetDouble(const std::string & str, double * val, double defaultVal)
51 *val = strtod(str.c_str(), &res);
55 *val = defaultVal; //Error!
62 int GetTime(const std::string & str, time_t * val, time_t defaultVal)
66 *val = strtol(str.c_str(), &res, 10);
70 *val = defaultVal; //Error!
77 //-----------------------------------------------------------------------------
78 std::string ReplaceStr(std::string source, const std::string & symlist, const char chgsym)
80 std::string::size_type pos=0;
82 while( (pos = source.find_first_of(symlist,pos)) != std::string::npos)
83 source.replace(pos, 1,1, chgsym);
88 int GetULongLongInt(const std::string & str, uint64_t * val, uint64_t defaultVal)
92 *val = strtoull(str.c_str(), &res, 10);
96 *val = defaultVal; //Error!
105 extern "C" STG::Store* GetStore()
107 static MYSQL_STORE plugin;
110 //-----------------------------------------------------------------------------
111 MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
116 //-----------------------------------------------------------------------------
117 int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<STG::ParamValue> & moduleParams,
118 const std::string & name, std::string & result)
122 std::vector<STG::ParamValue>::const_iterator pvi;
123 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
124 if (pvi == moduleParams.end() || pvi->value.empty())
126 errorStr = "Parameter \'" + name + "\' not found.";
130 result = pvi->value[0];
134 //-----------------------------------------------------------------------------
135 int MYSQL_STORE_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
137 if (ParseParam(s.moduleParams, "user", dbUser) < 0 &&
138 ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
140 if (ParseParam(s.moduleParams, "password", dbPass) < 0 &&
141 ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
143 if (ParseParam(s.moduleParams, "database", dbName) < 0 &&
144 ParseParam(s.moduleParams, "dbname", dbName) < 0)
146 if (ParseParam(s.moduleParams, "server", dbHost) < 0 &&
147 ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
151 std::string dbPortAsString;
152 if (ParseParam(s.moduleParams, "port", dbPortAsString) == 0 ||
153 ParseParam(s.moduleParams, "dbport", dbPortAsString) == 0)
155 if (GetInt<unsigned int>(dbPortAsString, &dbPort, 0) != 0)
157 errorStr = "Can't parse db port from string: \"" + dbPortAsString + "\"\n";
164 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
166 //-----------------------------------------------------------------------------
167 MYSQL_STORE::MYSQL_STORE()
168 : version("mysql_store v.0.68"),
170 logger(STG::PluginLogger::get("store_mysql"))
173 //-----------------------------------------------------------------------------
174 int MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
178 if( (ret = mysql_query(sock,sQuery)) )
180 for(int i=0; i<RepitTimes; i++)
182 if( (ret = mysql_query(sock,sQuery)) )
183 ;//need to send error result
191 //-----------------------------------------------------------------------------
193 //-----------------------------------------------------------------------------
194 int MYSQL_STORE::ParseSettings()
196 int ret = storeSettings.ParseSettings(settings);
200 errorStr = storeSettings.GetStrError();
203 if(storeSettings.GetDBPassword().length() == 0)
205 errorStr = "Database password must be not empty. Please read Manual.";
209 if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
210 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
211 0,storeSettings.GetDBPort(),NULL,0)))
213 errorStr = "Couldn't connect to mysql engine! With error:\n";
214 errorStr += mysql_error(&mysql);
220 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
222 std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
224 if(MysqlQuery(res.c_str(),sock))
226 errorStr = "Couldn't create database! With error:\n";
227 errorStr += mysql_error(sock);
233 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
235 errorStr = "Couldn't select database! With error:\n";
236 errorStr += mysql_error(sock);
241 ret = CheckAllTables(sock);
246 ret = CheckAllTables(sock);
250 logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
258 //-----------------------------------------------------------------------------
259 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
263 if (!(result=mysql_list_tables(sock,str.c_str() )))
265 errorStr = "Couldn't get tables list With error:\n";
266 errorStr += mysql_error(sock);
271 my_ulonglong num_rows = mysql_num_rows(result);
274 mysql_free_result(result);
276 return num_rows == 1;
278 //-----------------------------------------------------------------------------
279 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
281 //info-------------------------------------------------------------------------
282 if(!IsTablePresent("info",sock))
284 sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
286 if(MysqlQuery(qbuf,sock))
288 errorStr = "Couldn't create info table With error:\n";
289 errorStr += mysql_error(sock);
294 sprintf(qbuf,"INSERT INTO info SET version=0");
296 if(MysqlQuery(qbuf,sock))
298 errorStr = "Couldn't write default version. With error:\n";
299 errorStr += mysql_error(sock);
307 std::vector<std::string> info;
308 if (GetAllParams(&info, "info", "version"))
315 GetInt(info.front(), &schemaVersion, 0);
318 //admins-----------------------------------------------------------------------
319 if(!IsTablePresent("admins",sock))
321 sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
322 "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
323 "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
324 "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
325 "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
327 if(MysqlQuery(qbuf,sock))
329 errorStr = "Couldn't create admin table list With error:\n";
330 errorStr += mysql_error(sock);
335 sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
336 "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
337 "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
339 if(MysqlQuery(qbuf,sock))
341 errorStr = "Couldn't create default admin. With error:\n";
342 errorStr += mysql_error(sock);
348 //tariffs-----------------------------------------------------------------------
349 std::string param, res;
350 if(!IsTablePresent("tariffs",sock))
352 res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
354 for (int i = 0; i < DIR_NUM; i++)
356 strprintf(¶m, " PriceDayA%d DOUBLE DEFAULT 0.0,", i);
359 strprintf(¶m, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
362 strprintf(¶m, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
365 strprintf(¶m, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
368 strprintf(¶m, " Threshold%d INT DEFAULT 0,", i);
371 strprintf(¶m, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
374 strprintf(¶m, " NoDiscount%d INT DEFAULT 0,", i);
377 strprintf(¶m, " SinglePrice%d INT DEFAULT 0,", i);
381 res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
382 "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
383 "period VARCHAR(32) NOT NULL DEFAULT 'month',"
384 "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow',"
385 "change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0)";
387 if(MysqlQuery(res.c_str(),sock))
389 errorStr = "Couldn't create tariffs table list With error:\n";
390 errorStr += mysql_error(sock);
395 res = "INSERT INTO tariffs SET name='tariff',";
397 for (int i = 0; i < DIR_NUM; i++)
399 strprintf(¶m, " NoDiscount%d=1,", i);
402 strprintf(¶m, " Threshold%d=0,", i);
405 strprintf(¶m, " Time%d='0:0-0:0',", i);
410 strprintf(¶m, " SinglePrice%d=0,", i);
416 strprintf(¶m, " PriceDayA%d=0.0,", i);
421 strprintf(¶m, " PriceDayB%d=0.0,", i);
427 strprintf(¶m, " PriceNightA%d=0.0,", i);
432 strprintf(¶m, " PriceNightB%d=0.0,", i);
437 res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
438 "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
439 "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month',"\
440 "change_policy='allow', change_policy_timeout=0";
442 if(MysqlQuery(res.c_str(),sock))
444 errorStr = "Couldn't create default tariff. With error:\n";
445 errorStr += mysql_error(sock);
450 sprintf(qbuf,"UPDATE info SET version=1");
452 if(MysqlQuery(qbuf,sock))
454 errorStr = "Couldn't write default version. With error:\n";
455 errorStr += mysql_error(sock);
462 //users-----------------------------------------------------------------------
463 if(!IsTablePresent("users",sock))
465 res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
466 "Passive INT(3) DEFAULT 0,Down INT(3) DEFAULT 0,DisabledDetailStat INT(3) DEFAULT 0,AlwaysOnline INT(3) DEFAULT 0,Tariff VARCHAR(40) NOT NULL DEFAULT '',"\
467 "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
468 "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
469 "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
471 for (int i = 0; i < USERDATA_NUM; i++)
473 strprintf(¶m, " Userdata%d VARCHAR(254) NOT NULL,", i);
477 param = " CreditExpire INT(11) DEFAULT 0,";
480 strprintf(¶m, " IP VARCHAR(254) DEFAULT '*',");
483 for (int i = 0; i < DIR_NUM; i++)
485 strprintf(¶m, " D%d BIGINT(30) DEFAULT 0,", i);
488 strprintf(¶m, " U%d BIGINT(30) DEFAULT 0,", i);
492 strprintf(¶m, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
493 "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
494 "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
495 " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
498 if(MysqlQuery(res.c_str(),sock))
500 errorStr = "Couldn't create users table list With error:\n";
501 errorStr += mysql_error(sock);
502 errorStr += "\n\n" + res;
507 res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
508 "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
509 "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
510 "Phone='', RealName='',Tariff='tariff',TariffChange='',NAS='',";
512 for (int i = 0; i < USERDATA_NUM; i++)
514 strprintf(¶m, " Userdata%d='',", i);
518 for (int i = 0; i < DIR_NUM; i++)
520 strprintf(¶m, " D%d=0,", i);
523 strprintf(¶m, " U%d=0,", i);
527 res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
528 "LastCashAddTime=0, PassiveTime=0";
530 if(MysqlQuery(res.c_str(),sock))
532 errorStr = "Couldn't create default user. With error:\n";
533 errorStr += mysql_error(sock);
539 //logs-----------------------------------------------------------------------
540 if(!IsTablePresent("logs"))
542 sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
546 errorStr = "Couldn't create admin table list With error:\n";
547 errorStr += mysql_error(sock);
552 //messages---------------------------------------------------------------------
553 if(!IsTablePresent("messages",sock))
555 sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
556 "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
557 "stgRepeat INT, repeatPeriod INT, text TEXT)");
559 if(MysqlQuery(qbuf,sock))
561 errorStr = "Couldn't create messages table. With error:\n";
562 errorStr += mysql_error(sock);
568 //month_stat-------------------------------------------------------------------
569 if(!IsTablePresent("stat",sock))
571 res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
573 for (int i = 0; i < DIR_NUM; i++)
575 strprintf(¶m, " U%d BIGINT,", i);
578 strprintf(¶m, " D%d BIGINT,", i);
582 res += " cash DOUBLE, INDEX (login))";
584 if(MysqlQuery(res.c_str(),sock))
586 errorStr = "Couldn't create stat table. With error:\n";
587 errorStr += mysql_error(sock);
595 //-----------------------------------------------------------------------------
596 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
598 if (schemaVersion < 1)
600 if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
602 errorStr = "Couldn't update tariffs table to version 1. With error:\n";
603 errorStr += mysql_error(sock);
607 if (MysqlQuery("UPDATE info SET version = 1", sock))
609 errorStr = "Couldn't update DB schema version to 1. With error:\n";
610 errorStr += mysql_error(sock);
615 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
618 if (schemaVersion < 2)
620 if (MysqlQuery("ALTER TABLE tariffs ADD change_policy VARCHAR(32) NOT NULL DEFAULT 'allow'", sock) ||
621 MysqlQuery("ALTER TABLE tariffs ADD change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0", sock))
623 errorStr = "Couldn't update tariffs table to version 2. With error:\n";
624 errorStr += mysql_error(sock);
628 if (MysqlQuery("UPDATE info SET version = 2", sock))
630 errorStr = "Couldn't update DB schema version to 2. With error:\n";
631 errorStr += mysql_error(sock);
636 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
640 //-----------------------------------------------------------------------------
642 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList,
643 const std::string & table, const std::string & name) const
652 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
654 if(MysqlGetQuery(qbuf,sock))
656 errorStr = "Couldn't GetAllParams Query for: ";
657 errorStr += name + " - " + table + "\n";
658 errorStr += mysql_error(sock);
663 if (!(res=mysql_store_result(sock)))
665 errorStr = "Couldn't GetAllParams Results for: ";
666 errorStr += name + " - " + table + "\n";
667 errorStr += mysql_error(sock);
671 num = mysql_num_rows(res);
673 for(i = 0; i < num; i++)
675 row = mysql_fetch_row(res);
676 ParamList->push_back(row[0]);
679 mysql_free_result(res);
685 //-----------------------------------------------------------------------------
686 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
688 if(GetAllParams(usersList, "users", "login"))
693 //-----------------------------------------------------------------------------
694 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
696 if(GetAllParams(adminsList, "admins", "login"))
701 //-----------------------------------------------------------------------------
702 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
704 if(GetAllParams(tariffsList, "tariffs", "name"))
709 //-----------------------------------------------------------------------------
710 int MYSQL_STORE::AddUser(const std::string & login) const
712 std::string query = "INSERT INTO users SET login='" + login + "',Note='',NAS=''";
714 for (int i = 0; i < USERDATA_NUM; i++)
715 query += ",Userdata" + std::to_string(i) + "=''";
717 if(MysqlSetQuery(query.c_str()))
719 errorStr = "Couldn't add user:\n";
720 //errorStr += mysql_error(sock);
726 //-----------------------------------------------------------------------------
727 int MYSQL_STORE::DelUser(const std::string & login) const
729 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
731 if(MysqlSetQuery(qbuf))
733 errorStr = "Couldn't delete user:\n";
734 //errorStr += mysql_error(sock);
740 //-----------------------------------------------------------------------------
741 int MYSQL_STORE::RestoreUserConf(STG::UserConf * conf, const std::string & login) const
748 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
749 AlwaysOnline, Tariff, Address, Phone, Email, Note, \
750 RealName, StgGroup, Credit, TariffChange, ";
752 for (int i = 0; i < USERDATA_NUM; i++)
754 sprintf(qbuf, "Userdata%d, ", i);
758 query += "CreditExpire, IP FROM users WHERE login='";
759 query += login + "' LIMIT 1";
761 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
763 if(MysqlGetQuery(query.c_str(),sock))
765 errorStr = "Couldn't restore Tariff(on query):\n";
766 errorStr += mysql_error(sock);
771 if (!(res=mysql_store_result(sock)))
773 errorStr = "Couldn't restore Tariff(on getting result):\n";
774 errorStr += mysql_error(sock);
779 if (mysql_num_rows(res) != 1)
781 errorStr = "User not found";
786 row = mysql_fetch_row(res);
788 conf->password = row[1];
790 if (conf->password.empty())
792 mysql_free_result(res);
793 errorStr = "User \'" + login + "\' password is blank.";
798 if (GetInt(row[2],&conf->passive) != 0)
800 mysql_free_result(res);
801 errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
806 if (GetInt(row[3], &conf->disabled) != 0)
808 mysql_free_result(res);
809 errorStr = "User \'" + login + "\' data not read. Parameter Down.";
814 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
816 mysql_free_result(res);
817 errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
822 if (GetInt(row[5], &conf->alwaysOnline) != 0)
824 mysql_free_result(res);
825 errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
830 conf->tariffName = row[6];
832 if (conf->tariffName.empty())
834 mysql_free_result(res);
835 errorStr = "User \'" + login + "\' tariff is blank.";
840 conf->address = row[7];
841 conf->phone = row[8];
842 conf->email = row[9];
843 conf->note = row[10];
844 conf->realName = row[11];
845 conf->group = row[12];
847 if (GetDouble(row[13], &conf->credit, 0) != 0)
849 mysql_free_result(res);
850 errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
855 conf->nextTariff = row[14];
857 for (int i = 0; i < USERDATA_NUM; i++)
859 conf->userdata[i] = row[15+i];
862 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
864 std::string ipStr = row[16+USERDATA_NUM];
868 i = STG::UserIPs::parse(ipStr);
870 catch (const std::string & s)
872 mysql_free_result(res);
873 errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
879 mysql_free_result(res);
884 //-----------------------------------------------------------------------------
885 int MYSQL_STORE::RestoreUserStat(STG::UserStat * stat, const std::string & login) const
895 for (int i = 0; i < DIR_NUM; i++)
897 sprintf(qbuf, "D%d, U%d, ", i, i);
901 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
902 FROM users WHERE login = '";
903 query += login + "'";
905 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
907 if(MysqlGetQuery(query.c_str() ,sock))
909 errorStr = "Couldn't restore UserStat(on query):\n";
910 errorStr += mysql_error(sock);
915 if (!(res=mysql_store_result(sock)))
917 errorStr = "Couldn't restore UserStat(on getting result):\n";
918 errorStr += mysql_error(sock);
923 row = mysql_fetch_row(res);
925 unsigned int startPos=0;
929 for (int i = 0; i < DIR_NUM; i++)
932 sprintf(s, "D%d", i);
933 if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
935 mysql_free_result(res);
936 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
940 stat->monthDown[i] = traff;
942 sprintf(s, "U%d", i);
943 if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
945 mysql_free_result(res);
946 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
950 stat->monthUp[i] = traff;
953 startPos += (2*DIR_NUM);
955 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
957 mysql_free_result(res);
958 errorStr = "User \'" + login + "\' stat not read. Parameter Cash";
963 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
965 mysql_free_result(res);
966 errorStr = "User \'" + login + "\' stat not read. Parameter FreeMb";
971 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
973 mysql_free_result(res);
974 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAdd";
979 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
981 mysql_free_result(res);
982 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
987 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
989 mysql_free_result(res);
990 errorStr = "User \'" + login + "\' stat not read. Parameter PassiveTime";
995 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
997 mysql_free_result(res);
998 errorStr = "User \'" + login + "\' stat not read. Parameter LastActivityTime";
1003 mysql_free_result(res);
1007 //-----------------------------------------------------------------------------
1008 int MYSQL_STORE::SaveUserConf(const STG::UserConf & conf, const std::string & login) const
1013 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
1014 "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
1015 "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ",
1016 conf.password.c_str(),
1019 conf.disabledDetailStat,
1021 conf.tariffName.c_str(),
1022 (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
1023 (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
1024 (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
1025 (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
1026 (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
1027 (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
1029 conf.nextTariff.c_str()
1032 for (int i = 0; i < USERDATA_NUM; i++)
1034 strprintf(¶m, " Userdata%d='%s',", i,
1035 (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
1039 strprintf(¶m, " CreditExpire=%d,", conf.creditExpire);
1042 std::ostringstream ipStr;
1045 strprintf(¶m, " IP='%s'", ipStr.str().c_str());
1048 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1051 if(MysqlSetQuery(res.c_str()))
1053 errorStr = "Couldn't save user conf:\n";
1054 //errorStr += mysql_error(sock);
1060 //-----------------------------------------------------------------------------
1061 int MYSQL_STORE::SaveUserStat(const STG::UserStat & stat, const std::string & login) const
1066 res = "UPDATE users SET";
1068 for (int i = 0; i < DIR_NUM; i++)
1070 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1073 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1077 strprintf(¶m, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
1078 " PassiveTime=%d, LastActivityTime=%d",
1082 stat.lastCashAddTime,
1084 stat.lastActivityTime
1088 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1091 if(MysqlSetQuery(res.c_str()))
1093 errorStr = "Couldn't save user stat:\n";
1094 // errorStr += mysql_error(sock);
1100 //-----------------------------------------------------------------------------
1101 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
1103 std::string res, tempStr;
1112 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1113 if (!(sock=MysqlConnect())){
1114 errorStr = "Couldn't connect to Server";
1117 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1119 errorStr = "Couldn't get table " + tempStr + ":\n";
1120 errorStr += mysql_error(sock);
1125 my_ulonglong num_rows = mysql_num_rows(result);
1127 mysql_free_result(result);
1131 sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
1132 lt->tm_mon+1, lt->tm_year+1900);
1134 if(MysqlQuery(qbuf,sock))
1136 errorStr = "Couldn't create WriteDetailedStat table:\n";
1137 errorStr += mysql_error(sock);
1143 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
1147 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
1148 lt->tm_mon+1, lt->tm_year+1900,
1149 login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
1151 if(MysqlQuery(send.c_str(),sock))
1153 errorStr = "Couldn't write log string:\n";
1154 errorStr += mysql_error(sock);
1162 //-----------------------------------------------------------------------------
1163 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
1164 const std::string & admLogin,
1166 const std::string & paramName,
1167 const std::string & oldValue,
1168 const std::string & newValue,
1169 const std::string & message) const
1171 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
1172 + paramName + "\' parameter changed from \'" + oldValue +
1173 "\' to \'" + newValue + "\'. " + message;
1175 return WriteLogString(userLogMsg, login);
1177 //-----------------------------------------------------------------------------
1178 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1180 std::string logStr = "Connect, " + inet_ntostring(ip);
1181 return WriteLogString(logStr, login);
1183 //-----------------------------------------------------------------------------
1184 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
1185 const STG::DirTraff & up,
1186 const STG::DirTraff & down,
1187 const STG::DirTraff & sessionUp,
1188 const STG::DirTraff & sessionDown,
1191 const std::string & /*reason*/) const
1193 std::string logStr = "Disconnect, ";
1194 std::ostringstream sssu;
1195 std::ostringstream sssd;
1196 std::ostringstream ssmu;
1197 std::ostringstream ssmd;
1198 std::ostringstream sscash;
1204 sssd << sessionDown;
1208 logStr += " session upload: \'";
1209 logStr += sssu.str();
1210 logStr += "\' session download: \'";
1211 logStr += sssd.str();
1212 logStr += "\' month upload: \'";
1213 logStr += ssmu.str();
1214 logStr += "\' month download: \'";
1215 logStr += ssmd.str();
1216 logStr += "\' cash: \'";
1217 logStr += sscash.str();
1220 return WriteLogString(logStr, login);
1222 //-----------------------------------------------------------------------------
1223 int MYSQL_STORE::SaveMonthStat(const STG::UserStat & stat, int month, int year,
1224 const std::string & login) const
1226 std::string param, res;
1228 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,",
1229 login.c_str(), month+1, year+1900);
1231 for (int i = 0; i < DIR_NUM; i++)
1233 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1236 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1240 strprintf(¶m, " cash=%f", stat.cash);
1243 if(MysqlSetQuery(res.c_str()))
1245 errorStr = "Couldn't SaveMonthStat:\n";
1246 //errorStr += mysql_error(sock);
1252 //-----------------------------------------------------------------------------*/
1253 int MYSQL_STORE::AddAdmin(const std::string & login) const
1255 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
1257 if(MysqlSetQuery(qbuf))
1259 errorStr = "Couldn't add admin:\n";
1260 //errorStr += mysql_error(sock);
1266 //-----------------------------------------------------------------------------*/
1267 int MYSQL_STORE::DelAdmin(const std::string & login) const
1269 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
1271 if(MysqlSetQuery(qbuf))
1273 errorStr = "Couldn't delete admin:\n";
1274 //errorStr += mysql_error(sock);
1280 //-----------------------------------------------------------------------------*/
1281 int MYSQL_STORE::SaveAdmin(const STG::AdminConf & ac) const
1283 char passwordE[2 * ADM_PASSWD_LEN + 2];
1284 char pass[ADM_PASSWD_LEN + 1];
1285 char adminPass[ADM_PASSWD_LEN + 1];
1287 memset(pass, 0, sizeof(pass));
1288 memset(adminPass, 0, sizeof(adminPass));
1291 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1293 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1294 adminPass[ADM_PASSWD_LEN - 1] = 0;
1296 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1298 EncryptBlock(pass + 8*i, adminPass + 8*i, &ctx);
1301 pass[ADM_PASSWD_LEN - 1] = 0;
1302 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1304 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
1305 "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
1306 "WHERE login='%s' LIMIT 1",
1318 if(MysqlSetQuery(qbuf))
1320 errorStr = "Couldn't save admin:\n";
1321 //errorStr += mysql_error(sock);
1327 //-----------------------------------------------------------------------------
1328 int MYSQL_STORE::RestoreAdmin(STG::AdminConf * ac, const std::string & login) const
1330 char pass[ADM_PASSWD_LEN + 1];
1331 char password[ADM_PASSWD_LEN + 1];
1332 char passwordE[2*ADM_PASSWD_LEN + 2];
1335 memset(password, 0, sizeof(password));
1341 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
1343 if(MysqlGetQuery(qbuf,sock))
1345 errorStr = "Couldn't restore admin:\n";
1346 errorStr += mysql_error(sock);
1351 if (!(res=mysql_store_result(sock)))
1353 errorStr = "Couldn't restore admin:\n";
1354 errorStr += mysql_error(sock);
1359 if ( mysql_num_rows(res) == 0)
1361 mysql_free_result(res);
1362 errorStr = "Couldn't restore admin as couldn't found him in table.\n";
1367 row = mysql_fetch_row(res);
1373 mysql_free_result(res);
1374 errorStr = "Error in parameter password";
1379 memset(passwordE, 0, sizeof(passwordE));
1380 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1382 memset(pass, 0, sizeof(pass));
1384 if (passwordE[0] != 0)
1386 Decode21(pass, passwordE);
1387 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1389 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1391 DecryptBlock(password + 8*i, pass + 8*i, &ctx);
1399 ac->password = password;
1403 if (GetInt(row[2], &a) == 0)
1404 ac->priv.userConf = a;
1407 mysql_free_result(res);
1408 errorStr = "Error in parameter ChgConf";
1413 if (GetInt(row[3], &a) == 0)
1414 ac->priv.userPasswd = a;
1417 mysql_free_result(res);
1418 errorStr = "Error in parameter ChgPassword";
1423 if (GetInt(row[4], &a) == 0)
1424 ac->priv.userStat = a;
1427 mysql_free_result(res);
1428 errorStr = "Error in parameter ChgStat";
1433 if (GetInt(row[5], &a) == 0)
1434 ac->priv.userCash = a;
1437 mysql_free_result(res);
1438 errorStr = "Error in parameter ChgCash";
1443 if (GetInt(row[6], &a) == 0)
1444 ac->priv.userAddDel = a;
1447 mysql_free_result(res);
1448 errorStr = "Error in parameter UsrAddDel";
1453 if (GetInt(row[7], &a) == 0)
1454 ac->priv.tariffChg = a;
1457 mysql_free_result(res);
1458 errorStr = "Error in parameter ChgTariff";
1463 if (GetInt(row[8], &a) == 0)
1464 ac->priv.adminChg = a;
1467 mysql_free_result(res);
1468 errorStr = "Error in parameter ChgAdmin";
1473 mysql_free_result(res);
1477 //-----------------------------------------------------------------------------
1478 int MYSQL_STORE::AddTariff(const std::string & name) const
1480 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
1482 if(MysqlSetQuery(qbuf))
1484 errorStr = "Couldn't add tariff:\n";
1485 // errorStr += mysql_error(sock);
1491 //-----------------------------------------------------------------------------
1492 int MYSQL_STORE::DelTariff(const std::string & name) const
1494 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
1496 if(MysqlSetQuery(qbuf))
1498 errorStr = "Couldn't delete tariff: ";
1499 // errorStr += mysql_error(sock);
1505 //-----------------------------------------------------------------------------
1506 int MYSQL_STORE::RestoreTariff(STG::TariffData * td, const std::string & tariffName) const
1511 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
1513 if(MysqlGetQuery(qbuf,sock))
1515 errorStr = "Couldn't restore Tariff:\n";
1516 errorStr += mysql_error(sock);
1521 if (!(res=mysql_store_result(sock)))
1523 errorStr = "Couldn't restore Tariff:\n";
1524 errorStr += mysql_error(sock);
1530 td->tariffConf.name = tariffName;
1532 row = mysql_fetch_row(res);
1535 for (int i = 0; i<DIR_NUM; i++)
1537 strprintf(¶m, "Time%d", i);
1539 if (str.length() == 0)
1541 mysql_free_result(res);
1542 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1547 ParseTariffTimeStr(str.c_str(),
1548 td->dirPrice[i].hDay,
1549 td->dirPrice[i].mDay,
1550 td->dirPrice[i].hNight,
1551 td->dirPrice[i].mNight);
1553 strprintf(¶m, "PriceDayA%d", i);
1554 if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
1556 mysql_free_result(res);
1557 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1561 td->dirPrice[i].priceDayA /= (1024*1024);
1563 strprintf(¶m, "PriceDayB%d", i);
1564 if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
1566 mysql_free_result(res);
1567 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1571 td->dirPrice[i].priceDayB /= (1024*1024);
1573 strprintf(¶m, "PriceNightA%d", i);
1574 if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
1576 mysql_free_result(res);
1577 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1581 td->dirPrice[i].priceNightA /= (1024*1024);
1583 strprintf(¶m, "PriceNightB%d", i);
1584 if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
1586 mysql_free_result(res);
1587 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1591 td->dirPrice[i].priceNightB /= (1024*1024);
1593 strprintf(¶m, "Threshold%d", i);
1594 if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
1596 mysql_free_result(res);
1597 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1602 strprintf(¶m, "SinglePrice%d", i);
1603 if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
1605 mysql_free_result(res);
1606 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1611 strprintf(¶m, "NoDiscount%d", i);
1612 if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
1614 mysql_free_result(res);
1615 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1621 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
1623 mysql_free_result(res);
1624 errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1629 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
1631 mysql_free_result(res);
1632 errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1637 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
1639 mysql_free_result(res);
1640 errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1645 str = row[4+8*DIR_NUM];
1646 param = "TraffType";
1648 if (str.length() == 0)
1650 mysql_free_result(res);
1651 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1656 td->tariffConf.traffType = STG::Tariff::parseTraffType(str);
1658 if (schemaVersion > 0)
1660 str = row[5+8*DIR_NUM];
1663 if (str.length() == 0)
1665 mysql_free_result(res);
1666 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1671 td->tariffConf.period = STG::Tariff::parsePeriod(str);
1675 td->tariffConf.period = STG::Tariff::MONTH;
1678 if (schemaVersion > 1)
1680 str = row[6+8*DIR_NUM];
1681 param = "ChangePolicy";
1683 if (str.length() == 0)
1685 mysql_free_result(res);
1686 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1691 td->tariffConf.changePolicy = STG::Tariff::parseChangePolicy(str);
1693 str = row[7+8*DIR_NUM];
1694 param = "ChangePolicyTimeout";
1696 if (str.length() == 0)
1698 mysql_free_result(res);
1699 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1704 td->tariffConf.changePolicyTimeout = readTime(str);
1708 td->tariffConf.changePolicy = STG::Tariff::ALLOW;
1709 td->tariffConf.changePolicyTimeout = 0;
1712 mysql_free_result(res);
1716 //-----------------------------------------------------------------------------
1717 int MYSQL_STORE::SaveTariff(const STG::TariffData & td, const std::string & tariffName) const
1721 std::string res="UPDATE tariffs SET";
1723 for (int i = 0; i < DIR_NUM; i++)
1725 strprintf(¶m, " PriceDayA%d=%f,", i,
1726 td.dirPrice[i].priceDayA * pt_mega);
1729 strprintf(¶m, " PriceDayB%d=%f,", i,
1730 td.dirPrice[i].priceDayB * pt_mega);
1733 strprintf(¶m, " PriceNightA%d=%f,", i,
1734 td.dirPrice[i].priceNightA * pt_mega);
1737 strprintf(¶m, " PriceNightB%d=%f,", i,
1738 td.dirPrice[i].priceNightB * pt_mega);
1741 strprintf(¶m, " Threshold%d=%d,", i,
1742 td.dirPrice[i].threshold);
1746 strprintf(¶m, " Time%d", i);
1748 strprintf(&s, "%0d:%0d-%0d:%0d",
1749 td.dirPrice[i].hDay,
1750 td.dirPrice[i].mDay,
1751 td.dirPrice[i].hNight,
1752 td.dirPrice[i].mNight);
1754 res += (param + "='" + s + "',");
1756 strprintf(¶m, " NoDiscount%d=%d,", i,
1757 td.dirPrice[i].noDiscount);
1760 strprintf(¶m, " SinglePrice%d=%d,", i,
1761 td.dirPrice[i].singlePrice);
1765 strprintf(¶m, " PassiveCost=%f,", td.tariffConf.passiveCost);
1768 strprintf(¶m, " Fee=%f,", td.tariffConf.fee);
1771 strprintf(¶m, " Free=%f,", td.tariffConf.free);
1774 res += " TraffType='" + STG::Tariff::toString(td.tariffConf.traffType) + "'";
1776 if (schemaVersion > 0)
1777 res += ", Period='" + STG::Tariff::toString(td.tariffConf.period) + "'";
1779 if (schemaVersion > 1)
1780 res += ", change_policy='" + STG::Tariff::toString(td.tariffConf.changePolicy) + "'"\
1781 ", change_policy_timeout='" + formatTime(td.tariffConf.changePolicy) + "'";
1783 strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str());
1786 if(MysqlSetQuery(res.c_str()))
1788 errorStr = "Couldn't save tariff:\n";
1789 //errorStr += mysql_error(sock);
1795 //-----------------------------------------------------------------------------
1796 int MYSQL_STORE::WriteDetailedStat(const STG::TraffStat & statTree,
1798 const std::string & login) const
1800 std::string res, stTime, endTime, tempStr;
1807 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1815 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1817 if (!(sock=MysqlConnect())){
1822 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1824 errorStr = "Couldn't get table " + tempStr + ":\n";
1825 errorStr += mysql_error(sock);
1830 my_ulonglong num_rows = mysql_num_rows(result);
1832 mysql_free_result(result);
1836 sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
1837 "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
1838 "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
1839 "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
1840 lt->tm_mon+1, lt->tm_year+1900);
1842 if(MysqlQuery(qbuf,sock))
1844 errorStr = "Couldn't create WriteDetailedStat table:\n";
1845 errorStr += mysql_error(sock);
1854 lt1 = localtime(&lastStat);
1863 lt2 = localtime(&t);
1869 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
1870 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
1872 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
1873 "day=%d,startTime='%s',endTime='%s',",
1874 lt->tm_mon+1, lt->tm_year+1900,
1881 STG::TraffStat::const_iterator stIter;
1882 stIter = statTree.begin();
1884 while (stIter != statTree.end())
1886 strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f",
1887 inet_ntostring(stIter->first.ip).c_str(),
1889 stIter->second.down,
1894 if( MysqlQuery((res+tempStr).c_str(),sock) )
1896 errorStr = "Couldn't insert data in WriteDetailedStat:\n";
1897 errorStr += mysql_error(sock);
1902 result=mysql_store_result(sock);
1904 mysql_free_result(result);
1911 //-----------------------------------------------------------------------------
1912 int MYSQL_STORE::AddMessage(STG::Message * msg, const std::string & login) const
1916 gettimeofday(&tv, NULL);
1918 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
1920 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld",
1922 static_cast<long long>(msg->header.id)
1925 if(MysqlSetQuery(qbuf))
1927 errorStr = "Couldn't add message:\n";
1928 //errorStr += mysql_error(sock);
1932 return EditMessage(*msg, login);
1934 //-----------------------------------------------------------------------------
1935 int MYSQL_STORE::EditMessage(const STG::Message & msg, const std::string & login) const
1939 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
1940 "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
1941 "WHERE login='%s' AND id=%lld LIMIT 1",
1943 msg.header.lastSendTime,
1944 msg.header.creationTime,
1945 msg.header.showTime,
1947 msg.header.repeatPeriod,
1948 (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
1953 if(MysqlSetQuery(res.c_str()))
1955 errorStr = "Couldn't edit message:\n";
1956 //errorStr += mysql_error(sock);
1962 //-----------------------------------------------------------------------------
1963 int MYSQL_STORE::GetMessage(uint64_t id, STG::Message * msg, const std::string & login) const
1969 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
1970 login.c_str(), static_cast<unsigned long long>(id));
1972 if(MysqlGetQuery(qbuf,sock))
1974 errorStr = "Couldn't GetMessage:\n";
1975 errorStr += mysql_error(sock);
1980 if (!(res=mysql_store_result(sock)))
1982 errorStr = "Couldn't GetMessage:\n";
1983 errorStr += mysql_error(sock);
1988 row = mysql_fetch_row(res);
1990 if(row[2]&&str2x(row[2], msg->header.type))
1992 mysql_free_result(res);
1993 errorStr = "Invalid value in message header for user: " + login;
1998 if(row[3] && str2x(row[3], msg->header.lastSendTime))
2000 mysql_free_result(res);
2001 errorStr = "Invalid value in message header for user: " + login;
2006 if(row[4] && str2x(row[4], msg->header.creationTime))
2008 mysql_free_result(res);
2009 errorStr = "Invalid value in message header for user: " + login;
2014 if(row[5] && str2x(row[5], msg->header.showTime))
2016 mysql_free_result(res);
2017 errorStr = "Invalid value in message header for user: " + login;
2022 if(row[6] && str2x(row[6], msg->header.repeat))
2024 mysql_free_result(res);
2025 errorStr = "Invalid value in message header for user: " + login;
2030 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
2032 mysql_free_result(res);
2033 errorStr = "Invalid value in message header for user: " + login;
2038 msg->header.id = id;
2041 mysql_free_result(res);
2045 //-----------------------------------------------------------------------------
2046 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
2048 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
2049 login.c_str(), static_cast<long long>(id));
2051 if(MysqlSetQuery(qbuf))
2053 errorStr = "Couldn't delete Message:\n";
2054 //errorStr += mysql_error(sock);
2060 //-----------------------------------------------------------------------------
2061 int MYSQL_STORE::GetMessageHdrs(std::vector<STG::Message::Header> * hdrsList, const std::string & login) const
2066 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
2068 if(MysqlGetQuery(qbuf,sock))
2070 errorStr = "Couldn't GetMessageHdrs:\n";
2071 errorStr += mysql_error(sock);
2076 if (!(res=mysql_store_result(sock)))
2078 errorStr = "Couldn't GetMessageHdrs:\n";
2079 errorStr += mysql_error(sock);
2085 my_ulonglong num_rows = mysql_num_rows(res);
2088 for (i = 0; i < num_rows; i++)
2090 row = mysql_fetch_row(res);
2091 if (str2x(row[1], id))
2094 STG::Message::Header hdr;
2096 if(str2x(row[2], hdr.type))
2100 if(str2x(row[3], hdr.lastSendTime))
2104 if(str2x(row[4], hdr.creationTime))
2108 if(str2x(row[5], hdr.showTime))
2112 if(str2x(row[6], hdr.repeat))
2116 if(str2x(row[7], hdr.repeatPeriod))
2120 hdrsList->push_back(hdr);
2123 mysql_free_result(res);
2127 //-----------------------------------------------------------------------------
2129 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
2132 int ret=MysqlGetQuery(Query,sock);
2136 //-----------------------------------------------------------------------------
2137 int MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
2138 if (!(sock=MysqlConnect())) {
2141 return MysqlQuery(Query,sock);
2143 //-----------------------------------------------------------------------------
2144 MYSQL * MYSQL_STORE::MysqlConnect() const {
2146 if ( !(sock=mysql_init(NULL)) ){
2147 errorStr= "mysql init susck\n";
2150 if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
2151 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
2152 0,storeSettings.GetDBPort(),NULL,0)))
2154 errorStr = "Couldn't connect to mysql engine! With error:\n";
2155 errorStr += mysql_error(sock);
2159 if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
2160 errorStr = "Database lost !\n";
2166 //-----------------------------------------------------------------------------