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  *  Tariffs manipulation methods
 
  25  *  $Date: 2009/06/09 12:32:40 $
 
  35 #include "postgresql_store.h"
 
  36 #include "stg_locker.h"
 
  38 //-----------------------------------------------------------------------------
 
  39 int POSTGRESQL_STORE::GetTariffsList(vector<string> * tariffsList) const
 
  41 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
  43 if (PQstatus(connection) != CONNECTION_OK)
 
  45     printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
  48         strError = "Connection lost";
 
  49         printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): '%s'\n", strError.c_str());
 
  56 if (StartTransaction())
 
  58     printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to start transaction'\n");
 
  62 result = PQexec(connection, "SELECT name FROM tb_tariffs");
 
  64 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
  66     strError = PQresultErrorMessage(result);
 
  68     printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): '%s'\n", strError.c_str());
 
  69     if (RollbackTransaction())
 
  71         printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to rollback transaction'\n");
 
  76 int tuples = PQntuples(result);
 
  78 for (int i = 0; i < tuples; ++i)
 
  80     tariffsList->push_back(PQgetvalue(result, i, 0));
 
  85 if (CommitTransaction())
 
  87     printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to commit transaction'\n");
 
  94 //-----------------------------------------------------------------------------
 
  95 int POSTGRESQL_STORE::AddTariff(const string & name) const
 
  97 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
  99 if (PQstatus(connection) != CONNECTION_OK)
 
 101     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 104         strError = "Connection lost";
 
 105         printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): '%s'\n", strError.c_str());
 
 112 if (StartTransaction())
 
 114     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to start transaction'\n");
 
 118 std::string ename = name;
 
 120 if (EscapeString(ename))
 
 122     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
 
 123     if (RollbackTransaction())
 
 125         printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
 
 130 std::stringstream query;
 
 131 query << "SELECT sp_add_tariff('" << ename << "', " << DIR_NUM << ")";
 
 133 result = PQexec(connection, query.str().c_str());
 
 135 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 137     strError = PQresultErrorMessage(result);
 
 139     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): '%s'\n", strError.c_str());
 
 140     if (RollbackTransaction())
 
 142         printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
 
 149 if (CommitTransaction())
 
 151     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to commit transaction'\n");
 
 157 //-----------------------------------------------------------------------------
 
 158 int POSTGRESQL_STORE::DelTariff(const string & name) const
 
 160 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 162 if (PQstatus(connection) != CONNECTION_OK)
 
 164     printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 167         strError = "Connection lost";
 
 168         printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): '%s'\n", strError.c_str());
 
 175 if (StartTransaction())
 
 177     printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to start transaction'\n");
 
 181 std::string ename = name;
 
 183 if (EscapeString(ename))
 
 185     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
 
 186     if (RollbackTransaction())
 
 188         printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
 
 193 std::stringstream query;
 
 194 query << "DELETE FROM tb_tariffs WHERE name = '" << ename << "'";
 
 196 result = PQexec(connection, query.str().c_str());
 
 198 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 200     strError = PQresultErrorMessage(result);
 
 202     printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): '%s'\n", strError.c_str());
 
 203     if (RollbackTransaction())
 
 205         printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to rollback transaction'\n");
 
 212 if (CommitTransaction())
 
 214     printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to commit transaction'\n");
 
 220 //-----------------------------------------------------------------------------
 
 221 int POSTGRESQL_STORE::SaveTariff(const TARIFF_DATA & td,
 
 222                                  const string & tariffName) const
 
 224 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 226 if (PQstatus(connection) != CONNECTION_OK)
 
 228     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 231         strError = "Connection lost";
 
 232         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
 
 239 if (StartTransaction())
 
 241     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to start transaction'\n");
 
 245 std::string ename = tariffName;
 
 247 if (EscapeString(ename))
 
 249     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to escape name'\n");
 
 250     if (RollbackTransaction())
 
 252         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
 
 258 double pda, pdb, pna, pnb;
 
 261 std::stringstream query;
 
 262 query << "SELECT pk_tariff FROM tb_tariffs WHERE name = '" << ename << "'";
 
 264 result = PQexec(connection, query.str().c_str());
 
 266 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 268     strError = PQresultErrorMessage(result);
 
 270     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
 
 271     if (RollbackTransaction())
 
 273         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
 
 278 int tuples = PQntuples(result);
 
 282     strError = "Failed to fetch tariff ID";
 
 283     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
 285     if (RollbackTransaction())
 
 287         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
 
 292 std::stringstream tuple;
 
 293 tuple << PQgetvalue(result, 0, 0);
 
 300 query << "UPDATE tb_tariffs SET \
 
 301               fee = " << td.tariffConf.fee << ", \
 
 302               free = " << td.tariffConf.free << ", \
 
 303               passive_cost = " << td.tariffConf.passiveCost << ", \
 
 304               traff_type = " << td.tariffConf.traffType << " \
 
 305           WHERE pk_tariff = " << id;
 
 307 result = PQexec(connection, query.str().c_str());
 
 309 if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 311     strError = PQresultErrorMessage(result);
 
 313     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
 
 314     if (RollbackTransaction())
 
 316         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
 
 323 for(i = 0; i < DIR_NUM; i++)
 
 326     pda = td.dirPrice[i].priceDayA * 1024 * 1024;
 
 327     pdb = td.dirPrice[i].priceDayB * 1024 * 1024;
 
 329     if (td.dirPrice[i].singlePrice)
 
 336         pna = td.dirPrice[i].priceNightA * 1024 * 1024;
 
 337         pnb = td.dirPrice[i].priceNightB * 1024 * 1024;
 
 340     if (td.dirPrice[i].noDiscount)
 
 342         threshold = 0xffFFffFF;
 
 346         threshold = td.dirPrice[i].threshold;
 
 349     std::stringstream query;
 
 350     query << "UPDATE tb_tariffs_params SET \
 
 351                   price_day_a = " << pda << ", \
 
 352                   price_day_b = " << pdb << ", \
 
 353                   price_night_a = " << pna << ", \
 
 354                   price_night_b = " << pnb << ", \
 
 355                   threshold = " << threshold << ", \
 
 356                   time_day_begins = CAST('" << td.dirPrice[i].hDay
 
 358                                             << td.dirPrice[i].mDay << "' AS TIME), \
 
 359                   time_day_ends = CAST('" << td.dirPrice[i].hNight
 
 361                                           << td.dirPrice[i].mNight << "' AS TIME) \
 
 362              WHERE fk_tariff = " << id << " AND dir_num = " << i;
 
 364     result = PQexec(connection, query.str().c_str());
 
 366     if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 368         strError = PQresultErrorMessage(result);
 
 370         printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
 
 371         if (RollbackTransaction())
 
 373             printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
 
 381 if (CommitTransaction())
 
 383     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to commit transaction'\n");
 
 389 //-----------------------------------------------------------------------------
 
 390 int POSTGRESQL_STORE::RestoreTariff(TARIFF_DATA * td,
 
 391                                   const string & tariffName) const
 
 393 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 395 if (PQstatus(connection) != CONNECTION_OK)
 
 397     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
 
 400         strError = "Connection lost";
 
 401         printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
 
 408 if (StartTransaction())
 
 410     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to start transaction'\n");
 
 414 std::string ename = tariffName;
 
 416 if (EscapeString(ename))
 
 418     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to escape name'\n");
 
 419     if (RollbackTransaction())
 
 421         printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
 
 426 td->tariffConf.name = tariffName;
 
 428 std::stringstream query;
 
 429 query << "SELECT pk_tariff, \
 
 434           FROM tb_tariffs WHERE name = '" << ename << "'";
 
 436 result = PQexec(connection, query.str().c_str());
 
 438 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 440     strError = PQresultErrorMessage(result);
 
 442     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
 
 443     if (RollbackTransaction())
 
 445         printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
 
 450 int tuples = PQntuples(result);
 
 454     strError = "Failed to fetch tariff data";
 
 455     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
 
 457     if (RollbackTransaction())
 
 459         printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
 
 464 std::stringstream tuple;
 
 465 tuple << PQgetvalue(result, 0, 0) << " ";
 
 466 tuple << PQgetvalue(result, 0, 1) << " ";
 
 467 tuple << PQgetvalue(result, 0, 2) << " ";
 
 468 tuple << PQgetvalue(result, 0, 3) << " ";
 
 469 tuple << PQgetvalue(result, 0, 4) << " ";
 
 473 tuple >> td->tariffConf.fee;
 
 474 tuple >> td->tariffConf.free;
 
 475 tuple >> td->tariffConf.passiveCost;
 
 476 tuple >> td->tariffConf.traffType;
 
 481 query << "SELECT dir_num, \
 
 487                  EXTRACT(hour FROM time_day_begins), \
 
 488                  EXTRACT(minute FROM time_day_begins), \
 
 489                  EXTRACT(hour FROM time_day_ends), \
 
 490                  EXTRACT(minute FROM time_day_ends) \
 
 491           FROM tb_tariffs_params \
 
 492           WHERE fk_tariff = " << id;
 
 494 result = PQexec(connection, query.str().c_str());
 
 496 if (PQresultStatus(result) != PGRES_TUPLES_OK)
 
 498     strError = PQresultErrorMessage(result);
 
 500     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
 
 501     if (RollbackTransaction())
 
 503         printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
 
 508 tuples = PQntuples(result);
 
 510 if (tuples != DIR_NUM)
 
 512     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Tariff params count and DIR_NUM does not feet (wanted %d, actually %d)'\n", DIR_NUM, tuples);
 
 515 for (int i = 0; i < std::min(tuples, DIR_NUM); ++i)
 
 517     std::stringstream tuple;
 
 518     tuple << PQgetvalue(result, i, 0) << " ";
 
 519     tuple << PQgetvalue(result, i, 1) << " ";
 
 520     tuple << PQgetvalue(result, i, 2) << " ";
 
 521     tuple << PQgetvalue(result, i, 3) << " ";
 
 522     tuple << PQgetvalue(result, i, 4) << " ";
 
 523     tuple << PQgetvalue(result, i, 5) << " ";
 
 524     tuple << PQgetvalue(result, i, 6) << " ";
 
 525     tuple << PQgetvalue(result, i, 7) << " ";
 
 526     tuple << PQgetvalue(result, i, 8) << " ";
 
 527     tuple << PQgetvalue(result, i, 9) << " ";
 
 532     tuple >> td->dirPrice[dir].priceDayA;
 
 533     td->dirPrice[dir].priceDayA /= 1024 * 1024;
 
 534     tuple >> td->dirPrice[dir].priceDayB;
 
 535     td->dirPrice[dir].priceDayB /= 1024 * 1024;
 
 536     tuple >> td->dirPrice[dir].priceNightA;
 
 537     td->dirPrice[dir].priceNightA /= 1024 * 1024;
 
 538     tuple >> td->dirPrice[dir].priceNightB;
 
 539     td->dirPrice[dir].priceNightB /= 1024 * 1024;
 
 540     tuple >> td->dirPrice[dir].threshold;
 
 541     tuple >> td->dirPrice[dir].hDay;
 
 542     tuple >> td->dirPrice[dir].mDay;
 
 543     tuple >> td->dirPrice[dir].hNight;
 
 544     tuple >> td->dirPrice[dir].mNight;
 
 546     if (td->dirPrice[dir].priceDayA == td->dirPrice[dir].priceNightA &&
 
 547         td->dirPrice[dir].priceDayB == td->dirPrice[dir].priceNightB)
 
 549         td->dirPrice[dir].singlePrice = true;
 
 553         td->dirPrice[dir].singlePrice = false;
 
 555     if (td->dirPrice[dir].threshold == (int)0xffFFffFF)
 
 557         td->dirPrice[dir].noDiscount = true;
 
 562         td->dirPrice[dir].noDiscount = false;
 
 569 if (CommitTransaction())
 
 571     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to commit transaction'\n");
 
 577 //-----------------------------------------------------------------------------