2  *    This program is free software; you can redistribute it and/or modify
 
   3  *    it under the terms of the GNU General Public License as published by
 
   4  *    the Free Software Foundation; either version 2 of the License, or
 
   5  *    (at your option) any later version.
 
   7  *    This program is distributed in the hope that it will be useful,
 
   8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  10  *    GNU General Public License for more details.
 
  12  *    You should have received a copy of the GNU General Public License
 
  13  *    along with this program; if not, write to the Free Software
 
  14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
  18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
 
  22  *  User manipulation methods
 
  25  *  $Date: 2010/05/07 07:26:36 $
 
  36 #include "stg/stg_const.h"
 
  37 #include "stg/stg_locker.h"
 
  38 #include "../../../stg_timer.h"
 
  39 #include "postgresql_store.h"
 
  41 //-----------------------------------------------------------------------------
 
  42 int POSTGRESQL_STORE::GetUsersList(vector<string> * usersList) const
 
  44 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
  46 if (PQstatus(connection) != CONNECTION_OK)
 
  48     printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
  51         strError = "Connection lost";
 
  52         printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
 
  59 if (StartTransaction())
 
  61     printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to start transaction'\n");
 
  65 result = PQexec(connection, "SELECT name FROM tb_users");
 
  67 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
  69     strError = PQresultErrorMessage(result);
 
  71     printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
 
  72     if (RollbackTransaction())
 
  74         printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to rollback transaction'\n");
 
  79 int tuples = PQntuples(result);
 
  81 for (int i = 0; i < tuples; ++i)
 
  83     usersList->push_back(PQgetvalue(result, i, 0));
 
  88 if (CommitTransaction())
 
  90     printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to commit transaction'\n");
 
  97 //-----------------------------------------------------------------------------
 
  98 int POSTGRESQL_STORE::AddUser(const string & name) const
 
 100 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 102 if (PQstatus(connection) != CONNECTION_OK)
 
 104     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 107         strError = "Connection lost";
 
 108         printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
 
 115 if (StartTransaction())
 
 117     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to start transaction'\n");
 
 121 std::string elogin = name;
 
 123 if (EscapeString(elogin))
 
 125     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to escape login'\n");
 
 126     if (RollbackTransaction())
 
 128         printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
 
 133 std::stringstream query;
 
 134 query << "SELECT sp_add_user('" << elogin << "')";
 
 136 result = PQexec(connection, query.str().c_str());
 
 138 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 140     strError = PQresultErrorMessage(result);
 
 142     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
 
 143     if (RollbackTransaction())
 
 145         printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
 
 152 if (CommitTransaction())
 
 154     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to commit transaction'\n");
 
 161 //-----------------------------------------------------------------------------
 
 162 int POSTGRESQL_STORE::DelUser(const string & login) const
 
 164 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 166 if (PQstatus(connection) != CONNECTION_OK)
 
 168     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 171         strError = "Connection lost";
 
 172         printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
 
 179 if (StartTransaction())
 
 181     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to start transaction'\n");
 
 185 std::string elogin = login;
 
 187 if (EscapeString(elogin))
 
 189     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to escape login'\n");
 
 190     if (RollbackTransaction())
 
 192         printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
 
 197 std::stringstream query;
 
 198 query << "DELETE FROM tb_users WHERE name = '" << elogin << "'";
 
 200 result = PQexec(connection, query.str().c_str());
 
 202 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 204     strError = PQresultErrorMessage(result);
 
 206     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
 
 207     if (RollbackTransaction())
 
 209         printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
 
 216 if (CommitTransaction())
 
 218     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to commit transaction'\n");
 
 224 //-----------------------------------------------------------------------------
 
 225 int POSTGRESQL_STORE::SaveUserStat(const USER_STAT & stat,
 
 226                                    const string & login) const
 
 228 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 230 return SaveStat(stat, login);
 
 232 //-----------------------------------------------------------------------------
 
 233 int POSTGRESQL_STORE::SaveStat(const USER_STAT & stat,
 
 234                                const string & login,
 
 238 if (PQstatus(connection) != CONNECTION_OK)
 
 240     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 243         strError = "Connection lost";
 
 244         printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
 
 251 if (StartTransaction())
 
 253     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to start transaction'\n");
 
 257 std::string elogin = login;
 
 259 if (EscapeString(elogin))
 
 261     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to escape login'\n");
 
 262     if (RollbackTransaction())
 
 264         printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
 
 269 std::stringstream query;
 
 270 query << "UPDATE tb_users SET "
 
 271             "cash = " << stat.cash << ", "
 
 272             "free_mb = " << stat.freeMb << ", "
 
 273             "last_activity_time = CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), "
 
 274             "last_cash_add = " << stat.lastCashAdd << ", "
 
 275             "last_cash_add_time = CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), "
 
 276             "passive_time = " << stat.passiveTime << " "
 
 277          "WHERE name = '" << elogin << "'";
 
 279 result = PQexec(connection, query.str().c_str());
 
 281 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 283     strError = PQresultErrorMessage(result);
 
 285     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
 
 286     if (RollbackTransaction())
 
 288         printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
 
 297 MakeDate(date, year, month);
 
 299 for (int dir = 0; dir < DIR_NUM; ++dir)
 
 302     query << "SELECT sp_add_stats_traffic ("
 
 303                 "'" << elogin << "', "
 
 304                 "CAST('" << date << "' AS DATE), "
 
 305                 "CAST(" << dir << " AS SMALLINT), "
 
 306                 "CAST(" << stat.up[dir] << " AS BIGINT), "
 
 307                 "CAST(" << stat.down[dir] << " AS BIGINT))";
 
 309     result = PQexec(connection, query.str().c_str());
 
 311     if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 313         strError = PQresultErrorMessage(result);
 
 315         printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
 
 316         if (RollbackTransaction())
 
 318             printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
 
 326 if (CommitTransaction())
 
 328     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to commit transaction'\n");
 
 335 //-----------------------------------------------------------------------------
 
 336 int POSTGRESQL_STORE::SaveUserConf(const USER_CONF & conf,
 
 337                                  const string & login) const
 
 339 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 341 if (PQstatus(connection) != CONNECTION_OK)
 
 343     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 346         strError = "Connection lost";
 
 347         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
 
 354 if (StartTransaction())
 
 356     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to start transaction'\n");
 
 360 std::string elogin = login;
 
 362 if (EscapeString(elogin))
 
 364     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape login'\n");
 
 365     if (RollbackTransaction())
 
 367         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 372 std::stringstream query;
 
 373 query << "SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'";
 
 375 result = PQexec(connection, query.str().c_str());
 
 377 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 379     strError = PQresultErrorMessage(result);
 
 381     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
 
 382     if (RollbackTransaction())
 
 384         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 389 int tuples = PQntuples(result);
 
 393     strError = "Failed to fetch user's ID";
 
 394     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
 396     if (RollbackTransaction())
 
 398         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 403 std::stringstream tuple;
 
 404 tuple << PQgetvalue(result, 0, 0);
 
 412 std::string eaddress = conf.address;
 
 413 std::string eemail = conf.email;
 
 414 std::string egroup = conf.group;
 
 415 std::string enote = conf.note;
 
 416 std::string epassword = conf.password;
 
 417 std::string ephone = conf.phone;
 
 418 std::string erealname = conf.realName;
 
 419 std::string etariffname = conf.tariffName;
 
 420 std::string enexttariff = conf.nextTariff;
 
 421 std::string ecorporation = conf.corp;
 
 423 if (EscapeString(eaddress))
 
 425     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
 
 426     if (RollbackTransaction())
 
 428         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 433 if (EscapeString(eemail))
 
 435     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
 
 436     if (RollbackTransaction())
 
 438         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 443 if (EscapeString(egroup))
 
 445     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
 
 446     if (RollbackTransaction())
 
 448         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 453 if (EscapeString(enote))
 
 455     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
 
 456     if (RollbackTransaction())
 
 458         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 463 if (EscapeString(epassword))
 
 465     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
 
 466     if (RollbackTransaction())
 
 468         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 473 if (EscapeString(ephone))
 
 475     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
 
 476     if (RollbackTransaction())
 
 478         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 483 if (EscapeString(erealname))
 
 485     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
 
 486     if (RollbackTransaction())
 
 488         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 493 if (EscapeString(etariffname))
 
 495     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
 
 496     if (RollbackTransaction())
 
 498         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 503 if (EscapeString(enexttariff))
 
 505     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
 
 506     if (RollbackTransaction())
 
 508         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 513 if (EscapeString(ecorporation))
 
 515     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
 
 516     if (RollbackTransaction())
 
 518         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 524 query << "UPDATE tb_users SET "
 
 525              "address = '" << eaddress << "', "
 
 526              "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
 
 527              "credit = " << conf.credit << ", "
 
 528              "credit_expire = CAST('" << Int2TS(conf.creditExpire) << "' AS TIMESTAMP), "
 
 529              "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
 
 530              "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
 
 531              "email = '" << eemail << "', "
 
 532              "grp = '" << egroup << "', "
 
 533              "note = '" << enote << "', "
 
 534              "passive = " << (conf.passive ? "'t'" : "'f'") << ", "
 
 535              "passwd = '" << epassword << "', "
 
 536              "phone = '" << ephone << "', "
 
 537              "real_name = '" << erealname << "', "
 
 538              "fk_tariff = (SELECT pk_tariff "
 
 540                    "WHERE name = '" << etariffname << "'), "
 
 541              "fk_tariff_change = (SELECT pk_tariff "
 
 543                    "WHERE name = '" << enexttariff << "'), "
 
 544              "fk_corporation = (SELECT pk_corporation "
 
 545                    "FROM tb_corporations "
 
 546                    "WHERE name = '" << ecorporation << "') "
 
 547          "WHERE pk_user = " << uid;
 
 549 result = PQexec(connection, query.str().c_str());
 
 551 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 553     strError = PQresultErrorMessage(result);
 
 555     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
 
 556     if (RollbackTransaction())
 
 558         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 565 if (SaveUserServices(uid, conf.service))
 
 567     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
 
 568     if (RollbackTransaction())
 
 570         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 575 if (SaveUserData(uid, conf.userdata))
 
 577     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's data'\n");
 
 578     if (RollbackTransaction())
 
 580         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 585 if (SaveUserIPs(uid, conf.ips))
 
 587     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's IPs'\n");
 
 588     if (RollbackTransaction())
 
 590         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
 
 595 if (CommitTransaction())
 
 597     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to commit transaction'\n");
 
 604 //-----------------------------------------------------------------------------
 
 605 int POSTGRESQL_STORE::RestoreUserStat(USER_STAT * stat,
 
 606                                     const string & login) const
 
 608 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 610 if (PQstatus(connection) != CONNECTION_OK)
 
 612     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 615         strError = "Connection lost";
 
 616         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
 
 623 if (StartTransaction())
 
 625     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
 
 629 std::string elogin = login;
 
 631 if (EscapeString(elogin))
 
 633     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
 
 634     if (RollbackTransaction())
 
 636         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
 
 641 std::stringstream query;
 
 642 query << "SELECT cash, free_mb, "
 
 643             "last_activity_time, last_cash_add, "
 
 644             "last_cash_add_time, passive_time "
 
 646          "WHERE name = '" << elogin << "'";
 
 648 result = PQexec(connection, query.str().c_str());
 
 650 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 652     strError = PQresultErrorMessage(result);
 
 653     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
 
 655     if (RollbackTransaction())
 
 657         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
 
 662 int tuples = PQntuples(result);
 
 666     strError = "Failed to fetch user's stat";
 
 667     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
 669     if (RollbackTransaction())
 
 671         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
 
 676 std::stringstream tuple;
 
 677 tuple << PQgetvalue(result, 0, 0) << " ";
 
 678 tuple << PQgetvalue(result, 0, 1) << " ";
 
 679 stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 2));
 
 680 tuple << PQgetvalue(result, 0, 3) << " ";
 
 681 stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 4));
 
 682 tuple << PQgetvalue(result, 0, 5) << " ";
 
 689       >> stat->passiveTime;
 
 693 query << "SELECT dir_num, upload, download "
 
 694          "FROM tb_stats_traffic "
 
 695          "WHERE fk_user IN (SELECT pk_user FROM tb_users WHERE name = '" << elogin << "') AND "
 
 696                "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP))";
 
 698 result = PQexec(connection, query.str().c_str());
 
 700 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 702     strError = PQresultErrorMessage(result);
 
 703     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
 
 705     if (RollbackTransaction())
 
 707         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
 
 712 tuples = PQntuples(result);
 
 714 for (int i = 0; i < tuples; ++i)
 
 716     std::stringstream tuple;
 
 717     tuple << PQgetvalue(result, i, 0) << " ";
 
 718     tuple << PQgetvalue(result, i, 1) << " ";
 
 719     tuple << PQgetvalue(result, i, 2) << " ";
 
 724     tuple >> stat->up[dir];
 
 725     tuple >> stat->down[dir];
 
 730 if (CommitTransaction())
 
 732     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to commit transaction'\n");
 
 739 //-----------------------------------------------------------------------------
 
 740 int POSTGRESQL_STORE::RestoreUserConf(USER_CONF * conf,
 
 741                                     const string & login) const
 
 743 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 745 if (PQstatus(connection) != CONNECTION_OK)
 
 747     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 750         strError = "Connection lost";
 
 751         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
 
 758 if (StartTransaction())
 
 760     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
 
 764 std::string elogin = login;
 
 766 if (EscapeString(elogin))
 
 768     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
 
 769     if (RollbackTransaction())
 
 771         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
 
 776 std::stringstream query;
 
 777 query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, "
 
 778                 "tb_users.credit, tb_users.credit_expire, tb_users.disabled, "
 
 779                 "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, "
 
 780                 "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, "
 
 781                 "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name "
 
 782          "FROM tb_users LEFT JOIN tb_tariffs AS tf1 "
 
 783                             "ON tf1.pk_tariff = tb_users.fk_tariff "
 
 784                        "LEFT JOIN tb_tariffs AS tf2 "
 
 785                             "ON tf2.pk_tariff = tb_users.fk_tariff_change "
 
 786                        "LEFT JOIN tb_corporations "
 
 787                             "ON tb_corporations.pk_corporation = tb_users.fk_corporation "
 
 788          "WHERE tb_users.name = '" << elogin << "'";
 
 790 result = PQexec(connection, query.str().c_str());
 
 792 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 794     strError = PQresultErrorMessage(result);
 
 795     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
 
 797     if (RollbackTransaction())
 
 799         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
 
 804 int tuples = PQntuples(result);
 
 808     strError = "Failed to fetch user's stat";
 
 809     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
 811     if (RollbackTransaction())
 
 813         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
 
 820 std::stringstream tuple;
 
 822 tuple << PQgetvalue(result, 0, 0) << " ";               // uid
 
 823 conf->address = PQgetvalue(result, 0, 1);               // address
 
 824 conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
 
 825 tuple << PQgetvalue(result, 0, 3) << " ";               // credit
 
 826 conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4));  // creditExpire
 
 827 conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
 
 828 conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
 
 829 conf->email = PQgetvalue(result, 0, 7);                 // email
 
 830 conf->group = PQgetvalue(result, 0, 8);                 // group
 
 831 conf->note = PQgetvalue(result, 0, 9);                  // note
 
 832 conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1);
 
 833 conf->password = PQgetvalue(result, 0, 11);             // password
 
 834 conf->phone = PQgetvalue(result, 0, 12);                // phone
 
 835 conf->realName = PQgetvalue(result, 0, 13);             // realName
 
 836 conf->tariffName = PQgetvalue(result, 0, 14);           // tariffName
 
 837 conf->nextTariff = PQgetvalue(result, 0, 15);           // nextTariff
 
 838 conf->corp = PQgetvalue(result, 0, 16);                 // corp
 
 842 if (conf->tariffName == "")
 
 843     conf->tariffName = NO_TARIFF_NAME;
 
 844 if (conf->corp == "")
 
 845     conf->corp = NO_CORP_NAME;
 
 851 query << "SELECT name FROM tb_services "
 
 852          "WHERE pk_service IN (SELECT fk_service "
 
 853                               "FROM tb_users_services "
 
 854                               "WHERE fk_user = " << uid << ")";
 
 856 result = PQexec(connection, query.str().c_str());
 
 858 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 860     strError = PQresultErrorMessage(result);
 
 861     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
 
 863     if (RollbackTransaction())
 
 865         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
 
 870 tuples = PQntuples(result);
 
 872 for (int i = 0; i < tuples; ++i)
 
 874     conf->service.push_back(PQgetvalue(result, i, 0));
 
 880 query << "SELECT num, data "
 
 881          "FROM tb_users_data "
 
 882          "WHERE fk_user = " << uid;
 
 884 result = PQexec(connection, query.str().c_str());
 
 886 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 888     strError = PQresultErrorMessage(result);
 
 889     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
 
 891     if (RollbackTransaction())
 
 893         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
 
 898 tuples = PQntuples(result);
 
 900 for (int i = 0; i < tuples; ++i)
 
 903     if (str2x(PQgetvalue(result, i, 0), num))
 
 905         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to convert string to int'\n");
 
 909         if (num < USERDATA_NUM &&
 
 912             conf->userdata[num] = PQgetvalue(result, i, 1);
 
 920 query << "SELECT host(ip), masklen(ip) "
 
 921          "FROM tb_allowed_ip "
 
 922          "WHERE fk_user = " << uid;
 
 924 result = PQexec(connection, query.str().c_str());
 
 926 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 928     strError = PQresultErrorMessage(result);
 
 929     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
 
 931     if (RollbackTransaction())
 
 933         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
 
 938 tuples = PQntuples(result);
 
 941 for (int i = 0; i < tuples; ++i)
 
 947     ip = inet_strington(PQgetvalue(result, i, 0));
 
 949     if (str2x(PQgetvalue(result, i, 1), mask))
 
 951         printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to fetch mask'\n");
 
 963 if (CommitTransaction())
 
 965     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to commit transaction'\n");
 
 972 //-----------------------------------------------------------------------------
 
 973 int POSTGRESQL_STORE::WriteUserChgLog(const string & login,
 
 974                                     const string & admLogin,
 
 976                                     const string & paramName,
 
 977                                     const string & oldValue,
 
 978                                     const string & newValue,
 
 979                                     const string & message = "") const
 
 981 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 983 if (PQstatus(connection) != CONNECTION_OK)
 
 985     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 988         strError = "Connection lost";
 
 989         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
 
 996 if (StartTransaction())
 
 998     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to start transaction'\n");
 
1002 std::string elogin(login);
 
1003 std::string eadminLogin(admLogin);
 
1004 std::string eparam(paramName);
 
1005 std::string eold(oldValue);
 
1006 std::string enew(newValue);
 
1007 std::string emessage(message);
 
1009 if (EscapeString(elogin))
 
1011     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
 
1012     if (RollbackTransaction())
 
1014         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1019 if (EscapeString(eadminLogin))
 
1021     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
 
1022     if (RollbackTransaction())
 
1024         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1029 if (EscapeString(eparam))
 
1031     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
 
1032     if (RollbackTransaction())
 
1034         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1039 if (EscapeString(eold))
 
1041     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
 
1042     if (RollbackTransaction())
 
1044         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1049 if (EscapeString(enew))
 
1051     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
 
1052     if (RollbackTransaction())
 
1054         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1059 std::stringstream query;
 
1060 query << "SELECT sp_add_param_log_entry("
 
1061             "'" << elogin << "', "
 
1062             "'" << eadminLogin << "', CAST('"
 
1063             << inet_ntostring(admIP) << "/32' AS INET), "
 
1064             "'" << eparam << "', "
 
1065             "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
 
1066             "'" << eold << "', "
 
1067             "'" << enew << "', "
 
1068             "'" << emessage << "')";
 
1070 result = PQexec(connection, query.str().c_str());
 
1072 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
1074     strError = PQresultErrorMessage(result);
 
1076     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
 
1077     if (RollbackTransaction())
 
1079         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
 
1086 if (CommitTransaction())
 
1088     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to commit transaction'\n");
 
1095 //-----------------------------------------------------------------------------
 
1096 int POSTGRESQL_STORE::WriteUserConnect(const string & login, uint32_t ip) const
 
1098 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1100 if (PQstatus(connection) != CONNECTION_OK)
 
1102     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
1105         strError = "Connection lost";
 
1106         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
 
1113 if (StartTransaction())
 
1115     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to start transaction'\n");
 
1119 std::string elogin(login);
 
1121 if (EscapeString(elogin))
 
1123     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
 
1124     if (RollbackTransaction())
 
1126         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
 
1131 std::stringstream query;
 
1134     query << "SELECT sp_add_session_log_entry("
 
1135                  "'" << elogin << "', "
 
1136                  "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
 
1138                  << inet_ntostring(ip) << "/32' AS INET), 0)";
 
1142     query << "SELECT sp_add_session_log_entry("
 
1143                  "'" << elogin << "', "
 
1144                  "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
 
1146                  << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
 
1149 result = PQexec(connection, query.str().c_str());
 
1151 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
1153     strError = PQresultErrorMessage(result);
 
1155     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
 
1156     if (RollbackTransaction())
 
1158         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
 
1165 if (CommitTransaction())
 
1167     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to commit transaction'\n");
 
1174 //-----------------------------------------------------------------------------
 
1175 int POSTGRESQL_STORE::WriteUserDisconnect(const string & login,
 
1176                     const DIR_TRAFF & up,
 
1177                     const DIR_TRAFF & down,
 
1178                     const DIR_TRAFF & sessionUp,
 
1179                     const DIR_TRAFF & sessionDown,
 
1182                     const std::string & reason) const
 
1184 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1186 if (PQstatus(connection) != CONNECTION_OK)
 
1188     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
1191         strError = "Connection lost";
 
1192         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
 
1199 if (StartTransaction())
 
1201     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to start transaction'\n");
 
1205 std::string elogin(login);
 
1207 if (EscapeString(elogin))
 
1209     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
 
1210     if (RollbackTransaction())
 
1212         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1217 std::string ereason(reason);
 
1219 if (EscapeString(ereason))
 
1221     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
 
1222     if (RollbackTransaction())
 
1224         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1229 std::stringstream query;
 
1232     // Old database version - no freeMb logging support
 
1233     query << "SELECT sp_add_session_log_entry("
 
1234                 "'" << elogin << "', "
 
1235                 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
 
1236                 "'d', CAST('0.0.0.0/0' AS INET), "
 
1241     query << "SELECT sp_add_session_log_entry("
 
1242                 "'" << elogin << "', "
 
1243                 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
 
1244                 "'d', CAST('0.0.0.0/0' AS INET), "
 
1245                 << cash << ", " << freeMb << ", '" << ereason << "')";
 
1248 result = PQexec(connection, query.str().c_str());
 
1250 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
1252     strError = PQresultErrorMessage(result);
 
1254     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
 
1255     if (RollbackTransaction())
 
1257         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1262 int tuples = PQntuples(result);
 
1266     strError = "Failed to fetch session's log ID";
 
1267     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
1269     if (RollbackTransaction())
 
1271         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1278 if (str2x(PQgetvalue(result, 0, 0), lid))
 
1280     strError = "Failed to convert string to int";
 
1281     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
 
1283     if (RollbackTransaction())
 
1285         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1292 for (int i = 0; i < DIR_NUM; ++i)
 
1294     std::stringstream query;
 
1295     query << "INSERT INTO tb_sessions_data "
 
1299                  "session_download, "
 
1305                 << sessionUp[i] << ", "
 
1306                 << sessionDown[i] << ", "
 
1310     result = PQexec(connection, query.str().c_str());
 
1312     if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1314         strError = PQresultErrorMessage(result);
 
1316         printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
 
1317         if (RollbackTransaction())
 
1319             printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
 
1327 if (CommitTransaction())
 
1329     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to commit transaction'\n");
 
1336 //-----------------------------------------------------------------------------
 
1337 int POSTGRESQL_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> & statTree,
 
1339                                       const string & login) const
 
