]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/store/mysql/mysql_store.cpp
Merge pull request #2 from bobr-kun/MySQL_custom_port
[stg.git] / projects / stargazer / plugins / store / mysql / mysql_store.cpp
1 #include <sys/time.h>
2 #include <cerrno>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <algorithm>
6
7 #include <mysql.h>
8 #include <errmsg.h>
9
10 #include "stg/common.h"
11 #include "stg/user_ips.h"
12 #include "stg/user_conf.h"
13 #include "stg/user_stat.h"
14 #include "stg/blowfish.h"
15 #include "stg/plugin_creator.h"
16 #include "stg/logger.h"
17 #include "mysql_store.h"
18
19 #define adm_enc_passwd "cjeifY8m3"
20
21 namespace
22 {
23 char qbuf[4096];
24
25 const int pt_mega = 1024 * 1024;
26 const std::string badSyms = "'`";
27 const char repSym = '\"';
28 const int RepitTimes = 3;
29
30 template <typename T>
31 int GetInt(const std::string & str, T * val, T defaultVal = T())
32 {
33     char *res;
34
35     *val = static_cast<T>(strtoll(str.c_str(), &res, 10));
36
37     if (*res != 0)
38     {
39         *val = defaultVal; //Error!
40         return EINVAL;
41     }
42
43     return 0;
44 }
45
46 int GetDouble(const std::string & str, double * val, double defaultVal)
47 {
48     char *res;
49
50     *val = strtod(str.c_str(), &res);
51
52     if (*res != 0)
53     {
54         *val = defaultVal; //Error!
55         return EINVAL;
56     }
57
58     return 0;
59 }
60
61 int GetTime(const std::string & str, time_t * val, time_t defaultVal)
62 {
63     char *res;
64
65     *val = strtol(str.c_str(), &res, 10);
66
67     if (*res != 0)
68     {
69         *val = defaultVal; //Error!
70         return EINVAL;
71     }
72
73     return 0;
74 }
75
76 //-----------------------------------------------------------------------------
77 std::string ReplaceStr(std::string source, const std::string & symlist, const char chgsym)
78 {
79     std::string::size_type pos=0;
80
81     while( (pos = source.find_first_of(symlist,pos)) != std::string::npos)
82         source.replace(pos, 1,1, chgsym);
83
84     return source;
85 }
86
87 int GetULongLongInt(const std::string & str, uint64_t * val, uint64_t defaultVal)
88 {
89     char *res;
90
91     *val = strtoull(str.c_str(), &res, 10);
92
93     if (*res != 0)
94     {
95         *val = defaultVal; //Error!
96         return EINVAL;
97     }
98
99     return 0;
100 }
101
102 PLUGIN_CREATOR<MYSQL_STORE> msc;
103 }
104
105 extern "C" STORE * GetStore();
106 //-----------------------------------------------------------------------------
107 //-----------------------------------------------------------------------------
108 //-----------------------------------------------------------------------------
109 STORE * GetStore()
110 {
111 return msc.GetPlugin();
112 }
113 //-----------------------------------------------------------------------------
114 MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
115     : settings(NULL)
116     , dbPort(0)
117 {
118 }
119 //-----------------------------------------------------------------------------
120 int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<PARAM_VALUE> & moduleParams,
121                                      const std::string & name, std::string & result)
122 {
123 PARAM_VALUE pv;
124 pv.param = name;
125 std::vector<PARAM_VALUE>::const_iterator pvi;
126 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
127 if (pvi == moduleParams.end() || pvi->value.empty())
128     {
129     errorStr = "Parameter \'" + name + "\' not found.";
130     return -1;
131     }
132
133 result = pvi->value[0];
134
135 return 0;
136 }
137 //-----------------------------------------------------------------------------
138 int MYSQL_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
139 {
140 if (ParseParam(s.moduleParams, "user", dbUser) < 0 &&
141     ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
142     return -1;
143 if (ParseParam(s.moduleParams, "password", dbPass) < 0 &&
144     ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
145     return -1;
146 if (ParseParam(s.moduleParams, "database", dbName) < 0 &&
147     ParseParam(s.moduleParams, "dbname", dbName) < 0)
148     return -1;
149 if (ParseParam(s.moduleParams, "server", dbHost) < 0 &&
150     ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
151     return -1;
152
153 std::string dbPortAsString;
154 if (ParseParam(s.moduleParams, "port", dbPortAsString) == 0 ||
155     ParseParam(s.moduleParams, "dbport", dbPortAsString) == 0)
156 {
157     if (GetInt<unsigned int>(dbPortAsString, &dbPort, 0) != 0)
158     {
159         errorStr = "Can't parse db port from string: \"" + dbPortAsString + "\"\n";
160         return -1;
161     }
162 }
163
164 return 0;
165 }
166 //-----------------------------------------------------------------------------
167 //-----------------------------------------------------------------------------
168 //-----------------------------------------------------------------------------
169 MYSQL_STORE::MYSQL_STORE()
170     : version("mysql_store v.0.67"),
171       schemaVersion(0),
172       logger(GetPluginLogger(GetStgLogger(), "store_mysql"))
173 {
174 }
175 //-----------------------------------------------------------------------------
176 int    MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
177 {
178     int ret;
179
180     if( (ret = mysql_query(sock,sQuery)) )
181     {
182         for(int i=0; i<RepitTimes; i++)
183         {
184             if( (ret = mysql_query(sock,sQuery)) )
185                 ;//need to send error result
186             else
187                 return 0;
188         }
189     }
190
191     return ret;
192 }
193 //-----------------------------------------------------------------------------
194
195 //-----------------------------------------------------------------------------
196 int MYSQL_STORE::ParseSettings()
197 {
198 int ret = storeSettings.ParseSettings(settings);
199 MYSQL mysql;
200 mysql_init(&mysql);
201 if (ret)
202     errorStr = storeSettings.GetStrError();
203 else
204 {
205     if(storeSettings.GetDBPassword().length() == 0)
206     {
207         errorStr = "Database password must be not empty. Please read Manual.";
208         return -1;
209     }
210     MYSQL * sock;
211     if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
212             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
213             0,storeSettings.GetDBPort(),NULL,0)))
214         {
215             errorStr = "Couldn't connect to mysql engine! With error:\n";
216             errorStr += mysql_error(&mysql);
217             mysql_close(sock);
218             ret = -1;
219         }
220     else
221     {
222          if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
223          {
224              std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
225
226             if(MysqlQuery(res.c_str(),sock))
227             {
228                 errorStr = "Couldn't create database! With error:\n";
229                 errorStr += mysql_error(sock);
230                 mysql_close(sock);
231                 ret = -1;
232             }
233             else
234             {
235                  if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
236                  {
237                      errorStr = "Couldn't select database! With error:\n";
238                      errorStr += mysql_error(sock);
239                      mysql_close(sock);
240                      ret = -1;
241                  }
242                  else
243                      ret = CheckAllTables(sock);
244             }
245         }
246         else
247         {
248             ret = CheckAllTables(sock);
249         }
250         if (!ret)
251         {
252             logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
253             MakeUpdates(sock);
254         }
255         mysql_close(sock);
256     }
257 }
258 return ret;
259 }
260 //-----------------------------------------------------------------------------
261 bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
262 {
263 MYSQL_RES* result;
264
265 if (!(result=mysql_list_tables(sock,str.c_str() )))
266 {
267     errorStr = "Couldn't get tables list With error:\n";
268     errorStr += mysql_error(sock);
269     mysql_close(sock);
270     return -1;
271 }
272
273 my_ulonglong num_rows =  mysql_num_rows(result);
274
275 if(result)
276     mysql_free_result(result);
277
278 return num_rows == 1;
279 }
280 //-----------------------------------------------------------------------------
281 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
282 {
283 //info-------------------------------------------------------------------------
284 if(!IsTablePresent("info",sock))
285 {
286     sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
287
288     if(MysqlQuery(qbuf,sock))
289         {
290         errorStr = "Couldn't create info table With error:\n";
291         errorStr += mysql_error(sock);
292         mysql_close(sock);
293         return -1;
294         }
295
296     sprintf(qbuf,"INSERT INTO info SET version=0");
297
298     if(MysqlQuery(qbuf,sock))
299         {
300         errorStr = "Couldn't write default version. With error:\n";
301         errorStr += mysql_error(sock);
302         mysql_close(sock);
303         return -1;
304         }
305     schemaVersion = 0;
306 }
307 else
308 {
309     std::vector<std::string> info;
310     if (GetAllParams(&info, "info", "version"))
311         schemaVersion = 0;
312     else
313     {
314         if (info.empty())
315             schemaVersion = 0;
316         else
317             GetInt(info.front(), &schemaVersion, 0);
318     }
319 }
320 //admins-----------------------------------------------------------------------
321 if(!IsTablePresent("admins",sock))
322 {
323     sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
324         "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
325         "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
326         "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
327         "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
328
329     if(MysqlQuery(qbuf,sock))
330     {
331         errorStr = "Couldn't create admin table list With error:\n";
332         errorStr += mysql_error(sock);
333         mysql_close(sock);
334         return -1;
335     }
336
337     sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
338         "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
339         "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
340
341     if(MysqlQuery(qbuf,sock))
342     {
343         errorStr = "Couldn't create default admin. With error:\n";
344         errorStr += mysql_error(sock);
345         mysql_close(sock);
346         return -1;
347     }
348 }
349
350 //tariffs-----------------------------------------------------------------------
351 std::string param, res;
352 if(!IsTablePresent("tariffs",sock))
353 {
354     res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
355
356     for (int i = 0; i < DIR_NUM; i++)
357         {
358         strprintf(&param, " PriceDayA%d DOUBLE DEFAULT 0.0,", i);
359         res += param;
360
361         strprintf(&param, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
362         res += param;
363
364         strprintf(&param, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
365         res += param;
366
367         strprintf(&param, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
368         res += param;
369
370         strprintf(&param, " Threshold%d INT DEFAULT 0,", i);
371         res += param;
372
373         strprintf(&param, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
374         res += param;
375
376         strprintf(&param, " NoDiscount%d INT DEFAULT 0,", i);
377         res += param;
378
379         strprintf(&param, " SinglePrice%d INT DEFAULT 0,", i);
380         res += param;
381         }
382
383     res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
384         "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
385         "period VARCHAR(32) NOT NULL DEFAULT 'month',"
386         "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow',"
387         "change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0)";
388
389     if(MysqlQuery(res.c_str(),sock))
390     {
391         errorStr = "Couldn't create tariffs table list With error:\n";
392         errorStr += mysql_error(sock);
393         mysql_close(sock);
394         return -1;
395     }
396
397     res = "INSERT INTO tariffs SET name='tariff',";
398
399     for (int i = 0; i < DIR_NUM; i++)
400         {
401         strprintf(&param, " NoDiscount%d=1,", i);
402         res += param;
403
404         strprintf(&param, " Threshold%d=0,", i);
405         res += param;
406
407         strprintf(&param, " Time%d='0:0-0:0',", i);
408         res += param;
409
410         if(i != 0 && i != 1)
411         {
412             strprintf(&param, " SinglePrice%d=0,", i);
413             res += param;
414         }
415
416         if(i != 1)
417         {
418             strprintf(&param, " PriceDayA%d=0.0,", i);
419             res += param;
420         }
421         if(i != 1)
422         {
423             strprintf(&param, " PriceDayB%d=0.0,", i);
424             res += param;
425         }
426
427         if(i != 0)
428         {
429             strprintf(&param, " PriceNightA%d=0.0,", i);
430             res += param;
431         }
432         if(i != 0)
433         {
434             strprintf(&param, " PriceNightB%d=0.0,", i);
435             res += param;
436         }
437         }
438
439     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
440         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
441         "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month',"\
442         "change_policy='allow', change_policy_timeout=0";
443
444     if(MysqlQuery(res.c_str(),sock))
445     {
446         errorStr = "Couldn't create default tariff. With error:\n";
447         errorStr += mysql_error(sock);
448         mysql_close(sock);
449         return -1;
450     }
451
452     sprintf(qbuf,"UPDATE info SET version=1");
453
454     if(MysqlQuery(qbuf,sock))
455     {
456         errorStr = "Couldn't write default version. With error:\n";
457         errorStr += mysql_error(sock);
458         mysql_close(sock);
459         return -1;
460     }
461     schemaVersion = 2;
462 }
463
464 //users-----------------------------------------------------------------------
465 if(!IsTablePresent("users",sock))
466 {
467     res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
468         "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 '',"\
469         "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
470         "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
471         "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
472
473     for (int i = 0; i < USERDATA_NUM; i++)
474         {
475         strprintf(&param, " Userdata%d VARCHAR(254) NOT NULL,", i);
476         res += param;
477         }
478
479     param = " CreditExpire INT(11) DEFAULT 0,";
480     res += param;
481
482     strprintf(&param, " IP VARCHAR(254) DEFAULT '*',");
483     res += param;
484
485     for (int i = 0; i < DIR_NUM; i++)
486         {
487         strprintf(&param, " D%d BIGINT(30) DEFAULT 0,", i);
488         res += param;
489
490         strprintf(&param, " U%d BIGINT(30) DEFAULT 0,", i);
491         res += param;
492         }
493
494     strprintf(&param, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
495         "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
496         "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
497         " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
498     res += param;
499
500     if(MysqlQuery(res.c_str(),sock))
501     {
502         errorStr = "Couldn't create users table list With error:\n";
503         errorStr += mysql_error(sock);
504         errorStr += "\n\n" + res;
505         mysql_close(sock);
506         return -1;
507     }
508
509     res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
510         "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
511         "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
512         "Phone='', RealName='',Tariff='tariff',TariffChange='',NAS='',";
513
514     for (int i = 0; i < USERDATA_NUM; i++)
515         {
516         strprintf(&param, " Userdata%d='',", i);
517         res += param;
518         }
519
520     for (int i = 0; i < DIR_NUM; i++)
521         {
522         strprintf(&param, " D%d=0,", i);
523         res += param;
524
525         strprintf(&param, " U%d=0,", i);
526         res += param;
527         }
528
529     res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
530         "LastCashAddTime=0, PassiveTime=0";
531
532     if(MysqlQuery(res.c_str(),sock))
533     {
534         errorStr = "Couldn't create default user. With error:\n";
535         errorStr += mysql_error(sock);
536         mysql_close(sock);
537         return -1;
538     }
539 }
540 /*
541 //logs-----------------------------------------------------------------------
542 if(!IsTablePresent("logs"))
543 {
544     sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
545
546     if(MysqlQuery(qbuf))
547     {
548         errorStr = "Couldn't create admin table list With error:\n";
549         errorStr += mysql_error(sock);
550         return -1;
551     }
552 }
553 */
554 //messages---------------------------------------------------------------------
555 if(!IsTablePresent("messages",sock))
556 {
557     sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
558             "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
559             "stgRepeat INT, repeatPeriod INT, text TEXT)");
560
561     if(MysqlQuery(qbuf,sock))
562     {
563         errorStr = "Couldn't create messages table. With error:\n";
564         errorStr += mysql_error(sock);
565         mysql_close(sock);
566         return -1;
567     }
568 }
569
570 //month_stat-------------------------------------------------------------------
571 if(!IsTablePresent("stat",sock))
572 {
573     res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
574
575     for (int i = 0; i < DIR_NUM; i++)
576         {
577         strprintf(&param, " U%d BIGINT,", i);
578         res += param;
579
580         strprintf(&param, " D%d BIGINT,", i);
581         res += param;
582         }
583
584     res += " cash DOUBLE, INDEX (login))";
585
586     if(MysqlQuery(res.c_str(),sock))
587     {
588         errorStr = "Couldn't create stat table. With error:\n";
589         errorStr += mysql_error(sock);
590         mysql_close(sock);
591         return -1;
592     }
593 }
594
595 return 0;
596 }
597 //-----------------------------------------------------------------------------
598 int MYSQL_STORE::MakeUpdates(MYSQL * sock)
599 {
600 if (schemaVersion  < 1)
601     {
602     if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
603         {
604         errorStr = "Couldn't update tariffs table to version 1. With error:\n";
605         errorStr += mysql_error(sock);
606         mysql_close(sock);
607         return -1;
608         }
609     if (MysqlQuery("UPDATE info SET version = 1", sock))
610         {
611         errorStr = "Couldn't update DB schema version to 1. With error:\n";
612         errorStr += mysql_error(sock);
613         mysql_close(sock);
614         return -1;
615         }
616     schemaVersion = 1;
617     logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
618     }
619
620 if (schemaVersion  < 2)
621     {
622     if (MysqlQuery("ALTER TABLE tariffs ADD change_policy VARCHAR(32) NOT NULL DEFAULT 'allow'", sock) ||
623         MysqlQuery("ALTER TABLE tariffs ADD change_policy_timeout TIMESTAMP NOT NULL DEFAULT 0", sock))
624         {
625         errorStr = "Couldn't update tariffs table to version 2. With error:\n";
626         errorStr += mysql_error(sock);
627         mysql_close(sock);
628         return -1;
629         }
630     if (MysqlQuery("UPDATE info SET version = 2", sock))
631         {
632         errorStr = "Couldn't update DB schema version to 2. With error:\n";
633         errorStr += mysql_error(sock);
634         mysql_close(sock);
635         return -1;
636         }
637     schemaVersion = 2;
638     logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
639     }
640 return 0;
641 }
642 //-----------------------------------------------------------------------------
643
644 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList,
645                             const std::string & table, const std::string & name) const
646 {
647 MYSQL_RES *res;
648 MYSQL_ROW row;
649 MYSQL * sock=NULL;
650 my_ulonglong num, i;
651
652 ParamList->clear();
653
654 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
655
656 if(MysqlGetQuery(qbuf,sock))
657 {
658     errorStr = "Couldn't GetAllParams Query for: ";
659     errorStr += name + " - " + table + "\n";
660     errorStr += mysql_error(sock);
661     mysql_close(sock);
662     return -1;
663 }
664
665 if (!(res=mysql_store_result(sock)))
666 {
667     errorStr = "Couldn't GetAllParams Results for: ";
668     errorStr += name + " - " + table + "\n";
669     errorStr += mysql_error(sock);
670     return -1;
671 }
672
673 num = mysql_num_rows(res);
674
675 for(i = 0; i < num; i++)
676 {
677     row = mysql_fetch_row(res);
678     ParamList->push_back(row[0]);
679 }
680
681 mysql_free_result(res);
682 mysql_close(sock);
683
684 return 0;
685 }
686
687 //-----------------------------------------------------------------------------
688 int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
689 {
690 if(GetAllParams(usersList, "users", "login"))
691     return -1;
692
693 return 0;
694 }
695 //-----------------------------------------------------------------------------
696 int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
697 {
698 if(GetAllParams(adminsList, "admins", "login"))
699     return -1;
700
701 return 0;
702 }
703 //-----------------------------------------------------------------------------
704 int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
705 {
706 if(GetAllParams(tariffsList, "tariffs", "name"))
707     return -1;
708
709 return 0;
710 }
711 //-----------------------------------------------------------------------------
712 int MYSQL_STORE::AddUser(const std::string & login) const
713 {
714 std::string query = "INSERT INTO users SET login='" + login + "',Note='',NAS=''";
715
716 for (int i = 0; i < USERDATA_NUM; i++)
717     query += ",Userdata" + x2str(i) + "=''";
718
719 if(MysqlSetQuery(query.c_str()))
720 {
721     errorStr = "Couldn't add user:\n";
722     //errorStr += mysql_error(sock);
723     return -1;
724 }
725
726 return 0;
727 }
728 //-----------------------------------------------------------------------------
729 int MYSQL_STORE::DelUser(const std::string & login) const
730 {
731 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
732
733 if(MysqlSetQuery(qbuf))
734 {
735     errorStr = "Couldn't delete user:\n";
736     //errorStr += mysql_error(sock);
737     return -1;
738 }
739
740 return 0;
741 }
742 //-----------------------------------------------------------------------------
743 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
744 {
745 MYSQL_RES *res;
746 MYSQL_ROW row;
747 MYSQL * sock;
748 std::string query;
749
750 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
751          AlwaysOnline, Tariff, Address, Phone, Email, Note, \
752          RealName, StgGroup, Credit, TariffChange, ";
753
754 for (int i = 0; i < USERDATA_NUM; i++)
755 {
756     sprintf(qbuf, "Userdata%d, ", i);
757     query += qbuf;
758 }
759
760 query += "CreditExpire, IP FROM users WHERE login='";
761 query += login + "' LIMIT 1";
762
763 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
764
765 if(MysqlGetQuery(query.c_str(),sock))
766 {
767     errorStr = "Couldn't restore Tariff(on query):\n";
768     errorStr += mysql_error(sock);
769     mysql_close(sock);
770     return -1;
771 }
772
773 if (!(res=mysql_store_result(sock)))
774 {
775     errorStr = "Couldn't restore Tariff(on getting result):\n";
776     errorStr += mysql_error(sock);
777     mysql_close(sock);
778     return -1;
779 }
780
781 if (mysql_num_rows(res) != 1)
782 {
783     errorStr = "User not found";
784     mysql_close(sock);
785     return -1;
786 }
787
788 row = mysql_fetch_row(res);
789
790 conf->password = row[1];
791
792 if (conf->password.empty())
793     {
794     mysql_free_result(res);
795     errorStr = "User \'" + login + "\' password is blank.";
796     mysql_close(sock);
797     return -1;
798     }
799
800 if (GetInt(row[2],&conf->passive) != 0)
801     {
802     mysql_free_result(res);
803     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
804     mysql_close(sock);
805     return -1;
806     }
807
808 if (GetInt(row[3], &conf->disabled) != 0)
809     {
810     mysql_free_result(res);
811     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
812     mysql_close(sock);
813     return -1;
814     }
815
816 if (GetInt(row[4], &conf->disabledDetailStat) != 0)
817     {
818     mysql_free_result(res);
819     errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
820     mysql_close(sock);
821     return -1;
822     }
823
824 if (GetInt(row[5], &conf->alwaysOnline) != 0)
825     {
826     mysql_free_result(res);
827     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
828     mysql_close(sock);
829     return -1;
830     }
831
832 conf->tariffName = row[6];
833
834 if (conf->tariffName.empty())
835     {
836     mysql_free_result(res);
837     errorStr = "User \'" + login + "\' tariff is blank.";
838     mysql_close(sock);
839     return -1;
840     }
841
842 conf->address = row[7];
843 conf->phone = row[8];
844 conf->email = row[9];
845 conf->note = row[10];
846 conf->realName = row[11];
847 conf->group = row[12];
848
849 if (GetDouble(row[13], &conf->credit, 0) != 0)
850     {
851     mysql_free_result(res);
852     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
853     mysql_close(sock);
854     return -1;
855     }
856
857 conf->nextTariff = row[14];
858
859 for (int i = 0; i < USERDATA_NUM; i++)
860     {
861     conf->userdata[i] = row[15+i];
862     }
863
864 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
865
866 std::string ipStr = row[16+USERDATA_NUM];
867 USER_IPS i;
868 try
869     {
870     i = StrToIPS(ipStr);
871     }
872 catch (const std::string & s)
873     {
874     mysql_free_result(res);
875     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
876     mysql_close(sock);
877     return -1;
878     }
879 conf->ips = i;
880
881 mysql_free_result(res);
882 mysql_close(sock);
883
884 return 0;
885 }
886 //-----------------------------------------------------------------------------
887 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
888 {
889 MYSQL_RES *res;
890 MYSQL_ROW row;
891 MYSQL * sock;
892
893 std::string query;
894
895 query = "SELECT ";
896
897 for (int i = 0; i < DIR_NUM; i++)
898 {
899     sprintf(qbuf, "D%d, U%d, ", i, i);
900     query += qbuf;
901 }
902
903 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
904           FROM users WHERE login = '";
905 query += login + "'";
906
907 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
908
909 if(MysqlGetQuery(query.c_str() ,sock))
910 {
911     errorStr = "Couldn't restore UserStat(on query):\n";
912     errorStr += mysql_error(sock);
913     mysql_close(sock);
914     return -1;
915 }
916
917 if (!(res=mysql_store_result(sock)))
918 {
919     errorStr = "Couldn't restore UserStat(on getting result):\n";
920     errorStr += mysql_error(sock);
921     mysql_close(sock);
922     return -1;
923 }
924
925 row = mysql_fetch_row(res);
926
927 unsigned int startPos=0;
928
929 char s[22];
930
931 for (int i = 0; i < DIR_NUM; i++)
932     {
933     uint64_t traff;
934     sprintf(s, "D%d", i);
935     if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
936         {
937         mysql_free_result(res);
938         errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
939         mysql_close(sock);
940         return -1;
941         }
942     stat->monthDown[i] = traff;
943
944     sprintf(s, "U%d", i);
945     if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
946         {
947         mysql_free_result(res);
948         errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
949         mysql_close(sock);
950         return -1;
951         }
952     stat->monthUp[i] = traff;
953     }//for
954
955 startPos += (2*DIR_NUM);
956
957 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
958     {
959     mysql_free_result(res);
960     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
961     mysql_close(sock);
962     return -1;
963     }
964
965 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
966     {
967     mysql_free_result(res);
968     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
969     mysql_close(sock);
970     return -1;
971     }
972
973 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
974     {
975     mysql_free_result(res);
976     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
977     mysql_close(sock);
978     return -1;
979     }
980
981 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
982     {
983     mysql_free_result(res);
984     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
985     mysql_close(sock);
986     return -1;
987     }
988
989 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
990     {
991     mysql_free_result(res);
992     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
993     mysql_close(sock);
994     return -1;
995     }
996
997 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
998     {
999     mysql_free_result(res);
1000     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
1001     mysql_close(sock);
1002     return -1;
1003     }
1004
1005 mysql_free_result(res);
1006 mysql_close(sock);
1007 return 0;
1008 }
1009 //-----------------------------------------------------------------------------
1010 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
1011 {
1012 std::string param;
1013 std::string res;
1014
1015 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
1016     "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
1017     "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ",
1018     conf.password.c_str(),
1019     conf.passive,
1020     conf.disabled,
1021     conf.disabledDetailStat,
1022     conf.alwaysOnline,
1023     conf.tariffName.c_str(),
1024     (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
1025     (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
1026     (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
1027     (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
1028     (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
1029     (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
1030     conf.credit,
1031     conf.nextTariff.c_str()
1032     );
1033
1034 for (int i = 0; i < USERDATA_NUM; i++)
1035     {
1036     strprintf(&param, " Userdata%d='%s',", i,
1037         (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
1038     res += param;
1039     }
1040
1041 strprintf(&param, " CreditExpire=%d,", conf.creditExpire);
1042 res += param;
1043
1044 std::ostringstream ipStr;
1045 ipStr << conf.ips;
1046
1047 strprintf(&param, " IP='%s'", ipStr.str().c_str());
1048 res += param;
1049
1050 strprintf(&param, " WHERE login='%s' LIMIT 1", login.c_str());
1051 res += param;
1052
1053 if(MysqlSetQuery(res.c_str()))
1054 {
1055     errorStr = "Couldn't save user conf:\n";
1056     //errorStr += mysql_error(sock);
1057     return -1;
1058 }
1059
1060 return 0;
1061 }
1062 //-----------------------------------------------------------------------------
1063 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
1064 {
1065 std::string param;
1066 std::string res;
1067
1068 res = "UPDATE users SET";
1069
1070 for (int i = 0; i < DIR_NUM; i++)
1071     {
1072     strprintf(&param, " D%d=%lld,", i, stat.monthDown[i]);
1073     res += param;
1074
1075     strprintf(&param, " U%d=%lld,", i, stat.monthUp[i]);
1076     res += param;
1077     }
1078
1079 strprintf(&param, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
1080     " PassiveTime=%d, LastActivityTime=%d",
1081     stat.cash,
1082     stat.freeMb,
1083     stat.lastCashAdd,
1084     stat.lastCashAddTime,
1085     stat.passiveTime,
1086     stat.lastActivityTime
1087     );
1088 res += param;
1089
1090 strprintf(&param, " WHERE login='%s' LIMIT 1", login.c_str());
1091 res += param;
1092
1093 if(MysqlSetQuery(res.c_str()))
1094 {
1095     errorStr = "Couldn't save user stat:\n";
1096 //    errorStr += mysql_error(sock);
1097     return -1;
1098 }
1099
1100 return 0;
1101 }
1102 //-----------------------------------------------------------------------------
1103 int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
1104 {
1105 std::string res, tempStr;
1106 time_t t;
1107 tm * lt;
1108
1109 t = time(NULL);
1110 lt = localtime(&t);
1111
1112 MYSQL_RES* result;
1113 MYSQL * sock;
1114 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1115 if (!(sock=MysqlConnect())){
1116     errorStr = "Couldn't connect to Server";
1117     return -1;
1118 }
1119 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1120 {
1121     errorStr = "Couldn't get table " + tempStr + ":\n";
1122     errorStr += mysql_error(sock);
1123     mysql_close(sock);
1124     return -1;
1125 }
1126
1127 my_ulonglong num_rows =  mysql_num_rows(result);
1128
1129 mysql_free_result(result);
1130
1131 if (num_rows < 1)
1132 {
1133     sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
1134     lt->tm_mon+1, lt->tm_year+1900);
1135
1136     if(MysqlQuery(qbuf,sock))
1137     {
1138         errorStr = "Couldn't create WriteDetailedStat table:\n";
1139         errorStr += mysql_error(sock);
1140         mysql_close(sock);
1141         return -1;
1142     }
1143 }
1144
1145 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
1146
1147 std::string send;
1148
1149 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
1150         lt->tm_mon+1, lt->tm_year+1900,
1151     login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
1152
1153 if(MysqlQuery(send.c_str(),sock))
1154 {
1155     errorStr = "Couldn't write log string:\n";
1156     errorStr += mysql_error(sock);
1157     mysql_close(sock);
1158     return -1;
1159 }
1160 mysql_close(sock);
1161 return 0;
1162
1163 }
1164 //-----------------------------------------------------------------------------
1165 int MYSQL_STORE::WriteUserChgLog(const std::string & login,
1166                                  const std::string & admLogin,
1167                                  uint32_t       admIP,
1168                                  const std::string & paramName,
1169                                  const std::string & oldValue,
1170                                  const std::string & newValue,
1171                                  const std::string & message) const
1172 {
1173 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
1174     + paramName + "\' parameter changed from \'" + oldValue +
1175     "\' to \'" + newValue + "\'. " + message;
1176
1177 return WriteLogString(userLogMsg, login);
1178 }
1179 //-----------------------------------------------------------------------------
1180 int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1181 {
1182 std::string logStr = "Connect, " + inet_ntostring(ip);
1183 return WriteLogString(logStr, login);
1184 }
1185 //-----------------------------------------------------------------------------
1186 int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
1187                                      const DIR_TRAFF & up,
1188                                      const DIR_TRAFF & down,
1189                                      const DIR_TRAFF & sessionUp,
1190                                      const DIR_TRAFF & sessionDown,
1191                                      double cash,
1192                                      double /*freeMb*/,
1193                                      const std::string & /*reason*/) const
1194 {
1195 std::string logStr = "Disconnect, ";
1196 std::ostringstream sssu;
1197 std::ostringstream sssd;
1198 std::ostringstream ssmu;
1199 std::ostringstream ssmd;
1200 std::ostringstream sscash;
1201
1202 ssmu << up;
1203 ssmd << down;
1204
1205 sssu << sessionUp;
1206 sssd << sessionDown;
1207
1208 sscash << cash;
1209
1210 logStr += " session upload: \'";
1211 logStr += sssu.str();
1212 logStr += "\' session download: \'";
1213 logStr += sssd.str();
1214 logStr += "\' month upload: \'";
1215 logStr += ssmu.str();
1216 logStr += "\' month download: \'";
1217 logStr += ssmd.str();
1218 logStr += "\' cash: \'";
1219 logStr += sscash.str();
1220 logStr += "\'";
1221
1222 return WriteLogString(logStr, login);
1223 }
1224 //-----------------------------------------------------------------------------
1225 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year,
1226                                 const std::string & login) const
1227 {
1228 std::string param, res;
1229
1230 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,",
1231     login.c_str(), month+1, year+1900);
1232
1233 for (int i = 0; i < DIR_NUM; i++)
1234     {
1235     strprintf(&param, " U%d=%lld,", i, stat.monthUp[i]);
1236     res += param;
1237
1238     strprintf(&param, " D%d=%lld,", i, stat.monthDown[i]);
1239     res += param;
1240     }
1241
1242 strprintf(&param, " cash=%f", stat.cash);
1243 res += param;
1244
1245 if(MysqlSetQuery(res.c_str()))
1246 {
1247     errorStr = "Couldn't SaveMonthStat:\n";
1248     //errorStr += mysql_error(sock);
1249     return -1;
1250 }
1251
1252 return 0;
1253 }
1254 //-----------------------------------------------------------------------------*/
1255 int MYSQL_STORE::AddAdmin(const std::string & login) const
1256 {
1257 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
1258
1259 if(MysqlSetQuery(qbuf))
1260 {
1261     errorStr = "Couldn't add admin:\n";
1262     //errorStr += mysql_error(sock);
1263     return -1;
1264 }
1265
1266 return 0;
1267 }
1268 //-----------------------------------------------------------------------------*/
1269 int MYSQL_STORE::DelAdmin(const std::string & login) const
1270 {
1271 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
1272
1273 if(MysqlSetQuery(qbuf))
1274 {
1275     errorStr = "Couldn't delete admin:\n";
1276     //errorStr += mysql_error(sock);
1277     return -1;
1278 }
1279
1280 return 0;
1281 }
1282 //-----------------------------------------------------------------------------*/
1283 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
1284 {
1285 char passwordE[2 * ADM_PASSWD_LEN + 2];
1286 char pass[ADM_PASSWD_LEN + 1];
1287 char adminPass[ADM_PASSWD_LEN + 1];
1288
1289 memset(pass, 0, sizeof(pass));
1290 memset(adminPass, 0, sizeof(adminPass));
1291
1292 BLOWFISH_CTX ctx;
1293 InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1294
1295 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1296 adminPass[ADM_PASSWD_LEN - 1] = 0;
1297
1298 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1299     {
1300     EncryptBlock(pass + 8*i, adminPass + 8*i, &ctx);
1301     }
1302
1303 pass[ADM_PASSWD_LEN - 1] = 0;
1304 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1305
1306 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
1307     "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
1308     "WHERE login='%s' LIMIT 1",
1309     passwordE,
1310     ac.priv.userConf,
1311     ac.priv.userPasswd,
1312     ac.priv.userStat,
1313     ac.priv.userCash,
1314     ac.priv.userAddDel,
1315     ac.priv.tariffChg,
1316     ac.priv.adminChg,
1317     ac.login.c_str()
1318     );
1319
1320 if(MysqlSetQuery(qbuf))
1321 {
1322     errorStr = "Couldn't save admin:\n";
1323     //errorStr += mysql_error(sock);
1324     return -1;
1325 }
1326
1327 return 0;
1328 }
1329 //-----------------------------------------------------------------------------
1330 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
1331 {
1332 char pass[ADM_PASSWD_LEN + 1];
1333 char password[ADM_PASSWD_LEN + 1];
1334 char passwordE[2*ADM_PASSWD_LEN + 2];
1335 BLOWFISH_CTX ctx;
1336
1337 memset(password, 0, sizeof(password));
1338
1339 std::string p;
1340 MYSQL_RES *res;
1341 MYSQL_ROW row;
1342 MYSQL * sock;
1343 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
1344
1345 if(MysqlGetQuery(qbuf,sock))
1346 {
1347     errorStr = "Couldn't restore admin:\n";
1348     errorStr += mysql_error(sock);
1349     mysql_close(sock);
1350     return -1;
1351 }
1352
1353 if (!(res=mysql_store_result(sock)))
1354 {
1355     errorStr = "Couldn't restore admin:\n";
1356     errorStr += mysql_error(sock);
1357     mysql_close(sock);
1358     return -1;
1359 }
1360
1361 if ( mysql_num_rows(res) == 0)
1362 {
1363     mysql_free_result(res);
1364     errorStr = "Couldn't restore admin as couldn't found him in table.\n";
1365     mysql_close(sock);
1366     return -1;
1367 }
1368
1369 row = mysql_fetch_row(res);
1370
1371 p = row[1];
1372
1373 if(p.length() == 0)
1374 {
1375     mysql_free_result(res);
1376     errorStr = "Error in parameter password";
1377     mysql_close(sock);
1378     return -1;
1379 }
1380
1381 memset(passwordE, 0, sizeof(passwordE));
1382 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1383
1384 memset(pass, 0, sizeof(pass));
1385
1386 if (passwordE[0] != 0)
1387     {
1388     Decode21(pass, passwordE);
1389     InitContext(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1390
1391     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1392         {
1393         DecryptBlock(password + 8*i, pass + 8*i, &ctx);
1394         }
1395     }
1396 else
1397     {
1398     password[0] = 0;
1399     }
1400
1401 ac->password = password;
1402
1403 uint16_t a;
1404
1405 if (GetInt(row[2], &a) == 0)
1406     ac->priv.userConf = a;
1407 else
1408     {
1409     mysql_free_result(res);
1410     errorStr = "Error in parameter ChgConf";
1411     mysql_close(sock);
1412     return -1;
1413     }
1414
1415 if (GetInt(row[3], &a) == 0)
1416     ac->priv.userPasswd = a;
1417 else
1418     {
1419     mysql_free_result(res);
1420     errorStr = "Error in parameter ChgPassword";
1421     mysql_close(sock);
1422     return -1;
1423     }
1424
1425 if (GetInt(row[4], &a) == 0)
1426     ac->priv.userStat = a;
1427 else
1428     {
1429     mysql_free_result(res);
1430     errorStr = "Error in parameter ChgStat";
1431     mysql_close(sock);
1432     return -1;
1433     }
1434
1435 if (GetInt(row[5], &a) == 0)
1436     ac->priv.userCash = a;
1437 else
1438     {
1439     mysql_free_result(res);
1440     errorStr = "Error in parameter ChgCash";
1441     mysql_close(sock);
1442     return -1;
1443     }
1444
1445 if (GetInt(row[6], &a) == 0)
1446     ac->priv.userAddDel = a;
1447 else
1448     {
1449     mysql_free_result(res);
1450     errorStr = "Error in parameter UsrAddDel";
1451     mysql_close(sock);
1452     return -1;
1453     }
1454
1455 if (GetInt(row[7], &a) == 0)
1456     ac->priv.tariffChg = a;
1457 else
1458     {
1459     mysql_free_result(res);
1460     errorStr = "Error in parameter ChgTariff";
1461     mysql_close(sock);
1462     return -1;
1463     }
1464
1465 if (GetInt(row[8], &a) == 0)
1466     ac->priv.adminChg = a;
1467 else
1468     {
1469     mysql_free_result(res);
1470     errorStr = "Error in parameter ChgAdmin";
1471     mysql_close(sock);
1472     return -1;
1473     }
1474
1475 mysql_free_result(res);
1476 mysql_close(sock);
1477 return 0;
1478 }
1479 //-----------------------------------------------------------------------------
1480 int MYSQL_STORE::AddTariff(const std::string & name) const
1481 {
1482 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
1483
1484 if(MysqlSetQuery(qbuf))
1485 {
1486     errorStr = "Couldn't add tariff:\n";
1487 //    errorStr += mysql_error(sock);
1488     return -1;
1489 }
1490
1491 return 0;
1492 }
1493 //-----------------------------------------------------------------------------
1494 int MYSQL_STORE::DelTariff(const std::string & name) const
1495 {
1496 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
1497
1498 if(MysqlSetQuery(qbuf))
1499 {
1500     errorStr = "Couldn't delete tariff: ";
1501 //    errorStr += mysql_error(sock);
1502     return -1;
1503 }
1504
1505 return 0;
1506 }
1507 //-----------------------------------------------------------------------------
1508 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
1509 {
1510 MYSQL_RES *res;
1511 MYSQL_ROW row;
1512 MYSQL * sock;
1513 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
1514
1515 if(MysqlGetQuery(qbuf,sock))
1516 {
1517     errorStr = "Couldn't restore Tariff:\n";
1518     errorStr += mysql_error(sock);
1519     mysql_close(sock);
1520     return -1;
1521 }
1522
1523 if (!(res=mysql_store_result(sock)))
1524 {
1525     errorStr = "Couldn't restore Tariff:\n";
1526     errorStr += mysql_error(sock);
1527     mysql_close(sock);
1528     return -1;
1529 }
1530
1531 std::string str;
1532 td->tariffConf.name = tariffName;
1533
1534 row = mysql_fetch_row(res);
1535
1536 std::string param;
1537 for (int i = 0; i<DIR_NUM; i++)
1538     {
1539     strprintf(&param, "Time%d", i);
1540     str = row[6+i*8];
1541     if (str.length() == 0)
1542         {
1543         mysql_free_result(res);
1544         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1545         mysql_close(sock);
1546         return -1;
1547         }
1548
1549     ParseTariffTimeStr(str.c_str(),
1550                        td->dirPrice[i].hDay,
1551                        td->dirPrice[i].mDay,
1552                        td->dirPrice[i].hNight,
1553                        td->dirPrice[i].mNight);
1554
1555     strprintf(&param, "PriceDayA%d", i);
1556     if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
1557         {
1558         mysql_free_result(res);
1559         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1560         mysql_close(sock);
1561         return -1;
1562         }
1563     td->dirPrice[i].priceDayA /= (1024*1024);
1564
1565     strprintf(&param, "PriceDayB%d", i);
1566     if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
1567         {
1568         mysql_free_result(res);
1569         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1570         mysql_close(sock);
1571         return -1;
1572         }
1573     td->dirPrice[i].priceDayB /= (1024*1024);
1574
1575     strprintf(&param, "PriceNightA%d", i);
1576     if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
1577         {
1578         mysql_free_result(res);
1579         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1580         mysql_close(sock);
1581         return -1;
1582         }
1583     td->dirPrice[i].priceNightA /= (1024*1024);
1584
1585     strprintf(&param, "PriceNightB%d", i);
1586     if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
1587         {
1588         mysql_free_result(res);
1589         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1590         mysql_close(sock);
1591         return -1;
1592         }
1593     td->dirPrice[i].priceNightB /= (1024*1024);
1594
1595     strprintf(&param, "Threshold%d", i);
1596     if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
1597         {
1598         mysql_free_result(res);
1599         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1600         mysql_close(sock);
1601         return -1;
1602         }
1603
1604     strprintf(&param, "SinglePrice%d", i);
1605     if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
1606         {
1607         mysql_free_result(res);
1608         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1609         mysql_close(sock);
1610         return -1;
1611         }
1612
1613     strprintf(&param, "NoDiscount%d", i);
1614     if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
1615         {
1616         mysql_free_result(res);
1617         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1618         mysql_close(sock);
1619         return -1;
1620         }
1621     }//main for
1622
1623 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
1624     {
1625     mysql_free_result(res);
1626     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1627     mysql_close(sock);
1628     return -1;
1629     }
1630
1631 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
1632     {
1633     mysql_free_result(res);
1634     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1635     mysql_close(sock);
1636     return -1;
1637     }
1638
1639 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
1640     {
1641     mysql_free_result(res);
1642     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1643     mysql_close(sock);
1644     return -1;
1645     }
1646
1647     str = row[4+8*DIR_NUM];
1648     param = "TraffType";
1649
1650     if (str.length() == 0)
1651         {
1652         mysql_free_result(res);
1653         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1654         mysql_close(sock);
1655         return -1;
1656         }
1657
1658 td->tariffConf.traffType = TARIFF::StringToTraffType(str);
1659
1660 if (schemaVersion > 0)
1661 {
1662     str = row[5+8*DIR_NUM];
1663     param = "Period";
1664
1665     if (str.length() == 0)
1666         {
1667         mysql_free_result(res);
1668         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1669         mysql_close(sock);
1670         return -1;
1671         }
1672
1673     td->tariffConf.period = TARIFF::StringToPeriod(str);
1674     }
1675 else
1676     {
1677     td->tariffConf.period = TARIFF::MONTH;
1678     }
1679
1680 if (schemaVersion > 1)
1681     {
1682     str = row[6+8*DIR_NUM];
1683     param = "ChangePolicy";
1684
1685     if (str.length() == 0)
1686         {
1687         mysql_free_result(res);
1688         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1689         mysql_close(sock);
1690         return -1;
1691         }
1692
1693     td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
1694
1695     str = row[7+8*DIR_NUM];
1696     param = "ChangePolicyTimeout";
1697
1698     if (str.length() == 0)
1699         {
1700         mysql_free_result(res);
1701         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1702         mysql_close(sock);
1703         return -1;
1704         }
1705
1706     td->tariffConf.changePolicyTimeout = readTime(str);
1707     }
1708 else
1709     {
1710     td->tariffConf.changePolicy = TARIFF::ALLOW;
1711     td->tariffConf.changePolicyTimeout = 0;
1712     }
1713
1714 mysql_free_result(res);
1715 mysql_close(sock);
1716 return 0;
1717 }
1718 //-----------------------------------------------------------------------------
1719 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
1720 {
1721 std::string param;
1722
1723 std::string res="UPDATE tariffs SET";
1724
1725 for (int i = 0; i < DIR_NUM; i++)
1726     {
1727     strprintf(&param, " PriceDayA%d=%f,", i,
1728         td.dirPrice[i].priceDayA * pt_mega);
1729     res += param;
1730
1731     strprintf(&param, " PriceDayB%d=%f,", i,
1732         td.dirPrice[i].priceDayB * pt_mega);
1733     res += param;
1734
1735     strprintf(&param, " PriceNightA%d=%f,", i,
1736         td.dirPrice[i].priceNightA * pt_mega);
1737     res += param;
1738
1739     strprintf(&param, " PriceNightB%d=%f,", i,
1740         td.dirPrice[i].priceNightB * pt_mega);
1741     res += param;
1742
1743     strprintf(&param, " Threshold%d=%d,", i,
1744         td.dirPrice[i].threshold);
1745     res += param;
1746
1747     std::string s;
1748     strprintf(&param, " Time%d", i);
1749
1750     strprintf(&s, "%0d:%0d-%0d:%0d",
1751             td.dirPrice[i].hDay,
1752             td.dirPrice[i].mDay,
1753             td.dirPrice[i].hNight,
1754             td.dirPrice[i].mNight);
1755
1756     res += (param + "='" + s + "',");
1757
1758     strprintf(&param, " NoDiscount%d=%d,", i,
1759         td.dirPrice[i].noDiscount);
1760     res += param;
1761
1762     strprintf(&param, " SinglePrice%d=%d,", i,
1763         td.dirPrice[i].singlePrice);
1764     res += param;
1765     }
1766
1767 strprintf(&param, " PassiveCost=%f,", td.tariffConf.passiveCost);
1768 res += param;
1769
1770 strprintf(&param, " Fee=%f,", td.tariffConf.fee);
1771 res += param;
1772
1773 strprintf(&param, " Free=%f,", td.tariffConf.free);
1774 res += param;
1775
1776 res += " TraffType='" + TARIFF::TraffTypeToString(td.tariffConf.traffType) + "'";
1777
1778 if (schemaVersion > 0)
1779     res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
1780
1781 if (schemaVersion > 1)
1782     res += ", change_policy='" + TARIFF::ChangePolicyToString(td.tariffConf.changePolicy) + "'"\
1783            ", change_policy_timeout='" + formatTime(td.tariffConf.changePolicy) + "'";
1784
1785 strprintf(&param, " WHERE name='%s' LIMIT 1", tariffName.c_str());
1786 res += param;
1787
1788 if(MysqlSetQuery(res.c_str()))
1789 {
1790     errorStr = "Couldn't save tariff:\n";
1791     //errorStr += mysql_error(sock);
1792     return -1;
1793 }
1794
1795 return 0;
1796 }
1797 //-----------------------------------------------------------------------------
1798 int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
1799                                    time_t lastStat,
1800                                    const std::string & login) const
1801 {
1802 std::string res, stTime, endTime, tempStr;
1803 time_t t;
1804 tm * lt;
1805
1806 t = time(NULL);
1807 lt = localtime(&t);
1808
1809 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1810     {
1811         t -= 3600 * 24;
1812         lt = localtime(&t);
1813     }
1814
1815 MYSQL_RES* result;
1816 MYSQL * sock;
1817 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1818
1819 if (!(sock=MysqlConnect())){
1820     mysql_close(sock);
1821     return -1;
1822 }
1823
1824 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1825 {
1826     errorStr = "Couldn't get table " + tempStr + ":\n";
1827     errorStr += mysql_error(sock);
1828     mysql_close(sock);
1829     return -1;
1830 }
1831
1832 my_ulonglong num_rows =  mysql_num_rows(result);
1833
1834 mysql_free_result(result);
1835
1836 if (num_rows < 1)
1837 {
1838     sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
1839         "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
1840         "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
1841         "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
1842     lt->tm_mon+1, lt->tm_year+1900);
1843
1844     if(MysqlQuery(qbuf,sock))
1845     {
1846         errorStr = "Couldn't create WriteDetailedStat table:\n";
1847         errorStr += mysql_error(sock);
1848         mysql_close(sock);
1849         return -1;
1850     }
1851 }
1852
1853 struct tm * lt1;
1854 struct tm * lt2;
1855
1856 lt1 = localtime(&lastStat);
1857
1858 int h1, m1, s1;
1859 int h2, m2, s2;
1860
1861 h1 = lt1->tm_hour;
1862 m1 = lt1->tm_min;
1863 s1 = lt1->tm_sec;
1864
1865 lt2 = localtime(&t);
1866
1867 h2 = lt2->tm_hour;
1868 m2 = lt2->tm_min;
1869 s2 = lt2->tm_sec;
1870
1871 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
1872 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
1873
1874 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
1875     "day=%d,startTime='%s',endTime='%s',",
1876     lt->tm_mon+1, lt->tm_year+1900,
1877     login.c_str(),
1878     lt->tm_mday,
1879     stTime.c_str(),
1880     endTime.c_str()
1881     );
1882
1883 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
1884 stIter = statTree.begin();
1885
1886 while (stIter != statTree.end())
1887     {
1888         strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f",
1889                 inet_ntostring(stIter->first.ip).c_str(),
1890                 stIter->first.dir,
1891                 stIter->second.down,
1892                 stIter->second.up,
1893                 stIter->second.cash
1894             );
1895
1896         if( MysqlQuery((res+tempStr).c_str(),sock) )
1897         {
1898             errorStr = "Couldn't insert data in WriteDetailedStat:\n";
1899             errorStr += mysql_error(sock);
1900             mysql_close(sock);
1901             return -1;
1902         }
1903
1904         result=mysql_store_result(sock);
1905         if(result)
1906             mysql_free_result(result);
1907
1908         ++stIter;
1909     }
1910 mysql_close(sock);
1911 return 0;
1912 }
1913 //-----------------------------------------------------------------------------
1914 int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
1915 {
1916 struct timeval tv;
1917
1918 gettimeofday(&tv, NULL);
1919
1920 msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
1921
1922 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld",
1923     login.c_str(),
1924     static_cast<long long>(msg->header.id)
1925     );
1926
1927 if(MysqlSetQuery(qbuf))
1928 {
1929     errorStr = "Couldn't add message:\n";
1930     //errorStr += mysql_error(sock);
1931     return -1;
1932 }
1933
1934 return EditMessage(*msg, login);
1935 }
1936 //-----------------------------------------------------------------------------
1937 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
1938 {
1939 std::string res;
1940
1941 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
1942     "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
1943     "WHERE login='%s' AND id=%lld LIMIT 1",
1944     msg.header.type,
1945     msg.header.lastSendTime,
1946     msg.header.creationTime,
1947     msg.header.showTime,
1948     msg.header.repeat,
1949     msg.header.repeatPeriod,
1950     (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
1951     login.c_str(),
1952     msg.header.id
1953     );
1954
1955 if(MysqlSetQuery(res.c_str()))
1956 {
1957     errorStr = "Couldn't edit message:\n";
1958     //errorStr += mysql_error(sock);
1959     return -1;
1960 }
1961
1962 return 0;
1963 }
1964 //-----------------------------------------------------------------------------
1965 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
1966 {
1967 MYSQL_RES *res;
1968 MYSQL_ROW row;
1969 MYSQL * sock;
1970
1971 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
1972         login.c_str(), static_cast<unsigned long long>(id));
1973
1974 if(MysqlGetQuery(qbuf,sock))
1975 {
1976     errorStr = "Couldn't GetMessage:\n";
1977     errorStr += mysql_error(sock);
1978     mysql_close(sock);
1979     return -1;
1980 }
1981
1982 if (!(res=mysql_store_result(sock)))
1983 {
1984     errorStr = "Couldn't GetMessage:\n";
1985     errorStr += mysql_error(sock);
1986     mysql_close(sock);
1987     return -1;
1988 }
1989
1990 row = mysql_fetch_row(res);
1991
1992 if(row[2]&&str2x(row[2], msg->header.type))
1993 {
1994     mysql_free_result(res);
1995     errorStr = "Invalid value in message header for user: " + login;
1996     mysql_close(sock);
1997     return -1;
1998 }
1999
2000 if(row[3] && str2x(row[3], msg->header.lastSendTime))
2001 {
2002     mysql_free_result(res);
2003     errorStr = "Invalid value in message header for user: " + login;
2004     mysql_close(sock);
2005     return -1;
2006 }
2007
2008 if(row[4] && str2x(row[4], msg->header.creationTime))
2009 {
2010     mysql_free_result(res);
2011     errorStr = "Invalid value in message header for user: " + login;
2012     mysql_close(sock);
2013     return -1;
2014 }
2015
2016 if(row[5] && str2x(row[5], msg->header.showTime))
2017 {
2018     mysql_free_result(res);
2019     errorStr = "Invalid value in message header for user: " + login;
2020     mysql_close(sock);
2021     return -1;
2022 }
2023
2024 if(row[6] && str2x(row[6], msg->header.repeat))
2025 {
2026     mysql_free_result(res);
2027     errorStr = "Invalid value in message header for user: " + login;
2028     mysql_close(sock);
2029     return -1;
2030 }
2031
2032 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
2033 {
2034     mysql_free_result(res);
2035     errorStr = "Invalid value in message header for user: " + login;
2036     mysql_close(sock);
2037     return -1;
2038 }
2039
2040 msg->header.id = id;
2041 msg->text = row[8];
2042
2043 mysql_free_result(res);
2044 mysql_close(sock);
2045 return 0;
2046 }
2047 //-----------------------------------------------------------------------------
2048 int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
2049 {
2050 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
2051         login.c_str(), static_cast<long long>(id));
2052
2053 if(MysqlSetQuery(qbuf))
2054 {
2055     errorStr = "Couldn't delete Message:\n";
2056     //errorStr += mysql_error(sock);
2057     return -1;
2058 }
2059
2060 return 0;
2061 }
2062 //-----------------------------------------------------------------------------
2063 int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
2064 {
2065 MYSQL_RES *res;
2066 MYSQL_ROW row;
2067 MYSQL * sock;
2068 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
2069
2070 if(MysqlGetQuery(qbuf,sock))
2071 {
2072     errorStr = "Couldn't GetMessageHdrs:\n";
2073     errorStr += mysql_error(sock);
2074     mysql_close(sock);
2075     return -1;
2076 }
2077
2078 if (!(res=mysql_store_result(sock)))
2079 {
2080     errorStr = "Couldn't GetMessageHdrs:\n";
2081     errorStr += mysql_error(sock);
2082     mysql_close(sock);
2083     return -1;
2084 }
2085
2086 unsigned int i;
2087 my_ulonglong num_rows = mysql_num_rows(res);
2088 uint64_t id = 0;
2089
2090 for (i = 0; i < num_rows; i++)
2091 {
2092     row = mysql_fetch_row(res);
2093     if (str2x(row[1], id))
2094         continue;
2095
2096     STG_MSG_HDR hdr;
2097     if (row[2])
2098         if(str2x(row[2], hdr.type))
2099             continue;
2100
2101     if (row[3])
2102         if(str2x(row[3], hdr.lastSendTime))
2103             continue;
2104
2105     if (row[4])
2106         if(str2x(row[4], hdr.creationTime))
2107             continue;
2108
2109     if (row[5])
2110         if(str2x(row[5], hdr.showTime))
2111             continue;
2112
2113     if (row[6])
2114         if(str2x(row[6], hdr.repeat))
2115             continue;
2116
2117     if (row[7])
2118         if(str2x(row[7], hdr.repeatPeriod))
2119             continue;
2120
2121     hdr.id = id;
2122     hdrsList->push_back(hdr);
2123 }
2124
2125 mysql_free_result(res);
2126 mysql_close(sock);
2127 return 0;
2128 }
2129 //-----------------------------------------------------------------------------
2130
2131 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
2132
2133     MYSQL * sock;
2134     int ret=MysqlGetQuery(Query,sock);
2135     mysql_close(sock);
2136     return ret;
2137 }
2138 //-----------------------------------------------------------------------------
2139 int  MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
2140     if (!(sock=MysqlConnect())) {
2141         return -1;
2142     }
2143     return   MysqlQuery(Query,sock);
2144 }
2145 //-----------------------------------------------------------------------------
2146 MYSQL *  MYSQL_STORE::MysqlConnect() const {
2147     MYSQL * sock;
2148     if ( !(sock=mysql_init(NULL)) ){
2149         errorStr= "mysql init susck\n";
2150         return NULL;
2151     }
2152     if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
2153             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
2154             0,storeSettings.GetDBPort(),NULL,0)))
2155         {
2156             errorStr = "Couldn't connect to mysql engine! With error:\n";
2157             errorStr += mysql_error(sock);
2158             return NULL;
2159         }
2160     else{
2161          if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
2162              errorStr = "Database lost !\n";
2163              return NULL;
2164          }
2165     }
2166     return sock;
2167 }
2168 //-----------------------------------------------------------------------------