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()
 
 122 //-----------------------------------------------------------------------------
 
 123 int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<PARAM_VALUE> & moduleParams, 
 
 124                         const std::string & name, std::string & result)
 
 128 std::vector<PARAM_VALUE>::const_iterator pvi;
 
 129 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
 
 130 if (pvi == moduleParams.end())
 
 132     errorStr = "Parameter \'" + name + "\' not found.";
 
 136 result = pvi->value[0];
 
 140 //-----------------------------------------------------------------------------
 
 141 int MYSQL_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
 
 143 if (ParseParam(s.moduleParams, "user", dbUser) < 0 &&
 
 144     ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
 
 146 if (ParseParam(s.moduleParams, "password", dbPass) < 0 &&
 
 147     ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
 
 149 if (ParseParam(s.moduleParams, "database", dbName) < 0 &&
 
 150     ParseParam(s.moduleParams, "dbname", dbName) < 0)
 
 152 if (ParseParam(s.moduleParams, "server", dbHost) < 0 &&
 
 153     ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
 
 158 //-----------------------------------------------------------------------------
 
 159 //-----------------------------------------------------------------------------
 
 160 //-----------------------------------------------------------------------------
 
 161 MYSQL_STORE::MYSQL_STORE()
 
 163       version("mysql_store v.0.67"),
 
 166       logger(GetPluginLogger(GetStgLogger(), "store_mysql"))
 
 169 //-----------------------------------------------------------------------------
 
 170 int    MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
 
 174     if( (ret = mysql_query(sock,sQuery)) )
 
 176         for(int i=0; i<RepitTimes; i++)
 
 178             if( (ret = mysql_query(sock,sQuery)) )
 
 179                 ;//need to send error result
 
 187 //-----------------------------------------------------------------------------
 
 189 //-----------------------------------------------------------------------------
 
 190 int MYSQL_STORE::ParseSettings()
 
 192 int ret = storeSettings.ParseSettings(settings);
 
 197     errorStr = storeSettings.GetStrError();
 
 200     if(storeSettings.GetDBPassword().length() == 0)
 
 202         errorStr = "Database password must be not empty. Please read Manual.";
 
 206     if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
 
 207             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
 
 210             errorStr = "Couldn't connect to mysql engine! With error:\n";
 
 211             errorStr += mysql_error(&mysql);
 
 217          if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
 
 219              std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
 
 221             if(MysqlQuery(res.c_str(),sock))
 
 223                 errorStr = "Couldn't create database! With error:\n";
 
 224                 errorStr += mysql_error(sock);
 
 230                  if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
 
 232                     errorStr = "Couldn't select database! With error:\n";
 
 233                     errorStr += mysql_error(sock);
 
 237                  ret = CheckAllTables(sock);
 
 242             ret = CheckAllTables(sock);
 
 246             logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
 
 254 //-----------------------------------------------------------------------------
 
 255 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
 
 259 if (!(result=mysql_list_tables(sock,str.c_str() )))
 
 261     errorStr = "Couldn't get tables list With error:\n";
 
 262     errorStr += mysql_error(sock);
 
 267 my_ulonglong num_rows =  mysql_num_rows(result);
 
 270     mysql_free_result(result);
 
 272 return num_rows == 1;
 
 274 //-----------------------------------------------------------------------------
 
 275 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
 
 277 //info-------------------------------------------------------------------------
 
 278 if(!IsTablePresent("info",sock))
 
 280     sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
 
 282     if(MysqlQuery(qbuf,sock))
 
 284         errorStr = "Couldn't create info table With error:\n";
 
 285         errorStr += mysql_error(sock);
 
 290     sprintf(qbuf,"INSERT INTO info SET version=0");
 
 292     if(MysqlQuery(qbuf,sock))
 
 294         errorStr = "Couldn't write default version. With error:\n";
 
 295         errorStr += mysql_error(sock);
 
 303     std::vector<std::string> info;
 
 304     if (GetAllParams(&info, "info", "version"))
 
 311             GetInt(info.front(), &schemaVersion, 0);
 
 314 //admins-----------------------------------------------------------------------
 
 315 if(!IsTablePresent("admins",sock))
 
 317     sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
 
 318         "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
 
 319         "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
 
 320         "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
 
 321         "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
 
 323     if(MysqlQuery(qbuf,sock))
 
 325         errorStr = "Couldn't create admin table list With error:\n";
 
 326         errorStr += mysql_error(sock);
 
 331     sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
 
 332         "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
 
 333         "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
 
 335     if(MysqlQuery(qbuf,sock))
 
 337         errorStr = "Couldn't create default admin. With error:\n";
 
 338         errorStr += mysql_error(sock);
 
 344 //tariffs-----------------------------------------------------------------------
 
 345 std::string param, res;
 
 346 if(!IsTablePresent("tariffs",sock))
 
 348     res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
 
 350     for (int i = 0; i < DIR_NUM; i++)
 
 352         strprintf(¶m, " PriceDayA%d DOUBLE DEFAULT 0.0,", i); 
 
 355         strprintf(¶m, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
 
 358         strprintf(¶m, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
 
 361         strprintf(¶m, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
 
 364         strprintf(¶m, " Threshold%d INT DEFAULT 0,", i);
 
 367         strprintf(¶m, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
 
 370         strprintf(¶m, " NoDiscount%d INT DEFAULT 0,", i);
 
 373         strprintf(¶m, " SinglePrice%d INT DEFAULT 0,", i);
 
 377     res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
 
 378         "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
 
 379         "period VARCHAR(32) NOT NULL DEFAULT 'month')";
 
 381     if(MysqlQuery(res.c_str(),sock))
 
 383         errorStr = "Couldn't create tariffs table list With error:\n";
 
 384         errorStr += mysql_error(sock);
 
 389     res = "INSERT INTO tariffs SET name='tariff',";
 
 391     for (int i = 0; i < DIR_NUM; i++)
 
 393         strprintf(¶m, " NoDiscount%d=1,", i);
 
 396         strprintf(¶m, " Threshold%d=0,", i);
 
 399         strprintf(¶m, " Time%d='0:0-0:0',", i);
 
 404             strprintf(¶m, " SinglePrice%d=0,", i);
 
 410             strprintf(¶m, " PriceDayA%d=0.0,", i); 
 
 415             strprintf(¶m, " PriceDayB%d=0.0,", i);        
 
 421             strprintf(¶m, " PriceNightA%d=0.0,", i); 
 
 426             strprintf(¶m, " PriceNightB%d=0.0,", i);        
 
 431     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
 
 432         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
 
 433         "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month'";
 
 435     if(MysqlQuery(res.c_str(),sock))
 
 437         errorStr = "Couldn't create default tariff. With error:\n";
 
 438         errorStr += mysql_error(sock);
 
 443     sprintf(qbuf,"UPDATE info SET version=1");
 
 445     if(MysqlQuery(qbuf,sock))
 
 447         errorStr = "Couldn't write default version. With error:\n";
 
 448         errorStr += mysql_error(sock);
 
 455 //users-----------------------------------------------------------------------
 
 456 if(!IsTablePresent("users",sock))
 
 458     res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
 
 459         "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 '',"\
 
 460         "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
 
 461         "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
 
 462         "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
 
 464     for (int i = 0; i < USERDATA_NUM; i++)
 
 466         strprintf(¶m, " Userdata%d VARCHAR(254) NOT NULL,", i);
 
 470     param = " CreditExpire INT(11) DEFAULT 0,";
 
 473     strprintf(¶m, " IP VARCHAR(254) DEFAULT '*',");
 
 476     for (int i = 0; i < DIR_NUM; i++)
 
 478         strprintf(¶m, " D%d BIGINT(30) DEFAULT 0,", i);
 
 481         strprintf(¶m, " U%d BIGINT(30) DEFAULT 0,", i);
 
 485     strprintf(¶m, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
 
 486         "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
 
 487         "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
 
 488         " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
 
 491     if(MysqlQuery(res.c_str(),sock))
 
 493         errorStr = "Couldn't create users table list With error:\n";
 
 494         errorStr += mysql_error(sock);
 
 495         errorStr += "\n\n" + res;
 
 500     res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
 
 501         "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
 
 502         "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
 
 503         "Phone='', RealName='',Tariff='tariff',TariffChange='',Userdata0='',"\
 
 506     for (int i = 0; i < DIR_NUM; i++)
 
 508         strprintf(¶m, " D%d=0,", i);
 
 511         strprintf(¶m, " U%d=0,", i);
 
 515     res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
 
 516         "LastCashAddTime=0, PassiveTime=0";
 
 518     if(MysqlQuery(res.c_str(),sock))
 
 520         errorStr = "Couldn't create default user. With error:\n";
 
 521         errorStr += mysql_error(sock);
 
 527 //logs-----------------------------------------------------------------------
 
 528 if(!IsTablePresent("logs"))
 
 530     sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
 
 534         errorStr = "Couldn't create admin table list With error:\n";
 
 535         errorStr += mysql_error(sock);
 
 540 //messages---------------------------------------------------------------------
 
 541 if(!IsTablePresent("messages",sock))
 
 543     sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
 
 544             "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
 
 545             "stgRepeat INT, repeatPeriod INT, text TEXT)");
 
 547     if(MysqlQuery(qbuf,sock))
 
 549         errorStr = "Couldn't create messages table. With error:\n";
 
 550         errorStr += mysql_error(sock);
 
 556 //month_stat-------------------------------------------------------------------
 
 557 if(!IsTablePresent("stat",sock))
 
 559     res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
 
 561     for (int i = 0; i < DIR_NUM; i++)
 
 563         strprintf(¶m, " U%d BIGINT,", i); 
 
 566         strprintf(¶m, " D%d BIGINT,", i); 
 
 570     res += " cash DOUBLE, INDEX (login))";
 
 572     if(MysqlQuery(res.c_str(),sock))
 
 574         errorStr = "Couldn't create stat table. With error:\n";
 
 575         errorStr += mysql_error(sock);
 
 583 //-----------------------------------------------------------------------------
 
 584 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
 
 586 if (schemaVersion  < 1)
 
 588     if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
 
 590         errorStr = "Couldn't update tariffs table to version 1. With error:\n";
 
 591         errorStr += mysql_error(sock);
 
 595     if (MysqlQuery("UPDATE info SET version = 1", sock))
 
 597         errorStr = "Couldn't update DB schema version to 1. With error:\n";
 
 598         errorStr += mysql_error(sock);
 
 603     logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
 
 607 //-----------------------------------------------------------------------------
 
 609 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList, 
 
 610                             const std::string & table, const std::string & name) const
 
 619 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
 
 621 if(MysqlGetQuery(qbuf,sock))
 
 623     errorStr = "Couldn't GetAllParams Query for: ";
 
 624     errorStr += name + " - " + table + "\n";
 
 625     errorStr += mysql_error(sock);
 
 630 if (!(res=mysql_store_result(sock)))
 
 632     errorStr = "Couldn't GetAllParams Results for: ";
 
 633     errorStr += name + " - " + table + "\n";
 
 634     errorStr += mysql_error(sock);
 
 638 num = mysql_num_rows(res);
 
 640 for(i = 0; i < num; i++)
 
 642     row = mysql_fetch_row(res);    
 
 643     ParamList->push_back(row[0]);
 
 646 mysql_free_result(res);
 
 652 //-----------------------------------------------------------------------------
 
 653 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
 
 655 if(GetAllParams(usersList, "users", "login"))
 
 660 //-----------------------------------------------------------------------------
 
 661 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
 
 663 if(GetAllParams(adminsList, "admins", "login"))
 
 668 //-----------------------------------------------------------------------------
 
 669 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
 
 671 if(GetAllParams(tariffsList, "tariffs", "name"))
 
 676 //-----------------------------------------------------------------------------
 
 677 int MYSQL_STORE::AddUser(const std::string & login) const
 
 679 sprintf(qbuf,"INSERT INTO users SET login='%s'", login.c_str());
 
 681 if(MysqlSetQuery(qbuf))
 
 683     errorStr = "Couldn't add user:\n";
 
 684     //errorStr += mysql_error(sock);
 
 690 //-----------------------------------------------------------------------------
 
 691 int MYSQL_STORE::DelUser(const std::string & login) const
 
 693 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 695 if(MysqlSetQuery(qbuf))
 
 697     errorStr = "Couldn't delete user:\n";
 
 698     //errorStr += mysql_error(sock);
 
 704 //-----------------------------------------------------------------------------
 
 705 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
 
 712 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
 
 713          AlwaysOnline, Tariff, Address, Phone, Email, Note, \
 
 714          RealName, StgGroup, Credit, TariffChange, ";
 
 716 for (int i = 0; i < USERDATA_NUM; i++)
 
 718     sprintf(qbuf, "Userdata%d, ", i);
 
 722 query += "CreditExpire, IP FROM users WHERE login='";
 
 723 query += login + "' LIMIT 1";
 
 725 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 727 if(MysqlGetQuery(query.c_str(),sock))
 
 729     errorStr = "Couldn't restore Tariff(on query):\n";
 
 730     errorStr += mysql_error(sock);
 
 735 if (!(res=mysql_store_result(sock)))
 
 737     errorStr = "Couldn't restore Tariff(on getting result):\n";
 
 738     errorStr += mysql_error(sock);
 
 743 if (mysql_num_rows(res) != 1)
 
 745     errorStr = "User not found";
 
 750 row = mysql_fetch_row(res);
 
 754 conf->password = row[1];
 
 756 if (conf->password.empty())
 
 758     mysql_free_result(res);
 
 759     errorStr = "User \'" + login + "\' password is blank.";
 
 764 if (GetInt(row[2],&conf->passive) != 0)
 
 766     mysql_free_result(res);
 
 767     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
 
 772 if (GetInt(row[3], &conf->disabled) != 0)
 
 774     mysql_free_result(res);
 
 775     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
 
 780 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
 
 782     mysql_free_result(res);
 
 783     errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
 
 788 if (GetInt(row[5], &conf->alwaysOnline) != 0)
 
 790     mysql_free_result(res);
 
 791     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
 
 796 conf->tariffName = row[6];
 
 798 if (conf->tariffName.empty()) 
 
 800     mysql_free_result(res);
 
 801     errorStr = "User \'" + login + "\' tariff is blank.";
 
 806 conf->address = row[7];
 
 807 conf->phone = row[8];
 
 808 conf->email = row[9];
 
 809 conf->note = row[10];
 
 810 conf->realName = row[11];
 
 811 conf->group = row[12];
 
 813 if (GetDouble(row[13], &conf->credit, 0) != 0)
 
 815     mysql_free_result(res);
 
 816     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
 
 821 conf->nextTariff = row[14];
 
 823 for (int i = 0; i < USERDATA_NUM; i++)
 
 825     conf->userdata[i] = row[15+i];
 
 828 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
 
 830 std::string ipStr = row[16+USERDATA_NUM];
 
 836 catch (const std::string & s)
 
 838     mysql_free_result(res);
 
 839     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
 
 845 mysql_free_result(res);
 
 850 //-----------------------------------------------------------------------------
 
 851 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
 
 861 for (int i = 0; i < DIR_NUM; i++)
 
 863     sprintf(qbuf, "D%d, U%d, ", i, i);
 
 867 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
 
 868           FROM users WHERE login = '";
 
 869 query += login + "'";
 
 871 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
 
 873 if(MysqlGetQuery(query.c_str() ,sock))
 
 875     errorStr = "Couldn't restore UserStat(on query):\n";
 
 876     errorStr += mysql_error(sock);
 
 881 if (!(res=mysql_store_result(sock)))
 
 883     errorStr = "Couldn't restore UserStat(on getting result):\n";
 
 884     errorStr += mysql_error(sock);
 
 889 row = mysql_fetch_row(res);
 
 891 unsigned int startPos=0;
 
 895 for (int i = 0; i < DIR_NUM; i++)
 
 898     sprintf(s, "D%d", i);
 
 899     if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
 
 901         mysql_free_result(res);
 
 902         errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 906     stat->monthDown[i] = traff;
 
 908     sprintf(s, "U%d", i);
 
 909     if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
 
 911         mysql_free_result(res);
 
 912         errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 916     stat->monthUp[i] = traff;
 
 919 startPos += (2*DIR_NUM);
 
 921 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
 
 923     mysql_free_result(res);
 
 924     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
 
 929 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
 
 931     mysql_free_result(res);
 
 932     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
 
 937 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
 
 939     mysql_free_result(res);
 
 940     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
 
 945 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
 
 947     mysql_free_result(res);
 
 948     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
 
 953 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
 
 955     mysql_free_result(res);
 
 956     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
 
 961 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
 
 963     mysql_free_result(res);
 
 964     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
 
 969 mysql_free_result(res);
 
 973 //-----------------------------------------------------------------------------
 
 974 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
 
 979 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
 
 980     "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
 
 981     "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ", 
 
 982     conf.password.c_str(),
 
 985     conf.disabledDetailStat,
 
 987     conf.tariffName.c_str(),
 
 988     (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
 
 989     (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
 
 990     (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
 
 991     (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
 
 992     (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
 
 993     (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
 
 995     conf.nextTariff.c_str()
 
 998 for (int i = 0; i < USERDATA_NUM; i++)
 
1000     strprintf(¶m, " Userdata%d='%s',", i, 
 
1001         (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
 
1005 strprintf(¶m, " CreditExpire=%d,", conf.creditExpire);
 
1008 std::ostringstream ipStr;
 
1011 strprintf(¶m, " IP='%s'", ipStr.str().c_str());
 
1014 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
 
1017 if(MysqlSetQuery(res.c_str()))
 
1019     errorStr = "Couldn't save user conf:\n";
 
1020     //errorStr += mysql_error(sock);
 
1026 //-----------------------------------------------------------------------------
 
1027 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
 
1032 res = "UPDATE users SET";
 
1034 for (int i = 0; i < DIR_NUM; i++)
 
1036     strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);
 
1039     strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]);
 
1043 strprintf(¶m, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
 
1044     " PassiveTime=%d, LastActivityTime=%d", 
 
1048     stat.lastCashAddTime,
 
1050     stat.lastActivityTime
 
1054 strprintf(¶m, " WHERE login='%s' LIMIT 1", login.c_str());
 
1057 if(MysqlSetQuery(res.c_str()))
 
1059     errorStr = "Couldn't save user stat:\n";
 
1060 //    errorStr += mysql_error(sock);
 
1066 //-----------------------------------------------------------------------------
 
1067 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
 
1069 std::string res, tempStr;
 
1078 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
 
1079 if (!(sock=MysqlConnect())){
 
1080     errorStr = "Couldn't connect to Server";
 
1083 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
 
1085     errorStr = "Couldn't get table " + tempStr + ":\n";
 
1086     errorStr += mysql_error(sock);
 
1091 my_ulonglong num_rows =  mysql_num_rows(result);
 
1093 mysql_free_result(result);
 
1097     sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
 
1098     lt->tm_mon+1, lt->tm_year+1900);
 
1100     if(MysqlQuery(qbuf,sock))
 
1102         errorStr = "Couldn't create WriteDetailedStat table:\n";
 
1103         errorStr += mysql_error(sock);
 
1109 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
 
1113 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
 
1114         lt->tm_mon+1, lt->tm_year+1900,
 
1115     login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
 
1117 if(MysqlQuery(send.c_str(),sock))
 
1119     errorStr = "Couldn't write log string:\n";
 
1120     errorStr += mysql_error(sock);
 
1128 //-----------------------------------------------------------------------------
 
1129 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
 
1130                                  const std::string & admLogin,
 
1132                                  const std::string & paramName,
 
1133                                  const std::string & oldValue,
 
1134                                  const std::string & newValue,
 
1135                                  const std::string & message) const
 
1137 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
 
1138     + paramName + "\' parameter changed from \'" + oldValue +
 
1139     "\' to \'" + newValue + "\'. " + message;
 
1141 return WriteLogString(userLogMsg, login);
 
1143 //-----------------------------------------------------------------------------
 
1144 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
 
1146 std::string logStr = "Connect, " + inet_ntostring(ip);
 
1147 return WriteLogString(logStr, login);
 
1149 //-----------------------------------------------------------------------------
 
1150 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
 
1151                                      const DIR_TRAFF & up,
 
1152                                      const DIR_TRAFF & down,
 
1153                                      const DIR_TRAFF & sessionUp,
 
1154                                      const DIR_TRAFF & sessionDown,
 
1157                                      const std::string & /*reason*/) const
 
1159 std::string logStr = "Disconnect, ";
 
1160 std::ostringstream sssu;
 
1161 std::ostringstream sssd;
 
1162 std::ostringstream ssmu;
 
1163 std::ostringstream ssmd;
 
1164 std::ostringstream sscash;
 
1170 sssd << sessionDown;
 
1174 logStr += " session upload: \'";
 
1175 logStr += sssu.str();
 
1176 logStr += "\' session download: \'";
 
1177 logStr += sssd.str();
 
1178 logStr += "\' month upload: \'";
 
1179 logStr += ssmu.str();
 
1180 logStr += "\' month download: \'";
 
1181 logStr += ssmd.str();
 
1182 logStr += "\' cash: \'";
 
1183 logStr += sscash.str();
 
1186 return WriteLogString(logStr, login);
 
1188 //-----------------------------------------------------------------------------
 
1189 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, 
 
1190                                 const std::string & login) const
 
1192 std::string param, res;
 
1194 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,", 
 
1195     login.c_str(), month+1, year+1900);
 
1197 for (int i = 0; i < DIR_NUM; i++)
 
1199     strprintf(¶m, " U%d=%lld,", i, stat.monthUp[i]); 
 
1202     strprintf(¶m, " D%d=%lld,", i, stat.monthDown[i]);        
 
1206 strprintf(¶m, " cash=%f", stat.cash);        
 
1209 if(MysqlSetQuery(res.c_str()))
 
1211     errorStr = "Couldn't SaveMonthStat:\n";
 
1212     //errorStr += mysql_error(sock);
 
1218 //-----------------------------------------------------------------------------*/
 
1219 int MYSQL_STORE::AddAdmin(const std::string & login) const
 
1221 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
 
1223 if(MysqlSetQuery(qbuf))
 
1225     errorStr = "Couldn't add admin:\n";
 
1226     //errorStr += mysql_error(sock);
 
1232 //-----------------------------------------------------------------------------*/
 
1233 int MYSQL_STORE::DelAdmin(const std::string & login) const
 
1235 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
 
1237 if(MysqlSetQuery(qbuf))
 
1239     errorStr = "Couldn't delete admin:\n";
 
1240     //errorStr += mysql_error(sock);
 
1246 //-----------------------------------------------------------------------------*/
 
1247 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
 
1249 char passwordE[2 * ADM_PASSWD_LEN + 2];
 
1250 char pass[ADM_PASSWD_LEN + 1];
 
1251 char adminPass[ADM_PASSWD_LEN + 1];
 
1253 memset(pass, 0, sizeof(pass));
 
1254 memset(adminPass, 0, sizeof(adminPass));
 
1257 EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1259 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
 
1260 adminPass[ADM_PASSWD_LEN - 1] = 0;
 
1262 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1264     EncodeString(pass + 8*i, adminPass + 8*i, &ctx);
 
1267 pass[ADM_PASSWD_LEN - 1] = 0;
 
1268 Encode12(passwordE, pass, ADM_PASSWD_LEN);
 
1270 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
 
1271     "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
 
1272     "WHERE login='%s' LIMIT 1", 
 
1284 if(MysqlSetQuery(qbuf))
 
1286     errorStr = "Couldn't save admin:\n";
 
1287     //errorStr += mysql_error(sock);
 
1293 //-----------------------------------------------------------------------------
 
1294 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
 
1296 char pass[ADM_PASSWD_LEN + 1];
 
1297 char password[ADM_PASSWD_LEN + 1];
 
1298 char passwordE[2*ADM_PASSWD_LEN + 2];
 
1301 memset(pass, 0, sizeof(pass));
 
1302 memset(password, 0, sizeof(password));
 
1303 memset(passwordE, 0, sizeof(passwordE));
 
1309 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
 
1311 if(MysqlGetQuery(qbuf,sock))
 
1313     errorStr = "Couldn't restore admin:\n";
 
1314     errorStr += mysql_error(sock);
 
1319 if (!(res=mysql_store_result(sock)))
 
1321     errorStr = "Couldn't restore admin:\n";
 
1322     errorStr += mysql_error(sock);
 
1327 if ( mysql_num_rows(res) == 0)
 
1329     mysql_free_result(res);
 
1330     errorStr = "Couldn't restore admin as couldn't found him in table.\n";
 
1335 row = mysql_fetch_row(res);
 
1341     mysql_free_result(res);
 
1342     errorStr = "Error in parameter password";
 
1347 memset(passwordE, 0, sizeof(passwordE));
 
1348 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
 
1350 memset(pass, 0, sizeof(pass));
 
1352 if (passwordE[0] != 0)
 
1354     Decode21(pass, passwordE);
 
1355     EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1357     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1359         DecodeString(password + 8*i, pass + 8*i, &ctx);
 
1367 ac->password = password;
 
1371 if (GetInt(row[2], &a) == 0) 
 
1372     ac->priv.userConf = a;
 
1375     mysql_free_result(res);
 
1376     errorStr = "Error in parameter ChgConf";
 
1381 if (GetInt(row[3], &a) == 0) 
 
1382     ac->priv.userPasswd = a;
 
1385     mysql_free_result(res);
 
1386     errorStr = "Error in parameter ChgPassword";
 
1391 if (GetInt(row[4], &a) == 0) 
 
1392     ac->priv.userStat = a;
 
1395     mysql_free_result(res);
 
1396     errorStr = "Error in parameter ChgStat";
 
1401 if (GetInt(row[5], &a) == 0) 
 
1402     ac->priv.userCash = a;
 
1405     mysql_free_result(res);
 
1406     errorStr = "Error in parameter ChgCash";
 
1411 if (GetInt(row[6], &a) == 0) 
 
1412     ac->priv.userAddDel = a;
 
1415     mysql_free_result(res);
 
1416     errorStr = "Error in parameter UsrAddDel";
 
1421 if (GetInt(row[7], &a) == 0) 
 
1422     ac->priv.tariffChg = a;
 
1425     mysql_free_result(res);
 
1426     errorStr = "Error in parameter ChgTariff";
 
1431 if (GetInt(row[8], &a) == 0) 
 
1432     ac->priv.adminChg = a;
 
1435     mysql_free_result(res);
 
1436     errorStr = "Error in parameter ChgAdmin";
 
1441 mysql_free_result(res);
 
1445 //-----------------------------------------------------------------------------
 
1446 int MYSQL_STORE::AddTariff(const std::string & name) const
 
1448 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
 
1450 if(MysqlSetQuery(qbuf))
 
1452     errorStr = "Couldn't add tariff:\n";
 
1453 //    errorStr += mysql_error(sock);
 
1459 //-----------------------------------------------------------------------------
 
1460 int MYSQL_STORE::DelTariff(const std::string & name) const
 
1462 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
 
1464 if(MysqlSetQuery(qbuf))
 
1466     errorStr = "Couldn't delete tariff: ";
 
1467 //    errorStr += mysql_error(sock);
 
1473 //-----------------------------------------------------------------------------
 
1474 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
 
1479 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
 
1481 if(MysqlGetQuery(qbuf,sock))
 
1483     errorStr = "Couldn't restore Tariff:\n";
 
1484     errorStr += mysql_error(sock);
 
1489 if (!(res=mysql_store_result(sock)))
 
1491     errorStr = "Couldn't restore Tariff:\n";
 
1492     errorStr += mysql_error(sock);
 
1498 td->tariffConf.name = tariffName;
 
1500 row = mysql_fetch_row(res);
 
1503 for (int i = 0; i<DIR_NUM; i++)
 
1505     strprintf(¶m, "Time%d", i);
 
1507     if (str.length() == 0)
 
1509         mysql_free_result(res);
 
1510         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1515     ParseTariffTimeStr(str.c_str(), 
 
1516                        td->dirPrice[i].hDay, 
 
1517                        td->dirPrice[i].mDay, 
 
1518                        td->dirPrice[i].hNight, 
 
1519                        td->dirPrice[i].mNight);
 
1521     strprintf(¶m, "PriceDayA%d", i);
 
1522     if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
 
1524         mysql_free_result(res);
 
1525         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1529     td->dirPrice[i].priceDayA /= (1024*1024);
 
1531     strprintf(¶m, "PriceDayB%d", i);
 
1532     if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
 
1534         mysql_free_result(res);
 
1535         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1539     td->dirPrice[i].priceDayB /= (1024*1024);
 
1541     strprintf(¶m, "PriceNightA%d", i);
 
1542     if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
 
1544         mysql_free_result(res);
 
1545         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1549     td->dirPrice[i].priceNightA /= (1024*1024);
 
1551     strprintf(¶m, "PriceNightB%d", i);
 
1552     if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
 
1554         mysql_free_result(res);
 
1555         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1559     td->dirPrice[i].priceNightB /= (1024*1024);
 
1561     strprintf(¶m, "Threshold%d", i);
 
1562     if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
 
1564         mysql_free_result(res);
 
1565         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1570     strprintf(¶m, "SinglePrice%d", i);
 
1571     if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
 
1573         mysql_free_result(res);
 
1574         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1579     strprintf(¶m, "NoDiscount%d", i);
 
1580     if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
 
1582         mysql_free_result(res);
 
1583         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1589 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
 
1591     mysql_free_result(res);
 
1592     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
 
1597 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
 
1599     mysql_free_result(res);
 
1600     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
 
1605 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
 
1607     mysql_free_result(res);
 
1608     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
 
1613     str = row[4+8*DIR_NUM];
 
1614     param = "TraffType";
 
1616     if (str.length() == 0)
 
1618         mysql_free_result(res);
 
1619         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1624 if (!strcasecmp(str.c_str(), "up"))
 
1625     td->tariffConf.traffType = TRAFF_UP;
 
1627     if (!strcasecmp(str.c_str(), "down"))
 
1628         td->tariffConf.traffType = TRAFF_DOWN;
 
1630         if (!strcasecmp(str.c_str(), "up+down"))
 
1631             td->tariffConf.traffType = TRAFF_UP_DOWN;
 
1633             if (!strcasecmp(str.c_str(), "max"))
 
1634                 td->tariffConf.traffType = TRAFF_MAX;
 
1637                 mysql_free_result(res);
 
1638                 errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType incorrect";
 
1643 if (schemaVersion > 0)
 
1645     str = row[5+8*DIR_NUM];
 
1648     if (str.length() == 0)
 
1650         mysql_free_result(res);
 
1651         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1656     td->tariffConf.period = TARIFF::StringToPeriod(str);
 
1660     td->tariffConf.period = TARIFF::MONTH;
 
1663 mysql_free_result(res);
 
1667 //-----------------------------------------------------------------------------
 
1668 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
 
1672 std::string res="UPDATE tariffs SET";
 
1674 for (int i = 0; i < DIR_NUM; i++)
 
1676     strprintf(¶m, " PriceDayA%d=%f,", i, 
 
1677         td.dirPrice[i].priceDayA * pt_mega);
 
1680     strprintf(¶m, " PriceDayB%d=%f,", i, 
 
1681         td.dirPrice[i].priceDayB * pt_mega);        
 
1684     strprintf(¶m, " PriceNightA%d=%f,", i,
 
1685         td.dirPrice[i].priceNightA * pt_mega);
 
1688     strprintf(¶m, " PriceNightB%d=%f,", i, 
 
1689         td.dirPrice[i].priceNightB * pt_mega);
 
1692     strprintf(¶m, " Threshold%d=%d,", i, 
 
1693         td.dirPrice[i].threshold);
 
1697     strprintf(¶m, " Time%d", i);
 
1699     strprintf(&s, "%0d:%0d-%0d:%0d", 
 
1700             td.dirPrice[i].hDay,
 
1701             td.dirPrice[i].mDay,
 
1702             td.dirPrice[i].hNight,
 
1703             td.dirPrice[i].mNight);
 
1705     res += (param + "='" + s + "',");
 
1707     strprintf(¶m, " NoDiscount%d=%d,", i, 
 
1708         td.dirPrice[i].noDiscount);
 
1711     strprintf(¶m, " SinglePrice%d=%d,", i, 
 
1712         td.dirPrice[i].singlePrice);
 
1716 strprintf(¶m, " PassiveCost=%f,", td.tariffConf.passiveCost);
 
1719 strprintf(¶m, " Fee=%f,", td.tariffConf.fee);
 
1722 strprintf(¶m, " Free=%f,", td.tariffConf.free);
 
1725 switch (td.tariffConf.traffType)
 
1728         res += " TraffType='up'";
 
1731         res += " TraffType='down'";
 
1734         res += " TraffType='up+down'";
 
1737         res += " TraffType='max'";
 
1741 if (schemaVersion > 0)
 
1742     res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
 
1744 strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str());
 
1747 if(MysqlSetQuery(res.c_str()))
 
1749     errorStr = "Couldn't save tariff:\n";
 
1750     //errorStr += mysql_error(sock);
 
1756 //-----------------------------------------------------------------------------
 
1757 int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree, 
 
1759                                    const std::string & login) const
 
1761 std::string res, stTime, endTime, tempStr;
 
1768 if (lt->tm_hour == 0 && lt->tm_min <= 5)
 
1776 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
 
1778 if (!(sock=MysqlConnect())){
 
1783 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
 
1785     errorStr = "Couldn't get table " + tempStr + ":\n";
 
1786     errorStr += mysql_error(sock);
 
1791 my_ulonglong num_rows =  mysql_num_rows(result);
 
1793 mysql_free_result(result);
 
1797     sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
 
1798         "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
 
1799         "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
 
1800         "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
 
1801     lt->tm_mon+1, lt->tm_year+1900);
 
1803     if(MysqlQuery(qbuf,sock))
 
1805         errorStr = "Couldn't create WriteDetailedStat table:\n";
 
1806         errorStr += mysql_error(sock);
 
1815 lt1 = localtime(&lastStat);
 
1824 lt2 = localtime(&t);
 
1830 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
 
1831 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
 
1833 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
 
1834     "day=%d,startTime='%s',endTime='%s',", 
 
1835     lt->tm_mon+1, lt->tm_year+1900,
 
1842 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
 
1843 stIter = statTree.begin();
 
1845 while (stIter != statTree.end())
 
1847         strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f", 
 
1848                 inet_ntostring(stIter->first.ip).c_str(),
 
1850                 stIter->second.down, 
 
1855         if( MysqlQuery((res+tempStr).c_str(),sock) )
 
1857             errorStr = "Couldn't insert data in WriteDetailedStat:\n";
 
1858             errorStr += mysql_error(sock);
 
1863         result=mysql_store_result(sock);
 
1865             mysql_free_result(result);
 
1872 //-----------------------------------------------------------------------------
 
1873 int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
 
1877 gettimeofday(&tv, NULL);
 
1879 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
 
1881 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld", 
 
1883     static_cast<long long>(msg->header.id)
 
1886 if(MysqlSetQuery(qbuf))
 
1888     errorStr = "Couldn't add message:\n";
 
1889     //errorStr += mysql_error(sock);
 
1893 return EditMessage(*msg, login);
 
1895 //-----------------------------------------------------------------------------
 
1896 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
 
1900 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
 
1901     "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
 
1902     "WHERE login='%s' AND id=%lld LIMIT 1", 
 
1904     msg.header.lastSendTime,
 
1905     msg.header.creationTime,
 
1906     msg.header.showTime,
 
1908     msg.header.repeatPeriod,
 
1909     (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
 
1914 if(MysqlSetQuery(res.c_str()))
 
1916     errorStr = "Couldn't edit message:\n";
 
1917     //errorStr += mysql_error(sock);
 
1923 //-----------------------------------------------------------------------------
 
1924 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
 
1930 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
 
1931         login.c_str(), static_cast<unsigned long long>(id));
 
1933 if(MysqlGetQuery(qbuf,sock))
 
1935     errorStr = "Couldn't GetMessage:\n";
 
1936     errorStr += mysql_error(sock);
 
1941 if (!(res=mysql_store_result(sock)))
 
1943     errorStr = "Couldn't GetMessage:\n";
 
1944     errorStr += mysql_error(sock);
 
1949 row = mysql_fetch_row(res);
 
1951 if(row[2]&&str2x(row[2], msg->header.type))
 
1953     mysql_free_result(res);
 
1954     errorStr = "Invalid value in message header for user: " + login;
 
1959 if(row[3] && str2x(row[3], msg->header.lastSendTime))
 
1961     mysql_free_result(res);
 
1962     errorStr = "Invalid value in message header for user: " + login;
 
1967 if(row[4] && str2x(row[4], msg->header.creationTime))
 
1969     mysql_free_result(res);
 
1970     errorStr = "Invalid value in message header for user: " + login;
 
1975 if(row[5] && str2x(row[5], msg->header.showTime))
 
1977     mysql_free_result(res);
 
1978     errorStr = "Invalid value in message header for user: " + login;
 
1983 if(row[6] && str2x(row[6], msg->header.repeat))
 
1985     mysql_free_result(res);
 
1986     errorStr = "Invalid value in message header for user: " + login;
 
1991 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
 
1993     mysql_free_result(res);
 
1994     errorStr = "Invalid value in message header for user: " + login;
 
1999 msg->header.id = id;
 
2002 mysql_free_result(res);
 
2006 //-----------------------------------------------------------------------------
 
2007 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
 
2009 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1", 
 
2010         login.c_str(), static_cast<long long>(id));
 
2012 if(MysqlSetQuery(qbuf))
 
2014     errorStr = "Couldn't delete Message:\n";
 
2015     //errorStr += mysql_error(sock);
 
2021 //-----------------------------------------------------------------------------
 
2022 int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
 
2027 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
 
2029 if(MysqlGetQuery(qbuf,sock))
 
2031     errorStr = "Couldn't GetMessageHdrs:\n";
 
2032     errorStr += mysql_error(sock);
 
2037 if (!(res=mysql_store_result(sock)))
 
2039     errorStr = "Couldn't GetMessageHdrs:\n";
 
2040     errorStr += mysql_error(sock);
 
2046 my_ulonglong num_rows = mysql_num_rows(res);
 
2049 for (i = 0; i < num_rows; i++)
 
2051     row = mysql_fetch_row(res);
 
2052     if (str2x(row[1], id))
 
2057         if(str2x(row[2], hdr.type))
 
2061         if(str2x(row[3], hdr.lastSendTime))
 
2065         if(str2x(row[4], hdr.creationTime))
 
2069         if(str2x(row[5], hdr.showTime))
 
2073         if(str2x(row[6], hdr.repeat))
 
2077         if(str2x(row[7], hdr.repeatPeriod))
 
2081     hdrsList->push_back(hdr);
 
2084 mysql_free_result(res);
 
2088 //-----------------------------------------------------------------------------
 
2090 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
 
2093     int ret=MysqlGetQuery(Query,sock);
 
2097 //-----------------------------------------------------------------------------
 
2098 int  MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
 
2099     if (!(sock=MysqlConnect())) {
 
2102     return   MysqlQuery(Query,sock);
 
2104 //-----------------------------------------------------------------------------
 
2105 MYSQL *  MYSQL_STORE::MysqlConnect() const {
 
2107     if ( !(sock=mysql_init(NULL)) ){
 
2108         errorStr= "mysql init susck\n";
 
2111     if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
 
2112             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
 
2115             errorStr = "Couldn't connect to mysql engine! With error:\n";
 
2116             errorStr += mysql_error(sock);
 
2120          if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
 
2121              errorStr = "Database lost !\n";
 
2127 //-----------------------------------------------------------------------------