1341 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1343 if (PQstatus(connection) != CONNECTION_OK)
 
1345     printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
1348         strError = "Connection lost";
 
1349         printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
 
1356 if (StartTransaction())
 
1358     printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to start transaction'\n");
 
1362 std::string elogin(login);
 
1364 if (EscapeString(elogin))
 
1366     printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
 
1367     if (RollbackTransaction())
 
1369         printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
 
1374 map<IP_DIR_PAIR, STAT_NODE>::const_iterator it;
 
1375 time_t currTime = time(NULL);
 
1377 for (it = statTree.begin(); it != statTree.end(); ++it)
 
1379     std::stringstream query;
 
1380     query << "INSERT INTO tb_detail_stats "
 
1381                 "(till_time, from_time, fk_user, "
 
1382                  "dir_num, ip, download, upload, cost) "
 
1384                 "CAST('" << Int2TS(currTime) << "' AS TIMESTAMP), "
 
1385                 "CAST('" << Int2TS(lastStat) << "' AS TIMESTAMP), "
 
1386                 "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
 
1387                 << it->first.dir << ", "
 
1388                 << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
 
1389                 << it->second.down << ", "
 
1390                 << it->second.up << ", "
 
1391                 << it->second.cash << ")";
 
1393     result = PQexec(connection, query.str().c_str());
 
