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/common.h"
37 #include "stg/const.h"
38 #include "stg/locker.h"
39 #include "../../../stg_timer.h"
40 #include "postgresql_store.h"
42 //-----------------------------------------------------------------------------
43 int POSTGRESQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
45 STG_LOCKER lock(&mutex);
47 if (PQstatus(connection) != CONNECTION_OK)
49 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
52 strError = "Connection lost";
53 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
60 if (StartTransaction())
62 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to start transaction'\n");
66 result = PQexec(connection, "SELECT name FROM tb_users");
68 if (PQresultStatus(result) != PGRES_TUPLES_OK)
70 strError = PQresultErrorMessage(result);
72 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
73 if (RollbackTransaction())
75 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to rollback transaction'\n");
80 int tuples = PQntuples(result);
82 for (int i = 0; i < tuples; ++i)
84 usersList->push_back(PQgetvalue(result, i, 0));
89 if (CommitTransaction())
91 printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to commit transaction'\n");
98 //-----------------------------------------------------------------------------
99 int POSTGRESQL_STORE::AddUser(const std::string & name) const
101 STG_LOCKER lock(&mutex);
103 if (PQstatus(connection) != CONNECTION_OK)
105 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
108 strError = "Connection lost";
109 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
116 if (StartTransaction())
118 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to start transaction'\n");
122 std::string elogin = name;
124 if (EscapeString(elogin))
126 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to escape login'\n");
127 if (RollbackTransaction())
129 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
134 std::ostringstream query;
135 query << "SELECT sp_add_user('" << elogin << "')";
137 result = PQexec(connection, query.str().c_str());
139 if (PQresultStatus(result) != PGRES_TUPLES_OK)
141 strError = PQresultErrorMessage(result);
143 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
144 if (RollbackTransaction())
146 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
153 if (CommitTransaction())
155 printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to commit transaction'\n");
162 //-----------------------------------------------------------------------------
163 int POSTGRESQL_STORE::DelUser(const std::string & login) const
165 STG_LOCKER lock(&mutex);
167 if (PQstatus(connection) != CONNECTION_OK)
169 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
172 strError = "Connection lost";
173 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
180 if (StartTransaction())
182 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to start transaction'\n");
186 std::string elogin = login;
188 if (EscapeString(elogin))
190 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to escape login'\n");
191 if (RollbackTransaction())
193 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
198 std::ostringstream query;
199 query << "DELETE FROM tb_users WHERE name = '" << elogin << "'";
201 result = PQexec(connection, query.str().c_str());
203 if (PQresultStatus(result) != PGRES_COMMAND_OK)
205 strError = PQresultErrorMessage(result);
207 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
208 if (RollbackTransaction())
210 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
217 if (CommitTransaction())
219 printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to commit transaction'\n");
225 //-----------------------------------------------------------------------------
226 int POSTGRESQL_STORE::SaveUserStat(const USER_STAT & stat,
227 const std::string & login) const
229 STG_LOCKER lock(&mutex);
231 return SaveStat(stat, login);
233 //-----------------------------------------------------------------------------
234 int POSTGRESQL_STORE::SaveStat(const USER_STAT & stat,
235 const std::string & login,
239 if (PQstatus(connection) != CONNECTION_OK)
241 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
244 strError = "Connection lost";
245 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
252 if (StartTransaction())
254 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to start transaction'\n");
258 std::string elogin = login;
260 if (EscapeString(elogin))
262 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to escape login'\n");
263 if (RollbackTransaction())
265 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
270 std::ostringstream query;
271 query << "UPDATE tb_users SET "
272 "cash = " << stat.cash << ", "
273 "free_mb = " << stat.freeMb << ", "
274 "last_activity_time = CAST('" << formatTime(stat.lastActivityTime) << "' AS TIMESTAMP), "
275 "last_cash_add = " << stat.lastCashAdd << ", "
276 "last_cash_add_time = CAST('" << formatTime(stat.lastCashAddTime) << "' AS TIMESTAMP), "
277 "passive_time = " << stat.passiveTime << " "
278 "WHERE name = '" << elogin << "'";
280 result = PQexec(connection, query.str().c_str());
282 if (PQresultStatus(result) != PGRES_COMMAND_OK)
284 strError = PQresultErrorMessage(result);
286 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
287 if (RollbackTransaction())
289 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
298 MakeDate(date, year, month);
300 for (int dir = 0; dir < DIR_NUM; ++dir)
303 query << "SELECT sp_add_stats_traffic ("
304 "'" << elogin << "', "
305 "CAST('" << date << "' AS DATE), "
306 "CAST(" << dir << " AS SMALLINT), "
307 "CAST(" << stat.monthUp[dir] << " AS BIGINT), "
308 "CAST(" << stat.monthDown[dir] << " AS BIGINT))";
310 result = PQexec(connection, query.str().c_str());
312 if (PQresultStatus(result) != PGRES_TUPLES_OK)
314 strError = PQresultErrorMessage(result);
316 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
317 if (RollbackTransaction())
319 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
327 if (CommitTransaction())
329 printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to commit transaction'\n");
336 //-----------------------------------------------------------------------------
337 int POSTGRESQL_STORE::SaveUserConf(const USER_CONF & conf,
338 const std::string & login) const
340 STG_LOCKER lock(&mutex);
342 if (PQstatus(connection) != CONNECTION_OK)
344 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
347 strError = "Connection lost";
348 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
355 if (StartTransaction())
357 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to start transaction'\n");
361 std::string elogin = login;
363 if (EscapeString(elogin))
365 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape login'\n");
366 if (RollbackTransaction())
368 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
373 std::ostringstream query;
374 query << "SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'";
376 result = PQexec(connection, query.str().c_str());
378 if (PQresultStatus(result) != PGRES_TUPLES_OK)
380 strError = PQresultErrorMessage(result);
382 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
383 if (RollbackTransaction())
385 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
390 int tuples = PQntuples(result);
394 strError = "Failed to fetch user's ID";
395 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
397 if (RollbackTransaction())
399 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
407 std::stringstream tuple;
408 tuple << PQgetvalue(result, 0, 0);
415 std::string eaddress = conf.address;
416 std::string eemail = conf.email;
417 std::string egroup = conf.group;
418 std::string enote = conf.note;
419 std::string epassword = conf.password;
420 std::string ephone = conf.phone;
421 std::string erealname = conf.realName;
422 std::string etariffname = conf.tariffName;
423 std::string enexttariff = conf.nextTariff;
424 std::string ecorporation = conf.corp;
426 if (EscapeString(eaddress))
428 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
429 if (RollbackTransaction())
431 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
436 if (EscapeString(eemail))
438 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
439 if (RollbackTransaction())
441 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
446 if (EscapeString(egroup))
448 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
449 if (RollbackTransaction())
451 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
456 if (EscapeString(enote))
458 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
459 if (RollbackTransaction())
461 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
466 if (EscapeString(epassword))
468 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
469 if (RollbackTransaction())
471 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
476 if (EscapeString(ephone))
478 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
479 if (RollbackTransaction())
481 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
486 if (EscapeString(erealname))
488 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
489 if (RollbackTransaction())
491 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
496 if (EscapeString(etariffname))
498 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
499 if (RollbackTransaction())
501 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
506 if (EscapeString(enexttariff))
508 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
509 if (RollbackTransaction())
511 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
516 if (EscapeString(ecorporation))
518 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
519 if (RollbackTransaction())
521 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
527 query << "UPDATE tb_users SET "
528 "address = '" << eaddress << "', "
529 "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
530 "credit = " << conf.credit << ", "
531 "credit_expire = CAST('" << formatTime(conf.creditExpire) << "' AS TIMESTAMP), "
532 "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
533 "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
534 "email = '" << eemail << "', "
535 "grp = '" << egroup << "', "
536 "note = '" << enote << "', "
537 "passive = " << (conf.passive ? "'t'" : "'f'") << ", "
538 "passwd = '" << epassword << "', "
539 "phone = '" << ephone << "', "
540 "real_name = '" << erealname << "', "
541 "fk_tariff = (SELECT pk_tariff "
543 "WHERE name = '" << etariffname << "'), "
544 "fk_tariff_change = (SELECT pk_tariff "
546 "WHERE name = '" << enexttariff << "'), "
547 "fk_corporation = (SELECT pk_corporation "
548 "FROM tb_corporations "
549 "WHERE name = '" << ecorporation << "') "
550 "WHERE pk_user = " << uid;
552 result = PQexec(connection, query.str().c_str());
554 if (PQresultStatus(result) != PGRES_COMMAND_OK)
556 strError = PQresultErrorMessage(result);
558 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
559 if (RollbackTransaction())
561 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
568 if (SaveUserServices(uid, conf.services))
570 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
571 if (RollbackTransaction())
573 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
578 if (SaveUserData(uid, conf.userdata))
580 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's data'\n");
581 if (RollbackTransaction())
583 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
588 if (SaveUserIPs(uid, conf.ips))
590 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's IPs'\n");
591 if (RollbackTransaction())
593 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
598 if (CommitTransaction())
600 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to commit transaction'\n");
607 //-----------------------------------------------------------------------------
608 int POSTGRESQL_STORE::RestoreUserStat(USER_STAT * stat,
609 const std::string & login) const
611 STG_LOCKER lock(&mutex);
613 if (PQstatus(connection) != CONNECTION_OK)
615 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
618 strError = "Connection lost";
619 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
626 if (StartTransaction())
628 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
632 std::string elogin = login;
634 if (EscapeString(elogin))
636 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
637 if (RollbackTransaction())
639 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
645 std::ostringstream query;
646 query << "SELECT cash, free_mb, "
647 "last_activity_time, last_cash_add, "
648 "last_cash_add_time, passive_time "
650 "WHERE name = '" << elogin << "'";
652 result = PQexec(connection, query.str().c_str());
655 if (PQresultStatus(result) != PGRES_TUPLES_OK)
657 strError = PQresultErrorMessage(result);
658 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
660 if (RollbackTransaction())
662 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
667 int tuples = PQntuples(result);
671 strError = "Failed to fetch user's stat";
672 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
674 if (RollbackTransaction())
676 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
682 std::stringstream tuple;
683 tuple << PQgetvalue(result, 0, 0) << " ";
684 tuple << PQgetvalue(result, 0, 1) << " ";
685 stat->lastActivityTime = readTime(PQgetvalue(result, 0, 2));
686 tuple << PQgetvalue(result, 0, 3) << " ";
687 stat->lastCashAddTime = readTime(PQgetvalue(result, 0, 4));
688 tuple << PQgetvalue(result, 0, 5) << " ";
695 >> stat->passiveTime;
699 std::ostringstream query;
700 query << "SELECT dir_num, upload, download "
701 "FROM tb_stats_traffic "
702 "WHERE fk_user IN (SELECT pk_user FROM tb_users WHERE name = '" << elogin << "') AND "
703 "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << formatTime(stgTime) << "' AS TIMESTAMP))";
705 result = PQexec(connection, query.str().c_str());
708 if (PQresultStatus(result) != PGRES_TUPLES_OK)
710 strError = PQresultErrorMessage(result);
711 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
713 if (RollbackTransaction())
715 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
720 tuples = PQntuples(result);
722 for (int i = 0; i < tuples; ++i)
724 std::stringstream tuple;
725 tuple << PQgetvalue(result, i, 0) << " ";
726 tuple << PQgetvalue(result, i, 1) << " ";
727 tuple << PQgetvalue(result, i, 2) << " ";
732 tuple >> stat->monthUp[dir];
733 tuple >> stat->monthDown[dir];
738 if (CommitTransaction())
740 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to commit transaction'\n");
747 //-----------------------------------------------------------------------------
748 int POSTGRESQL_STORE::RestoreUserConf(USER_CONF * conf,
749 const std::string & login) const
751 STG_LOCKER lock(&mutex);
753 if (PQstatus(connection) != CONNECTION_OK)
755 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
758 strError = "Connection lost";
759 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
766 if (StartTransaction())
768 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to start transaction'\n");
772 std::string elogin = login;
774 if (EscapeString(elogin))
776 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
777 if (RollbackTransaction())
779 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
785 std::ostringstream query;
786 query << "SELECT tb_users.pk_user, tb_users.address, tb_users.always_online, "
787 "tb_users.credit, tb_users.credit_expire, tb_users.disabled, "
788 "tb_users.disabled_detail_stat, tb_users.email, tb_users.grp, "
789 "tb_users.note, tb_users.passive, tb_users.passwd, tb_users.phone, "
790 "tb_users.real_name, tf1.name, tf2.name, tb_corporations.name "
791 "FROM tb_users LEFT JOIN tb_tariffs AS tf1 "
792 "ON tf1.pk_tariff = tb_users.fk_tariff "
793 "LEFT JOIN tb_tariffs AS tf2 "
794 "ON tf2.pk_tariff = tb_users.fk_tariff_change "
795 "LEFT JOIN tb_corporations "
796 "ON tb_corporations.pk_corporation = tb_users.fk_corporation "
797 "WHERE tb_users.name = '" << elogin << "'";
799 result = PQexec(connection, query.str().c_str());
802 if (PQresultStatus(result) != PGRES_TUPLES_OK)
804 strError = PQresultErrorMessage(result);
805 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
807 if (RollbackTransaction())
809 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
814 int tuples = PQntuples(result);
818 strError = "Failed to fetch user's stat";
819 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
821 if (RollbackTransaction())
823 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
831 std::stringstream tuple;
832 tuple << PQgetvalue(result, 0, 0) << " "; // uid
833 conf->address = PQgetvalue(result, 0, 1); // address
834 conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
835 tuple << PQgetvalue(result, 0, 3) << " "; // credit
836 conf->creditExpire = readTime(PQgetvalue(result, 0, 4)); // creditExpire
837 conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
838 conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
839 conf->email = PQgetvalue(result, 0, 7); // email
840 conf->group = PQgetvalue(result, 0, 8); // group
841 conf->note = PQgetvalue(result, 0, 9); // note
842 conf->passive = !strncmp(PQgetvalue(result, 0, 10), "t", 1);
843 conf->password = PQgetvalue(result, 0, 11); // password
844 conf->phone = PQgetvalue(result, 0, 12); // phone
845 conf->realName = PQgetvalue(result, 0, 13); // realName
846 conf->tariffName = PQgetvalue(result, 0, 14); // tariffName
847 conf->nextTariff = PQgetvalue(result, 0, 15); // nextTariff
848 conf->corp = PQgetvalue(result, 0, 16); // corp
852 if (conf->tariffName == "")
853 conf->tariffName = NO_TARIFF_NAME;
854 if (conf->corp == "")
855 conf->corp = NO_CORP_NAME;
862 std::ostringstream query;
863 query << "SELECT name FROM tb_services "
864 "WHERE pk_service IN (SELECT fk_service "
865 "FROM tb_users_services "
866 "WHERE fk_user = " << uid << ")";
868 result = PQexec(connection, query.str().c_str());
871 if (PQresultStatus(result) != PGRES_TUPLES_OK)
873 strError = PQresultErrorMessage(result);
874 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
876 if (RollbackTransaction())
878 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
883 tuples = PQntuples(result);
885 for (int i = 0; i < tuples; ++i)
887 conf->services.push_back(PQgetvalue(result, i, 0));
893 std::ostringstream query;
894 query << "SELECT num, data "
895 "FROM tb_users_data "
896 "WHERE fk_user = " << uid;
898 result = PQexec(connection, query.str().c_str());
901 if (PQresultStatus(result) != PGRES_TUPLES_OK)
903 strError = PQresultErrorMessage(result);
904 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
906 if (RollbackTransaction())
908 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
913 tuples = PQntuples(result);
915 for (int i = 0; i < tuples; ++i)
918 if (str2x(PQgetvalue(result, i, 0), num))
920 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to convert string to int'\n");
924 if (num < USERDATA_NUM &&
927 conf->userdata[num] = PQgetvalue(result, i, 1);
935 std::ostringstream query;
936 query << "SELECT host(ip), masklen(ip) "
937 "FROM tb_allowed_ip "
938 "WHERE fk_user = " << uid;
940 result = PQexec(connection, query.str().c_str());
943 if (PQresultStatus(result) != PGRES_TUPLES_OK)
945 strError = PQresultErrorMessage(result);
946 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
948 if (RollbackTransaction())
950 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
955 tuples = PQntuples(result);
958 for (int i = 0; i < tuples; ++i)
962 im.ip = inet_strington(PQgetvalue(result, i, 0));
964 if (str2x(PQgetvalue(result, i, 1), im.mask))
966 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to fetch mask'\n");
976 if (CommitTransaction())
978 printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to commit transaction'\n");
985 //-----------------------------------------------------------------------------
986 int POSTGRESQL_STORE::WriteUserChgLog(const std::string & login,
987 const std::string & admLogin,
989 const std::string & paramName,
990 const std::string & oldValue,
991 const std::string & newValue,
992 const std::string & message = "") const
994 STG_LOCKER lock(&mutex);
996 if (PQstatus(connection) != CONNECTION_OK)
998 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1001 strError = "Connection lost";
1002 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1009 if (StartTransaction())
1011 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to start transaction'\n");
1015 std::string elogin(login);
1016 std::string eadminLogin(admLogin);
1017 std::string eparam(paramName);
1018 std::string eold(oldValue);
1019 std::string enew(newValue);
1020 std::string emessage(message);
1022 if (EscapeString(elogin))
1024 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
1025 if (RollbackTransaction())
1027 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1032 if (EscapeString(eadminLogin))
1034 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
1035 if (RollbackTransaction())
1037 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1042 if (EscapeString(eparam))
1044 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
1045 if (RollbackTransaction())
1047 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1052 if (EscapeString(eold))
1054 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
1055 if (RollbackTransaction())
1057 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1062 if (EscapeString(enew))
1064 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
1065 if (RollbackTransaction())
1067 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1072 std::ostringstream query;
1073 query << "SELECT sp_add_param_log_entry("
1074 "'" << elogin << "', "
1075 "'" << eadminLogin << "', CAST('"
1076 << inet_ntostring(admIP) << "/32' AS INET), "
1077 "'" << eparam << "', "
1078 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1079 "'" << eold << "', "
1080 "'" << enew << "', "
1081 "'" << emessage << "')";
1083 result = PQexec(connection, query.str().c_str());
1085 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1087 strError = PQresultErrorMessage(result);
1089 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): '%s'\n", strError.c_str());
1090 if (RollbackTransaction())
1092 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
1099 if (CommitTransaction())
1101 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to commit transaction'\n");
1108 //-----------------------------------------------------------------------------
1109 int POSTGRESQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
1111 STG_LOCKER lock(&mutex);
1113 if (PQstatus(connection) != CONNECTION_OK)
1115 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1118 strError = "Connection lost";
1119 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1126 if (StartTransaction())
1128 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to start transaction'\n");
1132 std::string elogin(login);
1134 if (EscapeString(elogin))
1136 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
1137 if (RollbackTransaction())
1139 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1144 std::ostringstream query;
1147 query << "SELECT sp_add_session_log_entry("
1148 "'" << elogin << "', "
1149 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1151 << inet_ntostring(ip) << "/32' AS INET), 0)";
1155 query << "SELECT sp_add_session_log_entry("
1156 "'" << elogin << "', "
1157 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1159 << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
1162 result = PQexec(connection, query.str().c_str());
1164 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1166 strError = PQresultErrorMessage(result);
1168 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): '%s'\n", strError.c_str());
1169 if (RollbackTransaction())
1171 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
1178 if (CommitTransaction())
1180 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to commit transaction'\n");
1187 //-----------------------------------------------------------------------------
1188 int POSTGRESQL_STORE::WriteUserDisconnect(const std::string & login,
1189 const DIR_TRAFF & monthUp,
1190 const DIR_TRAFF & monthDown,
1191 const DIR_TRAFF & sessionUp,
1192 const DIR_TRAFF & sessionDown,
1195 const std::string & reason) const
1197 STG_LOCKER lock(&mutex);
1199 if (PQstatus(connection) != CONNECTION_OK)
1201 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1204 strError = "Connection lost";
1205 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1212 if (StartTransaction())
1214 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to start transaction'\n");
1218 std::string elogin(login);
1220 if (EscapeString(elogin))
1222 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
1223 if (RollbackTransaction())
1225 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1230 std::string ereason(reason);
1232 if (EscapeString(ereason))
1234 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
1235 if (RollbackTransaction())
1237 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1243 std::ostringstream query;
1246 // Old database version - no freeMb logging support
1247 query << "SELECT sp_add_session_log_entry("
1248 "'" << elogin << "', "
1249 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1250 "'d', CAST('0.0.0.0/0' AS INET), "
1255 query << "SELECT sp_add_session_log_entry("
1256 "'" << elogin << "', "
1257 "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
1258 "'d', CAST('0.0.0.0/0' AS INET), "
1259 << cash << ", " << freeMb << ", '" << ereason << "')";
1262 result = PQexec(connection, query.str().c_str());
1265 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1267 strError = PQresultErrorMessage(result);
1269 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1270 if (RollbackTransaction())
1272 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1277 int tuples = PQntuples(result);
1281 strError = "Failed to fetch session's log ID";
1282 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
1284 if (RollbackTransaction())
1286 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1293 if (str2x(PQgetvalue(result, 0, 0), lid))
1295 strError = "Failed to convert string to int";
1296 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1298 if (RollbackTransaction())
1300 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1307 for (int i = 0; i < DIR_NUM; ++i)
1309 std::ostringstream query;
1310 query << "INSERT INTO tb_sessions_data "
1314 "session_download, "
1320 << sessionUp[i] << ", "
1321 << sessionDown[i] << ", "
1322 << monthUp[i] << ", "
1323 << monthDown[i] << ")";
1325 result = PQexec(connection, query.str().c_str());
1327 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1329 strError = PQresultErrorMessage(result);
1331 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
1332 if (RollbackTransaction())
1334 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
1342 if (CommitTransaction())
1344 printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to commit transaction'\n");
1351 //-----------------------------------------------------------------------------
1352 int POSTGRESQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
1354 const std::string & login) const
1356 STG_LOCKER lock(&mutex);
1358 if (PQstatus(connection) != CONNECTION_OK)
1360 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
1363 strError = "Connection lost";
1364 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1369 if (StartTransaction())
1371 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to start transaction'\n");
1375 std::string elogin(login);
1377 if (EscapeString(elogin))
1379 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
1380 if (RollbackTransaction())
1382 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1387 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator it;
1388 time_t currTime = time(NULL);
1390 for (it = statTree.begin(); it != statTree.end(); ++it)
1392 std::ostringstream query;
1393 query << "INSERT INTO tb_detail_stats "
1394 "(till_time, from_time, fk_user, "
1395 "dir_num, ip, download, upload, cost) "
1397 "CAST('" << formatTime(currTime) << "' AS TIMESTAMP), "
1398 "CAST('" << formatTime(lastStat) << "' AS TIMESTAMP), "
1399 "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
1400 << it->first.dir << ", "
1401 << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
1402 << it->second.down << ", "
1403 << it->second.up << ", "
1404 << it->second.cash << ")";
1406 PGresult * result = PQexec(connection, query.str().c_str());
1408 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1410 strError = PQresultErrorMessage(result);
1412 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): '%s'\n", strError.c_str());
1413 if (RollbackTransaction())
1415 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
1423 if (CommitTransaction())
1425 printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to commit transaction'\n");
1432 //-----------------------------------------------------------------------------
1433 int POSTGRESQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const
1435 STG_LOCKER lock(&mutex);
1437 return SaveStat(stat, login, year, month);
1440 //-----------------------------------------------------------------------------
1441 int POSTGRESQL_STORE::SaveUserServices(uint32_t uid,
1442 const std::vector<std::string> & services) const
1447 std::ostringstream query;
1448 query << "DELETE FROM tb_users_services WHERE fk_user = " << uid;
1450 result = PQexec(connection, query.str().c_str());
1452 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1454 strError = PQresultErrorMessage(result);
1456 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1463 std::vector<std::string>::const_iterator it;
1465 for (it = services.begin(); it != services.end(); ++it)
1467 std::string ename = *it;
1469 if (EscapeString(ename))
1471 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): 'Failed to escape service name'\n");
1475 std::ostringstream query;
1476 query << "INSERT INTO tb_users_services "
1477 "(fk_user, fk_service) "
1480 "(SELECT pk_service "
1482 "WHERE name = '" << ename << "'))";
1484 result = PQexec(connection, query.str().c_str());
1486 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1488 strError = PQresultErrorMessage(result);
1490 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserServices(): '%s'\n", strError.c_str());
1500 //-----------------------------------------------------------------------------
1501 int POSTGRESQL_STORE::SaveUserIPs(uint32_t uid,
1502 const USER_IPS & ips) const
1507 std::ostringstream query;
1508 query << "DELETE FROM tb_allowed_ip WHERE fk_user = " << uid;
1510 result = PQexec(connection, query.str().c_str());
1513 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1515 strError = PQresultErrorMessage(result);
1517 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1523 for (size_t i = 0; i < ips.Count(); ++i)
1525 std::ostringstream query;
1526 query << "INSERT INTO tb_allowed_ip "
1529 "(" << uid << ", CAST('"
1530 << inet_ntostring(ips[i].ip) << "/"
1531 << static_cast<int>(ips[i].mask) << "' AS INET))";
1533 result = PQexec(connection, query.str().c_str());
1535 if (PQresultStatus(result) != PGRES_COMMAND_OK)
1537 strError = PQresultErrorMessage(result);
1539 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserIPs(): '%s'\n", strError.c_str());
1549 //-----------------------------------------------------------------------------
1550 int POSTGRESQL_STORE::SaveUserData(uint32_t uid,
1551 const std::vector<std::string> & data) const
1553 for (unsigned i = 0; i < data.size(); ++i)
1555 std::string edata = data[i];
1557 if (EscapeString(edata))
1559 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): 'Failed to escape userdata field'\n");
1565 std::ostringstream query;
1566 query << "SELECT sp_set_user_data("
1568 << "CAST(" << i << " AS SMALLINT), "
1569 << "'" << edata << "')";
1571 result = PQexec(connection, query.str().c_str());
1573 if (PQresultStatus(result) != PGRES_TUPLES_OK)
1575 strError = PQresultErrorMessage(result);
1577 printfd(__FILE__, "POSTGRESQL_STORE::SaveUserData(): '%s'\n", strError.c_str());