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 $
29 #include "postgresql_store.h"
31 #include "stg/user_conf.h"
32 #include "stg/user_stat.h"
33 #include "stg/user_ips.h"
34 #include "stg/user_traff.h"
35 #include "stg/common.h"
36 #include "stg/const.h"
37 #include "../../../stg_timer.h"
46 //-----------------------------------------------------------------------------
47 int POSTGRESQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
49 std::lock_guard lock(m_mutex);
51 if (PQstatus(connection) != CONNECTION_OK)
53 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
56 strError = "Connection lost";
57 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
64 if (StartTransaction())
66 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to start transaction'\n");
70 result = PQexec(connection, "SELECT name FROM tb_users");
72 if (PQresultStatus(result) != PGRES_TUPLES_OK)
74 strError = PQresultErrorMessage(result);
76 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
77 if (RollbackTransaction())
79 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to rollback transaction'\n");
84 int tuples = PQntuples(result);
86 for (int i = 0; i < tuples; ++i)
88 usersList->push_back(PQgetvalue(result, i, 0));
93 if (CommitTransaction())
95 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to commit transaction'\n");
102 //-----------------------------------------------------------------------------
103 int POSTGRESQL_STORE::AddUser(const std::string & name) const
105 std::lock_guard lock(m_mutex);
107 if (PQstatus(connection) != CONNECTION_OK)
109 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
112 strError = "Connection lost";
113 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
120 if (StartTransaction())
122 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to start transaction'\n");
126 std::string elogin = name;
128 if (EscapeString(elogin))
130 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to escape login'\n");
131 if (RollbackTransaction())
133 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
138 std::ostringstream query;
139 query << "SELECT sp_add_user('" << elogin << "')";
141 result = PQexec(connection, query.str().c_str());
143 if (PQresultStatus(result) != PGRES_TUPLES_OK)
145 strError = PQresultErrorMessage(result);
147 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
148 if (RollbackTransaction())
150 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
157 if (CommitTransaction())
159 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to commit transaction'\n");
166 //-----------------------------------------------------------------------------
167 int POSTGRESQL_STORE::DelUser(const std::string & login) const
169 std::lock_guard lock(m_mutex);
171 if (PQstatus(connection) != CONNECTION_OK)
173 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
176 strError = "Connection lost";
177 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
184 if (StartTransaction())
186 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to start transaction'\n");
190 std::string elogin = login;
192 if (EscapeString(elogin))
194 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to escape login'\n");
195 if (RollbackTransaction())
197 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
202 std::ostringstream query;
203 query << "DELETE FROM tb_users WHERE name = '" << elogin << "'";
205 result = PQexec(connection, query.str().c_str());
207 if (PQresultStatus(result) != PGRES_COMMAND_OK)
209 strError = PQresultErrorMessage(result);
211 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
212 if (RollbackTransaction())
214 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
221 if (CommitTransaction())
223 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to commit transaction'\n");
229 //-----------------------------------------------------------------------------
230 int POSTGRESQL_STORE::SaveUserStat(const STG::UserStat & stat,
231 const std::string & login) const
233 std::lock_guard lock(m_mutex);
235 return SaveStat(stat, login);
237 //-----------------------------------------------------------------------------
238 int POSTGRESQL_STORE::SaveStat(const STG::UserStat & stat,
239 const std::string & login,
243 if (PQstatus(connection) != CONNECTION_OK)
245 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
248 strError = "Connection lost";
249 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
256 if (StartTransaction())
258 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to start transaction'\n");
262 std::string elogin = login;
264 if (EscapeString(elogin))
266 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to escape login'\n");
267 if (RollbackTransaction())
269 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
274 std::ostringstream query;
275 query << "UPDATE tb_users SET "
276 "cash = " << stat.cash << ", "
277 "free_mb = " << stat.freeMb << ", "
278 "last_activity_time = CAST('" << formatTime(stat.lastActivityTime) << "' AS TIMESTAMP), "
279 "last_cash_add = " << stat.lastCashAdd << ", "
280 "last_cash_add_time = CAST('" << formatTime(stat.lastCashAddTime) << "' AS TIMESTAMP), "
281 "passive_time = " << stat.passiveTime << " "
282 "WHERE name = '" << elogin << "'";
284 result = PQexec(connection, query.str().c_str());
286 if (PQresultStatus(result) != PGRES_COMMAND_OK)
288 strError = PQresultErrorMessage(result);
290 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
291 if (RollbackTransaction())
293 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
302 MakeDate(date, year, month);
304 for (int dir = 0; dir < DIR_NUM; ++dir)
307 query << "SELECT sp_add_stats_traffic ("
308 "'" << elogin << "', "
309 "CAST('" << date << "' AS DATE), "
310 "CAST(" << dir << " AS SMALLINT), "
311 "CAST(" << stat.monthUp[dir] << " AS BIGINT), "
312 "CAST(" << stat.monthDown[dir] << " AS BIGINT))";
314 result = PQexec(connection, query.str().c_str());
316 if (PQresultStatus(result) != PGRES_TUPLES_OK)
318 strError = PQresultErrorMessage(result);
320 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
321 if (RollbackTransaction())
323 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
331 if (CommitTransaction())
333 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to commit transaction'\n");
340 //-----------------------------------------------------------------------------
341 int POSTGRESQL_STORE::SaveUserConf(const STG::UserConf & conf,
342 const std::string & login) const
344 std::lock_guard lock(m_mutex);
346 if (PQstatus(connection) != CONNECTION_OK)
348 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
351 strError = "Connection lost";
352 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
359 if (StartTransaction())
361 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to start transaction'\n");
365 std::string elogin = login;
367 if (EscapeString(elogin))
369 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape login'\n");
370 if (RollbackTransaction())
372 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
377 std::ostringstream query;
378 query << "SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'";
380 result = PQexec(connection, query.str().c_str());
382 if (PQresultStatus(result) != PGRES_TUPLES_OK)
384 strError = PQresultErrorMessage(result);
386 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
387 if (RollbackTransaction())
389 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
394 int tuples = PQntuples(result);
398 strError = "Failed to fetch user's ID";
399 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
401 if (RollbackTransaction())
403 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
411 std::stringstream tuple;
412 tuple << PQgetvalue(result, 0, 0);
419 std::string eaddress = conf.address;
420 std::string eemail = conf.email;
421 std::string egroup = conf.group;
422 std::string enote = conf.note;
423 std::string epassword = conf.password;
424 std::string ephone = conf.phone;
425 std::string erealname = conf.realName;
426 std::string etariffname = conf.tariffName;
427 std::string enexttariff = conf.nextTariff;
428 std::string ecorporation = conf.corp;
430 if (EscapeString(eaddress))
432 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
433 if (RollbackTransaction())
435 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
440 if (EscapeString(eemail))
442 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
443 if (RollbackTransaction())
445 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
450 if (EscapeString(egroup))
452 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
453 if (RollbackTransaction())
455 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
460 if (EscapeString(enote))
462 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
463 if (RollbackTransaction())
465 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
470 if (EscapeString(epassword))
472 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
473 if (RollbackTransaction())
475 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
480 if (EscapeString(ephone))
482 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
483 if (RollbackTransaction())
485 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
490 if (EscapeString(erealname))
492 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
493 if (RollbackTransaction())
495 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
500 if (EscapeString(etariffname))
502 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
503 if (RollbackTransaction())
505 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
510 if (EscapeString(enexttariff))
512 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
513 if (RollbackTransaction())
515 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
520 if (EscapeString(ecorporation))
522 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
523 if (RollbackTransaction())
525 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
531 query << "UPDATE tb_users SET "
532 "address = '" << eaddress << "', "
533 "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
534 "credit = " << conf.credit << ", "
535 "credit_expire = CAST('" << formatTime(conf.creditExpire) << "' AS TIMESTAMP), "
536 "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
537 "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
538 "email = '" << eemail << "', "
539 "grp = '" << egroup << "', "
540 "note = '" << enote << "', "
541 "passive = " << (conf.passive ? "'t'" : "'f'") << ", "
542 "passwd = '" << epassword << "', "
543 "phone = '" << ephone << "', "
544 "real_name = '" << erealname << "', "
545 "fk_tariff = (SELECT pk_tariff "
547 "WHERE name = '" << etariffname << "'), "
548 "fk_tariff_change = (SELECT pk_tariff "
550 "WHERE name = '" << enexttariff << "'), "
551 "fk_corporation = (SELECT pk_corporation "
552 "FROM tb_corporations "
553 "WHERE name = '" << ecorporation << "') "
554 "WHERE pk_user = " << uid;
556 result = PQexec(connection, query.str().c_str());
558 if (PQresultStatus(result) != PGRES_COMMAND_OK)
560 strError = PQresultErrorMessage(result);
562 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
563 if (RollbackTransaction())
565 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
572 if (SaveUserServices(uid, conf.services))
574 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
575 if (RollbackTransaction())
577 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
582 if (SaveUserData(uid, conf.userdata))
584 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's data'\n");
585 if (RollbackTransaction())
587 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
592 if (SaveUserIPs(uid, conf.ips))
594 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's IPs'\n");
595 if (RollbackTransaction())
597 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
602 if (CommitTransaction())
604 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to commit transaction'\n");
611 //-----------------------------------------------------------------------------
612 int POSTGRESQL_STORE::RestoreUserStat(STG::UserStat * stat,
613 const std::string & login) const
615 std::lock_guard lock(m_mutex);
617 if (PQstatus(connection) != CONNECTION_OK)
619 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
622 strError = "Connection lost";
623 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
630 if (StartTransaction())
632 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
636 std::string elogin = login;
638 if (EscapeString(elogin))
640 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
641 if (RollbackTransaction())
643 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
649 std::ostringstream query;
650 query << "SELECT cash, free_mb, "
651 "last_activity_time, last_cash_add, "
652 "last_cash_add_time, passive_time "
654 "WHERE name = '" << elogin << "'";
656 result = PQexec(connection, query.str().c_str());
659 if (PQresultStatus(result) != PGRES_TUPLES_OK)
661 strError = PQresultErrorMessage(result);
662 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
664 if (RollbackTransaction())
666 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
671 int tuples = PQntuples(result);
675 strError = "Failed to fetch user's stat";
676 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
678 if (RollbackTransaction())
680 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
686 std::stringstream tuple;
687 tuple << PQgetvalue(result, 0, 0) << " ";
688 tuple << PQgetvalue(result, 0, 1) << " ";
689 stat->lastActivityTime = readTime(PQgetvalue(result, 0, 2));
690 tuple << PQgetvalue(result, 0, 3) << " ";
691 stat->lastCashAddTime = readTime(PQgetvalue(result, 0, 4));
692 tuple << PQgetvalue(result, 0, 5) << " ";
699 >> stat->passiveTime;
703 std::ostringstream query;
704 query << "SELECT dir_num, upload, download "
705 "FROM tb_stats_traffic "
706 "WHERE fk_user IN (SELECT pk_user FROM tb_users WHERE name = '" << elogin << "') AND "
707 "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << formatTime(stgTime) << "' AS TIMESTAMP))";
709 result = PQexec(connection, query.str().c_str());
712 if (PQresultStatus(result) != PGRES_TUPLES_OK)
714 strError = PQresultErrorMessage(result);
715 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
717 if (RollbackTransaction())
719 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
724 tuples = PQntuples(result);
726 for (int i = 0; i < tuples; ++i)
728 std::stringstream tuple;
729 tuple << PQgetvalue(result, i, 0) << " ";
730 tuple << PQgetvalue(result, i, 1) << " ";
731 tuple << PQgetvalue(result, i, 2) << " ";
736 tuple >> stat->monthUp[dir];
737 tuple >> stat->monthDown[dir];
742 if (CommitTransaction())
744 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to commit transaction'\n");
751 //-----------------------------------------------------------------------------
752 int POSTGRESQL_STORE::RestoreUserConf(STG::UserConf * conf,
753 const std::string & login) const
755 std::lock_guard lock(m_mutex);
757 if (PQstatus(connection) != CONNECTION_OK)
759 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
762 strError = "Connection lost";
763 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
770 if (StartTransaction())
772 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
776 std::string elogin = login;
778 if (EscapeString(elogin))
780 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
781 if (RollbackTransaction())
783 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
789 std::ostringstream query;
790 query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, "
791 "tb_users.credit, tb_users.credit_expire, tb_users.disabled, "
792 "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, "
793 "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, "
794 "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name "
795 "FROM tb_users LEFT JOIN tb_tariffs AS tf1 "
796 "ON tf1.pk_tariff = tb_users.fk_tariff "
797 "LEFT JOIN tb_tariffs AS tf2 "
798 "ON tf2.pk_tariff = tb_users.fk_tariff_change "
799 "LEFT JOIN tb_corporations "
800 "ON tb_corporations.pk_corporation = tb_users.fk_corporation "
801 "WHERE tb_users.name = '" << elogin << "'";
803 result = PQexec(connection, query.str().c_str());
806 if (PQresultStatus(result) != PGRES_TUPLES_OK)
808 strError = PQresultErrorMessage(result);
809 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
811 if (RollbackTransaction())
813 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
818 int tuples = PQntuples(result);
822 strError = "Failed to fetch user's stat";
823 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
825 if (RollbackTransaction())
827 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
835 std::stringstream tuple;
836 tuple << PQgetvalue(result, 0, 0) << " "; // uid
837 conf->address = PQgetvalue(result, 0, 1); // address
838 conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
839 tuple << PQgetvalue(result, 0, 3) << " "; // credit
840 conf->creditExpire = readTime(PQgetvalue(result, 0, 4)); // creditExpire
841 conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
842 conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
843 conf->email = PQgetvalue(result, 0, 7); // email
844 conf->group = PQgetvalue(result, 0, 8); // group
845 conf->note = PQgetvalue(result, 0, 9); // note
846 conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1);
847 conf->password = PQgetvalue(result, 0, 11); // password
848 conf->phone = PQgetvalue(result, 0, 12); // phone
849 conf->realName = PQgetvalue(result, 0, 13); // realName
850 conf->tariffName = PQgetvalue(result, 0, 14); // tariffName
851 conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff
852 conf->corp = PQgetvalue(result, 0, 16); // corp
856 if (conf->tariffName == "")
857 conf->tariffName = NO_TARIFF_NAME;
858 if (conf->corp == "")
859 conf->corp = NO_CORP_NAME;
866 std::ostringstream query;
867 query << "SELECT name FROM tb_services "
868 "WHERE pk_service IN (SELECT fk_service "
869 "FROM tb_users_services "
870 "WHERE fk_user = " << uid << ")";
872 result = PQexec(connection, query.str().c_str());
875 if (PQresultStatus(result) != PGRES_TUPLES_OK)
877 strError = PQresultErrorMessage(result);
878 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
880 if (RollbackTransaction())
882 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
887 tuples = PQntuples(result);
889 for (int i = 0; i < tuples; ++i)
891 conf->services.push_back(PQgetvalue(result, i, 0));
897 std::ostringstream query;
898 query << "SELECT num, data "
899 "FROM tb_users_data "
900 "WHERE fk_user = " << uid;
902 result = PQexec(connection, query.str().c_str());
905 if (PQresultStatus(result) != PGRES_TUPLES_OK)
907 strError = PQresultErrorMessage(result);
908 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
910 if (RollbackTransaction())
912 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
917 tuples = PQntuples(result);
919 for (int i = 0; i < tuples; ++i)
922 if (str2x(PQgetvalue(result, i, 0), num))
924 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to convert string to int'\n");
928 if (num < USERDATA_NUM &&
931 conf->userdata[num] = PQgetvalue(result, i, 1);
939 std::ostringstream query;
940 query << "SELECT host(ip), masklen(ip) "
941 "FROM tb_allowed_ip "
942 "WHERE fk_user = " << uid;
944 result = PQexec(connection, query.str().c_str());
947 if (PQresultStatus(result) != PGRES_TUPLES_OK)
949 strError = PQresultErrorMessage(result);
950 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
952 if (RollbackTransaction())
954 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
959 tuples = PQntuples(result);
962 for (int i = 0; i < tuples; ++i)
966 im.ip = inet_strington(PQgetvalue(result, i, 0));
968 if (str2x(PQgetvalue(result, i, 1), im.mask))
970 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to fetch mask'\n");
980 if (CommitTransaction())
982 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to commit transaction'\n");
989 //-----------------------------------------------------------------------------
990 int POSTGRESQL_STORE::WriteUserChgLog(const std::string & login,
991 const std::string & admLogin,
993 const std::string & paramName,
994 const std::string & oldValue,
995 const std::string & newValue,
996 const std::string & message = "") const
998 std::lock_guard lock(m_mutex);
1000 if (PQstatus(connection) != CONNECTION_OK)
1002 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1005 strError = "Connection lost";
1006 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1013 if (StartTransaction())
1015 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to start transaction'\n");
1019 std::string elogin(login);
1020 std::string eadminLogin(admLogin);
1021 std::string eparam(paramName);
1022 std::string eold(oldValue);
1023 std::string enew(newValue);
1024 std::string emessage(message);
1026 if (EscapeString(elogin))
1028 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
1029 if (RollbackTransaction())
1031 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1036 if (EscapeString(eadminLogin))
1038 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
1039 if (RollbackTransaction())
1041 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1046 if (EscapeString(eparam))
1048 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
1049 if (RollbackTransaction())
1051 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1056 if (EscapeString(eold))
1058 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
1059 if (RollbackTransaction())
1061 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1066 if (EscapeString(enew))
1068 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
1069 if (RollbackTransaction())
1071 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1076 std::ostringstream query;
1077 query << "SELECT sp_add_param_log_entry("
1078 "'" << elogin << "', "
1079 "'" << eadminLogin << "', CAST('"
1080 << inet_ntostring(admIP) << "/32' AS INET), "
1081 "'" << eparam << "', "
1082 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1083 "'" << eold << "', "
1084 "'" << enew << "', "
1085 "'" << emessage << "')";
1087 result = PQexec(connection, query.str().c_str());
1089 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1091 strError = PQresultErrorMessage(result);
1093 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1094 if (RollbackTransaction())
1096 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1103 if (CommitTransaction())
1105 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to commit transaction'\n");
1112 //-----------------------------------------------------------------------------
1113 int POSTGRESQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1115 std::lock_guard lock(m_mutex);
1117 if (PQstatus(connection) != CONNECTION_OK)
1119 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1122 strError = "Connection lost";
1123 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1130 if (StartTransaction())
1132 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to start transaction'\n");
1136 std::string elogin(login);
1138 if (EscapeString(elogin))
1140 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
1141 if (RollbackTransaction())
1143 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1148 std::ostringstream query;
1151 query << "SELECT sp_add_session_log_entry("
1152 "'" << elogin << "', "
1153 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1155 << inet_ntostring(ip) << "/32' AS INET), 0)";
1159 query << "SELECT sp_add_session_log_entry("
1160 "'" << elogin << "', "
1161 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1163 << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
1166 result = PQexec(connection, query.str().c_str());
1168 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1170 strError = PQresultErrorMessage(result);
1172 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1173 if (RollbackTransaction())
1175 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1182 if (CommitTransaction())
1184 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to commit transaction'\n");
1191 //-----------------------------------------------------------------------------
1192 int POSTGRESQL_STORE::WriteUserDisconnect(const std::string & login,
1193 const STG::DirTraff & monthUp,
1194 const STG::DirTraff & monthDown,
1195 const STG::DirTraff & sessionUp,
1196 const STG::DirTraff & sessionDown,
1199 const std::string & reason) const
1201 std::lock_guard lock(m_mutex);
1203 if (PQstatus(connection) != CONNECTION_OK)
1205 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1208 strError = "Connection lost";
1209 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1216 if (StartTransaction())
1218 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to start transaction'\n");
1222 std::string elogin(login);
1224 if (EscapeString(elogin))
1226 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
1227 if (RollbackTransaction())
1229 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1234 std::string ereason(reason);
1236 if (EscapeString(ereason))
1238 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
1239 if (RollbackTransaction())
1241 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1247 std::ostringstream query;
1250 // Old database version - no freeMb logging support
1251 query << "SELECT sp_add_session_log_entry("
1252 "'" << elogin << "', "
1253 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1254 "'d', CAST('0.0.0.0/0' AS INET), "
1259 query << "SELECT sp_add_session_log_entry("
1260 "'" << elogin << "', "
1261 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1262 "'d', CAST('0.0.0.0/0' AS INET), "
1263 << cash << ", " << freeMb << ", '" << ereason << "')";
1266 result = PQexec(connection, query.str().c_str());
1269 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1271 strError = PQresultErrorMessage(result);
1273 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1274 if (RollbackTransaction())
1276 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1281 int tuples = PQntuples(result);
1285 strError = "Failed to fetch session's log ID";
1286 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1288 if (RollbackTransaction())
1290 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1297 if (str2x(PQgetvalue(result, 0, 0), lid))
1299 strError = "Failed to convert string to int";
1300 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1302 if (RollbackTransaction())
1304 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1311 for (int i = 0; i < DIR_NUM; ++i)
1313 std::ostringstream query;
1314 query << "INSERT INTO tb_sessions_data "
1318 "session_download, "
1324 << sessionUp[i] << ", "
1325 << sessionDown[i] << ", "
1326 << monthUp[i] << ", "
1327 << monthDown[i] << ")";
1329 result = PQexec(connection, query.str().c_str());
1331 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1333 strError = PQresultErrorMessage(result);
1335 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1336 if (RollbackTransaction())
1338 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1346 if (CommitTransaction())
1348 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to commit transaction'\n");
1355 //-----------------------------------------------------------------------------
1356 int POSTGRESQL_STORE::WriteDetailedStat(const STG::TraffStat & statTree,
1358 const std::string & login) const
1360 std::lock_guard lock(m_mutex);
1362 if (PQstatus(connection) != CONNECTION_OK)
1364 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1367 strError = "Connection lost";
1368 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1373 if (StartTransaction())
1375 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to start transaction'\n");
1379 std::string elogin(login);
1381 if (EscapeString(elogin))
1383 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
1384 if (RollbackTransaction())
1386 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1391 STG::TraffStat::const_iterator it;
1392 time_t currTime = time(NULL);
1394 for (it = statTree.begin(); it != statTree.end(); ++it)
1396 std::ostringstream query;
1397 query << "INSERT INTO tb_detail_stats "
1398 "(till_time, from_time, fk_user, "
1399 "dir_num, ip, download, upload, cost) "
1401 "CAST('" << formatTime(currTime) << "' AS TIMESTAMP), "
1402 "CAST('" << formatTime(lastStat) << "' AS TIMESTAMP), "
1403 "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
1404 << it->first.dir << ", "
1405 << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
1406 << it->second.down << ", "
1407 << it->second.up << ", "
1408 << it->second.cash << ")";
1410 PGresult * result = PQexec(connection, query.str().c_str());
1412 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1414 strError = PQresultErrorMessage(result);
1416 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1417 if (RollbackTransaction())
1419 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1427 if (CommitTransaction())
1429 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to commit transaction'\n");
1436 //-----------------------------------------------------------------------------
1437 int POSTGRESQL_STORE::SaveMonthStat(const STG::UserStat & stat, int month, int year, const std::string & login) const
1439 std::lock_guard lock(m_mutex);
1441 return SaveStat(stat, login, year, month);
1444 //-----------------------------------------------------------------------------
1445 int POSTGRESQL_STORE::SaveUserServices(uint32_t uid,
1446 const std::vector<std::string> & services) const
1451 std::ostringstream query;
1452 query << "DELETE FROM tb_users_services WHERE fk_user = " << uid;
1454 result = PQexec(connection, query.str().c_str());
1456 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1458 strError = PQresultErrorMessage(result);
1460 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1467 std::vector<std::string>::const_iterator it;
1469 for (it = services.begin(); it != services.end(); ++it)
1471 std::string ename = *it;
1473 if (EscapeString(ename))
1475 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): 'Failed to escape service name'\n");
1479 std::ostringstream query;
1480 query << "INSERT INTO tb_users_services "
1481 "(fk_user, fk_service) "
1484 "(SELECT pk_service "
1486 "WHERE name = '" << ename << "'))";
1488 result = PQexec(connection, query.str().c_str());
1490 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1492 strError = PQresultErrorMessage(result);
1494 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1504 //-----------------------------------------------------------------------------
1505 int POSTGRESQL_STORE::SaveUserIPs(uint32_t uid,
1506 const STG::UserIPs & ips) const
1511 std::ostringstream query;
1512 query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid;
1514 result = PQexec(connection, query.str().c_str());
1517 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1519 strError = PQresultErrorMessage(result);
1521 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1527 for (size_t i = 0; i < ips.count(); ++i)
1529 std::ostringstream query;
1530 query << "INSERT INTO tb_allowed_ip "
1533 "(" << uid << ", CAST('"
1534 << inet_ntostring(ips[i].ip) << "/"
1535 << static_cast<int>(ips[i].mask) << "' AS INET))";
1537 result = PQexec(connection, query.str().c_str());
1539 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1541 strError = PQresultErrorMessage(result);
1543 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1553 //-----------------------------------------------------------------------------
1554 int POSTGRESQL_STORE::SaveUserData(uint32_t uid,
1555 const std::vector<std::string> & data) const
1557 for (unsigned i = 0; i < data.size(); ++i)
1559 std::string edata = data[i];
1561 if (EscapeString(edata))
1563 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): 'Failed to escape userdata field'\n");
1569 std::ostringstream query;
1570 query << "SELECT sp_set_user_data("
1572 << "CAST(" << i << " AS SMALLINT), "
1573 << "'" << edata << "')";
1575 result = PQexec(connection, query.str().c_str());
1577 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1579 strError = PQresultErrorMessage(result);
1581 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): '%s'\n", strError.c_str());