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" + x2str(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 //-----------------------------------------------------------------------------