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