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 "postgresql_store.h"
38 #include "stg_locker.h"
39 #include "../../../stg_timer.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());