]> git.stg.codes - stg.git/commitdiff
Implemented daily fee charge with backward compatibility.
authorMaxim Mamontov <faust.madf@gmail.com>
Wed, 27 Nov 2013 19:46:11 +0000 (21:46 +0200)
committerMaxim Mamontov <faust.madf@gmail.com>
Wed, 27 Nov 2013 19:46:11 +0000 (21:46 +0200)
25 files changed:
doc/xmlrpc/API-tariffs.xml
include/stg/tariff.h
include/stg/tariff_conf.h
projects/convertor/convertor.conf
projects/stargazer/build
projects/stargazer/inst/var/01-alter-02.mysql.sql
projects/stargazer/inst/var/01-alter-02.sql
projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp
projects/stargazer/plugins/store/files/file_store.cpp
projects/stargazer/plugins/store/firebird/Makefile
projects/stargazer/plugins/store/firebird/firebird_store.cpp
projects/stargazer/plugins/store/firebird/firebird_store.h
projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp
projects/stargazer/plugins/store/mysql/Makefile
projects/stargazer/plugins/store/mysql/mysql_store.cpp
projects/stargazer/plugins/store/mysql/mysql_store.h
projects/stargazer/plugins/store/postgresql/Makefile
projects/stargazer/plugins/store/postgresql/postgresql_store.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store.h
projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp
projects/stargazer/tariff_impl.h
projects/stargazer/user_impl.cpp
projects/stargazer/user_impl.h
projects/stargazer/users_impl.cpp

index d36b01dda869a561907cdf65b3b2779bf464d071..9b84889aee87560161d650904d0485c9ad5e9e5c 100644 (file)
                                 </para>
                             </listitem>
                         </varlistentry>
+                        <varlistentry>
+                            <term>string <parameter>period</parameter></term>
+                            <listitem>
+                                <para>Периодичность снятия абонплаты:
+                                    <simplelist type="vert">
+                                        <member>month &#151; ежемесячное снятие</member>
+                                        <member>day &#151; ежедневное снятие</member>
+                                    </simplelist>
+                                </para>
+                            </listitem>
+                        </varlistentry>
                         <varlistentry>
                             <term>array of struct <parameter>dirprices</parameter></term>
                             <listitem>
                                 </para>
                             </listitem>
                         </varlistentry>
+                        <varlistentry>
+                            <term>string <parameter>period</parameter></term>
+                            <listitem>
+                                <para>Периодичность снятия абонплаты:
+                                    <simplelist type="vert">
+                                        <member>month &#151; ежемесячное снятие</member>
+                                        <member>day &#151; ежедневное снятие</member>
+                                    </simplelist>
+                                </para>
+                            </listitem>
+                        </varlistentry>
                         <varlistentry>
                             <term>array of struct <parameter>dirprices</parameter></term>
                             <listitem>
                                         </para>
                                     </listitem>
                                 </varlistentry>
+                                <varlistentry>
+                                    <term>string <parameter>period</parameter></term>
+                                    <listitem>
+                                        <para>Периодичность снятия абонплаты:
+                                            <simplelist type="vert">
+                                                <member>month &#151; ежемесячное снятие</member>
+                                                <member>day &#151; ежедневное снятие</member>
+                                            </simplelist>
+                                        </para>
+                                    </listitem>
+                                </varlistentry>
                                 <varlistentry>
                                     <term>array of struct <parameter>dirprices</parameter></term>
                                     <listitem>
index a5b1d2e9253ad3a441e283e3409e19c4dd0ae6a4..d0bf20b6dd268ddf0f7b2fa772cedad1e89ebdb1 100644 (file)
 #ifndef TARIFF_H
 #define TARIFF_H
 
-#include <ctime>
+#include "os_int.h"
 
 #include <string>
+#include <cstring>
+#include <ctime>
 
-#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
index 5b2eebb981b57258ba92863ca4df1718af0ae2b5..376ed378e527fc1ed74c0a3d79ba290677661ebb 100644 (file)
 #ifndef TARIFF_CONF_H
 #define TARIFF_CONF_H
 
-#include <string>
-#include <vector>
-
+#include "tariff.h"
 #include "resetable.h"
 #include "const.h"
 
+#include <string>
+#include <vector>
+
 //-----------------------------------------------------------------------------
 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<double>      fee;
-    RESETABLE<double>      free;
-    RESETABLE<int>         traffType;
-    RESETABLE<double>      passiveCost;
-    RESETABLE<std::string> name;
+    RESETABLE<double>         fee;
+    RESETABLE<double>         free;
+    RESETABLE<int>            traffType;
+    RESETABLE<double>         passiveCost;
+    RESETABLE<std::string>    name;
+    RESETABLE<TARIFF::PERIOD> period;
 };
 //-----------------------------------------------------------------------------
 struct TARIFF_DATA
index 41e18b6823f087e3b7755b08822b997703f8b882..ab8e8e8dba9db7fae9f19d2a5c895a809c06e23f 100644 (file)
@@ -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
 #</DestStoreModule>
 
-<DestStoreModule store_postgresql>
+#<DestStoreModule store_postgresql>
     # 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
 
-</DestStoreModule>
+#</DestStoreModule>
 
-#<DestStoreModule store_mysql>
+<DestStoreModule store_mysql>
     # 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
 
