10 #include "stg/common.h"
11 #include "stg/user_ips.h"
12 #include "stg/user_conf.h"
13 #include "stg/user_stat.h"
14 #include "stg/blowfish.h"
15 #include "stg/plugin_creator.h"
16 #include "stg/logger.h"
17 #include "mysql_store.h"
19 #define adm_enc_passwd "cjeifY8m3"
25 const int pt_mega = 1024 * 1024;
26 const std::string badSyms = "'`";
27 const char repSym = '\"';
28 const int RepitTimes = 3;
31 int GetInt(const std::string & str, T * val, T defaultVal = T())
35 *val = static_cast<T>(strtoll(str.c_str(), &res, 10));
39 *val = defaultVal; //Error!
46 int GetDouble(const std::string & str, double * val, double defaultVal)
50 *val = strtod(str.c_str(), &res);
54 *val = defaultVal; //Error!
61 int GetTime(const std::string & str, time_t * val, time_t defaultVal)
65 *val = strtol(str.c_str(), &res, 10);
69 *val = defaultVal; //Error!
76 //-----------------------------------------------------------------------------
77 std::string ReplaceStr(std::string source, const std::string & symlist, const char chgsym)
79 std::string::size_type pos=0;
81 while( (pos = source.find_first_of(symlist,pos)) != std::string::npos)
82 source.replace(pos, 1,1, chgsym);
87 int GetULongLongInt(const std::string & str, uint64_t * val, uint64_t defaultVal)
91 *val = strtoull(str.c_str(), &res, 10);
95 *val = defaultVal; //Error!
102 PLUGIN_CREATOR<MYSQL_STORE> msc;
105 extern "C" STORE * GetStore();
106 //-----------------------------------------------------------------------------
107 //-----------------------------------------------------------------------------
108 //-----------------------------------------------------------------------------
111 return msc.GetPlugin();
113 //-----------------------------------------------------------------------------
114 MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
118 //-----------------------------------------------------------------------------
119 int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<PARAM_VALUE> & moduleParams,
120 const std::string & name, std::string & result)
124 std::vector<PARAM_VALUE>::const_iterator pvi;
125 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
126 if (pvi == moduleParams.end() || pvi->value.empty())
128 errorStr = "Parameter \'" + name + "\' not found.";
132 result = pvi->value[0];
136 //-----------------------------------------------------------------------------
137 int MYSQL_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
139 if (ParseParam(s.moduleParams, "user", dbUser) < 0 &&
140 ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
142 if (ParseParam(s.moduleParams, "password", dbPass) < 0 &&
143 ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
145 if (ParseParam(s.moduleParams, "database", dbName) < 0 &&
146 ParseParam(s.moduleParams, "dbname", dbName) < 0)
148 if (ParseParam(s.moduleParams, "server", dbHost) < 0 &&
149 ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
154 //-----------------------------------------------------------------------------
155 //-----------------------------------------------------------------------------
156 //-----------------------------------------------------------------------------
157 MYSQL_STORE::MYSQL_STORE()
158 : version("mysql_store v.0.67"),
160 logger(GetPluginLogger(GetStgLogger(), "store_mysql"))
163 //-----------------------------------------------------------------------------
164 int MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
168 if( (ret = mysql_query(sock,sQuery)) )
170 for(int i=0; i<RepitTimes; i++)
172 if( (ret = mysql_query(sock,sQuery)) )
173 ;//need to send error result
181 //-----------------------------------------------------------------------------
183 //-----------------------------------------------------------------------------
184 int MYSQL_STORE::ParseSettings()
186 int ret = storeSettings.ParseSettings(settings);
190 errorStr = storeSettings.GetStrError();
193 if(storeSettings.GetDBPassword().length() == 0)
195 errorStr = "Database password must be not empty. Please read Manual.";
199 if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
200 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
203 errorStr = "Couldn't connect to mysql engine! With error:\n";
204 errorStr += mysql_error(&mysql);
210 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
212 std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
214 if(MysqlQuery(res.c_str(),sock))
216 errorStr = "Couldn't create database! With error:\n";
217 errorStr += mysql_error(sock);
223 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
225 errorStr = "Couldn't select database! With error:\n";
226 errorStr += mysql_error(sock);
231 ret = CheckAllTables(sock);
236 ret = CheckAllTables(sock);
240 logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
248 //-----------------------------------------------------------------------------
249 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
253 if (!(result=mysql_list_tables(sock,str.c_str() )))
255 errorStr = "Couldn't get tables list With error:\n";
256 errorStr += mysql_error(sock);
261 my_ulonglong num_rows = mysql_num_rows(result);
264 mysql_free_result(result);
266 return num_rows == 1;
268 //-----------------------------------------------------------------------------
269 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
271 //info-------------------------------------------------------------------------
272 if(!IsTablePresent("info",sock))
274 sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
276 if(MysqlQuery(qbuf,sock))
278 errorStr = "Couldn't create info table With error:\n";
279 errorStr += mysql_error(sock);
284 sprintf(qbuf,"INSERT INTO info SET version=0");
286 if(MysqlQuery(qbuf,sock))
288 errorStr = "Couldn't write default version. With error:\n";
289 errorStr += mysql_error(sock);
297 std::vector<std::string> info;
298 if (GetAllParams(&info, "info", "version"))
305 GetInt(info.front(), &schemaVersion, 0);
308 //admins-----------------------------------------------------------------------
309 if(!IsTablePresent("admins",sock))
311 sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
312 "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
313 "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
314 "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
315 "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
317 if(MysqlQuery(qbuf,sock))
319 errorStr = "Couldn't create admin table list With error:\n";
320 errorStr += mysql_error(sock);
325 sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
326 "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
327 "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
329 if(MysqlQuery(qbuf,sock))
331 errorStr = "Couldn't create default admin. With error:\n";
332 errorStr += mysql_error(sock);
338 //tariffs-----------------------------------------------------------------------
339 std::string param, res;
340 if(!IsTablePresent("tariffs",sock))
342 res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
344 for (int i = 0; i < DIR_NUM; i++)
346 strprintf(¶m, " PriceDayA%d DOUBLE DEFAULT 0.0,", i);
349 strprintf(¶m, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
352 strprintf(¶m, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
355 strprintf(¶m, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
358 strprintf(¶m, " Threshold%d INT DEFAULT 0,", i);
361 strprintf(¶m, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
364 strprintf(¶m, " NoDiscount%d INT DEFAULT 0,", i);
367 strprintf(¶m, " SinglePrice%d INT DEFAULT 0,", i);
371 res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
372 "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
373 "period VARCHAR(32) NOT NULL DEFAULT 'month',"
374 "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow',"
375 "change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0)";
377 if(MysqlQuery(res.c_str(),sock))
379 errorStr = "Couldn't create tariffs table list With error:\n";
380 errorStr += mysql_error(sock);
385 res = "INSERT INTO tariffs SET name='tariff',";
387 for (int i = 0; i < DIR_NUM; i++)
389 strprintf(¶m, " NoDiscount%d=1,", i);
392 strprintf(¶m, " Threshold%d=0,", i);
395 strprintf(¶m, " Time%d='0:0-0:0',", i);
400 strprintf(¶m, " SinglePrice%d=0,", i);
406 strprintf(¶m, " PriceDayA%d=0.0,", i);
411 strprintf(¶m, " PriceDayB%d=0.0,", i);
417 strprintf(¶m, " PriceNightA%d=0.0,", i);
422 strprintf(¶m, " PriceNightB%d=0.0,", i);
427 res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
428 "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
429 "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month',"\
430 "change_policy='allow', change_policy_timeout=0";
432 if(MysqlQuery(res.c_str(),sock))
434 errorStr = "Couldn't create default tariff. With error:\n";
435 errorStr += mysql_error(sock);
440 sprintf(qbuf,"UPDATE info SET version=1");
442 if(MysqlQuery(qbuf,sock))
444 errorStr = "Couldn't write default version. With error:\n";
445 errorStr += mysql_error(sock);
452 //users-----------------------------------------------------------------------
453 if(!IsTablePresent("users",sock))
455 res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
456 "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 '',"\
457 "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
458 "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
459 "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
461 for (int i = 0; i < USERDATA_NUM; i++)
463 strprintf(¶m, " Userdata%d VARCHAR(254) NOT NULL,", i);
467 param = " CreditExpire INT(11) DEFAULT 0,";
470 strprintf(¶m, " IP VARCHAR(254) DEFAULT '*',");
473 for (int i = 0; i < DIR_NUM; i++)
475 strprintf(¶m, " D%d BIGINT(30) DEFAULT 0,", i);
478 strprintf(¶m, " U%d BIGINT(30) DEFAULT 0,", i);
482 strprintf(¶m, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
483 "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
484 "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
485 " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
488 if(MysqlQuery(res.c_str(),sock))
490 errorStr = "Couldn't create users table list With error:\n";
491 errorStr += mysql_error(sock);
492 errorStr += "\n\n" + res;
497 res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
498 "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
499 "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
500 "Phone='', RealName='',Tariff='tariff',TariffChange='',NAS='',";
502 for (int i = 0; i < USERDATA_NUM; i++)
504 strprintf(¶m, " Userdata%d='',", i);
508 for (int i = 0; i < DIR_NUM; i++)
510 strprintf(¶m, " D%d=0,", i);
513 strprintf(¶m, " U%d=0,", i);
517 res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
518 "LastCashAddTime=0, PassiveTime=0";
520 if(MysqlQuery(res.c_str(),sock))
522 errorStr = "Couldn't create default user. With error:\n";
523 errorStr += mysql_error(sock);
529 //logs-----------------------------------------------------------------------
530 if(!IsTablePresent("logs"))
532 sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
536 errorStr = "Couldn't create admin table list With error:\n";
537 errorStr += mysql_error(sock);
542 //messages---------------------------------------------------------------------
543 if(!IsTablePresent("messages",sock))
545 sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
546 "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
547 "stgRepeat INT, repeatPeriod INT, text TEXT)");
549 if(MysqlQuery(qbuf,sock))
551 errorStr = "Couldn't create messages table. With error:\n";
552 errorStr += mysql_error(sock);
558 //month_stat-------------------------------------------------------------------
559 if(!IsTablePresent("stat",sock))
561 res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
563 for (int i = 0; i < DIR_NUM; i++)
565 strprintf(¶m, " U%d BIGINT,", i);
568 strprintf(¶m, " D%d BIGINT,", i);
572 res += " cash DOUBLE, INDEX (login))";
574 if(MysqlQuery(res.c_str(),sock))
576 errorStr = "Couldn't create stat table. With error:\n";
577 errorStr += mysql_error(sock);
585 //-----------------------------------------------------------------------------
586 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
588 if (schemaVersion < 1)
590 if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
592 errorStr = "Couldn't update tariffs table to version 1. With error:\n";
593 errorStr += mysql_error(sock);
597 if (MysqlQuery("UPDATE info SET version = 1", sock))
599 errorStr = "Couldn't update DB schema version to 1. With error:\n";
600 errorStr += mysql_error(sock);
605 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
608 if (schemaVersion < 2)
610 if (MysqlQuery("ALTER TABLE tariffs ADD change_policy VARCHAR(32) NOT NULL DEFAULT 'allow'", sock) ||
611 MysqlQuery("ALTER TABLE tariffs ADD change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0", sock))
613 errorStr = "Couldn't update tariffs table to version 2. With error:\n";
614 errorStr += mysql_error(sock);
618 if (MysqlQuery("UPDATE info SET version = 2", sock))
620 errorStr = "Couldn't update DB schema version to 2. With error:\n";
621 errorStr += mysql_error(sock);
626 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
630 //-----------------------------------------------------------------------------
632 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList,
633 const std::string & table, const std::string & name) const
642 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
644 if(MysqlGetQuery(qbuf,sock))
646 errorStr = "Couldn't GetAllParams Query for: ";
647 errorStr += name + " - " + table + "\n";
648 errorStr += mysql_error(sock);
653 if (!(res=mysql_store_result(sock)))
655 errorStr = "Couldn't GetAllParams Results for: ";
656 errorStr += name + " - " + table + "\n";
657 errorStr += mysql_error(sock);
661 num = mysql_num_rows(res);
663 for(i = 0; i < num; i++)
665 row = mysql_fetch_row(res);
666 ParamList->push_back(row[0]);
669 mysql_free_result(res);
675 //-----------------------------------------------------------------------------
676 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
678 if(GetAllParams(usersList, "users", "login"))
683 //-----------------------------------------------------------------------------
684 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
686 if(GetAllParams(adminsList, "admins", "login"))
691 //-----------------------------------------------------------------------------
692 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
694 if(GetAllParams(tariffsList, "tariffs", "name"))
699 //-----------------------------------------------------------------------------
700 int MYSQL_STORE::AddUser(const std::string & login) const
702 std::string query = "INSERT INTO users SET login='" + login + "',Note='',NAS=''";
704 for (int i = 0; i < USERDATA_NUM; i++)
705 query += ",Userdata" + x2str(i) + "=''";
707 if(MysqlSetQuery(query.c_str()))
709 errorStr = "Couldn't add user:\n";
710 //errorStr += mysql_error(sock);
716 //-----------------------------------------------------------------------------
717 int MYSQL_STORE::DelUser(const std::string & login) const
719 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
721 if(MysqlSetQuery(qbuf))
723 errorStr = "Couldn't delete user:\n";
724 //errorStr += mysql_error(sock);
730 //-----------------------------------------------------------------------------
731 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
738 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
739 AlwaysOnline, Tariff, Address, Phone, Email, Note, \
740 RealName, StgGroup, Credit, TariffChange, ";
742 for (int i = 0; i < USERDATA_NUM; i++)
744 sprintf(qbuf, "Userdata%d, ", i);
748 query += "CreditExpire, IP FROM users WHERE login='";
749 query += login + "' LIMIT 1";
751 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
753 if(MysqlGetQuery(query.c_str(),sock))
755 errorStr = "Couldn't restore Tariff(on query):\n";
756 errorStr += mysql_error(sock);
761 if (!(res=mysql_store_result(sock)))
763 errorStr = "Couldn't restore Tariff(on getting result):\n";
764 errorStr += mysql_error(sock);
769 if (mysql_num_rows(res) != 1)
771 errorStr = "User not found";
776 row = mysql_fetch_row(res);
778 conf->password = row[1];
780 if (conf->password.empty())
782 mysql_free_result(res);
783 errorStr = "User \'" + login + "\' password is blank.";
788 if (GetInt(row[2],&conf->passive) != 0)
790 mysql_free_result(res);
791 errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
796 if (GetInt(row[3], &conf->disabled) != 0)
798 mysql_free_result(res);
799 errorStr = "User \'" + login + "\' data not read. Parameter Down.";
804 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
806 mysql_free_result(res);
807 errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
812 if (GetInt(row[5], &conf->alwaysOnline) != 0)
814 mysql_free_result(res);
815 errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
820 conf->tariffName = row[6];
822 if (conf->tariffName.empty())
824 mysql_free_result(res);
825 errorStr = "User \'" + login + "\' tariff is blank.";
830 conf->address = row[7];
831 conf->phone = row[8];
832 conf->email = row[9];
833 conf->note = row[10];
834 conf->realName = row[11];
835 conf->group = row[12];
837 if (GetDouble(row[13], &conf->credit, 0) != 0)
839 mysql_free_result(res);
840 errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
845 conf->nextTariff = row[14];
847 for (int i = 0; i < USERDATA_NUM; i++)
849 conf->userdata[i] = row[15+i];
852 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
854 std::string ipStr = row[16+USERDATA_NUM];
860 catch (const std::string & s)
862 mysql_free_result(res);
863 errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
869 mysql_free_result(res);
874 //-----------------------------------------------------------------------------
875 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
885 for (int i = 0; i < DIR_NUM; i++)
887 sprintf(qbuf, "D%d, U%d, ", i, i);
891 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
892 FROM users WHERE login = '";
893 query += login + "'";
895 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
897 if(MysqlGetQuery(query.c_str() ,sock))
899 errorStr = "Couldn't restore UserStat(on query):\n";
900 errorStr += mysql_error(sock);
905 if (!(res=mysql_store_result(sock)))
907 errorStr = "Couldn't restore UserStat(on getting result):\n";
908 errorStr += mysql_error(sock);
913 row = mysql_fetch_row(res);
915 unsigned int startPos=0;
919 for (int i = 0; i < DIR_NUM; i++)
922 sprintf(s, "D%d", i);
923 if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
925 mysql_free_result(res);
926 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
930 stat->monthDown[i] = traff;
932 sprintf(s, "U%d", i);
933 if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
935 mysql_free_result(res);
936 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
940 stat->monthUp[i] = traff;
943 startPos += (2*DIR_NUM);
945 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
947 mysql_free_result(res);
948 errorStr = "User \'" + login + "\' stat not read. Parameter Cash";
953 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
955 mysql_free_result(res);
956 errorStr = "User \'" + login + "\' stat not read. Parameter FreeMb";
961 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
963 mysql_free_result(res);
964 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAdd";
969 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
971 mysql_free_result(res);
972 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
977 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
979 mysql_free_result(res);
980 errorStr = "User \'" + login + "\' stat not read. Parameter PassiveTime";
985 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
987 mysql_free_result(res);
988 errorStr = "User \'" + login + "\' stat not read. Parameter LastActivityTime";
993 mysql_free_result(res);
997 //-----------------------------------------------------------------------------
998 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
1003 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
1004 "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
1005 "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ",
1006 conf.password.c_str(),
1009 conf.disabledDetailStat,
1011 conf.tariffName.c_str(),
1012 (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
1013 (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
1014 (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
1015 (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
1016 (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
1017 (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
1019 conf.nextTariff.c_str()
1022 for (int i = 0; i < USERDATA_NUM; i++)
1024 strprintf(¶m, " Userdata%d='%s',", i,
1025 (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
1029 strprintf(¶m, " CreditExpire=%d,", conf.creditExpire);
1032 std::ostringstream ipStr;
1035 strprintf(¶m, " IP='%s'", ipStr.str().c_str());
1038 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1041 if(MysqlSetQuery(res.c_str()))
1043 errorStr = "Couldn't save user conf:\n";
1044 //errorStr += mysql_error(sock);
1050 //-----------------------------------------------------------------------------
1051 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
1056 res = "UPDATE users SET";
1058 for (int i = 0; i < DIR_NUM; i++)
1060 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1063 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1067 strprintf(¶m, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
1068 " PassiveTime=%d, LastActivityTime=%d",
1072 stat.lastCashAddTime,
1074 stat.lastActivityTime
1078 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1081 if(MysqlSetQuery(res.c_str()))
1083 errorStr = "Couldn't save user stat:\n";
1084 // errorStr += mysql_error(sock);
1090 //-----------------------------------------------------------------------------
1091 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
1093 std::string res, tempStr;
1102 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1103 if (!(sock=MysqlConnect())){
1104 errorStr = "Couldn't connect to Server";
1107 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1109 errorStr = "Couldn't get table " + tempStr + ":\n";
1110 errorStr += mysql_error(sock);
1115 my_ulonglong num_rows = mysql_num_rows(result);
1117 mysql_free_result(result);
1121 sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
1122 lt->tm_mon+1, lt->tm_year+1900);
1124 if(MysqlQuery(qbuf,sock))
1126 errorStr = "Couldn't create WriteDetailedStat table:\n";
1127 errorStr += mysql_error(sock);
1133 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
1137 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
1138 lt->tm_mon+1, lt->tm_year+1900,
1139 login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
1141 if(MysqlQuery(send.c_str(),sock))
1143 errorStr = "Couldn't write log string:\n";
1144 errorStr += mysql_error(sock);
1152 //-----------------------------------------------------------------------------
1153 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
1154 const std::string & admLogin,
1156 const std::string & paramName,
1157 const std::string & oldValue,
1158 const std::string & newValue,
1159 const std::string & message) const
1161 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
1162 + paramName + "\' parameter changed from \'" + oldValue +
1163 "\' to \'" + newValue + "\'. " + message;
1165 return WriteLogString(userLogMsg, login);
1167 //-----------------------------------------------------------------------------
1168 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1170 std::string logStr = "Connect, " + inet_ntostring(ip);
1171 return WriteLogString(logStr, login);
1173 //-----------------------------------------------------------------------------
1174 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
1175 const DIR_TRAFF & up,
1176 const DIR_TRAFF & down,
1177 const DIR_TRAFF & sessionUp,
1178 const DIR_TRAFF & sessionDown,
1181 const std::string & /*reason*/) const
1183 std::string logStr = "Disconnect, ";
1184 std::ostringstream sssu;
1185 std::ostringstream sssd;
1186 std::ostringstream ssmu;
1187 std::ostringstream ssmd;
1188 std::ostringstream sscash;
1194 sssd << sessionDown;
1198 logStr += " session upload: \'";
1199 logStr += sssu.str();
1200 logStr += "\' session download: \'";
1201 logStr += sssd.str();
1202 logStr += "\' month upload: \'";
1203 logStr += ssmu.str();
1204 logStr += "\' month download: \'";
1205 logStr += ssmd.str();
1206 logStr += "\' cash: \'";
1207 logStr += sscash.str();
1210 return WriteLogString(logStr, login);
1212 //-----------------------------------------------------------------------------
1213 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year,
1214 const std::string & login) const
1216 std::string param, res;
1218 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,",
1219 login.c_str(), month+1, year+1900);
1221 for (int i = 0; i < DIR_NUM; i++)
1223 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1226 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1230 strprintf(¶m, " cash=%f", stat.cash);
1233 if(MysqlSetQuery(res.c_str()))
1235 errorStr = "Couldn't SaveMonthStat:\n";
1236 //errorStr += mysql_error(sock);
1242 //-----------------------------------------------------------------------------*/
1243 int MYSQL_STORE::AddAdmin(const std::string & login) const
1245 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
1247 if(MysqlSetQuery(qbuf))
1249 errorStr = "Couldn't add admin:\n";
1250 //errorStr += mysql_error(sock);
1256 //-----------------------------------------------------------------------------*/
1257 int MYSQL_STORE::DelAdmin(const std::string & login) const
1259 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
1261 if(MysqlSetQuery(qbuf))
1263 errorStr = "Couldn't delete admin:\n";
1264 //errorStr += mysql_error(sock);
1270 //-----------------------------------------------------------------------------*/
1271 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
1273 char passwordE[2 * ADM_PASSWD_LEN + 2];
1274 char pass[ADM_PASSWD_LEN + 1];
1275 char adminPass[ADM_PASSWD_LEN + 1];
1277 memset(pass, 0, sizeof(pass));
1278 memset(adminPass, 0, sizeof(adminPass));
1281 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1283 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1284 adminPass[ADM_PASSWD_LEN - 1] = 0;
1286 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1288 EncryptBlock(pass + 8*i, adminPass + 8*i, &ctx);
1291 pass[ADM_PASSWD_LEN - 1] = 0;
1292 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1294 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
1295 "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
1296 "WHERE login='%s' LIMIT 1",
1308 if(MysqlSetQuery(qbuf))
1310 errorStr = "Couldn't save admin:\n";
1311 //errorStr += mysql_error(sock);
1317 //-----------------------------------------------------------------------------
1318 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
1320 char pass[ADM_PASSWD_LEN + 1];
1321 char password[ADM_PASSWD_LEN + 1];
1322 char passwordE[2*ADM_PASSWD_LEN + 2];
1325 memset(password, 0, sizeof(password));
1331 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
1333 if(MysqlGetQuery(qbuf,sock))
1335 errorStr = "Couldn't restore admin:\n";
1336 errorStr += mysql_error(sock);
1341 if (!(res=mysql_store_result(sock)))
1343 errorStr = "Couldn't restore admin:\n";
1344 errorStr += mysql_error(sock);
1349 if ( mysql_num_rows(res) == 0)
1351 mysql_free_result(res);
1352 errorStr = "Couldn't restore admin as couldn't found him in table.\n";
1357 row = mysql_fetch_row(res);
1363 mysql_free_result(res);
1364 errorStr = "Error in parameter password";
1369 memset(passwordE, 0, sizeof(passwordE));
1370 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1372 memset(pass, 0, sizeof(pass));
1374 if (passwordE[0] != 0)
1376 Decode21(pass, passwordE);
1377 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1379 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1381 DecryptBlock(password + 8*i, pass + 8*i, &ctx);
1389 ac->password = password;
1393 if (GetInt(row[2], &a) == 0)
1394 ac->priv.userConf = a;
1397 mysql_free_result(res);
1398 errorStr = "Error in parameter ChgConf";
1403 if (GetInt(row[3], &a) == 0)
1404 ac->priv.userPasswd = a;
1407 mysql_free_result(res);
1408 errorStr = "Error in parameter ChgPassword";
1413 if (GetInt(row[4], &a) == 0)
1414 ac->priv.userStat = a;
1417 mysql_free_result(res);
1418 errorStr = "Error in parameter ChgStat";
1423 if (GetInt(row[5], &a) == 0)
1424 ac->priv.userCash = a;
1427 mysql_free_result(res);
1428 errorStr = "Error in parameter ChgCash";
1433 if (GetInt(row[6], &a) == 0)
1434 ac->priv.userAddDel = a;
1437 mysql_free_result(res);
1438 errorStr = "Error in parameter UsrAddDel";
1443 if (GetInt(row[7], &a) == 0)
1444 ac->priv.tariffChg = a;
1447 mysql_free_result(res);
1448 errorStr = "Error in parameter ChgTariff";
1453 if (GetInt(row[8], &a) == 0)
1454 ac->priv.adminChg = a;
1457 mysql_free_result(res);
1458 errorStr = "Error in parameter ChgAdmin";
1463 mysql_free_result(res);
1467 //-----------------------------------------------------------------------------
1468 int MYSQL_STORE::AddTariff(const std::string & name) const
1470 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
1472 if(MysqlSetQuery(qbuf))
1474 errorStr = "Couldn't add tariff:\n";
1475 // errorStr += mysql_error(sock);
1481 //-----------------------------------------------------------------------------
1482 int MYSQL_STORE::DelTariff(const std::string & name) const
1484 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
1486 if(MysqlSetQuery(qbuf))
1488 errorStr = "Couldn't delete tariff: ";
1489 // errorStr += mysql_error(sock);
1495 //-----------------------------------------------------------------------------
1496 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
1501 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
1503 if(MysqlGetQuery(qbuf,sock))
1505 errorStr = "Couldn't restore Tariff:\n";
1506 errorStr += mysql_error(sock);
1511 if (!(res=mysql_store_result(sock)))
1513 errorStr = "Couldn't restore Tariff:\n";
1514 errorStr += mysql_error(sock);
1520 td->tariffConf.name = tariffName;
1522 row = mysql_fetch_row(res);
1525 for (int i = 0; i<DIR_NUM; i++)
1527 strprintf(¶m, "Time%d", i);
1529 if (str.length() == 0)
1531 mysql_free_result(res);
1532 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1537 ParseTariffTimeStr(str.c_str(),
1538 td->dirPrice[i].hDay,
1539 td->dirPrice[i].mDay,
1540 td->dirPrice[i].hNight,
1541 td->dirPrice[i].mNight);
1543 strprintf(¶m, "PriceDayA%d", i);
1544 if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
1546 mysql_free_result(res);
1547 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1551 td->dirPrice[i].priceDayA /= (1024*1024);
1553 strprintf(¶m, "PriceDayB%d", i);
1554 if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
1556 mysql_free_result(res);
1557 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1561 td->dirPrice[i].priceDayB /= (1024*1024);
1563 strprintf(¶m, "PriceNightA%d", i);
1564 if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
1566 mysql_free_result(res);
1567 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1571 td->dirPrice[i].priceNightA /= (1024*1024);
1573 strprintf(¶m, "PriceNightB%d", i);
1574 if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
1576 mysql_free_result(res);
1577 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1581 td->dirPrice[i].priceNightB /= (1024*1024);
1583 strprintf(¶m, "Threshold%d", i);
1584 if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
1586 mysql_free_result(res);
1587 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1592 strprintf(¶m, "SinglePrice%d", i);
1593 if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
1595 mysql_free_result(res);
1596 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1601 strprintf(¶m, "NoDiscount%d", i);
1602 if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
1604 mysql_free_result(res);
1605 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1611 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
1613 mysql_free_result(res);
1614 errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1619 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
1621 mysql_free_result(res);
1622 errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1627 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
1629 mysql_free_result(res);
1630 errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1635 str = row[4+8*DIR_NUM];
1636 param = "TraffType";
1638 if (str.length() == 0)
1640 mysql_free_result(res);
1641 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1646 td->tariffConf.traffType = TARIFF::StringToTraffType(str);
1648 if (schemaVersion > 0)
1650 str = row[5+8*DIR_NUM];
1653 if (str.length() == 0)
1655 mysql_free_result(res);
1656 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1661 td->tariffConf.period = TARIFF::StringToPeriod(str);
1665 td->tariffConf.period = TARIFF::MONTH;
1668 if (schemaVersion > 1)
1670 str = row[6+8*DIR_NUM];
1671 param = "ChangePolicy";
1673 if (str.length() == 0)
1675 mysql_free_result(res);
1676 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1681 td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
1683 str = row[7+8*DIR_NUM];
1684 param = "ChangePolicyTimeout";
1686 if (str.length() == 0)
1688 mysql_free_result(res);
1689 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1694 td->tariffConf.changePolicyTimeout = readTime(str);
1698 td->tariffConf.changePolicy = TARIFF::ALLOW;
1699 td->tariffConf.changePolicyTimeout = 0;
1702 mysql_free_result(res);
1706 //-----------------------------------------------------------------------------
1707 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
1711 std::string res="UPDATE tariffs SET";
1713 for (int i = 0; i < DIR_NUM; i++)
1715 strprintf(¶m, " PriceDayA%d=%f,", i,
1716 td.dirPrice[i].priceDayA * pt_mega);
1719 strprintf(¶m, " PriceDayB%d=%f,", i,
1720 td.dirPrice[i].priceDayB * pt_mega);
1723 strprintf(¶m, " PriceNightA%d=%f,", i,
1724 td.dirPrice[i].priceNightA * pt_mega);
1727 strprintf(¶m, " PriceNightB%d=%f,", i,
1728 td.dirPrice[i].priceNightB * pt_mega);
1731 strprintf(¶m, " Threshold%d=%d,", i,
1732 td.dirPrice[i].threshold);
1736 strprintf(¶m, " Time%d", i);
1738 strprintf(&s, "%0d:%0d-%0d:%0d",
1739 td.dirPrice[i].hDay,
1740 td.dirPrice[i].mDay,
1741 td.dirPrice[i].hNight,
1742 td.dirPrice[i].mNight);
1744 res += (param + "='" + s + "',");
1746 strprintf(¶m, " NoDiscount%d=%d,", i,
1747 td.dirPrice[i].noDiscount);
1750 strprintf(¶m, " SinglePrice%d=%d,", i,
1751 td.dirPrice[i].singlePrice);
1755 strprintf(¶m, " PassiveCost=%f,", td.tariffConf.passiveCost);
1758 strprintf(¶m, " Fee=%f,", td.tariffConf.fee);
1761 strprintf(¶m, " Free=%f,", td.tariffConf.free);
1764 res += " TraffType='" + TARIFF::TraffTypeToString(td.tariffConf.traffType) + "'";
1766 if (schemaVersion > 0)
1767 res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
1769 if (schemaVersion > 1)
1770 res += ", change_policy='" + TARIFF::ChangePolicyToString(td.tariffConf.changePolicy) + "'"\
1771 ", change_policy_timeout='" + formatTime(td.tariffConf.changePolicy) + "'";
1773 strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str());
1776 if(MysqlSetQuery(res.c_str()))
1778 errorStr = "Couldn't save tariff:\n";
1779 //errorStr += mysql_error(sock);
1785 //-----------------------------------------------------------------------------
1786 int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
1788 const std::string & login) const
1790 std::string res, stTime, endTime, tempStr;
1797 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1805 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1807 if (!(sock=MysqlConnect())){
1812 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1814 errorStr = "Couldn't get table " + tempStr + ":\n";
1815 errorStr += mysql_error(sock);
1820 my_ulonglong num_rows = mysql_num_rows(result);
1822 mysql_free_result(result);
1826 sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
1827 "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
1828 "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
1829 "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
1830 lt->tm_mon+1, lt->tm_year+1900);
1832 if(MysqlQuery(qbuf,sock))
1834 errorStr = "Couldn't create WriteDetailedStat table:\n";
1835 errorStr += mysql_error(sock);
1844 lt1 = localtime(&lastStat);
1853 lt2 = localtime(&t);
1859 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
1860 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
1862 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
1863 "day=%d,startTime='%s',endTime='%s',",
1864 lt->tm_mon+1, lt->tm_year+1900,
1871 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
1872 stIter = statTree.begin();
1874 while (stIter != statTree.end())
1876 strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f",
1877 inet_ntostring(stIter->first.ip).c_str(),
1879 stIter->second.down,
1884 if( MysqlQuery((res+tempStr).c_str(),sock) )
1886 errorStr = "Couldn't insert data in WriteDetailedStat:\n";
1887 errorStr += mysql_error(sock);
1892 result=mysql_store_result(sock);
1894 mysql_free_result(result);
1901 //-----------------------------------------------------------------------------
1902 int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
1906 gettimeofday(&tv, NULL);
1908 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
1910 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld",
1912 static_cast<long long>(msg->header.id)
1915 if(MysqlSetQuery(qbuf))
1917 errorStr = "Couldn't add message:\n";
1918 //errorStr += mysql_error(sock);
1922 return EditMessage(*msg, login);
1924 //-----------------------------------------------------------------------------
1925 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
1929 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
1930 "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
1931 "WHERE login='%s' AND id=%lld LIMIT 1",
1933 msg.header.lastSendTime,
1934 msg.header.creationTime,
1935 msg.header.showTime,
1937 msg.header.repeatPeriod,
1938 (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
1943 if(MysqlSetQuery(res.c_str()))
1945 errorStr = "Couldn't edit message:\n";
1946 //errorStr += mysql_error(sock);
1952 //-----------------------------------------------------------------------------
1953 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
1959 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
1960 login.c_str(), static_cast<unsigned long long>(id));
1962 if(MysqlGetQuery(qbuf,sock))
1964 errorStr = "Couldn't GetMessage:\n";
1965 errorStr += mysql_error(sock);
1970 if (!(res=mysql_store_result(sock)))
1972 errorStr = "Couldn't GetMessage:\n";
1973 errorStr += mysql_error(sock);
1978 row = mysql_fetch_row(res);
1980 if(row[2]&&str2x(row[2], msg->header.type))
1982 mysql_free_result(res);
1983 errorStr = "Invalid value in message header for user: " + login;
1988 if(row[3] && str2x(row[3], msg->header.lastSendTime))
1990 mysql_free_result(res);
1991 errorStr = "Invalid value in message header for user: " + login;
1996 if(row[4] && str2x(row[4], msg->header.creationTime))
1998 mysql_free_result(res);
1999 errorStr = "Invalid value in message header for user: " + login;
2004 if(row[5] && str2x(row[5], msg->header.showTime))
2006 mysql_free_result(res);
2007 errorStr = "Invalid value in message header for user: " + login;
2012 if(row[6] && str2x(row[6], msg->header.repeat))
2014 mysql_free_result(res);
2015 errorStr = "Invalid value in message header for user: " + login;
2020 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
2022 mysql_free_result(res);
2023 errorStr = "Invalid value in message header for user: " + login;
2028 msg->header.id = id;
2031 mysql_free_result(res);
2035 //-----------------------------------------------------------------------------
2036 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
2038 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
2039 login.c_str(), static_cast<long long>(id));
2041 if(MysqlSetQuery(qbuf))
2043 errorStr = "Couldn't delete Message:\n";
2044 //errorStr += mysql_error(sock);
2050 //-----------------------------------------------------------------------------
2051 int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
2056 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
2058 if(MysqlGetQuery(qbuf,sock))
2060 errorStr = "Couldn't GetMessageHdrs:\n";
2061 errorStr += mysql_error(sock);
2066 if (!(res=mysql_store_result(sock)))
2068 errorStr = "Couldn't GetMessageHdrs:\n";
2069 errorStr += mysql_error(sock);
2075 my_ulonglong num_rows = mysql_num_rows(res);
2078 for (i = 0; i < num_rows; i++)
2080 row = mysql_fetch_row(res);
2081 if (str2x(row[1], id))
2086 if(str2x(row[2], hdr.type))
2090 if(str2x(row[3], hdr.lastSendTime))
2094 if(str2x(row[4], hdr.creationTime))
2098 if(str2x(row[5], hdr.showTime))
2102 if(str2x(row[6], hdr.repeat))
2106 if(str2x(row[7], hdr.repeatPeriod))
2110 hdrsList->push_back(hdr);
2113 mysql_free_result(res);
2117 //-----------------------------------------------------------------------------
2119 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
2122 int ret=MysqlGetQuery(Query,sock);
2126 //-----------------------------------------------------------------------------
2127 int MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
2128 if (!(sock=MysqlConnect())) {
2131 return MysqlQuery(Query,sock);
2133 //-----------------------------------------------------------------------------
2134 MYSQL * MYSQL_STORE::MysqlConnect() const {
2136 if ( !(sock=mysql_init(NULL)) ){
2137 errorStr= "mysql init susck\n";
2140 if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
2141 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
2144 errorStr = "Couldn't connect to mysql engine! With error:\n";
2145 errorStr += mysql_error(sock);
2149 if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
2150 errorStr = "Database lost !\n";
2156 //-----------------------------------------------------------------------------