7 #include <mysql/errmsg.h>
9 #include "stg/common.h"
10 #include "stg/user_ips.h"
11 #include "stg/user_conf.h"
12 #include "stg/user_stat.h"
13 #include "stg/blowfish.h"
14 #include "stg/plugin_creator.h"
15 #include "stg/logger.h"
16 #include "mysql_store.h"
18 #define adm_enc_passwd "cjeifY8m3"
24 const int pt_mega = 1024 * 1024;
25 const std::string badSyms = "'`";
26 const char repSym = '\"';
27 const int RepitTimes = 3;
30 int GetInt(const std::string & str, T * val, T defaultVal = T())
34 *val = static_cast<T>(strtoll(str.c_str(), &res, 10));
38 *val = defaultVal; //Error!
45 int GetDouble(const std::string & str, double * val, double defaultVal)
49 *val = strtod(str.c_str(), &res);
53 *val = defaultVal; //Error!
60 int GetTime(const std::string & str, time_t * val, time_t defaultVal)
64 *val = strtol(str.c_str(), &res, 10);
68 *val = defaultVal; //Error!
75 //-----------------------------------------------------------------------------
76 std::string ReplaceStr(std::string source, const std::string & symlist, const char chgsym)
78 std::string::size_type pos=0;
80 while( (pos = source.find_first_of(symlist,pos)) != std::string::npos)
81 source.replace(pos, 1,1, chgsym);
86 int GetULongLongInt(const std::string & str, uint64_t * val, uint64_t defaultVal)
90 *val = strtoull(str.c_str(), &res, 10);
94 *val = defaultVal; //Error!
101 PLUGIN_CREATOR<MYSQL_STORE> msc;
104 extern "C" STORE * GetStore();
105 //-----------------------------------------------------------------------------
106 //-----------------------------------------------------------------------------
107 //-----------------------------------------------------------------------------
110 return msc.GetPlugin();
112 //-----------------------------------------------------------------------------
113 MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
117 //-----------------------------------------------------------------------------
118 int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<PARAM_VALUE> & moduleParams,
119 const std::string & name, std::string & result)
123 std::vector<PARAM_VALUE>::const_iterator pvi;
124 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
125 if (pvi == moduleParams.end() || pvi->value.empty())
127 errorStr = "Parameter \'" + name + "\' not found.";
131 result = pvi->value[0];
135 //-----------------------------------------------------------------------------
136 int MYSQL_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
138 if (ParseParam(s.moduleParams, "user", dbUser) < 0 &&
139 ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
141 if (ParseParam(s.moduleParams, "password", dbPass) < 0 &&
142 ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
144 if (ParseParam(s.moduleParams, "database", dbName) < 0 &&
145 ParseParam(s.moduleParams, "dbname", dbName) < 0)
147 if (ParseParam(s.moduleParams, "server", dbHost) < 0 &&
148 ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
153 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
155 //-----------------------------------------------------------------------------
156 MYSQL_STORE::MYSQL_STORE()
157 : version("mysql_store v.0.67"),
159 logger(GetPluginLogger(GetStgLogger(), "store_mysql"))
162 //-----------------------------------------------------------------------------
163 int MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
167 if( (ret = mysql_query(sock,sQuery)) )
169 for(int i=0; i<RepitTimes; i++)
171 if( (ret = mysql_query(sock,sQuery)) )
172 ;//need to send error result
180 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 int MYSQL_STORE::ParseSettings()
185 int ret = storeSettings.ParseSettings(settings);
189 errorStr = storeSettings.GetStrError();
192 if(storeSettings.GetDBPassword().length() == 0)
194 errorStr = "Database password must be not empty. Please read Manual.";
198 if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
199 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
202 errorStr = "Couldn't connect to mysql engine! With error:\n";
203 errorStr += mysql_error(&mysql);
209 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
211 std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
213 if(MysqlQuery(res.c_str(),sock))
215 errorStr = "Couldn't create database! With error:\n";
216 errorStr += mysql_error(sock);
222 if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
224 errorStr = "Couldn't select database! With error:\n";
225 errorStr += mysql_error(sock);
230 ret = CheckAllTables(sock);
235 ret = CheckAllTables(sock);
239 logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
247 //-----------------------------------------------------------------------------
248 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
252 if (!(result=mysql_list_tables(sock,str.c_str() )))
254 errorStr = "Couldn't get tables list With error:\n";
255 errorStr += mysql_error(sock);
260 my_ulonglong num_rows = mysql_num_rows(result);
263 mysql_free_result(result);
265 return num_rows == 1;
267 //-----------------------------------------------------------------------------
268 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
270 //info-------------------------------------------------------------------------
271 if(!IsTablePresent("info",sock))
273 sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
275 if(MysqlQuery(qbuf,sock))
277 errorStr = "Couldn't create info table With error:\n";
278 errorStr += mysql_error(sock);
283 sprintf(qbuf,"INSERT INTO info SET version=0");
285 if(MysqlQuery(qbuf,sock))
287 errorStr = "Couldn't write default version. With error:\n";
288 errorStr += mysql_error(sock);
296 std::vector<std::string> info;
297 if (GetAllParams(&info, "info", "version"))
304 GetInt(info.front(), &schemaVersion, 0);
307 //admins-----------------------------------------------------------------------
308 if(!IsTablePresent("admins",sock))
310 sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
311 "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
312 "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
313 "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
314 "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
316 if(MysqlQuery(qbuf,sock))
318 errorStr = "Couldn't create admin table list With error:\n";
319 errorStr += mysql_error(sock);
324 sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
325 "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
326 "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
328 if(MysqlQuery(qbuf,sock))
330 errorStr = "Couldn't create default admin. With error:\n";
331 errorStr += mysql_error(sock);
337 //tariffs-----------------------------------------------------------------------
338 std::string param, res;
339 if(!IsTablePresent("tariffs",sock))
341 res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
343 for (int i = 0; i < DIR_NUM; i++)
345 strprintf(¶m, " PriceDayA%d DOUBLE DEFAULT 0.0,", i);
348 strprintf(¶m, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
351 strprintf(¶m, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
354 strprintf(¶m, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
357 strprintf(¶m, " Threshold%d INT DEFAULT 0,", i);
360 strprintf(¶m, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
363 strprintf(¶m, " NoDiscount%d INT DEFAULT 0,", i);
366 strprintf(¶m, " SinglePrice%d INT DEFAULT 0,", i);
370 res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
371 "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
372 "period VARCHAR(32) NOT NULL DEFAULT 'month',"
373 "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow',"
374 "change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0)";
376 if(MysqlQuery(res.c_str(),sock))
378 errorStr = "Couldn't create tariffs table list With error:\n";
379 errorStr += mysql_error(sock);
384 res = "INSERT INTO tariffs SET name='tariff',";
386 for (int i = 0; i < DIR_NUM; i++)
388 strprintf(¶m, " NoDiscount%d=1,", i);
391 strprintf(¶m, " Threshold%d=0,", i);
394 strprintf(¶m, " Time%d='0:0-0:0',", i);
399 strprintf(¶m, " SinglePrice%d=0,", i);
405 strprintf(¶m, " PriceDayA%d=0.0,", i);
410 strprintf(¶m, " PriceDayB%d=0.0,", i);
416 strprintf(¶m, " PriceNightA%d=0.0,", i);
421 strprintf(¶m, " PriceNightB%d=0.0,", i);
426 res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
427 "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
428 "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month',"\
429 "change_policy='allow', change_policy_timeout=0";
431 if(MysqlQuery(res.c_str(),sock))
433 errorStr = "Couldn't create default tariff. With error:\n";
434 errorStr += mysql_error(sock);
439 sprintf(qbuf,"UPDATE info SET version=1");
441 if(MysqlQuery(qbuf,sock))
443 errorStr = "Couldn't write default version. With error:\n";
444 errorStr += mysql_error(sock);
451 //users-----------------------------------------------------------------------
452 if(!IsTablePresent("users",sock))
454 res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
455 "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 '',"\
456 "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
457 "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
458 "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
460 for (int i = 0; i < USERDATA_NUM; i++)
462 strprintf(¶m, " Userdata%d VARCHAR(254) NOT NULL,", i);
466 param = " CreditExpire INT(11) DEFAULT 0,";
469 strprintf(¶m, " IP VARCHAR(254) DEFAULT '*',");
472 for (int i = 0; i < DIR_NUM; i++)
474 strprintf(¶m, " D%d BIGINT(30) DEFAULT 0,", i);
477 strprintf(¶m, " U%d BIGINT(30) DEFAULT 0,", i);
481 strprintf(¶m, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
482 "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
483 "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
484 " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
487 if(MysqlQuery(res.c_str(),sock))
489 errorStr = "Couldn't create users table list With error:\n";
490 errorStr += mysql_error(sock);
491 errorStr += "\n\n" + res;
496 res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
497 "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
498 "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
499 "Phone='', RealName='',Tariff='tariff',TariffChange='',NAS='',";
501 for (int i = 0; i < USERDATA_NUM; i++)
503 strprintf(¶m, " Userdata%d='',", i);
507 for (int i = 0; i < DIR_NUM; i++)
509 strprintf(¶m, " D%d=0,", i);
512 strprintf(¶m, " U%d=0,", i);
516 res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
517 "LastCashAddTime=0, PassiveTime=0";
519 if(MysqlQuery(res.c_str(),sock))
521 errorStr = "Couldn't create default user. With error:\n";
522 errorStr += mysql_error(sock);
528 //logs-----------------------------------------------------------------------
529 if(!IsTablePresent("logs"))
531 sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
535 errorStr = "Couldn't create admin table list With error:\n";
536 errorStr += mysql_error(sock);
541 //messages---------------------------------------------------------------------
542 if(!IsTablePresent("messages",sock))
544 sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
545 "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
546 "stgRepeat INT, repeatPeriod INT, text TEXT)");
548 if(MysqlQuery(qbuf,sock))
550 errorStr = "Couldn't create messages table. With error:\n";
551 errorStr += mysql_error(sock);
557 //month_stat-------------------------------------------------------------------
558 if(!IsTablePresent("stat",sock))
560 res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
562 for (int i = 0; i < DIR_NUM; i++)
564 strprintf(¶m, " U%d BIGINT,", i);
567 strprintf(¶m, " D%d BIGINT,", i);
571 res += " cash DOUBLE, INDEX (login))";
573 if(MysqlQuery(res.c_str(),sock))
575 errorStr = "Couldn't create stat table. With error:\n";
576 errorStr += mysql_error(sock);
584 //-----------------------------------------------------------------------------
585 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
587 if (schemaVersion < 1)
589 if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
591 errorStr = "Couldn't update tariffs table to version 1. With error:\n";
592 errorStr += mysql_error(sock);
596 if (MysqlQuery("UPDATE info SET version = 1", sock))
598 errorStr = "Couldn't update DB schema version to 1. With error:\n";
599 errorStr += mysql_error(sock);
604 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
607 if (schemaVersion < 2)
609 if (MysqlQuery("ALTER TABLE tariffs ADD change_policy VARCHAR(32) NOT NULL DEFAULT 'allow'", sock) ||
610 MysqlQuery("ALTER TABLE tariffs ADD change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0", sock))
612 errorStr = "Couldn't update tariffs table to version 2. With error:\n";
613 errorStr += mysql_error(sock);
617 if (MysqlQuery("UPDATE info SET version = 2", sock))
619 errorStr = "Couldn't update DB schema version to 2. With error:\n";
620 errorStr += mysql_error(sock);
625 logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
629 //-----------------------------------------------------------------------------
631 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList,
632 const std::string & table, const std::string & name) const
641 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
643 if(MysqlGetQuery(qbuf,sock))
645 errorStr = "Couldn't GetAllParams Query for: ";
646 errorStr += name + " - " + table + "\n";
647 errorStr += mysql_error(sock);
652 if (!(res=mysql_store_result(sock)))
654 errorStr = "Couldn't GetAllParams Results for: ";
655 errorStr += name + " - " + table + "\n";
656 errorStr += mysql_error(sock);
660 num = mysql_num_rows(res);
662 for(i = 0; i < num; i++)
664 row = mysql_fetch_row(res);
665 ParamList->push_back(row[0]);
668 mysql_free_result(res);
674 //-----------------------------------------------------------------------------
675 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
677 if(GetAllParams(usersList, "users", "login"))
682 //-----------------------------------------------------------------------------
683 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
685 if(GetAllParams(adminsList, "admins", "login"))
690 //-----------------------------------------------------------------------------
691 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
693 if(GetAllParams(tariffsList, "tariffs", "name"))
698 //-----------------------------------------------------------------------------
699 int MYSQL_STORE::AddUser(const std::string & login) const
701 std::string query = "INSERT INTO users SET login='" + login + "',Note='',NAS=''";
703 for (int i = 0; i < USERDATA_NUM; i++)
704 query += ",Userdata" + std::to_string(i) + "=''";
706 if(MysqlSetQuery(query.c_str()))
708 errorStr = "Couldn't add user:\n";
709 //errorStr += mysql_error(sock);
715 //-----------------------------------------------------------------------------
716 int MYSQL_STORE::DelUser(const std::string & login) const
718 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
720 if(MysqlSetQuery(qbuf))
722 errorStr = "Couldn't delete user:\n";
723 //errorStr += mysql_error(sock);
729 //-----------------------------------------------------------------------------
730 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
737 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
738 AlwaysOnline, Tariff, Address, Phone, Email, Note, \
739 RealName, StgGroup, Credit, TariffChange, ";
741 for (int i = 0; i < USERDATA_NUM; i++)
743 sprintf(qbuf, "Userdata%d, ", i);
747 query += "CreditExpire, IP FROM users WHERE login='";
748 query += login + "' LIMIT 1";
750 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
752 if(MysqlGetQuery(query.c_str(),sock))
754 errorStr = "Couldn't restore Tariff(on query):\n";
755 errorStr += mysql_error(sock);
760 if (!(res=mysql_store_result(sock)))
762 errorStr = "Couldn't restore Tariff(on getting result):\n";
763 errorStr += mysql_error(sock);
768 if (mysql_num_rows(res) != 1)
770 errorStr = "User not found";
775 row = mysql_fetch_row(res);
777 conf->password = row[1];
779 if (conf->password.empty())
781 mysql_free_result(res);
782 errorStr = "User \'" + login + "\' password is blank.";
787 if (GetInt(row[2],&conf->passive) != 0)
789 mysql_free_result(res);
790 errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
795 if (GetInt(row[3], &conf->disabled) != 0)
797 mysql_free_result(res);
798 errorStr = "User \'" + login + "\' data not read. Parameter Down.";
803 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
805 mysql_free_result(res);
806 errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
811 if (GetInt(row[5], &conf->alwaysOnline) != 0)
813 mysql_free_result(res);
814 errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
819 conf->tariffName = row[6];
821 if (conf->tariffName.empty())
823 mysql_free_result(res);
824 errorStr = "User \'" + login + "\' tariff is blank.";
829 conf->address = row[7];
830 conf->phone = row[8];
831 conf->email = row[9];
832 conf->note = row[10];
833 conf->realName = row[11];
834 conf->group = row[12];
836 if (GetDouble(row[13], &conf->credit, 0) != 0)
838 mysql_free_result(res);
839 errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
844 conf->nextTariff = row[14];
846 for (int i = 0; i < USERDATA_NUM; i++)
848 conf->userdata[i] = row[15+i];
851 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
853 std::string ipStr = row[16+USERDATA_NUM];
859 catch (const std::string & s)
861 mysql_free_result(res);
862 errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
868 mysql_free_result(res);
873 //-----------------------------------------------------------------------------
874 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
884 for (int i = 0; i < DIR_NUM; i++)
886 sprintf(qbuf, "D%d, U%d, ", i, i);
890 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
891 FROM users WHERE login = '";
892 query += login + "'";
894 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
896 if(MysqlGetQuery(query.c_str() ,sock))
898 errorStr = "Couldn't restore UserStat(on query):\n";
899 errorStr += mysql_error(sock);
904 if (!(res=mysql_store_result(sock)))
906 errorStr = "Couldn't restore UserStat(on getting result):\n";
907 errorStr += mysql_error(sock);
912 row = mysql_fetch_row(res);
914 unsigned int startPos=0;
918 for (int i = 0; i < DIR_NUM; i++)
921 sprintf(s, "D%d", i);
922 if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
924 mysql_free_result(res);
925 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
929 stat->monthDown[i] = traff;
931 sprintf(s, "U%d", i);
932 if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
934 mysql_free_result(res);
935 errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
939 stat->monthUp[i] = traff;
942 startPos += (2*DIR_NUM);
944 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
946 mysql_free_result(res);
947 errorStr = "User \'" + login + "\' stat not read. Parameter Cash";
952 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
954 mysql_free_result(res);
955 errorStr = "User \'" + login + "\' stat not read. Parameter FreeMb";
960 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
962 mysql_free_result(res);
963 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAdd";
968 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
970 mysql_free_result(res);
971 errorStr = "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
976 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
978 mysql_free_result(res);
979 errorStr = "User \'" + login + "\' stat not read. Parameter PassiveTime";
984 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
986 mysql_free_result(res);
987 errorStr = "User \'" + login + "\' stat not read. Parameter LastActivityTime";
992 mysql_free_result(res);
996 //-----------------------------------------------------------------------------
997 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
1002 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
1003 "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
1004 "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ",
1005 conf.password.c_str(),
1008 conf.disabledDetailStat,
1010 conf.tariffName.c_str(),
1011 (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
1012 (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
1013 (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
1014 (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
1015 (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
1016 (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
1018 conf.nextTariff.c_str()
1021 for (int i = 0; i < USERDATA_NUM; i++)
1023 strprintf(¶m, " Userdata%d='%s',", i,
1024 (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
1028 strprintf(¶m, " CreditExpire=%d,", conf.creditExpire);
1031 std::ostringstream ipStr;
1034 strprintf(¶m, " IP='%s'", ipStr.str().c_str());
1037 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1040 if(MysqlSetQuery(res.c_str()))
1042 errorStr = "Couldn't save user conf:\n";
1043 //errorStr += mysql_error(sock);
1049 //-----------------------------------------------------------------------------
1050 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
1055 res = "UPDATE users SET";
1057 for (int i = 0; i < DIR_NUM; i++)
1059 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1062 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1066 strprintf(¶m, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
1067 " PassiveTime=%d, LastActivityTime=%d",
1071 stat.lastCashAddTime,
1073 stat.lastActivityTime
1077 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
1080 if(MysqlSetQuery(res.c_str()))
1082 errorStr = "Couldn't save user stat:\n";
1083 // errorStr += mysql_error(sock);
1089 //-----------------------------------------------------------------------------
1090 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
1092 std::string res, tempStr;
1101 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1102 if (!(sock=MysqlConnect())){
1103 errorStr = "Couldn't connect to Server";
1106 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1108 errorStr = "Couldn't get table " + tempStr + ":\n";
1109 errorStr += mysql_error(sock);
1114 my_ulonglong num_rows = mysql_num_rows(result);
1116 mysql_free_result(result);
1120 sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
1121 lt->tm_mon+1, lt->tm_year+1900);
1123 if(MysqlQuery(qbuf,sock))
1125 errorStr = "Couldn't create WriteDetailedStat table:\n";
1126 errorStr += mysql_error(sock);
1132 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
1136 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
1137 lt->tm_mon+1, lt->tm_year+1900,
1138 login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
1140 if(MysqlQuery(send.c_str(),sock))
1142 errorStr = "Couldn't write log string:\n";
1143 errorStr += mysql_error(sock);
1151 //-----------------------------------------------------------------------------
1152 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
1153 const std::string & admLogin,
1155 const std::string & paramName,
1156 const std::string & oldValue,
1157 const std::string & newValue,
1158 const std::string & message) const
1160 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
1161 + paramName + "\' parameter changed from \'" + oldValue +
1162 "\' to \'" + newValue + "\'. " + message;
1164 return WriteLogString(userLogMsg, login);
1166 //-----------------------------------------------------------------------------
1167 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1169 std::string logStr = "Connect, " + inet_ntostring(ip);
1170 return WriteLogString(logStr, login);
1172 //-----------------------------------------------------------------------------
1173 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
1174 const DIR_TRAFF & up,
1175 const DIR_TRAFF & down,
1176 const DIR_TRAFF & sessionUp,
1177 const DIR_TRAFF & sessionDown,
1180 const std::string & /*reason*/) const
1182 std::string logStr = "Disconnect, ";
1183 std::ostringstream sssu;
1184 std::ostringstream sssd;
1185 std::ostringstream ssmu;
1186 std::ostringstream ssmd;
1187 std::ostringstream sscash;
1193 sssd << sessionDown;
1197 logStr += " session upload: \'";
1198 logStr += sssu.str();
1199 logStr += "\' session download: \'";
1200 logStr += sssd.str();
1201 logStr += "\' month upload: \'";
1202 logStr += ssmu.str();
1203 logStr += "\' month download: \'";
1204 logStr += ssmd.str();
1205 logStr += "\' cash: \'";
1206 logStr += sscash.str();
1209 return WriteLogString(logStr, login);
1211 //-----------------------------------------------------------------------------
1212 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year,
1213 const std::string & login) const
1215 std::string param, res;
1217 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,",
1218 login.c_str(), month+1, year+1900);
1220 for (int i = 0; i < DIR_NUM; i++)
1222 strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
1225 strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
1229 strprintf(¶m, " cash=%f", stat.cash);
1232 if(MysqlSetQuery(res.c_str()))
1234 errorStr = "Couldn't SaveMonthStat:\n";
1235 //errorStr += mysql_error(sock);
1241 //-----------------------------------------------------------------------------*/
1242 int MYSQL_STORE::AddAdmin(const std::string & login) const
1244 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
1246 if(MysqlSetQuery(qbuf))
1248 errorStr = "Couldn't add admin:\n";
1249 //errorStr += mysql_error(sock);
1255 //-----------------------------------------------------------------------------*/
1256 int MYSQL_STORE::DelAdmin(const std::string & login) const
1258 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
1260 if(MysqlSetQuery(qbuf))
1262 errorStr = "Couldn't delete admin:\n";
1263 //errorStr += mysql_error(sock);
1269 //-----------------------------------------------------------------------------*/
1270 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
1272 char passwordE[2 * ADM_PASSWD_LEN + 2];
1273 char pass[ADM_PASSWD_LEN + 1];
1274 char adminPass[ADM_PASSWD_LEN + 1];
1276 memset(pass, 0, sizeof(pass));
1277 memset(adminPass, 0, sizeof(adminPass));
1280 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1282 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1283 adminPass[ADM_PASSWD_LEN - 1] = 0;
1285 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1287 EncryptBlock(pass + 8*i, adminPass + 8*i, &ctx);
1290 pass[ADM_PASSWD_LEN - 1] = 0;
1291 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1293 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
1294 "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
1295 "WHERE login='%s' LIMIT 1",
1307 if(MysqlSetQuery(qbuf))
1309 errorStr = "Couldn't save admin:\n";
1310 //errorStr += mysql_error(sock);
1316 //-----------------------------------------------------------------------------
1317 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
1319 char pass[ADM_PASSWD_LEN + 1];
1320 char password[ADM_PASSWD_LEN + 1];
1321 char passwordE[2*ADM_PASSWD_LEN + 2];
1324 memset(password, 0, sizeof(password));
1330 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
1332 if(MysqlGetQuery(qbuf,sock))
1334 errorStr = "Couldn't restore admin:\n";
1335 errorStr += mysql_error(sock);
1340 if (!(res=mysql_store_result(sock)))
1342 errorStr = "Couldn't restore admin:\n";
1343 errorStr += mysql_error(sock);
1348 if ( mysql_num_rows(res) == 0)
1350 mysql_free_result(res);
1351 errorStr = "Couldn't restore admin as couldn't found him in table.\n";
1356 row = mysql_fetch_row(res);
1362 mysql_free_result(res);
1363 errorStr = "Error in parameter password";
1368 memset(passwordE, 0, sizeof(passwordE));
1369 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1371 memset(pass, 0, sizeof(pass));
1373 if (passwordE[0] != 0)
1375 Decode21(pass, passwordE);
1376 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1378 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1380 DecryptBlock(password + 8*i, pass + 8*i, &ctx);
1388 ac->password = password;
1392 if (GetInt(row[2], &a) == 0)
1393 ac->priv.userConf = a;
1396 mysql_free_result(res);
1397 errorStr = "Error in parameter ChgConf";
1402 if (GetInt(row[3], &a) == 0)
1403 ac->priv.userPasswd = a;
1406 mysql_free_result(res);
1407 errorStr = "Error in parameter ChgPassword";
1412 if (GetInt(row[4], &a) == 0)
1413 ac->priv.userStat = a;
1416 mysql_free_result(res);
1417 errorStr = "Error in parameter ChgStat";
1422 if (GetInt(row[5], &a) == 0)
1423 ac->priv.userCash = a;
1426 mysql_free_result(res);
1427 errorStr = "Error in parameter ChgCash";
1432 if (GetInt(row[6], &a) == 0)
1433 ac->priv.userAddDel = a;
1436 mysql_free_result(res);
1437 errorStr = "Error in parameter UsrAddDel";
1442 if (GetInt(row[7], &a) == 0)
1443 ac->priv.tariffChg = a;
1446 mysql_free_result(res);
1447 errorStr = "Error in parameter ChgTariff";
1452 if (GetInt(row[8], &a) == 0)
1453 ac->priv.adminChg = a;
1456 mysql_free_result(res);
1457 errorStr = "Error in parameter ChgAdmin";
1462 mysql_free_result(res);
1466 //-----------------------------------------------------------------------------
1467 int MYSQL_STORE::AddTariff(const std::string & name) const
1469 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
1471 if(MysqlSetQuery(qbuf))
1473 errorStr = "Couldn't add tariff:\n";
1474 // errorStr += mysql_error(sock);
1480 //-----------------------------------------------------------------------------
1481 int MYSQL_STORE::DelTariff(const std::string & name) const
1483 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
1485 if(MysqlSetQuery(qbuf))
1487 errorStr = "Couldn't delete tariff: ";
1488 // errorStr += mysql_error(sock);
1494 //-----------------------------------------------------------------------------
1495 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
1500 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
1502 if(MysqlGetQuery(qbuf,sock))
1504 errorStr = "Couldn't restore Tariff:\n";
1505 errorStr += mysql_error(sock);
1510 if (!(res=mysql_store_result(sock)))
1512 errorStr = "Couldn't restore Tariff:\n";
1513 errorStr += mysql_error(sock);
1519 td->tariffConf.name = tariffName;
1521 row = mysql_fetch_row(res);
1524 for (int i = 0; i<DIR_NUM; i++)
1526 strprintf(¶m, "Time%d", i);
1528 if (str.length() == 0)
1530 mysql_free_result(res);
1531 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1536 ParseTariffTimeStr(str.c_str(),
1537 td->dirPrice[i].hDay,
1538 td->dirPrice[i].mDay,
1539 td->dirPrice[i].hNight,
1540 td->dirPrice[i].mNight);
1542 strprintf(¶m, "PriceDayA%d", i);
1543 if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
1545 mysql_free_result(res);
1546 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1550 td->dirPrice[i].priceDayA /= (1024*1024);
1552 strprintf(¶m, "PriceDayB%d", i);
1553 if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
1555 mysql_free_result(res);
1556 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1560 td->dirPrice[i].priceDayB /= (1024*1024);
1562 strprintf(¶m, "PriceNightA%d", i);
1563 if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
1565 mysql_free_result(res);
1566 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1570 td->dirPrice[i].priceNightA /= (1024*1024);
1572 strprintf(¶m, "PriceNightB%d", i);
1573 if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
1575 mysql_free_result(res);
1576 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1580 td->dirPrice[i].priceNightB /= (1024*1024);
1582 strprintf(¶m, "Threshold%d", i);
1583 if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
1585 mysql_free_result(res);
1586 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1591 strprintf(¶m, "SinglePrice%d", i);
1592 if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
1594 mysql_free_result(res);
1595 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1600 strprintf(¶m, "NoDiscount%d", i);
1601 if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
1603 mysql_free_result(res);
1604 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1610 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
1612 mysql_free_result(res);
1613 errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1618 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
1620 mysql_free_result(res);
1621 errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1626 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
1628 mysql_free_result(res);
1629 errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1634 str = row[4+8*DIR_NUM];
1635 param = "TraffType";
1637 if (str.length() == 0)
1639 mysql_free_result(res);
1640 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1645 td->tariffConf.traffType = TARIFF::StringToTraffType(str);
1647 if (schemaVersion > 0)
1649 str = row[5+8*DIR_NUM];
1652 if (str.length() == 0)
1654 mysql_free_result(res);
1655 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1660 td->tariffConf.period = TARIFF::StringToPeriod(str);
1664 td->tariffConf.period = TARIFF::MONTH;
1667 if (schemaVersion > 1)
1669 str = row[6+8*DIR_NUM];
1670 param = "ChangePolicy";
1672 if (str.length() == 0)
1674 mysql_free_result(res);
1675 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1680 td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
1682 str = row[7+8*DIR_NUM];
1683 param = "ChangePolicyTimeout";
1685 if (str.length() == 0)
1687 mysql_free_result(res);
1688 errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1693 td->tariffConf.changePolicyTimeout = readTime(str);
1697 td->tariffConf.changePolicy = TARIFF::ALLOW;
1698 td->tariffConf.changePolicyTimeout = 0;
1701 mysql_free_result(res);
1705 //-----------------------------------------------------------------------------
1706 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
1710 std::string res="UPDATE tariffs SET";
1712 for (int i = 0; i < DIR_NUM; i++)
1714 strprintf(¶m, " PriceDayA%d=%f,", i,
1715 td.dirPrice[i].priceDayA * pt_mega);
1718 strprintf(¶m, " PriceDayB%d=%f,", i,
1719 td.dirPrice[i].priceDayB * pt_mega);
1722 strprintf(¶m, " PriceNightA%d=%f,", i,
1723 td.dirPrice[i].priceNightA * pt_mega);
1726 strprintf(¶m, " PriceNightB%d=%f,", i,
1727 td.dirPrice[i].priceNightB * pt_mega);
1730 strprintf(¶m, " Threshold%d=%d,", i,
1731 td.dirPrice[i].threshold);
1735 strprintf(¶m, " Time%d", i);
1737 strprintf(&s, "%0d:%0d-%0d:%0d",
1738 td.dirPrice[i].hDay,
1739 td.dirPrice[i].mDay,
1740 td.dirPrice[i].hNight,
1741 td.dirPrice[i].mNight);
1743 res += (param + "='" + s + "',");
1745 strprintf(¶m, " NoDiscount%d=%d,", i,
1746 td.dirPrice[i].noDiscount);
1749 strprintf(¶m, " SinglePrice%d=%d,", i,
1750 td.dirPrice[i].singlePrice);
1754 strprintf(¶m, " PassiveCost=%f,", td.tariffConf.passiveCost);
1757 strprintf(¶m, " Fee=%f,", td.tariffConf.fee);
1760 strprintf(¶m, " Free=%f,", td.tariffConf.free);
1763 res += " TraffType='" + TARIFF::TraffTypeToString(td.tariffConf.traffType) + "'";
1765 if (schemaVersion > 0)
1766 res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
1768 if (schemaVersion > 1)
1769 res += ", change_policy='" + TARIFF::ChangePolicyToString(td.tariffConf.changePolicy) + "'"\
1770 ", change_policy_timeout='" + formatTime(td.tariffConf.changePolicy) + "'";
1772 strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str());
1775 if(MysqlSetQuery(res.c_str()))
1777 errorStr = "Couldn't save tariff:\n";
1778 //errorStr += mysql_error(sock);
1784 //-----------------------------------------------------------------------------
1785 int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
1787 const std::string & login) const
1789 std::string res, stTime, endTime, tempStr;
1796 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1804 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1806 if (!(sock=MysqlConnect())){
1811 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1813 errorStr = "Couldn't get table " + tempStr + ":\n";
1814 errorStr += mysql_error(sock);
1819 my_ulonglong num_rows = mysql_num_rows(result);
1821 mysql_free_result(result);
1825 sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
1826 "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
1827 "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
1828 "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
1829 lt->tm_mon+1, lt->tm_year+1900);
1831 if(MysqlQuery(qbuf,sock))
1833 errorStr = "Couldn't create WriteDetailedStat table:\n";
1834 errorStr += mysql_error(sock);
1843 lt1 = localtime(&lastStat);
1852 lt2 = localtime(&t);
1858 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
1859 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
1861 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
1862 "day=%d,startTime='%s',endTime='%s',",
1863 lt->tm_mon+1, lt->tm_year+1900,
1870 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
1871 stIter = statTree.begin();
1873 while (stIter != statTree.end())
1875 strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f",
1876 inet_ntostring(stIter->first.ip).c_str(),
1878 stIter->second.down,
1883 if( MysqlQuery((res+tempStr).c_str(),sock) )
1885 errorStr = "Couldn't insert data in WriteDetailedStat:\n";
1886 errorStr += mysql_error(sock);
1891 result=mysql_store_result(sock);
1893 mysql_free_result(result);
1900 //-----------------------------------------------------------------------------
1901 int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
1905 gettimeofday(&tv, NULL);
1907 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
1909 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld",
1911 static_cast<long long>(msg->header.id)
1914 if(MysqlSetQuery(qbuf))
1916 errorStr = "Couldn't add message:\n";
1917 //errorStr += mysql_error(sock);
1921 return EditMessage(*msg, login);
1923 //-----------------------------------------------------------------------------
1924 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
1928 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
1929 "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
1930 "WHERE login='%s' AND id=%lld LIMIT 1",
1932 msg.header.lastSendTime,
1933 msg.header.creationTime,
1934 msg.header.showTime,
1936 msg.header.repeatPeriod,
1937 (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
1942 if(MysqlSetQuery(res.c_str()))
1944 errorStr = "Couldn't edit message:\n";
1945 //errorStr += mysql_error(sock);
1951 //-----------------------------------------------------------------------------
1952 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
1958 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
1959 login.c_str(), static_cast<unsigned long long>(id));
1961 if(MysqlGetQuery(qbuf,sock))
1963 errorStr = "Couldn't GetMessage:\n";
1964 errorStr += mysql_error(sock);
1969 if (!(res=mysql_store_result(sock)))
1971 errorStr = "Couldn't GetMessage:\n";
1972 errorStr += mysql_error(sock);
1977 row = mysql_fetch_row(res);
1979 if(row[2]&&str2x(row[2], msg->header.type))
1981 mysql_free_result(res);
1982 errorStr = "Invalid value in message header for user: " + login;
1987 if(row[3] && str2x(row[3], msg->header.lastSendTime))
1989 mysql_free_result(res);
1990 errorStr = "Invalid value in message header for user: " + login;
1995 if(row[4] && str2x(row[4], msg->header.creationTime))
1997 mysql_free_result(res);
1998 errorStr = "Invalid value in message header for user: " + login;
2003 if(row[5] && str2x(row[5], msg->header.showTime))
2005 mysql_free_result(res);
2006 errorStr = "Invalid value in message header for user: " + login;
2011 if(row[6] && str2x(row[6], msg->header.repeat))
2013 mysql_free_result(res);
2014 errorStr = "Invalid value in message header for user: " + login;
2019 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
2021 mysql_free_result(res);
2022 errorStr = "Invalid value in message header for user: " + login;
2027 msg->header.id = id;
2030 mysql_free_result(res);
2034 //-----------------------------------------------------------------------------
2035 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
2037 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
2038 login.c_str(), static_cast<long long>(id));
2040 if(MysqlSetQuery(qbuf))
2042 errorStr = "Couldn't delete Message:\n";
2043 //errorStr += mysql_error(sock);
2049 //-----------------------------------------------------------------------------
2050 int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
2055 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
2057 if(MysqlGetQuery(qbuf,sock))
2059 errorStr = "Couldn't GetMessageHdrs:\n";
2060 errorStr += mysql_error(sock);
2065 if (!(res=mysql_store_result(sock)))
2067 errorStr = "Couldn't GetMessageHdrs:\n";
2068 errorStr += mysql_error(sock);
2074 my_ulonglong num_rows = mysql_num_rows(res);
2077 for (i = 0; i < num_rows; i++)
2079 row = mysql_fetch_row(res);
2080 if (str2x(row[1], id))
2085 if(str2x(row[2], hdr.type))
2089 if(str2x(row[3], hdr.lastSendTime))
2093 if(str2x(row[4], hdr.creationTime))
2097 if(str2x(row[5], hdr.showTime))
2101 if(str2x(row[6], hdr.repeat))
2105 if(str2x(row[7], hdr.repeatPeriod))
2109 hdrsList->push_back(hdr);
2112 mysql_free_result(res);
2116 //-----------------------------------------------------------------------------
2118 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
2121 int ret=MysqlGetQuery(Query,sock);
2125 //-----------------------------------------------------------------------------
2126 int MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
2127 if (!(sock=MysqlConnect())) {
2130 return MysqlQuery(Query,sock);
2132 //-----------------------------------------------------------------------------
2133 MYSQL * MYSQL_STORE::MysqlConnect() const {
2135 if ( !(sock=mysql_init(NULL)) ){
2136 errorStr= "mysql init susck\n";
2139 if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
2140 storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
2143 errorStr = "Couldn't connect to mysql engine! With error:\n";
2144 errorStr += mysql_error(sock);
2148 if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
2149 errorStr = "Database lost !\n";
2155 //-----------------------------------------------------------------------------