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/const.h"
37 #include "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 if (PQstatus(connection) != CONNECTION_OK)
232 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
235 strError = "Connection lost";
236 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str());
241 if (StartTransaction())
243 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to start transaction'\n");
247 std::string elogin = login;
249 if (EscapeString(elogin))
251 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to escape login'\n");
252 if (RollbackTransaction())
254 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n");
259 std::stringstream query;
260 query << "UPDATE tb_users SET "
261 "cash = " << stat.cash << ", "
262 "free_mb = " << stat.freeMb << ", "
263 "last_activity_time = CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), "
264 "last_cash_add = " << stat.lastCashAdd << ", "
265 "last_cash_add_time = CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), "
266 "passive_time = " << stat.passiveTime << " "
267 "WHERE name = '" << elogin << "'";
269 PGresult * result = PQexec(connection, query.str().c_str());
271 if (PQresultStatus(result) != PGRES_COMMAND_OK)
273 strError = PQresultErrorMessage(result);
275 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str());
276 if (RollbackTransaction())
278 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n");
285 for (int dir = 0; dir < DIR_NUM; ++dir)
288 query << "SELECT sp_add_stats_traffic ("
289 "'" << elogin << "', "
290 "CAST(" << dir << " AS SMALLINT), "
291 "CAST(" << stat.up[dir] << " AS BIGINT), "
292 "CAST(" << stat.down[dir] << " AS BIGINT))";
294 result = PQexec(connection, query.str().c_str());
296 if (PQresultStatus(result) != PGRES_TUPLES_OK)
298 strError = PQresultErrorMessage(result);
300 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): '%s'\n", strError.c_str());
301 if (RollbackTransaction())
303 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to rollback transaction'\n");
311 if (CommitTransaction())
313 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserStat(): 'Failed to commit transaction'\n");
320 //-----------------------------------------------------------------------------
321 int POSTGRESQL_STORE::SaveUserConf(const USER_CONF & conf,
322 const string & login) const
324 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
326 if (PQstatus(connection) != CONNECTION_OK)
328 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
331 strError = "Connection lost";
332 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
339 if (StartTransaction())
341 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to start transaction'\n");
345 std::string elogin = login;
347 if (EscapeString(elogin))
349 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape login'\n");
350 if (RollbackTransaction())
352 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
357 std::stringstream query;
358 query << "SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'";
360 result = PQexec(connection, query.str().c_str());
362 if (PQresultStatus(result) != PGRES_TUPLES_OK)
364 strError = PQresultErrorMessage(result);
366 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
367 if (RollbackTransaction())
369 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
374 int tuples = PQntuples(result);
378 strError = "Failed to fetch user's ID";
379 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
381 if (RollbackTransaction())
383 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
388 std::stringstream tuple;
389 tuple << PQgetvalue(result, 0, 0);
397 std::string eaddress = conf.address;
398 std::string eemail = conf.email;
399 std::string egroup = conf.group;
400 std::string enote = conf.note;
401 std::string epassword = conf.password;
402 std::string ephone = conf.phone;
403 std::string erealname = conf.realName;
404 std::string etariffname = conf.tariffName;
405 std::string enexttariff = conf.nextTariff;
406 std::string ecorporation = conf.corp;
408 if (EscapeString(eaddress))
410 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
411 if (RollbackTransaction())
413 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
418 if (EscapeString(eemail))
420 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
421 if (RollbackTransaction())
423 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
428 if (EscapeString(egroup))
430 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
431 if (RollbackTransaction())
433 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
438 if (EscapeString(enote))
440 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
441 if (RollbackTransaction())
443 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
448 if (EscapeString(epassword))
450 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
451 if (RollbackTransaction())
453 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
458 if (EscapeString(ephone))
460 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
461 if (RollbackTransaction())
463 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
468 if (EscapeString(erealname))
470 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
471 if (RollbackTransaction())
473 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
478 if (EscapeString(etariffname))
480 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
481 if (RollbackTransaction())
483 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
488 if (EscapeString(enexttariff))
490 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
491 if (RollbackTransaction())
493 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
498 if (EscapeString(ecorporation))
500 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
501 if (RollbackTransaction())
503 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
509 query << "UPDATE tb_users SET "
510 "address = '" << eaddress << "', "
511 "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
512 "credit = " << conf.credit << ", "
513 "credit_expire = CAST('" << Int2TS(conf.creditExpire) << "' AS TIMESTAMP), "
514 "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
515 "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
516 "email = '" << eemail << "', "
517 "grp = '" << egroup << "', "
518 "note = '" << enote << "', "
519 "passive = " << (conf.passive ? "'t'" : "'f'") << ", "
520 "passwd = '" << epassword << "', "
521 "phone = '" << ephone << "', "
522 "real_name = '" << erealname << "', "
523 "fk_tariff = (SELECT pk_tariff "
525 "WHERE name = '" << etariffname << "'), "
526 "fk_tariff_change = (SELECT pk_tariff "
528 "WHERE name = '" << enexttariff << "'), "
529 "fk_corporation = (SELECT pk_corporation "
530 "FROM tb_corporations "
531 "WHERE name = '" << ecorporation << "') "
532 "WHERE pk_user = " << uid;
534 result = PQexec(connection, query.str().c_str());
536 if (PQresultStatus(result) != PGRES_COMMAND_OK)
538 strError = PQresultErrorMessage(result);
540 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
541 if (RollbackTransaction())
543 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
550 if (SaveUserServices(uid, conf.service))
552 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
553 if (RollbackTransaction())
555 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
560 if (SaveUserData(uid, conf.userdata))
562 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's data'\n");
563 if (RollbackTransaction())
565 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
570 if (SaveUserIPs(uid, conf.ips))
572 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's IPs'\n");
573 if (RollbackTransaction())
575 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
580 if (CommitTransaction())
582 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to commit transaction'\n");
589 //-----------------------------------------------------------------------------
590 int POSTGRESQL_STORE::RestoreUserStat(USER_STAT * stat,
591 const string & login) const
593 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
595 if (PQstatus(connection) != CONNECTION_OK)
597 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
600 strError = "Connection lost";
601 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
608 if (StartTransaction())
610 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
614 std::string elogin = login;
616 if (EscapeString(elogin))
618 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
619 if (RollbackTransaction())
621 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
626 std::stringstream query;
627 query << "SELECT pk_user, cash, free_mb, "
628 "last_activity_time, last_cash_add, "
629 "last_cash_add_time, passive_time "
631 "WHERE name = '" << elogin << "'";
633 result = PQexec(connection, query.str().c_str());
635 if (PQresultStatus(result) != PGRES_TUPLES_OK)
637 strError = PQresultErrorMessage(result);
638 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
640 if (RollbackTransaction())
642 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
647 int tuples = PQntuples(result);
651 strError = "Failed to fetch user's stat";
652 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
654 if (RollbackTransaction())
656 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
661 std::stringstream tuple;
662 tuple << PQgetvalue(result, 0, 0) << " ";
663 tuple << PQgetvalue(result, 0, 1) << " ";
664 tuple << PQgetvalue(result, 0, 2) << " ";
665 stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 3));
666 tuple << PQgetvalue(result, 0, 4) << " ";
667 stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 5));
668 tuple << PQgetvalue(result, 0, 6);
678 >> stat->passiveTime;
682 query << "SELECT dir_num, upload, download "
683 "FROM tb_stats_traffic "
684 "WHERE fk_user = " << uid;
686 result = PQexec(connection, query.str().c_str());
688 if (PQresultStatus(result) != PGRES_TUPLES_OK)
690 strError = PQresultErrorMessage(result);
691 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
693 if (RollbackTransaction())
695 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
700 tuples = PQntuples(result);
702 for (int i = 0; i < tuples; ++i)
704 std::stringstream tuple;
705 tuple << PQgetvalue(result, i, 0) << " ";
706 tuple << PQgetvalue(result, i, 1) << " ";
707 tuple << PQgetvalue(result, i, 2) << " ";
712 tuple >> stat->up[dir];
713 tuple >> stat->down[dir];
718 if (CommitTransaction())
720 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to commit transaction'\n");
727 //-----------------------------------------------------------------------------
728 int POSTGRESQL_STORE::RestoreUserConf(USER_CONF * conf,
729 const string & login) const
731 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
733 if (PQstatus(connection) != CONNECTION_OK)
735 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
738 strError = "Connection lost";
739 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
746 if (StartTransaction())
748 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
752 std::string elogin = login;
754 if (EscapeString(elogin))
756 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
757 if (RollbackTransaction())
759 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
764 std::stringstream query;
765 query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, "
766 "tb_users.credit, tb_users.credit_expire, tb_users.disabled, "
767 "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, "
768 "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, "
769 "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name "
770 "FROM tb_users LEFT JOIN tb_tariffs AS tf1 "
771 "ON tf1.pk_tariff = tb_users.fk_tariff "
772 "LEFT JOIN tb_tariffs AS tf2 "
773 "ON tf2.pk_tariff = tb_users.fk_tariff_change "
774 "LEFT JOIN tb_corporations "
775 "ON tb_corporations.pk_corporation = tb_users.fk_corporation "
776 "WHERE tb_users.name = '" << elogin << "'";
778 result = PQexec(connection, query.str().c_str());
780 if (PQresultStatus(result) != PGRES_TUPLES_OK)
782 strError = PQresultErrorMessage(result);
783 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
785 if (RollbackTransaction())
787 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
792 int tuples = PQntuples(result);
796 strError = "Failed to fetch user's stat";
797 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
799 if (RollbackTransaction())
801 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
808 std::stringstream tuple;
810 tuple << PQgetvalue(result, 0, 0) << " "; // uid
811 conf->address = PQgetvalue(result, 0, 1); // address
812 conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
813 tuple << PQgetvalue(result, 0, 3) << " "; // credit
814 conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4)); // creditExpire
815 conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
816 conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
817 conf->email = PQgetvalue(result, 0, 7); // email
818 conf->group = PQgetvalue(result, 0, 8); // group
819 conf->note = PQgetvalue(result, 0, 9); // note
820 conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1);
821 conf->password = PQgetvalue(result, 0, 11); // password
822 conf->phone = PQgetvalue(result, 0, 12); // phone
823 conf->realName = PQgetvalue(result, 0, 13); // realName
824 conf->tariffName = PQgetvalue(result, 0, 14); // tariffName
825 conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff
826 conf->corp = PQgetvalue(result, 0, 16); // corp
830 if (conf->tariffName == "")
831 conf->tariffName = NO_TARIFF_NAME;
832 if (conf->corp == "")
833 conf->corp = NO_CORP_NAME;
839 query << "SELECT name FROM tb_services "
840 "WHERE pk_service IN (SELECT fk_service "
841 "FROM tb_users_services "
842 "WHERE fk_user = " << uid << ")";
844 result = PQexec(connection, query.str().c_str());
846 if (PQresultStatus(result) != PGRES_TUPLES_OK)
848 strError = PQresultErrorMessage(result);
849 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
851 if (RollbackTransaction())
853 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
858 tuples = PQntuples(result);
860 for (int i = 0; i < tuples; ++i)
862 conf->service.push_back(PQgetvalue(result, i, 0));
868 query << "SELECT num, data "
869 "FROM tb_users_data "
870 "WHERE fk_user = " << uid;
872 result = PQexec(connection, query.str().c_str());
874 if (PQresultStatus(result) != PGRES_TUPLES_OK)
876 strError = PQresultErrorMessage(result);
877 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
879 if (RollbackTransaction())
881 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
886 tuples = PQntuples(result);
888 for (int i = 0; i < tuples; ++i)
891 if (str2x(PQgetvalue(result, i, 0), num))
893 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to convert string to int'\n");
897 if (num < USERDATA_NUM &&
900 conf->userdata[num] = PQgetvalue(result, i, 1);
908 query << "SELECT host(ip), masklen(ip) "
909 "FROM tb_allowed_ip "
910 "WHERE fk_user = " << uid;
912 result = PQexec(connection, query.str().c_str());
914 if (PQresultStatus(result) != PGRES_TUPLES_OK)
916 strError = PQresultErrorMessage(result);
917 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
919 if (RollbackTransaction())
921 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
926 tuples = PQntuples(result);
929 for (int i = 0; i < tuples; ++i)
935 ip = inet_strington(PQgetvalue(result, i, 0));
937 if (str2x(PQgetvalue(result, i, 1), mask))
939 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to fetch mask'\n");
951 if (CommitTransaction())
953 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to commit transaction'\n");
960 //-----------------------------------------------------------------------------
961 int POSTGRESQL_STORE::WriteUserChgLog(const string & login,
962 const string & admLogin,
964 const string & paramName,
965 const string & oldValue,
966 const string & newValue,
967 const string & message = "") const
969 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
971 if (PQstatus(connection) != CONNECTION_OK)
973 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
976 strError = "Connection lost";
977 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
984 if (StartTransaction())
986 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to start transaction'\n");
990 std::string elogin(login);
991 std::string eadminLogin(admLogin);
992 std::string eparam(paramName);
993 std::string eold(oldValue);
994 std::string enew(newValue);
995 std::string emessage(message);
997 if (EscapeString(elogin))
999 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
1000 if (RollbackTransaction())
1002 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1007 if (EscapeString(eadminLogin))
1009 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
1010 if (RollbackTransaction())
1012 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1017 if (EscapeString(eparam))
1019 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
1020 if (RollbackTransaction())
1022 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1027 if (EscapeString(eold))
1029 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
1030 if (RollbackTransaction())
1032 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1037 if (EscapeString(enew))
1039 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
1040 if (RollbackTransaction())
1042 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1047 std::stringstream query;
1048 query << "SELECT sp_add_param_log_entry("
1049 "'" << elogin << "', "
1050 "'" << eadminLogin << "', CAST('"
1051 << inet_ntostring(admIP) << "/32' AS INET), "
1052 "'" << eparam << "', "
1053 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1054 "'" << eold << "', "
1055 "'" << enew << "', "
1056 "'" << emessage << "')";
1058 result = PQexec(connection, query.str().c_str());
1060 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1062 strError = PQresultErrorMessage(result);
1064 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1065 if (RollbackTransaction())
1067 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1074 if (CommitTransaction())
1076 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to commit transaction'\n");
1083 //-----------------------------------------------------------------------------
1084 int POSTGRESQL_STORE::WriteUserConnect(const string & login, uint32_t ip) const
1086 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1088 if (PQstatus(connection) != CONNECTION_OK)
1090 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1093 strError = "Connection lost";
1094 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1101 if (StartTransaction())
1103 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to start transaction'\n");
1107 std::string elogin(login);
1109 if (EscapeString(elogin))
1111 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
1112 if (RollbackTransaction())
1114 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1119 std::stringstream query;
1122 query << "SELECT sp_add_session_log_entry("
1123 "'" << elogin << "', "
1124 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1126 << inet_ntostring(ip) << "/32' AS INET), 0)";
1130 query << "SELECT sp_add_session_log_entry("
1131 "'" << elogin << "', "
1132 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1134 << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
1137 result = PQexec(connection, query.str().c_str());
1139 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1141 strError = PQresultErrorMessage(result);
1143 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1144 if (RollbackTransaction())
1146 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1153 if (CommitTransaction())
1155 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to commit transaction'\n");
1162 //-----------------------------------------------------------------------------
1163 int POSTGRESQL_STORE::WriteUserDisconnect(const string & login,
1164 const DIR_TRAFF & up,
1165 const DIR_TRAFF & down,
1166 const DIR_TRAFF & sessionUp,
1167 const DIR_TRAFF & sessionDown,
1170 const std::string & reason) const
1172 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1174 if (PQstatus(connection) != CONNECTION_OK)
1176 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1179 strError = "Connection lost";
1180 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1187 if (StartTransaction())
1189 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to start transaction'\n");
1193 std::string elogin(login);
1195 if (EscapeString(elogin))
1197 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
1198 if (RollbackTransaction())
1200 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1205 std::string ereason(reason);
1207 if (EscapeString(ereason))
1209 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
1210 if (RollbackTransaction())
1212 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1217 std::stringstream query;
1220 // Old database version - no freeMb logging support
1221 query << "SELECT sp_add_session_log_entry("
1222 "'" << elogin << "', "
1223 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1224 "'d', CAST('0.0.0.0/0' AS INET), "
1229 query << "SELECT sp_add_session_log_entry("
1230 "'" << elogin << "', "
1231 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1232 "'d', CAST('0.0.0.0/0' AS INET), "
1233 << cash << ", " << freeMb << ", '" << ereason << "')";
1236 result = PQexec(connection, query.str().c_str());
1238 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1240 strError = PQresultErrorMessage(result);
1242 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1243 if (RollbackTransaction())
1245 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1250 int tuples = PQntuples(result);
1254 strError = "Failed to fetch session's log ID";
1255 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1257 if (RollbackTransaction())
1259 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1266 if (str2x(PQgetvalue(result, 0, 0), lid))
1268 strError = "Failed to convert string to int";
1269 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1271 if (RollbackTransaction())
1273 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1280 for (int i = 0; i < DIR_NUM; ++i)
1282 std::stringstream query;
1283 query << "INSERT INTO tb_sessions_data "
1287 "session_download, "
1293 << sessionUp[i] << ", "
1294 << sessionDown[i] << ", "
1298 result = PQexec(connection, query.str().c_str());
1300 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1302 strError = PQresultErrorMessage(result);
1304 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1305 if (RollbackTransaction())
1307 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1315 if (CommitTransaction())
1317 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to commit transaction'\n");
1324 //-----------------------------------------------------------------------------
1325 int POSTGRESQL_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> & statTree,
1327 const string & login) const
1329 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1331 if (PQstatus(connection) != CONNECTION_OK)
1333 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1336 strError = "Connection lost";
1337 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1344 if (StartTransaction())
1346 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to start transaction'\n");
1350 std::string elogin(login);
1352 if (EscapeString(elogin))
1354 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
1355 if (RollbackTransaction())
1357 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1362 map<IP_DIR_PAIR, STAT_NODE>::const_iterator it;
1363 time_t currTime = time(NULL);
1365 for (it = statTree.begin(); it != statTree.end(); ++it)
1367 std::stringstream query;
1368 query << "INSERT INTO tb_detail_stats "
1369 "(till_time, from_time, fk_user, "
1370 "dir_num, ip, download, upload, cost) "
1372 "CAST('" << Int2TS(currTime) << "' AS TIMESTAMP), "
1373 "CAST('" << Int2TS(lastStat) << "' AS TIMESTAMP), "
1374 "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
1375 << it->first.dir << ", "
1376 << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
1377 << it->second.down << ", "
1378 << it->second.up << ", "
1379 << it->second.cash << ")";
1381 result = PQexec(connection, query.str().c_str());
1383 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1385 strError = PQresultErrorMessage(result);
1387 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1388 if (RollbackTransaction())
1390 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1398 if (CommitTransaction())
1400 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to commit transaction'\n");
1407 //-----------------------------------------------------------------------------
1408 int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const
1410 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1412 if (PQstatus(connection) != CONNECTION_OK)
1414 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1417 strError = "Connection lost";
1418 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1423 if (StartTransaction())
1425 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to start transaction'\n");
1429 std::string elogin = login;
1431 if (EscapeString(elogin))
1433 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to escape login'\n");
1434 if (RollbackTransaction())
1436 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1443 MakeDate(date, year, month);
1445 std::stringstream query;
1446 query << "SELECT sp_add_month_stats("
1447 "'" << elogin << "',"
1448 "CAST('" << date << "' AS DATE), "
1449 "CAST(" << stat.cash << " AS dm_money), "
1450 "CAST(" << stat.freeMb << " AS dm_money), "
1451 "CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), "
1452 "CAST(" << stat.lastCashAdd << " AS dm_money), "
1453 "CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), "
1454 "CAST(" << stat.passiveTime << " AS INTEGER))";
1456 PGresult * result = PQexec(connection, query.str().c_str());
1458 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1460 strError = PQresultErrorMessage(result);
1462 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1463 if (RollbackTransaction())
1465 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1470 int tuples = PQntuples(result);
1474 strError = "Failed to fetch month stat's ID";
1475 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1477 if (RollbackTransaction())
1479 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1486 if (str2x(PQgetvalue(result, 0, 0), sid))
1488 strError = "Failed to convert string to int";
1489 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1491 if (RollbackTransaction())
1493 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1500 for (int dir = 0; dir < DIR_NUM; ++dir)
1503 query << "SELECT sp_add_month_stats_traffic ("
1505 "CAST(" << dir << " AS SMALLINT), "
1506 "CAST(" << stat.up[dir] << " AS BIGINT), "
1507 "CAST(" << stat.down[dir] << " AS BIGINT))";
1509 result = PQexec(connection, query.str().c_str());
1511 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1513 strError = PQresultErrorMessage(result);
1515 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1516 if (RollbackTransaction())
1518 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1526 if (CommitTransaction())
1528 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to commit transaction'\n");
1535 //-----------------------------------------------------------------------------
1536 int POSTGRESQL_STORE::SaveUserServices(uint32_t uid,
1537 const std::vector<std::string> & services) const
1541 std::stringstream query;
1542 query << "DELETE FROM tb_users_services WHERE fk_user = " << uid;
1544 result = PQexec(connection, query.str().c_str());
1546 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1548 strError = PQresultErrorMessage(result);
1550 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1556 std::vector<std::string>::const_iterator it;
1558 for (it = services.begin(); it != services.end(); ++it)
1560 std::string ename = *it;
1562 if (EscapeString(ename))
1564 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): 'Failed to escape service name'\n");
1568 std::stringstream query;
1569 query << "INSERT INTO tb_users_services "
1570 "(fk_user, fk_service) "
1573 "(SELECT pk_service "
1575 "WHERE name = '" << ename << "'))";
1577 result = PQexec(connection, query.str().c_str());
1579 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1581 strError = PQresultErrorMessage(result);
1583 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1593 //-----------------------------------------------------------------------------
1594 int POSTGRESQL_STORE::SaveUserIPs(uint32_t uid,
1595 const USER_IPS & ips) const
1599 std::stringstream query;
1600 query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid;
1602 result = PQexec(connection, query.str().c_str());
1604 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1606 strError = PQresultErrorMessage(result);
1608 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1614 for (int i = 0; i < ips.Count(); ++i)
1616 std::stringstream query;
1617 query << "INSERT INTO tb_allowed_ip "
1620 "(" << uid << ", CAST('"
1621 << inet_ntostring(ips[i].ip) << "/"
1622 << static_cast<int>(ips[i].mask) << "' AS INET))";
1624 result = PQexec(connection, query.str().c_str());
1626 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1628 strError = PQresultErrorMessage(result);
1630 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1640 //-----------------------------------------------------------------------------
1641 int POSTGRESQL_STORE::SaveUserData(uint32_t uid,
1642 const std::vector<std::string> & data) const
1644 for (unsigned i = 0; i < data.size(); ++i)
1646 std::string edata = data[i];
1648 if (EscapeString(edata))
1650 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): 'Failed to escape userdata field'\n");
1656 std::stringstream query;
1657 query << "SELECT sp_set_user_data("
1659 << "CAST(" << i << " AS SMALLINT), "
1660 << "'" << edata << "')";
1662 result = PQexec(connection, query.str().c_str());
1664 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1666 strError = PQresultErrorMessage(result);
1668 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): '%s'\n", strError.c_str());