1395     if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1397         strError = PQresultErrorMessage(result);
 
1399         printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
 
1400         if (RollbackTransaction())
 
1402             printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
 
1410 if (CommitTransaction())
 
1412     printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to commit transaction'\n");
 
1419 //-----------------------------------------------------------------------------
 
1420 int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const
 
1422 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1424 return SaveStat(stat, login, year, month);
 
1427 //-----------------------------------------------------------------------------
 
1428 int POSTGRESQL_STORE::SaveUserServices(uint32_t uid,
 
1429                                        const std::vector<std::string> & services) const
 
1433 std::stringstream query;
 
1434 query << "DELETE FROM tb_users_services WHERE fk_user = " << uid;
 
1436 result = PQexec(connection, query.str().c_str());
 
1438 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1440     strError = PQresultErrorMessage(result);
 
1442     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
 
1448 std::vector<std::string>::const_iterator it;
 
1450 for (it = services.begin(); it != services.end(); ++it)
 
1452     std::string ename = *it;
 
1454     if (EscapeString(ename))
 
1456         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): 'Failed to escape service name'\n");
 
1460     std::stringstream query;
 
1461     query << "INSERT INTO tb_users_services "
 
1462                 "(fk_user, fk_service) "
 
1465                   "(SELECT pk_service "
 
