From f907011b4827e85763372cdea76944b3b1cc3fd2 Mon Sep 17 00:00:00 2001 From: Maxim Mamontov Date: Wed, 27 Nov 2013 21:46:11 +0200 Subject: [PATCH 1/1] Implemented daily fee charge with backward compatibility. --- doc/xmlrpc/API-tariffs.xml | 33 +++++ include/stg/tariff.h | 32 ++++- include/stg/tariff_conf.h | 40 +++--- projects/convertor/convertor.conf | 39 +++--- projects/stargazer/build | 3 +- .../stargazer/inst/var/01-alter-02.mysql.sql | 9 +- projects/stargazer/inst/var/01-alter-02.sql | 2 +- .../configuration/rpcconfig/tariff_helper.cpp | 6 + .../configuration/sgconfig/parser_tariff.cpp | 8 ++ .../plugins/store/files/file_store.cpp | 9 +- .../stargazer/plugins/store/firebird/Makefile | 3 + .../plugins/store/firebird/firebird_store.cpp | 42 +++++- .../plugins/store/firebird/firebird_store.h | 5 + .../store/firebird/firebird_store_tariffs.cpp | 51 +++++-- .../stargazer/plugins/store/mysql/Makefile | 1 + .../plugins/store/mysql/mysql_store.cpp | 125 ++++++++++++++++-- .../plugins/store/mysql/mysql_store.h | 6 +- .../plugins/store/postgresql/Makefile | 1 + .../store/postgresql/postgresql_store.cpp | 6 +- .../store/postgresql/postgresql_store.h | 4 + .../postgresql/postgresql_store_tariffs.cpp | 83 +++++++----- projects/stargazer/tariff_impl.h | 1 + projects/stargazer/user_impl.cpp | 39 ++++++ projects/stargazer/user_impl.h | 1 + projects/stargazer/users_impl.cpp | 2 + 25 files changed, 445 insertions(+), 106 deletions(-) diff --git a/doc/xmlrpc/API-tariffs.xml b/doc/xmlrpc/API-tariffs.xml index d36b01dd..9b84889a 100644 --- a/doc/xmlrpc/API-tariffs.xml +++ b/doc/xmlrpc/API-tariffs.xml @@ -113,6 +113,17 @@ + + string period + + Периодичность снятия абонплаты: + + month — ежемесячное снятие + day — ежедневное снятие + + + + array of struct dirprices @@ -277,6 +288,17 @@ + + string period + + Периодичность снятия абонплаты: + + month — ежемесячное снятие + day — ежедневное снятие + + + + array of struct dirprices @@ -541,6 +563,17 @@ + + string period + + Периодичность снятия абонплаты: + + month — ежемесячное снятие + day — ежедневное снятие + + + + array of struct dirprices diff --git a/include/stg/tariff.h b/include/stg/tariff.h index a5b1d2e9..d0bf20b6 100644 --- a/include/stg/tariff.h +++ b/include/stg/tariff.h @@ -21,15 +21,21 @@ #ifndef TARIFF_H #define TARIFF_H -#include +#include "os_int.h" #include +#include +#include -#include "os_int.h" -#include "tariff_conf.h" +struct TARIFF_DATA; class TARIFF { public: + enum PERIOD { DAY = 0, MONTH }; + + static std::string PeriodToString(PERIOD period); + static PERIOD StringToPeriod(const std::string& value); + virtual ~TARIFF() {} virtual double GetPriceWithTraffType(uint64_t up, uint64_t down, @@ -39,6 +45,7 @@ public: virtual double GetPassiveCost() const = 0; virtual double GetFee() const = 0; virtual double GetFree() const = 0; + virtual PERIOD GetPeriod() const = 0; virtual const std::string & GetName() const = 0; virtual void SetName(const std::string & name) = 0; @@ -49,4 +56,23 @@ public: virtual const TARIFF_DATA & GetTariffData() const = 0; }; +inline +std::string TARIFF::PeriodToString(TARIFF::PERIOD period) +{ +switch (period) + { + case DAY: return "day"; + case MONTH: return "month"; + } +return "month"; // Classic behaviour. +} + +inline +TARIFF::PERIOD TARIFF::StringToPeriod(const std::string& value) +{ +if (strcasecmp(value.c_str(), "day") == 0) + return DAY; +return MONTH; // Classic behaviour. +} + #endif diff --git a/include/stg/tariff_conf.h b/include/stg/tariff_conf.h index 5b2eebb9..376ed378 100644 --- a/include/stg/tariff_conf.h +++ b/include/stg/tariff_conf.h @@ -27,12 +27,13 @@ #ifndef TARIFF_CONF_H #define TARIFF_CONF_H -#include -#include - +#include "tariff.h" #include "resetable.h" #include "const.h" +#include +#include + //----------------------------------------------------------------------------- enum { @@ -135,18 +136,20 @@ struct DIRPRICE_DATA_RES //----------------------------------------------------------------------------- struct TARIFF_CONF { - double fee; - double free; - int traffType; - double passiveCost; - std::string name; + double fee; + double free; + int traffType; + double passiveCost; + std::string name; + TARIFF::PERIOD period; TARIFF_CONF() : fee(0), free(0), traffType(TRAFF_UP_DOWN), passiveCost(0), - name() + name(), + period(TARIFF::MONTH) {} TARIFF_CONF(const std::string & n) @@ -154,7 +157,8 @@ struct TARIFF_CONF free(0), traffType(TRAFF_UP_DOWN), passiveCost(0), - name(n) + name(n), + period(TARIFF::MONTH) {} }; //----------------------------------------------------------------------------- @@ -165,7 +169,8 @@ struct TARIFF_CONF_RES free(), traffType(), passiveCost(), - name() + name(), + period() {} TARIFF_CONF_RES & operator=(const TARIFF_CONF & tc) @@ -175,6 +180,7 @@ struct TARIFF_CONF_RES traffType = tc.traffType; passiveCost = tc.passiveCost; name = tc.name; + period = tc.period; return *this; } @@ -186,14 +192,16 @@ struct TARIFF_CONF_RES tc.name = name; tc.passiveCost = passiveCost; tc.traffType = traffType; + tc.period = period; return tc; } - RESETABLE fee; - RESETABLE free; - RESETABLE traffType; - RESETABLE passiveCost; - RESETABLE name; + RESETABLE fee; + RESETABLE free; + RESETABLE traffType; + RESETABLE passiveCost; + RESETABLE name; + RESETABLE period; }; //----------------------------------------------------------------------------- struct TARIFF_DATA diff --git a/projects/convertor/convertor.conf b/projects/convertor/convertor.conf index 41e18b68..ab8e8e8d 100644 --- a/projects/convertor/convertor.conf +++ b/projects/convertor/convertor.conf @@ -6,10 +6,9 @@ # Parameter: required # Value: directory path # Default: /usr/lib/stg -ModulesPath = /usr/lib/stg +ModulesPath = ../stargazer/modules -################################################################################# -Store module +#################################################################################Store module # Configure the module that works with the database server # Option - the name of the module without 'mod_' at the beginning and '.so' # in the end ie full name of the module mod_store_files.so @@ -18,7 +17,7 @@ Store module # Working server directory, provides data on tariffs, users, administrators. # Parameter: required # Value: directory path - WorkDir = /var/stargazer + WorkDir = ../stargazer/var/stargazer # Owner, group and permissions of the files of user statistics (stat) # Parameter: required @@ -48,77 +47,77 @@ Store module # Parameter: required # Value: IP address or DNS name # Default: localhost - # server = localhost +# server = localhost # Path to the database on the server or its alias # Parameter: required # Value: file path # Default: /var/stg/stargazer.fdb - # database = /var/stg/stargazer.fdb +# database = /var/stg/stargazer.fdb # Database username # Parameter: required # Value: any, supported by database # Default: stg - # user = stg +# user = stg # Database password # Parameter: required # Value: any, supported by database # Default: 123456 - # password = 123456 +# password = 123456 # - +# # Database server address # Parameter: required # Value: IP address or DNS name # Default: localhost - server = localhost +# server = altair.local # Database name # Parameter: required # Value: any, supported by database # Default: stargazer - database = stargazer +# database = stg # Database username # Parameter: mandatory # Value: any, supported by database # Default: stg - user = stg +# user = stg # Database password # Parameter: required # Value: any, supported by database # Default: 123456 - password = 123456 +# password = 123456 - +# -# + # Database server address # Parameter: required # Value: IP address or DNS name # Default: localhost - # dbhost = localhost + dbhost = altair.local # Database name # Parameter: required # Value: any, supported by database # Default: stg - # dbname = stg + dbname = stg # Database username # Parameter: required # Value: any, supported by database # Default: stg - # dbuser = stg + dbuser = stg # Database password # Parameter: required # Value: any, supported by database # Default: 123456 - # rootdbpass = 123456 + rootdbpass = 123456 -# + diff --git a/projects/stargazer/build b/projects/stargazer/build index 60c8e1ff..3a57e70e 100755 --- a/projects/stargazer/build +++ b/projects/stargazer/build @@ -113,8 +113,7 @@ if [ "$OS" = "linux" ] then DEFS="$DEFS -DLINUX" PLUGINS="$PLUGINS - capture/ether_linux - capture/ipq_linux" + capture/ether_linux" LIB_THREAD=-lpthread else if [ "$OS" = "bsd" ] diff --git a/projects/stargazer/inst/var/01-alter-02.mysql.sql b/projects/stargazer/inst/var/01-alter-02.mysql.sql index c5aea323..1f1b044b 100644 --- a/projects/stargazer/inst/var/01-alter-02.mysql.sql +++ b/projects/stargazer/inst/var/01-alter-02.mysql.sql @@ -2,4 +2,11 @@ * DB migration from v01 to v02 (mysql) */ -ALTER TABLE users ADD DisabledDetailStat INT(3) DEFAULT 0; +ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'; + +CREATE TABLE info +( + version INTEGER NOT NULL +); + +INSERT INTO info VALUES (1); diff --git a/projects/stargazer/inst/var/01-alter-02.sql b/projects/stargazer/inst/var/01-alter-02.sql index 065d1a79..628a016a 100644 --- a/projects/stargazer/inst/var/01-alter-02.sql +++ b/projects/stargazer/inst/var/01-alter-02.sql @@ -12,4 +12,4 @@ CREATE TABLE tb_info version INTEGER NOT NULL ); -INSERT INTO tb_info VALUES (5); +INSERT INTO tb_info VALUES (1); diff --git a/projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp b/projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp index fad12886..85abf820 100644 --- a/projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp +++ b/projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp @@ -12,6 +12,7 @@ structVal["fee"] = xmlrpc_c::value_double(data.tariffConf.fee); structVal["freemb"] = xmlrpc_c::value_double(data.tariffConf.free); structVal["passivecost"] = xmlrpc_c::value_double(data.tariffConf.passiveCost); structVal["traffType"] = xmlrpc_c::value_int(data.tariffConf.traffType); +structVal["period"] = xmlrpc_c::value_string(TARIFF::PeriodToString(data.tariffConf.period)); std::vector prices(DIR_NUM); @@ -65,6 +66,11 @@ if ((it = structVal.find("traffType")) != structVal.end()) data.tariffConf.traffType = xmlrpc_c::value_int(it->second); } +if ((it = structVal.find("period")) != structVal.end()) + { + data.tariffConf.period = TARIFF::StringToPeriod(xmlrpc_c::value_string(it->second)); + } + if ((it = structVal.find("dirprices")) != structVal.end()) { std::vector prices( diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp b/projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp index 9bac0294..bb855faf 100644 --- a/projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp +++ b/projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp @@ -145,6 +145,8 @@ for (; it != dataList.end(); ++it) break; } + answerList->push_back("tariffConf.period) + "\"/>"); + answerList->push_back(""); } answerList->push_back(""); @@ -451,6 +453,12 @@ else } return 0; } + + if (strcasecmp(el, "Period") == 0) + { + td.tariffConf.period = TARIFF::StringToPeriod(attr[1]); + return 0; + } } return -1; } diff --git a/projects/stargazer/plugins/store/files/file_store.cpp b/projects/stargazer/plugins/store/files/file_store.cpp index 0149f07c..fa0483a8 100644 --- a/projects/stargazer/plugins/store/files/file_store.cpp +++ b/projects/stargazer/plugins/store/files/file_store.cpp @@ -1479,6 +1479,11 @@ else printfd(__FILE__, "FILES_STORE::RestoreTariff - invalid trafftype for tariff '%s'\n", tariffName.c_str()); return -1; } + +if (conf.ReadString("Period", &str, "month") < 0) + td->tariffConf.period = TARIFF::MONTH; +else + td->tariffConf.period = TARIFF::StringToPeriod(str); return 0; } //----------------------------------------------------------------------------- @@ -1554,6 +1559,8 @@ string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf"; cf.WriteString("TraffType", "max"); break; } + + cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period)); } return 0; @@ -1847,7 +1854,7 @@ if (rename((fileName + ".new").c_str(), fileName.c_str()) < 0) { STG_LOCKER lock(&mutex, __FILE__, __LINE__); errorStr = "Error moving dir from " + fileName + ".new to " + fileName; - printfd(__FILE__, "FILES_STORE::SaveTariff - rename failed. Message: '%s'\n", strerror(errno)); + printfd(__FILE__, "FILES_STORE::EditMessage - rename failed. Message: '%s'\n", strerror(errno)); return -1; } diff --git a/projects/stargazer/plugins/store/firebird/Makefile b/projects/stargazer/plugins/store/firebird/Makefile index b4cce929..b1485805 100644 --- a/projects/stargazer/plugins/store/firebird/Makefile +++ b/projects/stargazer/plugins/store/firebird/Makefile @@ -20,7 +20,10 @@ SRCS = ./firebird_store.cpp \ STGLIBS = ibpp \ common \ locker \ + logger \ crypto +LIBS = -lfbclient + include ../../Makefile.in diff --git a/projects/stargazer/plugins/store/firebird/firebird_store.cpp b/projects/stargazer/plugins/store/firebird/firebird_store.cpp index 3085981f..8bddf9ca 100644 --- a/projects/stargazer/plugins/store/firebird/firebird_store.cpp +++ b/projects/stargazer/plugins/store/firebird/firebird_store.cpp @@ -32,6 +32,7 @@ #include "stg/ibpp.h" #include "stg/plugin_creator.h" +#include "stg/logger.h" #include "firebird_store.h" using namespace std; @@ -56,7 +57,9 @@ FIREBIRD_STORE::FIREBIRD_STORE() db(), mutex(), til(IBPP::ilConcurrency), - tlr(IBPP::lrWait) + tlr(IBPP::lrWait), + schemaVersion(0), + WriteServLog(GetStgLogger()) { pthread_mutex_init(&mutex, NULL); } @@ -130,6 +133,7 @@ try { db = IBPP::DatabaseFactory(db_server, db_database, db_user, db_password, "", "KOI8U", ""); db->Connect(); + return CheckVersion(); } catch (IBPP::Exception & ex) { @@ -141,3 +145,39 @@ catch (IBPP::Exception & ex) return 0; } //----------------------------------------------------------------------------- +int FIREBIRD_STORE::CheckVersion() +{ +IBPP::Transaction tr = IBPP::TransactionFactory(db, IBPP::amRead, til, tlr); +IBPP::Statement st = IBPP::StatementFactory(db, tr); + +string name; + +try + { + tr->Start(); + st->Execute("SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG=0 AND RDB$RELATION_NAME = 'TB_INFO'"); + if (!st->Fetch()) + { + schemaVersion = 0; + } + else + { + st->Execute("SELECT version FROM tb_info"); + while (st->Fetch()) + st->Get(1, schemaVersion); + } + tr->Commit(); + WriteServLog("FIREBIRD_STORE: Current DB schema version: %d", schemaVersion); + } + +catch (IBPP::Exception & ex) + { + tr->Rollback(); + strError = "IBPP exception"; + printfd(__FILE__, ex.what()); + return -1; + } + +return 0; +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/plugins/store/firebird/firebird_store.h b/projects/stargazer/plugins/store/firebird/firebird_store.h index 58054cba..a5905fef 100644 --- a/projects/stargazer/plugins/store/firebird/firebird_store.h +++ b/projects/stargazer/plugins/store/firebird/firebird_store.h @@ -44,6 +44,8 @@ struct ToLower { extern "C" STORE * GetStore(); +class STG_LOGGER; + class FIREBIRD_STORE : public STORE { public: FIREBIRD_STORE(); @@ -127,8 +129,11 @@ private: mutable pthread_mutex_t mutex; mutable IBPP::TIL til; mutable IBPP::TLR tlr; + int schemaVersion; + STG_LOGGER & WriteServLog; int SaveStat(const USER_STAT & stat, const std::string & login, int year = 0, int month = 0) const; + int CheckVersion(); }; time_t ts2time_t(const IBPP::Timestamp & ts); diff --git a/projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp b/projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp index 8967d6ea..e6ebd45f 100644 --- a/projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp +++ b/projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp @@ -144,17 +144,36 @@ try } st->Get(1, id); st->Close(); - st->Prepare("update tb_tariffs set \ - fee = ?, \ - free = ?, \ - passive_cost = ?, \ - traff_type = ? \ - where pk_tariff = ?"); - st->Set(1, td.tariffConf.fee); - st->Set(2, td.tariffConf.free); - st->Set(3, td.tariffConf.passiveCost); - st->Set(4, td.tariffConf.traffType); - st->Set(5, id); + if (schemaVersion > 0) + { + st->Prepare("update tb_tariffs set \ + fee = ?, \ + free = ?, \ + passive_cost = ?, \ + traff_type = ?, \ + period = ? \ + where pk_tariff = ?"); + st->Set(1, td.tariffConf.fee); + st->Set(2, td.tariffConf.free); + st->Set(3, td.tariffConf.passiveCost); + st->Set(4, td.tariffConf.traffType); + st->Set(5, TARIFF::PeriodToString(td.tariffConf.period)); + st->Set(6, id); + } + else + { + st->Prepare("update tb_tariffs set \ + fee = ?, \ + free = ?, \ + passive_cost = ?, \ + traff_type = ? \ + where pk_tariff = ?"); + st->Set(1, td.tariffConf.fee); + st->Set(2, td.tariffConf.free); + st->Set(3, td.tariffConf.passiveCost); + st->Set(4, td.tariffConf.traffType); + st->Set(5, id); + } st->Execute(); st->Close(); @@ -198,7 +217,7 @@ try threshold = ?, \ time_day_begins = ?, \ time_day_ends = ? \ - where fk_tariff = ? and dir_num = ?"); + where fk_tariff = ? and dir_num = ?"); st->Set(1, pda); st->Set(2, pdb); st->Set(3, pna); @@ -244,7 +263,7 @@ td->tariffConf.name = tariffName; try { tr->Start(); - st->Prepare("select * from tb_tariffs where name = ?"); + st->Prepare("select * from tb_tariffs where name = ?"); // TODO: explicit field order! st->Set(1, tariffName); st->Execute(); if (!st->Fetch()) @@ -259,6 +278,12 @@ try st->Get(4, td->tariffConf.free); st->Get(5, td->tariffConf.passiveCost); st->Get(6, td->tariffConf.traffType); + if (schemaVersion > 0) + { + std::string period; + st->Get(7, period); + td->tariffConf.period = TARIFF::StringToPeriod(period); + } st->Close(); st->Prepare("select * from tb_tariffs_params where fk_tariff = ?"); st->Set(1, id); diff --git a/projects/stargazer/plugins/store/mysql/Makefile b/projects/stargazer/plugins/store/mysql/Makefile index 57c52a6b..d38660bf 100644 --- a/projects/stargazer/plugins/store/mysql/Makefile +++ b/projects/stargazer/plugins/store/mysql/Makefile @@ -9,6 +9,7 @@ PROG = mod_store_mysql.so SRCS = ./mysql_store.cpp STGLIBS = common \ + logger \ crypto MYSQL_CFLAGS = $(shell mysql_config --cflags) diff --git a/projects/stargazer/plugins/store/mysql/mysql_store.cpp b/projects/stargazer/plugins/store/mysql/mysql_store.cpp index 9d8f9c83..95ac298d 100644 --- a/projects/stargazer/plugins/store/mysql/mysql_store.cpp +++ b/projects/stargazer/plugins/store/mysql/mysql_store.cpp @@ -13,6 +13,7 @@ #include "stg/user_stat.h" #include "stg/blowfish.h" #include "stg/plugin_creator.h" +#include "stg/logger.h" #include "mysql_store.h" #define adm_enc_passwd "cjeifY8m3" @@ -157,7 +158,9 @@ MYSQL_STORE::MYSQL_STORE() : errorStr(), version("mysql_store v.0.67"), storeSettings(), - settings() + settings(), + schemaVersion(0), + WriteServLog(GetStgLogger()) { }; //----------------------------------------------------------------------------- @@ -230,12 +233,18 @@ else } ret = CheckAllTables(sock); } - } - else - ret = CheckAllTables(sock); - mysql_close(sock); + } + else + { + ret = CheckAllTables(sock); + } + if (!ret) + { + WriteServLog("MYSQL_STORE: Current DB schema version: %d", schemaVersion); + MakeUpdates(sock); + } + mysql_close(sock); } - } return ret; } @@ -262,6 +271,43 @@ return (num_rows == 1); //----------------------------------------------------------------------------- int MYSQL_STORE::CheckAllTables(MYSQL * sock) { +//info------------------------------------------------------------------------- +if(!IsTablePresent("info",sock)) +{ + sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)"); + + if(MysqlQuery(qbuf,sock)) + { + errorStr = "Couldn't create info table With error:\n"; + errorStr += mysql_error(sock); + mysql_close(sock); + return -1; + } + + sprintf(qbuf,"INSERT INTO info SET version=0"); + + if(MysqlQuery(qbuf,sock)) + { + errorStr = "Couldn't write default version. With error:\n"; + errorStr += mysql_error(sock); + mysql_close(sock); + return -1; + } + schemaVersion = 0; +} +else +{ + std::vector info; + if (GetAllParams(&info, "info", "version")) + schemaVersion = 0; + else + { + if (info.empty()) + schemaVersion = 0; + else + GetInt(info.front(), &schemaVersion, 0); + } +} //admins----------------------------------------------------------------------- if(!IsTablePresent("admins",sock)) { @@ -325,8 +371,9 @@ if(!IsTablePresent("tariffs",sock)) res += param; } - res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"\ - "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '')"; + res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0," + "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT ''," + "period VARCHAR(32) NOT NULL DEFAULT 'month')"; if(MysqlQuery(res.c_str(),sock)) { @@ -380,7 +427,7 @@ if(!IsTablePresent("tariffs",sock)) res += "PassiveCost=0.0, Fee=10.0, Free=0,"\ "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\ - "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down'"; + "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month'"; if(MysqlQuery(res.c_str(),sock)) { @@ -389,6 +436,17 @@ if(!IsTablePresent("tariffs",sock)) mysql_close(sock); return -1; } + + sprintf(qbuf,"UPDATE info SET version=1"); + + if(MysqlQuery(qbuf,sock)) + { + errorStr = "Couldn't write default version. With error:\n"; + errorStr += mysql_error(sock); + mysql_close(sock); + return -1; + } + schemaVersion = 1; } //users----------------------------------------------------------------------- @@ -520,6 +578,29 @@ if(!IsTablePresent("stat",sock)) return 0; } //----------------------------------------------------------------------------- +int MYSQL_STORE::MakeUpdates(MYSQL * sock) +{ +if (schemaVersion < 1) + { + if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock)) + { + errorStr = "Couldn't update tariffs table to version 1. With error:\n"; + errorStr += mysql_error(sock); + mysql_close(sock); + return -1; + } + if (MysqlQuery("UPDATE info SET version = 1", sock)) + { + errorStr = "Couldn't update DB schema version to 1. With error:\n"; + errorStr += mysql_error(sock); + mysql_close(sock); + return -1; + } + schemaVersion = 1; + WriteServLog("MYSQL_STORE: Updated DB schema to version %d", schemaVersion); + } +return 0; +} //----------------------------------------------------------------------------- int MYSQL_STORE::GetAllParams(vector * ParamList, @@ -1555,6 +1636,26 @@ else return -1; } +if (schemaVersion > 0) +{ + str = row[5+8*DIR_NUM]; + param = "Period"; + + if (str.length() == 0) + { + mysql_free_result(res); + errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param; + mysql_close(sock); + return -1; + } + + td->tariffConf.period = TARIFF::StringToPeriod(str); + } +else + { + td->tariffConf.period = TARIFF::MONTH; + } + mysql_free_result(res); mysql_close(sock); return 0; @@ -1632,12 +1733,16 @@ switch (td.tariffConf.traffType) res += " TraffType='max'"; break; } + +if (schemaVersion > 0) + res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'"; + strprintf(¶m, " WHERE name='%s' LIMIT 1", tariffName.c_str()); res += param; if(MysqlSetQuery(res.c_str())) { - errorStr = "Couldn't save admin:\n"; + errorStr = "Couldn't save tariff:\n"; //errorStr += mysql_error(sock); return -1; } diff --git a/projects/stargazer/plugins/store/mysql/mysql_store.h b/projects/stargazer/plugins/store/mysql/mysql_store.h index d0d4f70d..8818f590 100644 --- a/projects/stargazer/plugins/store/mysql/mysql_store.h +++ b/projects/stargazer/plugins/store/mysql/mysql_store.h @@ -18,6 +18,7 @@ using namespace std; //----------------------------------------------------------------------------- extern "C" STORE * GetStore(); +class STG_LOGGER; //----------------------------------------------------------------------------- class MYSQL_STORE_SETTINGS { @@ -132,15 +133,18 @@ private: virtual int WriteLogString(const string & str, const string & login) const; int GetAllParams(vector * ParamList, const string & table, const string & name) const; int CheckAllTables(MYSQL * sock); + int MakeUpdates(MYSQL * sock); bool IsTablePresent(const string & str,MYSQL * sock); mutable string errorStr; - int MysqlQuery(const char* sQuery,MYSQL * sock) const; + int MysqlQuery(const char* sQuery,MYSQL * sock) const; int MysqlGetQuery(const char * Query,MYSQL * & sock) const; int MysqlSetQuery(const char * Query) const; MYSQL * MysqlConnect() const ; string version; MYSQL_STORE_SETTINGS storeSettings; MODULE_SETTINGS settings; + int schemaVersion; + STG_LOGGER & WriteServLog; }; //----------------------------------------------------------------------------- diff --git a/projects/stargazer/plugins/store/postgresql/Makefile b/projects/stargazer/plugins/store/postgresql/Makefile index b59e45cd..990d965a 100644 --- a/projects/stargazer/plugins/store/postgresql/Makefile +++ b/projects/stargazer/plugins/store/postgresql/Makefile @@ -17,6 +17,7 @@ SRCS = ./postgresql_store.cpp \ STGLIBS = common \ crypto \ + logger \ locker PG_CFLAGS = $(shell pg_config --includedir) diff --git a/projects/stargazer/plugins/store/postgresql/postgresql_store.cpp b/projects/stargazer/plugins/store/postgresql/postgresql_store.cpp index 073fccab..51eec8f4 100644 --- a/projects/stargazer/plugins/store/postgresql/postgresql_store.cpp +++ b/projects/stargazer/plugins/store/postgresql/postgresql_store.cpp @@ -46,6 +46,7 @@ #include "stg/module_settings.h" #include "stg/plugin_creator.h" +#include "stg/logger.h" #include "postgresql_store_utils.h" #include "postgresql_store.h" @@ -70,7 +71,8 @@ POSTGRESQL_STORE::POSTGRESQL_STORE() mutex(), version(0), retries(3), - connection(NULL) + connection(NULL), + WriteServLog(GetStgLogger()) { pthread_mutex_init(&mutex, NULL); } @@ -231,6 +233,8 @@ if (CommitTransaction()) return -1; } +WriteServLog("POSTGRESQL_STORE: Current DB schema version: %d", version); + return 0; } //----------------------------------------------------------------------------- diff --git a/projects/stargazer/plugins/store/postgresql/postgresql_store.h b/projects/stargazer/plugins/store/postgresql/postgresql_store.h index edba0359..a88df88b 100644 --- a/projects/stargazer/plugins/store/postgresql/postgresql_store.h +++ b/projects/stargazer/plugins/store/postgresql/postgresql_store.h @@ -43,6 +43,8 @@ extern "C" STORE * GetStore(); +class STG_LOGGER; + class POSTGRESQL_STORE : public STORE { public: POSTGRESQL_STORE(); @@ -158,6 +160,8 @@ private: int retries; PGconn * connection; + + STG_LOGGER & WriteServLog; }; extern const volatile time_t stgTime; diff --git a/projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp b/projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp index bb647563..ffce2846 100644 --- a/projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp +++ b/projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp @@ -121,9 +121,9 @@ if (EscapeString(ename)) { printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n"); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -184,9 +184,9 @@ if (EscapeString(ename)) { printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n"); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -248,9 +248,9 @@ if (EscapeString(ename)) { printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to escape name'\n"); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -283,9 +283,9 @@ if (tuples != 1) printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples); PQclear(result); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -301,8 +301,12 @@ query << "UPDATE tb_tariffs SET \ fee = " << td.tariffConf.fee << ", \ free = " << td.tariffConf.free << ", \ passive_cost = " << td.tariffConf.passiveCost << ", \ - traff_type = " << td.tariffConf.traffType << " \ - WHERE pk_tariff = " << id; + traff_type = " << td.tariffConf.traffType; + +if (version > 6) + query << ", period = '" << TARIFF::PeriodToString(td.tariffConf.period) << "'"; + +query << " WHERE pk_tariff = " << id; result = PQexec(connection, query.str().c_str()); @@ -417,9 +421,9 @@ if (EscapeString(ename)) { printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to escape name'\n"); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -428,10 +432,14 @@ td->tariffConf.name = tariffName; std::stringstream query; query << "SELECT pk_tariff, \ fee, \ - free, \ - passive_cost, \ - traff_type \ - FROM tb_tariffs WHERE name = '" << ename << "'"; + free, \ + passive_cost, \ + traff_type"; + +if (version > 6) + query << ", period"; + +query << " FROM tb_tariffs WHERE name = '" << ename << "'"; result = PQexec(connection, query.str().c_str()); @@ -455,9 +463,9 @@ if (tuples != 1) printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples); PQclear(result); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); + } return -1; } @@ -475,21 +483,24 @@ tuple >> td->tariffConf.free; tuple >> td->tariffConf.passiveCost; tuple >> td->tariffConf.traffType; +if (version > 6) + td->tariffConf.period = TARIFF::StringToPeriod(PQgetvalue(result, 0, 5)); + PQclear(result); query.str(""); query << "SELECT dir_num, \ price_day_a, \ price_day_b, \ - price_night_a, \ - price_night_b, \ - threshold, \ - EXTRACT(hour FROM time_day_begins), \ - EXTRACT(minute FROM time_day_begins), \ - EXTRACT(hour FROM time_day_ends), \ - EXTRACT(minute FROM time_day_ends) \ - FROM tb_tariffs_params \ - WHERE fk_tariff = " << id; + price_night_a, \ + price_night_b, \ + threshold, \ + EXTRACT(hour FROM time_day_begins), \ + EXTRACT(minute FROM time_day_begins), \ + EXTRACT(hour FROM time_day_ends), \ + EXTRACT(minute FROM time_day_ends) \ + FROM tb_tariffs_params \ + WHERE fk_tariff = " << id; result = PQexec(connection, query.str().c_str()); @@ -499,9 +510,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK) PQclear(result); printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str()); if (RollbackTransaction()) - { - printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); - } + { + printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n"); + } return -1; } diff --git a/projects/stargazer/tariff_impl.h b/projects/stargazer/tariff_impl.h index f33c08af..b471f0d0 100644 --- a/projects/stargazer/tariff_impl.h +++ b/projects/stargazer/tariff_impl.h @@ -71,6 +71,7 @@ public: double GetPassiveCost() const { return tariffData.tariffConf.passiveCost; } double GetFee() const { return tariffData.tariffConf.fee; } double GetFree() const { return tariffData.tariffConf.free; } + PERIOD GetPeriod() const { return tariffData.tariffConf.period; } void Print() const; diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp index 733e6256..42650eff 100644 --- a/projects/stargazer/user_impl.cpp +++ b/projects/stargazer/user_impl.cpp @@ -1231,6 +1231,9 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__); if (passive.ConstData() || tariff == NULL) return; +if (tariff->GetPeriod() != TARIFF::MONTH) + return; + double fee = tariff->GetFee() / DaysInCurrentMonth(); if (fee == 0.0) @@ -1261,6 +1264,9 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__); if (tariff == NULL) return; +if (tariff->GetPeriod() != TARIFF::MONTH) + return; + double passiveTimePart = 1.0; if (!settings->GetFullFee()) { @@ -1315,6 +1321,39 @@ switch (settings->GetFeeChargeType()) } } //----------------------------------------------------------------------------- +void USER_IMPL::ProcessDailyFee() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (passive.ConstData() || tariff == NULL) + return; + +if (tariff->GetPeriod() != TARIFF::DAY) + return; + +double fee = tariff->GetFee(); + +if (fee == 0.0) + return; + +double c = cash; +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 1: + if (c + credit >= 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 2: + if (c + credit >= fee) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + } +ResetPassiveTime(); +} +//----------------------------------------------------------------------------- void USER_IMPL::SetPrepaidTraff() { if (tariff != NULL) diff --git a/projects/stargazer/user_impl.h b/projects/stargazer/user_impl.h index 2fc2729e..17623294 100644 --- a/projects/stargazer/user_impl.h +++ b/projects/stargazer/user_impl.h @@ -210,6 +210,7 @@ public: void ProcessDayFee(); void ProcessDayFeeSpread(); void ProcessNewMonth(); + void ProcessDailyFee(); bool IsInetable(); std::string GetEnabledDirs(); diff --git a/projects/stargazer/users_impl.cpp b/projects/stargazer/users_impl.cpp index fc2b8d2f..dfcc556f 100644 --- a/projects/stargazer/users_impl.cpp +++ b/projects/stargazer/users_impl.cpp @@ -497,6 +497,8 @@ else } } +std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee)); + if (settings->GetDayFeeIsLastDay()) { printfd(__FILE__, "DayResetTraff - 2 -\n"); -- 2.44.2