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);
 
 229                  ret = CheckAllTables(sock);
 
 234             ret = CheckAllTables(sock);
 
 238             logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
 
 246 //-----------------------------------------------------------------------------
 
 247 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
 
 251 if (!(result=mysql_list_tables(sock,str.c_str() )))
 
 253     errorStr = "Couldn't get tables list With error:\n";
 
 254     errorStr += mysql_error(sock);
 
 259 my_ulonglong num_rows =  mysql_num_rows(result);
 
 262     mysql_free_result(result);
 
 264 return num_rows == 1;
 
 266 //-----------------------------------------------------------------------------
 
 267 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
 
 269 //info-------------------------------------------------------------------------
 
 270 if(!IsTablePresent("info",sock))
 
 272     sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
 
 274     if(MysqlQuery(qbuf,sock))
 
 276         errorStr = "Couldn't create info table With error:\n";
 
 277         errorStr += mysql_error(sock);
 
 282     sprintf(qbuf,"INSERT INTO info SET version=0");
 
 284     if(MysqlQuery(qbuf,sock))
 
 286         errorStr = "Couldn't write default version. With error:\n";
 
 287         errorStr += mysql_error(sock);
 
 295     std::vector<std::string> info;
 
 296     if (GetAllParams(&info, "info", "version"))
 
 303             GetInt(info.front(), &schemaVersion, 0);
 
 306 //admins-----------------------------------------------------------------------
 
 307 if(!IsTablePresent("admins",sock))
 
 309     sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
 
 310         "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
 
 311         "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
 
 312         "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
 
 313         "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
 
 315     if(MysqlQuery(qbuf,sock))
 
 317         errorStr = "Couldn't create admin table list With error:\n";
 
 318         errorStr += mysql_error(sock);
 
 323     sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
 
 324         "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
 
 325         "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
 
 327     if(MysqlQuery(qbuf,sock))
 
 329         errorStr = "Couldn't create default admin. With error:\n";
 
 330         errorStr += mysql_error(sock);
 
 336 //tariffs-----------------------------------------------------------------------
 
 337 std::string param, res;
 
 338 if(!IsTablePresent("tariffs",sock))
 
 340     res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
 
 342     for (int i = 0; i < DIR_NUM; i++)
 
 344         strprintf(¶m, " PriceDayA%d DOUBLE DEFAULT 0.0,", i); 
 
 347         strprintf(¶m, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
 
 350         strprintf(¶m, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
 
 353         strprintf(¶m, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
 
 356         strprintf(¶m, " Threshold%d INT DEFAULT 0,", i);
 
 359         strprintf(¶m, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
 
 362         strprintf(¶m, " NoDiscount%d INT DEFAULT 0,", i);
 
 365         strprintf(¶m, " SinglePrice%d INT DEFAULT 0,", i);
 
 369     res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
 
 370         "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
 
 371         "period VARCHAR(32) NOT NULL DEFAULT 'month',"
 
 372         "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow')";
 
 374     if(MysqlQuery(res.c_str(),sock))
 
 376         errorStr = "Couldn't create tariffs table list With error:\n";
 
 377         errorStr += mysql_error(sock);
 
 382     res = "INSERT INTO tariffs SET name='tariff',";
 
 384     for (int i = 0; i < DIR_NUM; i++)
 
 386         strprintf(¶m, " NoDiscount%d=1,", i);
 
 389         strprintf(¶m, " Threshold%d=0,", i);
 
 392         strprintf(¶m, " Time%d='0:0-0:0',", i);
 
 397             strprintf(¶m, " SinglePrice%d=0,", i);
 
 403             strprintf(¶m, " PriceDayA%d=0.0,", i); 
 
 408             strprintf(¶m, " PriceDayB%d=0.0,", i);        
 
 414             strprintf(¶m, " PriceNightA%d=0.0,", i); 
 
 419             strprintf(¶m, " PriceNightB%d=0.0,", i);        
 
 424     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
 
 425         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
 
 426         "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month'";
 
 428     if(MysqlQuery(res.c_str(),sock))
 
 430         errorStr = "Couldn't create default tariff. With error:\n";
 
 431         errorStr += mysql_error(sock);
 
 436     sprintf(qbuf,"UPDATE info SET version=1");
 
 438     if(MysqlQuery(qbuf,sock))
 
 440         errorStr = "Couldn't write default version. With error:\n";
 
 441         errorStr += mysql_error(sock);
 
 448 //users-----------------------------------------------------------------------
 
 449 if(!IsTablePresent("users",sock))
 
 451     res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
 
 452         "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 '',"\
 
 453         "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
 
 454         "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
 
 455         "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
 
 457     for (int i = 0; i < USERDATA_NUM; i++)
 
 459         strprintf(¶m, " Userdata%d VARCHAR(254) NOT NULL,", i);
 
 463     param = " CreditExpire INT(11) DEFAULT 0,";
 
 466     strprintf(¶m, " IP VARCHAR(254) DEFAULT '*',");
 
 469     for (int i = 0; i < DIR_NUM; i++)
 
 471         strprintf(¶m, " D%d BIGINT(30) DEFAULT 0,", i);
 
 474         strprintf(¶m, " U%d BIGINT(30) DEFAULT 0,", i);
 
 478     strprintf(¶m, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
 
 479         "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
 
 480         "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
 
 481         " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
 
 484     if(MysqlQuery(res.c_str(),sock))
 
 486         errorStr = "Couldn't create users table list With error:\n";
 
 487         errorStr += mysql_error(sock);
 
 488         errorStr += "\n\n" + res;
 
 493     res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
 
 494         "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
 
 495         "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
 
 496         "Phone='', RealName='',Tariff='tariff',TariffChange='',NAS='',";
 
 498     for (int i = 0; i < USERDATA_NUM; i++)
 
 500         strprintf(¶m, " Userdata%d='',", i);
 
 504     for (int i = 0; i < DIR_NUM; i++)
 
 506         strprintf(¶m, " D%d=0,", i);
 
 509         strprintf(¶m, " U%d=0,", i);
 
 513     res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
 
 514         "LastCashAddTime=0, PassiveTime=0";
 
 516     if(MysqlQuery(res.c_str(),sock))
 
 518         errorStr = "Couldn't create default user. With error:\n";
 
 519         errorStr += mysql_error(sock);
 
 525 //logs-----------------------------------------------------------------------
 
 526 if(!IsTablePresent("logs"))
 
 528     sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
 
 532         errorStr = "Couldn't create admin table list With error:\n";
 
 533         errorStr += mysql_error(sock);
 
 538 //messages---------------------------------------------------------------------
 
 539 if(!IsTablePresent("messages",sock))
 
 541     sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
 
 542             "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
 
 543             "stgRepeat INT, repeatPeriod INT, text TEXT)");
 
 545     if(MysqlQuery(qbuf,sock))
 
 547         errorStr = "Couldn't create messages table. With error:\n";
 
 548         errorStr += mysql_error(sock);
 
 554 //month_stat-------------------------------------------------------------------
 
 555 if(!IsTablePresent("stat",sock))
 
 557     res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
 
 559     for (int i = 0; i < DIR_NUM; i++)
 
 561         strprintf(¶m, " U%d BIGINT,", i); 
 
 564         strprintf(¶m, " D%d BIGINT,", i); 
 
 568     res += " cash DOUBLE, INDEX (login))";
 
 570     if(MysqlQuery(res.c_str(),sock))
 
 572         errorStr = "Couldn't create stat table. With error:\n";
 
 573         errorStr += mysql_error(sock);
 
 581 //-----------------------------------------------------------------------------
 
 582 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
 
 584 if (schemaVersion  < 1)
 
 586     if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
 
 588         errorStr = "Couldn't update tariffs table to version 1. With error:\n";
 
 589         errorStr += mysql_error(sock);
 
 593     if (MysqlQuery("UPDATE info SET version = 1", sock))
 
 595         errorStr = "Couldn't update DB schema version to 1. With error:\n";
 
 596         errorStr += mysql_error(sock);
 
 601     logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
 
 605 //-----------------------------------------------------------------------------
 
 607 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList, 
 
 608                             const std::string & table, const std::string & name) const
 
 617 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
 
 619 if(MysqlGetQuery(qbuf,sock))
 
 621     errorStr = "Couldn't GetAllParams Query for: ";
 
 622     errorStr += name + " - " + table + "\n";
 
 623     errorStr += mysql_error(sock);
 
 628 if (!(res=mysql_store_result(sock)))
 
 630     errorStr = "Couldn't GetAllParams Results for: ";
 
 631     errorStr += name + " - " + table + "\n";
 
 632     errorStr += mysql_error(sock);
 
 636 num = mysql_num_rows(res);
 
 638 for(i = 0; i < num; i++)
 
 640     row = mysql_fetch_row(res);    
 
 641     ParamList->push_back(row[0]);
 
 644 mysql_free_result(res);
 
 650 //-----------------------------------------------------------------------------
 
 651 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
 
 653 if(GetAllParams(usersList, "users", "login"))
 
 658 //-----------------------------------------------------------------------------
 
 659 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
 
 661 if(GetAllParams(adminsList, "admins", "login"))
 
 666 //-----------------------------------------------------------------------------
 
 667 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
 
 669 if(GetAllParams(tariffsList, "tariffs", "name"))
 
 674 //-----------------------------------------------------------------------------
 
 675 int MYSQL_STORE::AddUser(const std::string & login) const
 
 677 std::string query = "INSERT INTO users SET login='" + login + "',Note='',NAS=''";
 
 679 for (int i = 0; i < USERDATA_NUM; i++)
 
 680     query += ",Userdata" + x2str(i) + "=''";
 
 682 if(MysqlSetQuery(query.c_str()))
 
 684     errorStr = "Couldn't add user:\n";
 
 685     //errorStr += mysql_error(sock);
 
 691 //-----------------------------------------------------------------------------
 
 692 int MYSQL_STORE::DelUser(const std::string & login) const
 
 694 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 696 if(MysqlSetQuery(qbuf))
 
 698     errorStr = "Couldn't delete user:\n";
 
 699     //errorStr += mysql_error(sock);
 
 705 //-----------------------------------------------------------------------------
 
 706 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
 
 713 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
 
 714          AlwaysOnline, Tariff, Address, Phone, Email, Note, \
 
 715          RealName, StgGroup, Credit, TariffChange, ";
 
 717 for (int i = 0; i < USERDATA_NUM; i++)
 
 719     sprintf(qbuf, "Userdata%d, ", i);
 
 723 query += "CreditExpire, IP FROM users WHERE login='";
 
 724 query += login + "' LIMIT 1";
 
 726 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 728 if(MysqlGetQuery(query.c_str(),sock))
 
 730     errorStr = "Couldn't restore Tariff(on query):\n";
 
 731     errorStr += mysql_error(sock);
 
 736 if (!(res=mysql_store_result(sock)))
 
 738     errorStr = "Couldn't restore Tariff(on getting result):\n";
 
 739     errorStr += mysql_error(sock);
 
 744 if (mysql_num_rows(res) != 1)
 
 746     errorStr = "User not found";
 
 751 row = mysql_fetch_row(res);
 
 753 conf->password = row[1];
 
 755 if (conf->password.empty())
 
 757     mysql_free_result(res);
 
 758     errorStr = "User \'" + login + "\' password is blank.";
 
 763 if (GetInt(row[2],&conf->passive) != 0)
 
 765     mysql_free_result(res);
 
 766     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
 
 771 if (GetInt(row[3], &conf->disabled) != 0)
 
 773     mysql_free_result(res);
 
 774     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
 
 779 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
 
 781     mysql_free_result(res);
 
 782     errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
 
 787 if (GetInt(row[5], &conf->alwaysOnline) != 0)
 
 789     mysql_free_result(res);
 
 790     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
 
 795 conf->tariffName = row[6];
 
 797 if (conf->tariffName.empty()) 
 
 799     mysql_free_result(res);
 
 800     errorStr = "User \'" + login + "\' tariff is blank.";
 
 805 conf->address = row[7];
 
 806 conf->phone = row[8];
 
 807 conf->email = row[9];
 
 808 conf->note = row[10];
 
 809 conf->realName = row[11];
 
 810 conf->group = row[12];
 
 812 if (GetDouble(row[13], &conf->credit, 0) != 0)
 
 814     mysql_free_result(res);
 
 815     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
 
 820 conf->nextTariff = row[14];
 
 822 for (int i = 0; i < USERDATA_NUM; i++)
 
 824     conf->userdata[i] = row[15+i];
 
 827 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
 
 829 std::string ipStr = row[16+USERDATA_NUM];
 
 835 catch (const std::string & s)
 
 837     mysql_free_result(res);
 
 838     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
 
 844 mysql_free_result(res);
 
 849 //-----------------------------------------------------------------------------
 
 850 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
 
 860 for (int i = 0; i < DIR_NUM; i++)
 
 862     sprintf(qbuf, "D%d, U%d, ", i, i);
 
 866 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
 
 867           FROM users WHERE login = '";
 
 868 query += login + "'";
 
 870 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 872 if(MysqlGetQuery(query.c_str() ,sock))
 
 874     errorStr = "Couldn't restore UserStat(on query):\n";
 
 875     errorStr += mysql_error(sock);
 
 880 if (!(res=mysql_store_result(sock)))
 
 882     errorStr = "Couldn't restore UserStat(on getting result):\n";
 
 883     errorStr += mysql_error(sock);
 
 888 row = mysql_fetch_row(res);
 
 890 unsigned int startPos=0;
 
 894 for (int i = 0; i < DIR_NUM; i++)
 
 897     sprintf(s, "D%d", i);
 
 898     if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
 
 900         mysql_free_result(res);
 
 901         errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 905     stat->monthDown[i] = traff;
 
 907     sprintf(s, "U%d", i);
 
 908     if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
 
 910         mysql_free_result(res);
 
 911         errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 915     stat->monthUp[i] = traff;
 
 918 startPos += (2*DIR_NUM);
 
 920 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
 
 922     mysql_free_result(res);
 
 923     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
 
 928 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
 
 930     mysql_free_result(res);
 
 931     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
 
 936 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
 
 938     mysql_free_result(res);
 
 939     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
 
 944 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
 
 946     mysql_free_result(res);
 
 947     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
 
 952 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
 
 954     mysql_free_result(res);
 
 955     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
 
 960 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
 
 962     mysql_free_result(res);
 
 963     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
 
 968 mysql_free_result(res);
 
 972 //-----------------------------------------------------------------------------
 
 973 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
 
 978 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
 
 979     "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
 
 980     "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ", 
 
 981     conf.password.c_str(),
 
 984     conf.disabledDetailStat,
 
 986     conf.tariffName.c_str(),
 
 987     (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
 
 988     (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
 
 989     (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
 
 990     (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
 
 991     (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
 
 992     (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
 
 994     conf.nextTariff.c_str()
 
 997 for (int i = 0; i < USERDATA_NUM; i++)
 
 999     strprintf(¶m, " Userdata%d='%s',", i, 
 
1000         (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
 
1004 strprintf(¶m, " CreditExpire=%d,", conf.creditExpire);
 
1007 std::ostringstream ipStr;
 
1010 strprintf(¶m, " IP='%s'", ipStr.str().c_str());
 
1013 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
 
1016 if(MysqlSetQuery(res.c_str()))
 
1018     errorStr = "Couldn't save user conf:\n";
 
1019     //errorStr += mysql_error(sock);
 
1025 //-----------------------------------------------------------------------------
 
1026 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
 
1031 res = "UPDATE users SET";
 
1033 for (int i = 0; i < DIR_NUM; i++)
 
1035     strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
 
1038     strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
 
1042 strprintf(¶m, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
 
1043     " PassiveTime=%d, LastActivityTime=%d", 
 
1047     stat.lastCashAddTime,
 
1049     stat.lastActivityTime
 
1053 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
 
1056 if(MysqlSetQuery(res.c_str()))
 
1058     errorStr = "Couldn't save user stat:\n";
 
1059 //    errorStr += mysql_error(sock);
 
1065 //-----------------------------------------------------------------------------
 
1066 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
 
1068 std::string res, tempStr;
 
1077 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
 
1078 if (!(sock=MysqlConnect())){
 
1079     errorStr = "Couldn't connect to Server";
 
1082 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
 
1084     errorStr = "Couldn't get table " + tempStr + ":\n";
 
1085     errorStr += mysql_error(sock);
 
1090 my_ulonglong num_rows =  mysql_num_rows(result);
 
1092 mysql_free_result(result);
 
1096     sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
 
1097     lt->tm_mon+1, lt->tm_year+1900);
 
1099     if(MysqlQuery(qbuf,sock))
 
1101         errorStr = "Couldn't create WriteDetailedStat table:\n";
 
1102         errorStr += mysql_error(sock);
 
1108 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
 
1112 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
 
1113         lt->tm_mon+1, lt->tm_year+1900,
 
1114     login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
 
1116 if(MysqlQuery(send.c_str(),sock))
 
1118     errorStr = "Couldn't write log string:\n";
 
1119     errorStr += mysql_error(sock);
 
1127 //-----------------------------------------------------------------------------
 
1128 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
 
1129                                  const std::string & admLogin,
 
1131                                  const std::string & paramName,
 
1132                                  const std::string & oldValue,
 
1133                                  const std::string & newValue,
 
1134                                  const std::string & message) const
 
1136 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
 
1137     + paramName + "\' parameter changed from \'" + oldValue +
 
1138     "\' to \'" + newValue + "\'. " + message;
 
1140 return WriteLogString(userLogMsg, login);
 
1142 //-----------------------------------------------------------------------------
 
1143 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
 
1145 std::string logStr = "Connect, " + inet_ntostring(ip);
 
1146 return WriteLogString(logStr, login);
 
1148 //-----------------------------------------------------------------------------
 
1149 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
 
1150                                      const DIR_TRAFF & up,
 
1151                                      const DIR_TRAFF & down,
 
1152                                      const DIR_TRAFF & sessionUp,
 
1153                                      const DIR_TRAFF & sessionDown,
 
1156                                      const std::string & /*reason*/) const
 
1158 std::string logStr = "Disconnect, ";
 
1159 std::ostringstream sssu;
 
1160 std::ostringstream sssd;
 
1161 std::ostringstream ssmu;
 
1162 std::ostringstream ssmd;
 
1163 std::ostringstream sscash;
 
1169 sssd << sessionDown;
 
1173 logStr += " session upload: \'";
 
1174 logStr += sssu.str();
 
1175 logStr += "\' session download: \'";
 
1176 logStr += sssd.str();
 
1177 logStr += "\' month upload: \'";
 
1178 logStr += ssmu.str();
 
1179 logStr += "\' month download: \'";
 
1180 logStr += ssmd.str();
 
1181 logStr += "\' cash: \'";
 
1182 logStr += sscash.str();
 
1185 return WriteLogString(logStr, login);
 
1187 //-----------------------------------------------------------------------------
 
1188 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, 
 
1189                                 const std::string & login) const
 
1191 std::string param, res;
 
1193 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,", 
 
1194     login.c_str(), month+1, year+1900);
 
1196 for (int i = 0; i < DIR_NUM; i++)
 
1198     strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]); 
 
1201     strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);        
 
1205 strprintf(¶m, " cash=%f", stat.cash);        
 
1208 if(MysqlSetQuery(res.c_str()))
 
1210     errorStr = "Couldn't SaveMonthStat:\n";
 
1211     //errorStr += mysql_error(sock);
 
1217 //-----------------------------------------------------------------------------*/
 
1218 int MYSQL_STORE::AddAdmin(const std::string & login) const
 
1220 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
 
1222 if(MysqlSetQuery(qbuf))
 
1224     errorStr = "Couldn't add admin:\n";
 
1225     //errorStr += mysql_error(sock);
 
1231 //-----------------------------------------------------------------------------*/
 
1232 int MYSQL_STORE::DelAdmin(const std::string & login) const
 
1234 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
 
1236 if(MysqlSetQuery(qbuf))
 
1238     errorStr = "Couldn't delete admin:\n";
 
1239     //errorStr += mysql_error(sock);
 
1245 //-----------------------------------------------------------------------------*/
 
1246 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
 
1248 char passwordE[2 * ADM_PASSWD_LEN + 2];
 
1249 char pass[ADM_PASSWD_LEN + 1];
 
1250 char adminPass[ADM_PASSWD_LEN + 1];
 
1252 memset(pass, 0, sizeof(pass));
 
1253 memset(adminPass, 0, sizeof(adminPass));
 
1256 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1258 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
 
1259 adminPass[ADM_PASSWD_LEN - 1] = 0;
 
1261 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1263     EncryptBlock(pass + 8*i, adminPass + 8*i, &ctx);
 
1266 pass[ADM_PASSWD_LEN - 1] = 0;
 
1267 Encode12(passwordE, pass, ADM_PASSWD_LEN);
 
1269 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
 
1270     "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
 
1271     "WHERE login='%s' LIMIT 1", 
 
1283 if(MysqlSetQuery(qbuf))
 
1285     errorStr = "Couldn't save admin:\n";
 
1286     //errorStr += mysql_error(sock);
 
1292 //-----------------------------------------------------------------------------
 
1293 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
 
1295 char pass[ADM_PASSWD_LEN + 1];
 
1296 char password[ADM_PASSWD_LEN + 1];
 
1297 char passwordE[2*ADM_PASSWD_LEN + 2];
 
1300 memset(password, 0, sizeof(password));
 
1306 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
 
1308 if(MysqlGetQuery(qbuf,sock))
 
1310     errorStr = "Couldn't restore admin:\n";
 
1311     errorStr += mysql_error(sock);
 
1316 if (!(res=mysql_store_result(sock)))
 
1318     errorStr = "Couldn't restore admin:\n";
 
1319     errorStr += mysql_error(sock);
 
1324 if ( mysql_num_rows(res) == 0)
 
1326     mysql_free_result(res);
 
1327     errorStr = "Couldn't restore admin as couldn't found him in table.\n";
 
1332 row = mysql_fetch_row(res);
 
1338     mysql_free_result(res);
 
1339     errorStr = "Error in parameter password";
 
1344 memset(passwordE, 0, sizeof(passwordE));
 
1345 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
 
1347 memset(pass, 0, sizeof(pass));
 
1349 if (passwordE[0] != 0)
 
1351     Decode21(pass, passwordE);
 
1352     InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1354     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1356         DecryptBlock(password + 8*i, pass + 8*i, &ctx);
 
1364 ac->password = password;
 
1368 if (GetInt(row[2], &a) == 0) 
 
1369     ac->priv.userConf = a;
 
1372     mysql_free_result(res);
 
1373     errorStr = "Error in parameter ChgConf";
 
1378 if (GetInt(row[3], &a) == 0) 
 
1379     ac->priv.userPasswd = a;
 
1382     mysql_free_result(res);
 
1383     errorStr = "Error in parameter ChgPassword";
 
1388 if (GetInt(row[4], &a) == 0) 
 
1389     ac->priv.userStat = a;
 
1392     mysql_free_result(res);
 
1393     errorStr = "Error in parameter ChgStat";
 
1398 if (GetInt(row[5], &a) == 0) 
 
1399     ac->priv.userCash = a;
 
1402     mysql_free_result(res);
 
1403     errorStr = "Error in parameter ChgCash";
 
1408 if (GetInt(row[6], &a) == 0) 
 
1409     ac->priv.userAddDel = a;
 
1412     mysql_free_result(res);
 
1413     errorStr = "Error in parameter UsrAddDel";
 
1418 if (GetInt(row[7], &a) == 0) 
 
1419     ac->priv.tariffChg = a;
 
1422     mysql_free_result(res);
 
1423     errorStr = "Error in parameter ChgTariff";
 
1428 if (GetInt(row[8], &a) == 0) 
 
1429     ac->priv.adminChg = a;
 
1432     mysql_free_result(res);
 
1433     errorStr = "Error in parameter ChgAdmin";
 
1438 mysql_free_result(res);
 
1442 //-----------------------------------------------------------------------------
 
1443 int MYSQL_STORE::AddTariff(const std::string & name) const
 
1445 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
 
1447 if(MysqlSetQuery(qbuf))
 
1449     errorStr = "Couldn't add tariff:\n";
 
1450 //    errorStr += mysql_error(sock);
 
1456 //-----------------------------------------------------------------------------
 
1457 int MYSQL_STORE::DelTariff(const std::string & name) const
 
1459 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
 
1461 if(MysqlSetQuery(qbuf))
 
1463     errorStr = "Couldn't delete tariff: ";
 
1464 //    errorStr += mysql_error(sock);
 
1470 //-----------------------------------------------------------------------------
 
1471 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
 
1476 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
 
1478 if(MysqlGetQuery(qbuf,sock))
 
1480     errorStr = "Couldn't restore Tariff:\n";
 
1481     errorStr += mysql_error(sock);
 
1486 if (!(res=mysql_store_result(sock)))
 
1488     errorStr = "Couldn't restore Tariff:\n";
 
1489     errorStr += mysql_error(sock);
 
1495 td->tariffConf.name = tariffName;
 
1497 row = mysql_fetch_row(res);
 
1500 for (int i = 0; i<DIR_NUM; i++)
 
1502     strprintf(¶m, "Time%d", i);
 
1504     if (str.length() == 0)
 
1506         mysql_free_result(res);
 
1507         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1512     ParseTariffTimeStr(str.c_str(), 
 
1513                        td->dirPrice[i].hDay, 
 
1514                        td->dirPrice[i].mDay, 
 
1515                        td->dirPrice[i].hNight, 
 
1516                        td->dirPrice[i].mNight);
 
1518     strprintf(¶m, "PriceDayA%d", i);
 
1519     if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
 
1521         mysql_free_result(res);
 
1522         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1526     td->dirPrice[i].priceDayA /= (1024*1024);
 
1528     strprintf(¶m, "PriceDayB%d", i);
 
1529     if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
 
1531         mysql_free_result(res);
 
1532         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1536     td->dirPrice[i].priceDayB /= (1024*1024);
 
1538     strprintf(¶m, "PriceNightA%d", i);
 
1539     if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
 
1541         mysql_free_result(res);
 
1542         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1546     td->dirPrice[i].priceNightA /= (1024*1024);
 
1548     strprintf(¶m, "PriceNightB%d", i);
 
1549     if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
 
1551         mysql_free_result(res);
 
1552         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1556     td->dirPrice[i].priceNightB /= (1024*1024);
 
1558     strprintf(¶m, "Threshold%d", i);
 
1559     if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
 
1561         mysql_free_result(res);
 
1562         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1567     strprintf(¶m, "SinglePrice%d", i);
 
1568     if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
 
1570         mysql_free_result(res);
 
1571         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1576     strprintf(¶m, "NoDiscount%d", i);
 
1577     if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
 
1579         mysql_free_result(res);
 
1580         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1586 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
 
1588     mysql_free_result(res);
 
1589     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
 
1594 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
 
1596     mysql_free_result(res);
 
1597     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
 
1602 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
 
1604     mysql_free_result(res);
 
1605     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
 
1610     str = row[4+8*DIR_NUM];
 
1611     param = "TraffType";
 
1613     if (str.length() == 0)
 
1615         mysql_free_result(res);
 
1616         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1621 td->tariffConf.traffType = TARIFF::StringToTraffType(str);
 
1623 if (schemaVersion > 0)
 
1625     str = row[5+8*DIR_NUM];
 
1628     if (str.length() == 0)
 
1630         mysql_free_result(res);
 
1631         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1636     td->tariffConf.period = TARIFF::StringToPeriod(str);
 
1640     td->tariffConf.period = TARIFF::MONTH;
 
1643 mysql_free_result(res);
 
1647 //-----------------------------------------------------------------------------
 
1648 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
 
1652 std::string res="UPDATE tariffs SET";
 
1654 for (int i = 0; i < DIR_NUM; i++)
 
1656     strprintf(¶m, " PriceDayA%d=%f,", i, 
 
1657         td.dirPrice[i].priceDayA * pt_mega);
 
1660     strprintf(¶m, " PriceDayB%d=%f,", i, 
 
1661         td.dirPrice[i].priceDayB * pt_mega);        
 
1664     strprintf(¶m, " PriceNightA%d=%f,", i,
 
1665         td.dirPrice[i].priceNightA * pt_mega);
 
1668     strprintf(¶m, " PriceNightB%d=%f,", i, 
 
1669         td.dirPrice[i].priceNightB * pt_mega);
 
1672     strprintf(¶m, " Threshold%d=%d,", i, 
 
1673         td.dirPrice[i].threshold);
 
1677     strprintf(¶m, " Time%d", i);
 
1679     strprintf(&s, "%0d:%0d-%0d:%0d", 
 
1680             td.dirPrice[i].hDay,
 
1681             td.dirPrice[i].mDay,
 
1682             td.dirPrice[i].hNight,
 
1683             td.dirPrice[i].mNight);
 
1685     res += (param + "='" + s + "',");
 
1687     strprintf(¶m, " NoDiscount%d=%d,", i, 
 
1688         td.dirPrice[i].noDiscount);
 
1691     strprintf(¶m, " SinglePrice%d=%d,", i, 
 
1692         td.dirPrice[i].singlePrice);
 
1696 strprintf(¶m, " PassiveCost=%f,", td.tariffConf.passiveCost);
 
1699 strprintf(¶m, " Fee=%f,", td.tariffConf.fee);
 
1702 strprintf(¶m, " Free=%f,", td.tariffConf.free);
 
1705 res += " TraffType='" + TARIFF::TraffTypeToString(td.tariffConf.traffType) + "'";
 
1707 if (schemaVersion > 0)
 
1708     res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
 
1710 strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str());
 
1713 if(MysqlSetQuery(res.c_str()))
 
1715     errorStr = "Couldn't save tariff:\n";
 
1716     //errorStr += mysql_error(sock);
 
1722 //-----------------------------------------------------------------------------
 
1723 int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree, 
 
1725                                    const std::string & login) const
 
1727 std::string res, stTime, endTime, tempStr;
 
1734 if (lt->tm_hour == 0 && lt->tm_min <= 5)
 
1742 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
 
1744 if (!(sock=MysqlConnect())){
 
1749 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
 
1751     errorStr = "Couldn't get table " + tempStr + ":\n";
 
1752     errorStr += mysql_error(sock);
 
1757 my_ulonglong num_rows =  mysql_num_rows(result);
 
1759 mysql_free_result(result);
 
1763     sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
 
1764         "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
 
1765         "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
 
1766         "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
 
1767     lt->tm_mon+1, lt->tm_year+1900);
 
1769     if(MysqlQuery(qbuf,sock))
 
1771         errorStr = "Couldn't create WriteDetailedStat table:\n";
 
1772         errorStr += mysql_error(sock);
 
1781 lt1 = localtime(&lastStat);
 
1790 lt2 = localtime(&t);
 
1796 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
 
1797 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
 
1799 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
 
1800     "day=%d,startTime='%s',endTime='%s',", 
 
1801     lt->tm_mon+1, lt->tm_year+1900,
 
1808 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
 
1809 stIter = statTree.begin();
 
1811 while (stIter != statTree.end())
 
1813         strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f", 
 
1814                 inet_ntostring(stIter->first.ip).c_str(),
 
1816                 stIter->second.down, 
 
1821         if( MysqlQuery((res+tempStr).c_str(),sock) )
 
1823             errorStr = "Couldn't insert data in WriteDetailedStat:\n";
 
1824             errorStr += mysql_error(sock);
 
1829         result=mysql_store_result(sock);
 
1831             mysql_free_result(result);
 
1838 //-----------------------------------------------------------------------------
 
1839 int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
 
1843 gettimeofday(&tv, NULL);
 
1845 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
 
1847 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld", 
 
1849     static_cast<long long>(msg->header.id)
 
1852 if(MysqlSetQuery(qbuf))
 
1854     errorStr = "Couldn't add message:\n";
 
1855     //errorStr += mysql_error(sock);
 
1859 return EditMessage(*msg, login);
 
1861 //-----------------------------------------------------------------------------
 
1862 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
 
1866 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
 
1867     "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
 
1868     "WHERE login='%s' AND id=%lld LIMIT 1", 
 
1870     msg.header.lastSendTime,
 
1871     msg.header.creationTime,
 
1872     msg.header.showTime,
 
1874     msg.header.repeatPeriod,
 
1875     (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
 
1880 if(MysqlSetQuery(res.c_str()))
 
1882     errorStr = "Couldn't edit message:\n";
 
1883     //errorStr += mysql_error(sock);
 
1889 //-----------------------------------------------------------------------------
 
1890 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
 
1896 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
 
1897         login.c_str(), static_cast<unsigned long long>(id));
 
1899 if(MysqlGetQuery(qbuf,sock))
 
1901     errorStr = "Couldn't GetMessage:\n";
 
1902     errorStr += mysql_error(sock);
 
1907 if (!(res=mysql_store_result(sock)))
 
1909     errorStr = "Couldn't GetMessage:\n";
 
1910     errorStr += mysql_error(sock);
 
1915 row = mysql_fetch_row(res);
 
1917 if(row[2]&&str2x(row[2], msg->header.type))
 
1919     mysql_free_result(res);
 
1920     errorStr = "Invalid value in message header for user: " + login;
 
1925 if(row[3] && str2x(row[3], msg->header.lastSendTime))
 
1927     mysql_free_result(res);
 
1928     errorStr = "Invalid value in message header for user: " + login;
 
1933 if(row[4] && str2x(row[4], msg->header.creationTime))
 
1935     mysql_free_result(res);
 
1936     errorStr = "Invalid value in message header for user: " + login;
 
1941 if(row[5] && str2x(row[5], msg->header.showTime))
 
1943     mysql_free_result(res);
 
1944     errorStr = "Invalid value in message header for user: " + login;
 
1949 if(row[6] && str2x(row[6], msg->header.repeat))
 
1951     mysql_free_result(res);
 
1952     errorStr = "Invalid value in message header for user: " + login;
 
1957 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
 
1959     mysql_free_result(res);
 
1960     errorStr = "Invalid value in message header for user: " + login;
 
1965 msg->header.id = id;
 
1968 mysql_free_result(res);
 
1972 //-----------------------------------------------------------------------------
 
1973 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
 
1975 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1", 
 
1976         login.c_str(), static_cast<long long>(id));
 
1978 if(MysqlSetQuery(qbuf))
 
1980     errorStr = "Couldn't delete Message:\n";
 
1981     //errorStr += mysql_error(sock);
 
1987 //-----------------------------------------------------------------------------
 
1988 int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
 
1993 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
 
1995 if(MysqlGetQuery(qbuf,sock))
 
1997     errorStr = "Couldn't GetMessageHdrs:\n";
 
1998     errorStr += mysql_error(sock);
 
2003 if (!(res=mysql_store_result(sock)))
 
2005     errorStr = "Couldn't GetMessageHdrs:\n";
 
2006     errorStr += mysql_error(sock);
 
2012 my_ulonglong num_rows = mysql_num_rows(res);
 
2015 for (i = 0; i < num_rows; i++)
 
2017     row = mysql_fetch_row(res);
 
2018     if (str2x(row[1], id))
 
2023         if(str2x(row[2], hdr.type))
 
2027         if(str2x(row[3], hdr.lastSendTime))
 
2031         if(str2x(row[4], hdr.creationTime))
 
2035         if(str2x(row[5], hdr.showTime))
 
2039         if(str2x(row[6], hdr.repeat))
 
2043         if(str2x(row[7], hdr.repeatPeriod))
 
2047     hdrsList->push_back(hdr);
 
2050 mysql_free_result(res);
 
2054 //-----------------------------------------------------------------------------
 
2056 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
 
2059     int ret=MysqlGetQuery(Query,sock);
 
2063 //-----------------------------------------------------------------------------
 
2064 int  MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
 
2065     if (!(sock=MysqlConnect())) {
 
2068     return   MysqlQuery(Query,sock);
 
2070 //-----------------------------------------------------------------------------
 
2071 MYSQL *  MYSQL_STORE::MysqlConnect() const {
 
2073     if ( !(sock=mysql_init(NULL)) ){
 
2074         errorStr= "mysql init susck\n";
 
2077     if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
 
2078             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
 
2081             errorStr = "Couldn't connect to mysql engine! With error:\n";
 
2082             errorStr += mysql_error(sock);
 
2086          if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
 
2087              errorStr = "Database lost !\n";
 
2093 //-----------------------------------------------------------------------------