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