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(std::vector<std::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 std::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::ostringstream 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 std::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::ostringstream 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 std::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::ostringstream 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 std::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::ostringstream 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");
391 std::stringstream tuple;
392 tuple << PQgetvalue(result, 0, 0);
399 std::string eaddress = conf.address;
400 std::string eemail = conf.email;
401 std::string egroup = conf.group;
402 std::string enote = conf.note;
403 std::string epassword = conf.password;
404 std::string ephone = conf.phone;
405 std::string erealname = conf.realName;
406 std::string etariffname = conf.tariffName;
407 std::string enexttariff = conf.nextTariff;
408 std::string ecorporation = conf.corp;
410 if (EscapeString(eaddress))
412 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
413 if (RollbackTransaction())
415 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
420 if (EscapeString(eemail))
422 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
423 if (RollbackTransaction())
425 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
430 if (EscapeString(egroup))
432 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
433 if (RollbackTransaction())
435 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
440 if (EscapeString(enote))
442 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
443 if (RollbackTransaction())
445 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
450 if (EscapeString(epassword))
452 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
453 if (RollbackTransaction())
455 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
460 if (EscapeString(ephone))
462 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
463 if (RollbackTransaction())
465 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
470 if (EscapeString(erealname))
472 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
473 if (RollbackTransaction())
475 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
480 if (EscapeString(etariffname))
482 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
483 if (RollbackTransaction())
485 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
490 if (EscapeString(enexttariff))
492 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
493 if (RollbackTransaction())
495 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
500 if (EscapeString(ecorporation))
502 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
503 if (RollbackTransaction())
505 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
511 query << "UPDATE tb_users SET "
512 "address = '" << eaddress << "', "
513 "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
514 "credit = " << conf.credit << ", "
515 "credit_expire = CAST('" << Int2TS(conf.creditExpire) << "' AS TIMESTAMP), "
516 "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
517 "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
518 "email = '" << eemail << "', "
519 "grp = '" << egroup << "', "
520 "note = '" << enote << "', "
521 "passive = " << (conf.passive ? "'t'" : "'f'") << ", "
522 "passwd = '" << epassword << "', "
523 "phone = '" << ephone << "', "
524 "real_name = '" << erealname << "', "
525 "fk_tariff = (SELECT pk_tariff "
527 "WHERE name = '" << etariffname << "'), "
528 "fk_tariff_change = (SELECT pk_tariff "
530 "WHERE name = '" << enexttariff << "'), "
531 "fk_corporation = (SELECT pk_corporation "
532 "FROM tb_corporations "
533 "WHERE name = '" << ecorporation << "') "
534 "WHERE pk_user = " << uid;
536 result = PQexec(connection, query.str().c_str());
538 if (PQresultStatus(result) != PGRES_COMMAND_OK)
540 strError = PQresultErrorMessage(result);
542 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
543 if (RollbackTransaction())
545 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
552 if (SaveUserServices(uid, conf.service))
554 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
555 if (RollbackTransaction())
557 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
562 if (SaveUserData(uid, conf.userdata))
564 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's data'\n");
565 if (RollbackTransaction())
567 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
572 if (SaveUserIPs(uid, conf.ips))
574 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's IPs'\n");
575 if (RollbackTransaction())
577 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
582 if (CommitTransaction())
584 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to commit transaction'\n");
591 //-----------------------------------------------------------------------------
592 int POSTGRESQL_STORE::RestoreUserStat(USER_STAT * stat,
593 const std::string & login) const
595 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
597 if (PQstatus(connection) != CONNECTION_OK)
599 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
602 strError = "Connection lost";
603 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
610 if (StartTransaction())
612 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
616 std::string elogin = login;
618 if (EscapeString(elogin))
620 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
621 if (RollbackTransaction())
623 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
629 std::ostringstream query;
630 query << "SELECT pk_user, cash, free_mb, "
631 "last_activity_time, last_cash_add, "
632 "last_cash_add_time, passive_time "
634 "WHERE name = '" << elogin << "'";
636 result = PQexec(connection, query.str().c_str());
639 if (PQresultStatus(result) != PGRES_TUPLES_OK)
641 strError = PQresultErrorMessage(result);
642 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
644 if (RollbackTransaction())
646 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
651 int tuples = PQntuples(result);
655 strError = "Failed to fetch user's stat";
656 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
658 if (RollbackTransaction())
660 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
668 std::stringstream tuple;
669 tuple << PQgetvalue(result, 0, 0) << " ";
670 tuple << PQgetvalue(result, 0, 1) << " ";
671 tuple << PQgetvalue(result, 0, 2) << " ";
672 stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 3));
673 tuple << PQgetvalue(result, 0, 4) << " ";
674 stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 5));
675 tuple << PQgetvalue(result, 0, 6) << " ";
683 >> stat->passiveTime;
687 std::ostringstream query;
688 query << "SELECT dir_num, upload, download "
689 "FROM tb_stats_traffic "
690 "WHERE fk_user = " << uid;
692 result = PQexec(connection, query.str().c_str());
695 if (PQresultStatus(result) != PGRES_TUPLES_OK)
697 strError = PQresultErrorMessage(result);
698 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
700 if (RollbackTransaction())
702 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
707 tuples = PQntuples(result);
709 for (int i = 0; i < tuples; ++i)
711 std::stringstream tuple;
712 tuple << PQgetvalue(result, i, 0) << " ";
713 tuple << PQgetvalue(result, i, 1) << " ";
714 tuple << PQgetvalue(result, i, 2) << " ";
719 tuple >> stat->up[dir];
720 tuple >> stat->down[dir];
725 if (CommitTransaction())
727 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to commit transaction'\n");
734 //-----------------------------------------------------------------------------
735 int POSTGRESQL_STORE::RestoreUserConf(USER_CONF * conf,
736 const std::string & login) const
738 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
740 if (PQstatus(connection) != CONNECTION_OK)
742 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
745 strError = "Connection lost";
746 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
753 if (StartTransaction())
755 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
759 std::string elogin = login;
761 if (EscapeString(elogin))
763 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
764 if (RollbackTransaction())
766 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
772 std::ostringstream query;
773 query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, "
774 "tb_users.credit, tb_users.credit_expire, tb_users.disabled, "
775 "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, "
776 "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, "
777 "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name "
778 "FROM tb_users LEFT JOIN tb_tariffs AS tf1 "
779 "ON tf1.pk_tariff = tb_users.fk_tariff "
780 "LEFT JOIN tb_tariffs AS tf2 "
781 "ON tf2.pk_tariff = tb_users.fk_tariff_change "
782 "LEFT JOIN tb_corporations "
783 "ON tb_corporations.pk_corporation = tb_users.fk_corporation "
784 "WHERE tb_users.name = '" << elogin << "'";
786 result = PQexec(connection, query.str().c_str());
789 if (PQresultStatus(result) != PGRES_TUPLES_OK)
791 strError = PQresultErrorMessage(result);
792 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
794 if (RollbackTransaction())
796 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
801 int tuples = PQntuples(result);
805 strError = "Failed to fetch user's stat";
806 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
808 if (RollbackTransaction())
810 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
818 std::stringstream tuple;
819 tuple << PQgetvalue(result, 0, 0) << " "; // uid
820 conf->address = PQgetvalue(result, 0, 1); // address
821 conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
822 tuple << PQgetvalue(result, 0, 3) << " "; // credit
823 conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4)); // creditExpire
824 conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
825 conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
826 conf->email = PQgetvalue(result, 0, 7); // email
827 conf->group = PQgetvalue(result, 0, 8); // group
828 conf->note = PQgetvalue(result, 0, 9); // note
829 conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1);
830 conf->password = PQgetvalue(result, 0, 11); // password
831 conf->phone = PQgetvalue(result, 0, 12); // phone
832 conf->realName = PQgetvalue(result, 0, 13); // realName
833 conf->tariffName = PQgetvalue(result, 0, 14); // tariffName
834 conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff
835 conf->corp = PQgetvalue(result, 0, 16); // corp
839 if (conf->tariffName == "")
840 conf->tariffName = NO_TARIFF_NAME;
841 if (conf->corp == "")
842 conf->corp = NO_CORP_NAME;
849 std::ostringstream query;
850 query << "SELECT name FROM tb_services "
851 "WHERE pk_service IN (SELECT fk_service "
852 "FROM tb_users_services "
853 "WHERE fk_user = " << uid << ")";
855 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 std::ostringstream query;
881 query << "SELECT num, data "
882 "FROM tb_users_data "
883 "WHERE fk_user = " << uid;
885 result = PQexec(connection, query.str().c_str());
888 if (PQresultStatus(result) != PGRES_TUPLES_OK)
890 strError = PQresultErrorMessage(result);
891 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
893 if (RollbackTransaction())
895 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
900 tuples = PQntuples(result);
902 for (int i = 0; i < tuples; ++i)
905 if (str2x(PQgetvalue(result, i, 0), num))
907 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to convert string to int'\n");
911 if (num < USERDATA_NUM &&
914 conf->userdata[num] = PQgetvalue(result, i, 1);
922 std::ostringstream query;
923 query << "SELECT host(ip), masklen(ip) "
924 "FROM tb_allowed_ip "
925 "WHERE fk_user = " << uid;
927 result = PQexec(connection, query.str().c_str());
930 if (PQresultStatus(result) != PGRES_TUPLES_OK)
932 strError = PQresultErrorMessage(result);
933 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
935 if (RollbackTransaction())
937 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
942 tuples = PQntuples(result);
945 for (int i = 0; i < tuples; ++i)
951 ip = inet_strington(PQgetvalue(result, i, 0));
953 if (str2x(PQgetvalue(result, i, 1), mask))
955 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to fetch mask'\n");
967 if (CommitTransaction())
969 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to commit transaction'\n");
976 //-----------------------------------------------------------------------------
977 int POSTGRESQL_STORE::WriteUserChgLog(const std::string & login,
978 const std::string & admLogin,
980 const std::string & paramName,
981 const std::string & oldValue,
982 const std::string & newValue,
983 const std::string & message = "") const
985 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
987 if (PQstatus(connection) != CONNECTION_OK)
989 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
992 strError = "Connection lost";
993 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1000 if (StartTransaction())
1002 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to start transaction'\n");
1006 std::string elogin(login);
1007 std::string eadminLogin(admLogin);
1008 std::string eparam(paramName);
1009 std::string eold(oldValue);
1010 std::string enew(newValue);
1011 std::string emessage(message);
1013 if (EscapeString(elogin))
1015 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
1016 if (RollbackTransaction())
1018 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1023 if (EscapeString(eadminLogin))
1025 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
1026 if (RollbackTransaction())
1028 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1033 if (EscapeString(eparam))
1035 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
1036 if (RollbackTransaction())
1038 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1043 if (EscapeString(eold))
1045 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
1046 if (RollbackTransaction())
1048 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1053 if (EscapeString(enew))
1055 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
1056 if (RollbackTransaction())
1058 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1063 std::ostringstream query;
1064 query << "SELECT sp_add_param_log_entry("
1065 "'" << elogin << "', "
1066 "'" << eadminLogin << "', CAST('"
1067 << inet_ntostring(admIP) << "/32' AS INET), "
1068 "'" << eparam << "', "
1069 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1070 "'" << eold << "', "
1071 "'" << enew << "', "
1072 "'" << emessage << "')";
1074 result = PQexec(connection, query.str().c_str());
1076 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1078 strError = PQresultErrorMessage(result);
1080 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1081 if (RollbackTransaction())
1083 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1090 if (CommitTransaction())
1092 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to commit transaction'\n");
1099 //-----------------------------------------------------------------------------
1100 int POSTGRESQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1102 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1104 if (PQstatus(connection) != CONNECTION_OK)
1106 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1109 strError = "Connection lost";
1110 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1117 if (StartTransaction())
1119 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to start transaction'\n");
1123 std::string elogin(login);
1125 if (EscapeString(elogin))
1127 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
1128 if (RollbackTransaction())
1130 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1135 std::ostringstream query;
1138 query << "SELECT sp_add_session_log_entry("
1139 "'" << elogin << "', "
1140 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1142 << inet_ntostring(ip) << "/32' AS INET), 0)";
1146 query << "SELECT sp_add_session_log_entry("
1147 "'" << elogin << "', "
1148 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1150 << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
1153 result = PQexec(connection, query.str().c_str());
1155 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1157 strError = PQresultErrorMessage(result);
1159 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1160 if (RollbackTransaction())
1162 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1169 if (CommitTransaction())
1171 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to commit transaction'\n");
1178 //-----------------------------------------------------------------------------
1179 int POSTGRESQL_STORE::WriteUserDisconnect(const std::string & login,
1180 const DIR_TRAFF & up,
1181 const DIR_TRAFF & down,
1182 const DIR_TRAFF & sessionUp,
1183 const DIR_TRAFF & sessionDown,
1186 const std::string & reason) const
1188 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1190 if (PQstatus(connection) != CONNECTION_OK)
1192 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1195 strError = "Connection lost";
1196 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1203 if (StartTransaction())
1205 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to start transaction'\n");
1209 std::string elogin(login);
1211 if (EscapeString(elogin))
1213 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
1214 if (RollbackTransaction())
1216 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1221 std::string ereason(reason);
1223 if (EscapeString(ereason))
1225 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
1226 if (RollbackTransaction())
1228 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1234 std::ostringstream query;
1237 // Old database version - no freeMb logging support
1238 query << "SELECT sp_add_session_log_entry("
1239 "'" << elogin << "', "
1240 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1241 "'d', CAST('0.0.0.0/0' AS INET), "
1246 query << "SELECT sp_add_session_log_entry("
1247 "'" << elogin << "', "
1248 "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
1249 "'d', CAST('0.0.0.0/0' AS INET), "
1250 << cash << ", " << freeMb << ", '" << ereason << "')";
1253 result = PQexec(connection, query.str().c_str());
1256 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1258 strError = PQresultErrorMessage(result);
1260 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1261 if (RollbackTransaction())
1263 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1268 int tuples = PQntuples(result);
1272 strError = "Failed to fetch session's log ID";
1273 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1275 if (RollbackTransaction())
1277 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1284 if (str2x(PQgetvalue(result, 0, 0), lid))
1286 strError = "Failed to convert string to int";
1287 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1289 if (RollbackTransaction())
1291 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1298 for (int i = 0; i < DIR_NUM; ++i)
1300 std::ostringstream query;
1301 query << "INSERT INTO tb_sessions_data "
1305 "session_download, "
1311 << sessionUp[i] << ", "
1312 << sessionDown[i] << ", "
1316 result = PQexec(connection, query.str().c_str());
1318 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1320 strError = PQresultErrorMessage(result);
1322 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1323 if (RollbackTransaction())
1325 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1333 if (CommitTransaction())
1335 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to commit transaction'\n");
1342 //-----------------------------------------------------------------------------
1343 int POSTGRESQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
1345 const std::string & login) const
1347 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1349 if (PQstatus(connection) != CONNECTION_OK)
1351 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1354 strError = "Connection lost";
1355 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1362 if (StartTransaction())
1364 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to start transaction'\n");
1368 std::string elogin(login);
1370 if (EscapeString(elogin))
1372 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
1373 if (RollbackTransaction())
1375 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1380 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator it;
1381 time_t currTime = time(NULL);
1383 for (it = statTree.begin(); it != statTree.end(); ++it)
1385 std::ostringstream query;
1386 query << "INSERT INTO tb_detail_stats "
1387 "(till_time, from_time, fk_user, "
1388 "dir_num, ip, download, upload, cost) "
1390 "CAST('" << Int2TS(currTime) << "' AS TIMESTAMP), "
1391 "CAST('" << Int2TS(lastStat) << "' AS TIMESTAMP), "
1392 "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
1393 << it->first.dir << ", "
1394 << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
1395 << it->second.down << ", "
1396 << it->second.up << ", "
1397 << it->second.cash << ")";
1399 result = PQexec(connection, query.str().c_str());
1401 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1403 strError = PQresultErrorMessage(result);
1405 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1406 if (RollbackTransaction())
1408 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1416 if (CommitTransaction())
1418 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to commit transaction'\n");
1425 //-----------------------------------------------------------------------------
1426 int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const
1428 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1430 if (PQstatus(connection) != CONNECTION_OK)
1432 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1435 strError = "Connection lost";
1436 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1441 if (StartTransaction())
1443 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to start transaction'\n");
1447 std::string elogin = login;
1449 if (EscapeString(elogin))
1451 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to escape login'\n");
1452 if (RollbackTransaction())
1454 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1461 MakeDate(date, year, month);
1463 std::stringstream query;
1464 query << "SELECT sp_add_month_stats("
1465 "'" << elogin << "',"
1466 "CAST('" << date << "' AS DATE), "
1467 "CAST(" << stat.cash << " AS dm_money), "
1468 "CAST(" << stat.freeMb << " AS dm_money), "
1469 "CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), "
1470 "CAST(" << stat.lastCashAdd << " AS dm_money), "
1471 "CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), "
1472 "CAST(" << stat.passiveTime << " AS INTEGER))";
1474 PGresult * result = PQexec(connection, query.str().c_str());
1476 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1478 strError = PQresultErrorMessage(result);
1480 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1481 if (RollbackTransaction())
1483 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1488 int tuples = PQntuples(result);
1492 strError = "Failed to fetch month stat's ID";
1493 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1495 if (RollbackTransaction())
1497 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1504 if (str2x(PQgetvalue(result, 0, 0), sid))
1506 strError = "Failed to convert string to int";
1507 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1509 if (RollbackTransaction())
1511 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1518 for (int dir = 0; dir < DIR_NUM; ++dir)
1521 query << "SELECT sp_add_month_stats_traffic ("
1523 "CAST(" << dir << " AS SMALLINT), "
1524 "CAST(" << stat.up[dir] << " AS BIGINT), "
1525 "CAST(" << stat.down[dir] << " AS BIGINT))";
1527 result = PQexec(connection, query.str().c_str());
1529 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1531 strError = PQresultErrorMessage(result);
1533 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): '%s'\n", strError.c_str());
1534 if (RollbackTransaction())
1536 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to rollback transaction'\n");
1544 if (CommitTransaction())
1546 printfd(__FILE__, "POSTGRESQL_STORE::SaveMonthStat(): 'Failed to commit transaction'\n");
1553 //-----------------------------------------------------------------------------
1554 int POSTGRESQL_STORE::SaveUserServices(uint32_t uid,
1555 const std::vector<std::string> & services) const
1560 std::ostringstream query;
1561 query << "DELETE FROM tb_users_services WHERE fk_user = " << uid;
1563 result = PQexec(connection, query.str().c_str());
1565 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1567 strError = PQresultErrorMessage(result);
1569 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1576 std::vector<std::string>::const_iterator it;
1578 for (it = services.begin(); it != services.end(); ++it)
1580 std::string ename = *it;
1582 if (EscapeString(ename))
1584 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): 'Failed to escape service name'\n");
1588 std::ostringstream query;
1589 query << "INSERT INTO tb_users_services "
1590 "(fk_user, fk_service) "
1593 "(SELECT pk_service "
1595 "WHERE name = '" << ename << "'))";
1597 result = PQexec(connection, query.str().c_str());
1599 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1601 strError = PQresultErrorMessage(result);
1603 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1613 //-----------------------------------------------------------------------------
1614 int POSTGRESQL_STORE::SaveUserIPs(uint32_t uid,
1615 const USER_IPS & ips) const
1620 std::ostringstream query;
1621 query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid;
1623 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());
1636 for (size_t i = 0; i < ips.Count(); ++i)
1638 std::ostringstream query;
1639 query << "INSERT INTO tb_allowed_ip "
1642 "(" << uid << ", CAST('"
1643 << inet_ntostring(ips[i].ip) << "/"
1644 << static_cast<int>(ips[i].mask) << "' AS INET))";
1646 result = PQexec(connection, query.str().c_str());
1648 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1650 strError = PQresultErrorMessage(result);
1652 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1662 //-----------------------------------------------------------------------------
1663 int POSTGRESQL_STORE::SaveUserData(uint32_t uid,
1664 const std::vector<std::string> & data) const
1666 for (unsigned i = 0; i < data.size(); ++i)
1668 std::string edata = data[i];
1670 if (EscapeString(edata))
1672 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): 'Failed to escape userdata field'\n");
1678 std::ostringstream query;
1679 query << "SELECT sp_set_user_data("
1681 << "CAST(" << i << " AS SMALLINT), "
1682 << "'" << edata << "')";
1684 result = PQexec(connection, query.str().c_str());
1686 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1688 strError = PQresultErrorMessage(result);
1690 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): '%s'\n", strError.c_str());