1467                    "WHERE name = '" << ename << "'))";
 
1469     result = PQexec(connection, query.str().c_str());
 
1471     if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1473         strError = PQresultErrorMessage(result);
 
1475         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
 
1485 //-----------------------------------------------------------------------------
 
1486 int POSTGRESQL_STORE::SaveUserIPs(uint32_t uid,
 
1487                                   const USER_IPS & ips) const
 
1491 std::stringstream query;
 
1492 query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid;
 
1494 result = PQexec(connection, query.str().c_str());
 
1496 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1498     strError = PQresultErrorMessage(result);
 
1500     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
 
1506 for (int i = 0; i < ips.Count(); ++i)
 
1508     std::stringstream query;
 
1509     query << "INSERT INTO tb_allowed_ip "
 
1512                 "(" << uid << ", CAST('"
 
1513                     << inet_ntostring(ips[i].ip) << "/"
 
1514                     << static_cast<int>(ips[i].mask) << "' AS INET))";
 
1516     result = PQexec(connection, query.str().c_str());
 
1518     if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
1520         strError = PQresultErrorMessage(result);
 
1522         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
 
1532 //-----------------------------------------------------------------------------
 
1533 int POSTGRESQL_STORE::SaveUserData(uint32_t uid,
 
1534                                    const std::vector<std::string> & data) const
 
1536 for (unsigned i = 0; i < data.size(); ++i)
 
1538     std::string edata = data[i];
 
1540     if (EscapeString(edata))
 
1542         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): 'Failed to escape userdata field'\n");
 
1548     std::stringstream query;
 
1549     query << "SELECT sp_set_user_data("
 
1551                 << "CAST(" << i << " AS SMALLINT), "
 
1552                 << "'" << edata << "')";
 
1554     result = PQexec(connection, query.str().c_str());
 
1556     if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
1558         strError = PQresultErrorMessage(result);
 
1560         printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): '%s'\n", strError.c_str());