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