-#</DestStoreModule>
+</DestStoreModule>
index 60c8e1ff035e4c07008c3cec1c62146fbf9f084a..3a57e70e962b1a64e0a46e9eea12038aaa40bb0e 100755 (executable)
@@ -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" ]
index c5aea323eb57a1d04275c7fe29e9b9f7551e2717..1f1b044b7f10d85cdc5c8456a4c7ed7ee2ec2818 100644 (file)
@@ -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);
index 065d1a79109a22807079e6dea099fdc286f59244..628a016a1fbcf1bc4b9240b0a4767f85dd1b8262 100644 (file)
@@ -12,4 +12,4 @@ CREATE TABLE tb_info
     version INTEGER NOT NULL
 );
 
-INSERT INTO tb_info VALUES (5);
+INSERT INTO tb_info VALUES (1);
index fad12886f651d870866a459225efbf5e591416b9..85abf8205a5e59822db40850c3b37d4de905be45 100644 (file)
@@ -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<xmlrpc_c::value> 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<xmlrpc_c::value> prices(
index 9bac0294bbc171d731ea169813cea5c14e58b966..bb855fafc07ba679c057b7bfbda772ae8424f0c6 100644 (file)
@@ -145,6 +145,8 @@ for (; it != dataList.end(); ++it)
             break;
         }
 
+    answerList->push_back("<Period value=\"" + TARIFF::PeriodToString(it->tariffConf.period) + "\"/>");
+
     answerList->push_back("</tariff>");
     }
 answerList->push_back("</Tariffs>");
@@ -451,6 +453,12 @@ else
             }
         return 0;
         }
+
+    if (strcasecmp(el, "Period") == 0)
+        {
+        td.tariffConf.period = TARIFF::StringToPeriod(attr[1]);
+        return 0;
+        }
     }
 return -1;
 }
index 0149f07cec36e8f5b21be227f9279e9fa5ed8196..fa0483a8894213944c1215a694c8eefb4fe82343 100644 (file)
@@ -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;
     }
 
index b4cce929949d7e5b0a78af6fcef9690984f58158..b14858057c343739b58f45b2d1ec26aa62a777ca 100644 (file)
@@ -20,7 +20,10 @@ SRCS =       ./firebird_store.cpp \
 STGLIBS = ibpp \
          common \
          locker \
+         logger \
          crypto
 
+LIBS = -lfbclient
+
 include ../../Makefile.in
 
index 3085981fc222ec6e82b9875c78f120d88b11522a..8bddf9ca6c329537f614a02ae44d2c098b5b9468 100644 (file)
@@ -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;
+}
+//-----------------------------------------------------------------------------
index 58054cba724b0cc67c34738d8e4cd8f80cf8c253..a5905fefa8438570e7e2606cf2f9571a0c328a1c 100644 (file)
@@ -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);
index 8967d6eaa55d4fcc57956e8a011bac2c7508a9b4..e6ebd45f54bfe93f815f3e90d84af9b00ed86e2f 100644 (file)
@@ -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);
index 57c52a6b0b94cf9eb829e29fa3aac0a5a5662cdf..d38660bfebc2c6d0532403ed2ea1e102e7c57b4f 100644 (file)
@@ -9,6 +9,7 @@ PROG = mod_store_mysql.so
 SRCS = ./mysql_store.cpp
 
 STGLIBS = common \
+         logger \
          crypto
 
 MYSQL_CFLAGS = $(shell mysql_config --cflags)
index 9d8f9c8348dfc5700c2473dd33d46922b90a91d8..95ac298d732529891e18de18844a56df3b3518ca 100644 (file)
@@ -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<std::string> 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<string> * 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(&param, " 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;
 }
index d0d4f70d67b9ca592671e6b4fbdb1ca636454fd0..8818f590cb603291aba8a481c1d318f6f910f0f8 100644 (file)
@@ -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<string> * 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;
 };
 //-----------------------------------------------------------------------------
 
index b59e45cd19e550ec8c74f46bbb7d15cc57e07380..990d965a62de35d9840a11f4e20f91c02720bc72 100644 (file)
@@ -17,6 +17,7 @@ SRCS =        ./postgresql_store.cpp \
 
 STGLIBS = common \
          crypto \
+         logger \
          locker
 
 PG_CFLAGS = $(shell pg_config --includedir)
index 073fccab5d92ce84e8a46c5dd6d25e7973e6914b..51eec8f414626463cb72a99b61873e44d5309283 100644 (file)
@@ -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;
 }
 //-----------------------------------------------------------------------------
index edba035927bac2e9dbdb7c0cd340898bea46ddf5..a88df88b93fba855bb1d4d612d39254e2e5d9012 100644 (file)
@@ -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;
index bb64756369d712a801347f06d913d0eb35fc1f7c..ffce284614452cf9f87a3d5cd77257aaf90daffc 100644 (file)
@@ -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;
     }
 
index f33c08af0aa1340b3ba1bf0db72e60e964d0709c..b471f0d04014e5c072dc7807c2ca6867c66302bd 100644 (file)
@@ -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;
 
index 733e625692bed34418c0a2dcdbccf0362fbc5571..42650effed158034cd7e30569df661bf0763f376 100644 (file)
@@ -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)
index 2fc2729e2aefc566e1a7cb443b3f2d9e0c7c4ed4..17623294548d208ab31452f19c7db131c5d53c33 100644 (file)
@@ -210,6 +210,7 @@ public:
     void            ProcessDayFee();
     void            ProcessDayFeeSpread();
     void            ProcessNewMonth();
+    void            ProcessDailyFee();
 
     bool            IsInetable();
     std::string     GetEnabledDirs();
index fc2b8d2fcdc4f5889793658d0373718c5bb7fc21..dfcc556fbf87726ae1e1a20986e7b4d601b68928 100644 (file)
@@ -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");