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 $
29 #include "postgresql_store.h"
31 #include "stg/tariff_conf.h"
32 #include "stg/common.h"
44 const int pt_mega = 1024 * 1024;
48 //-----------------------------------------------------------------------------
49 int POSTGRESQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
51 std::lock_guard lock(m_mutex);
53 if (PQstatus(connection) != CONNECTION_OK)
55 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
58 strError = "Connection lost";
59 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): '%s'\n", strError.c_str());
66 if (StartTransaction())
68 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to start transaction'\n");
72 result = PQexec(connection, "SELECT name FROM tb_tariffs");
74 if (PQresultStatus(result) != PGRES_TUPLES_OK)
76 strError = PQresultErrorMessage(result);
78 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): '%s'\n", strError.c_str());
79 if (RollbackTransaction())
81 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to rollback transaction'\n");
86 int tuples = PQntuples(result);
88 for (int i = 0; i < tuples; ++i)
90 tariffsList->push_back(PQgetvalue(result, i, 0));
95 if (CommitTransaction())
97 printfd(__FILE__, "POSTGRESQL_STORE::GetTariffsList(): 'Failed to commit transaction'\n");
104 //-----------------------------------------------------------------------------
105 int POSTGRESQL_STORE::AddTariff(const std::string & name) const
107 std::lock_guard lock(m_mutex);
109 if (PQstatus(connection) != CONNECTION_OK)
111 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
114 strError = "Connection lost";
115 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): '%s'\n", strError.c_str());
122 if (StartTransaction())
124 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to start transaction'\n");
128 std::string ename = name;
130 if (EscapeString(ename))
132 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
133 if (RollbackTransaction())
135 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
140 std::ostringstream query;
141 query << "SELECT sp_add_tariff('" << ename << "', " << DIR_NUM << ")";
143 result = PQexec(connection, query.str().c_str());
145 if (PQresultStatus(result) != PGRES_TUPLES_OK)
147 strError = PQresultErrorMessage(result);
149 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): '%s'\n", strError.c_str());
150 if (RollbackTransaction())
152 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
159 if (CommitTransaction())
161 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to commit transaction'\n");
167 //-----------------------------------------------------------------------------
168 int POSTGRESQL_STORE::DelTariff(const std::string & name) const
170 std::lock_guard lock(m_mutex);
172 if (PQstatus(connection) != CONNECTION_OK)
174 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
177 strError = "Connection lost";
178 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): '%s'\n", strError.c_str());
185 if (StartTransaction())
187 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to start transaction'\n");
191 std::string ename = name;
193 if (EscapeString(ename))
195 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
196 if (RollbackTransaction())
198 printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
203 std::ostringstream query;
204 query << "DELETE FROM tb_tariffs WHERE name = '" << ename << "'";
206 result = PQexec(connection, query.str().c_str());
208 if (PQresultStatus(result) != PGRES_COMMAND_OK)
210 strError = PQresultErrorMessage(result);
212 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): '%s'\n", strError.c_str());
213 if (RollbackTransaction())
215 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to rollback transaction'\n");
222 if (CommitTransaction())
224 printfd(__FILE__, "POSTGRESQL_STORE::DelTariff(): 'Failed to commit transaction'\n");
230 //-----------------------------------------------------------------------------
231 int POSTGRESQL_STORE::SaveTariff(const STG::TariffData & td,
232 const std::string & tariffName) const
234 std::lock_guard lock(m_mutex);
236 if (PQstatus(connection) != CONNECTION_OK)
238 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
241 strError = "Connection lost";
242 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
249 if (StartTransaction())
251 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to start transaction'\n");
255 std::string ename = tariffName;
257 if (EscapeString(ename))
259 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to escape name'\n");
260 if (RollbackTransaction())
262 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
268 std::ostringstream query;
269 query << "SELECT pk_tariff FROM tb_tariffs WHERE name = '" << ename << "'";
271 result = PQexec(connection, query.str().c_str());
274 if (PQresultStatus(result) != PGRES_TUPLES_OK)
276 strError = PQresultErrorMessage(result);
278 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
279 if (RollbackTransaction())
281 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
286 int tuples = PQntuples(result);
290 strError = "Failed to fetch tariff ID";
291 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
293 if (RollbackTransaction())
295 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
303 std::stringstream tuple;
304 tuple << PQgetvalue(result, 0, 0);
312 std::ostringstream query;
313 query << "UPDATE tb_tariffs SET \
314 fee = " << td.tariffConf.fee << ", \
315 free = " << td.tariffConf.free << ", \
316 passive_cost = " << td.tariffConf.passiveCost << ", \
317 traff_type = " << td.tariffConf.traffType;
320 query << ", period = '" << STG::Tariff::toString(td.tariffConf.period) << "'";
323 query << ", change_policy = '" << STG::Tariff::toString(td.tariffConf.changePolicy) << "', \
324 change_policy_timeout = CAST('" << formatTime(td.tariffConf.changePolicyTimeout) << "' AS TIMESTAMP)";
326 query << " WHERE pk_tariff = " << id;
328 result = PQexec(connection, query.str().c_str());
331 if (PQresultStatus(result) != PGRES_COMMAND_OK)
333 strError = PQresultErrorMessage(result);
335 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
336 if (RollbackTransaction())
338 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
345 for(int i = 0; i < DIR_NUM; i++)
347 double pda = td.dirPrice[i].priceDayA * 1024 * 1024;
348 double pdb = td.dirPrice[i].priceDayB * 1024 * 1024;
352 if (td.dirPrice[i].singlePrice)
359 pna = td.dirPrice[i].priceNightA * 1024 * 1024;
360 pnb = td.dirPrice[i].priceNightB * 1024 * 1024;
364 if (td.dirPrice[i].noDiscount)
366 threshold = 0xffFFffFF;
370 threshold = td.dirPrice[i].threshold;
374 std::ostringstream query;
375 query << "UPDATE tb_tariffs_params SET \
376 price_day_a = " << pda << ", \
377 price_day_b = " << pdb << ", \
378 price_night_a = " << pna << ", \
379 price_night_b = " << pnb << ", \
380 threshold = " << threshold << ", \
381 time_day_begins = CAST('" << td.dirPrice[i].hDay
383 << td.dirPrice[i].mDay << "' AS TIME), \
384 time_day_ends = CAST('" << td.dirPrice[i].hNight
386 << td.dirPrice[i].mNight << "' AS TIME) \
387 WHERE fk_tariff = " << id << " AND dir_num = " << i;
389 result = PQexec(connection, query.str().c_str());
392 if (PQresultStatus(result) != PGRES_COMMAND_OK)
394 strError = PQresultErrorMessage(result);
396 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): '%s'\n", strError.c_str());
397 if (RollbackTransaction())
399 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
407 if (CommitTransaction())
409 printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to commit transaction'\n");
415 //-----------------------------------------------------------------------------
416 int POSTGRESQL_STORE::RestoreTariff(STG::TariffData * td,
417 const std::string & tariffName) const
419 std::lock_guard lock(m_mutex);
421 if (PQstatus(connection) != CONNECTION_OK)
423 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
426 strError = "Connection lost";
427 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
434 if (StartTransaction())
436 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to start transaction'\n");
440 std::string ename = tariffName;
442 if (EscapeString(ename))
444 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to escape name'\n");
445 if (RollbackTransaction())
447 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
452 td->tariffConf.name = tariffName;
454 std::ostringstream query;
455 query << "SELECT pk_tariff, \
465 query << ", change_policy \
466 , change_policy_timeout";
468 query << " FROM tb_tariffs WHERE name = '" << ename << "'";
470 result = PQexec(connection, query.str().c_str());
472 if (PQresultStatus(result) != PGRES_TUPLES_OK)
474 strError = PQresultErrorMessage(result);
476 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
477 if (RollbackTransaction())
479 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
484 int tuples = PQntuples(result);
488 strError = "Failed to fetch tariff data";
489 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
491 if (RollbackTransaction())
493 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
501 std::stringstream tuple;
502 tuple << PQgetvalue(result, 0, 0) << " ";
503 tuple << PQgetvalue(result, 0, 1) << " ";
504 tuple << PQgetvalue(result, 0, 2) << " ";
505 tuple << PQgetvalue(result, 0, 3) << " ";
506 tuple << PQgetvalue(result, 0, 4) << " ";
509 tuple >> td->tariffConf.fee;
510 tuple >> td->tariffConf.free;
511 tuple >> td->tariffConf.passiveCost;
514 td->tariffConf.traffType = static_cast<STG::Tariff::TraffType>(traffType);
518 td->tariffConf.period = STG::Tariff::parsePeriod(PQgetvalue(result, 0, 5));
522 td->tariffConf.changePolicy = STG::Tariff::parseChangePolicy(PQgetvalue(result, 0, 6));
523 td->tariffConf.changePolicyTimeout = readTime(PQgetvalue(result, 0, 7));
529 query << "SELECT dir_num, \
535 EXTRACT(hour FROM time_day_begins), \
536 EXTRACT(minute FROM time_day_begins), \
537 EXTRACT(hour FROM time_day_ends), \
538 EXTRACT(minute FROM time_day_ends) \
539 FROM tb_tariffs_params \
540 WHERE fk_tariff = " << id;
542 result = PQexec(connection, query.str().c_str());
544 if (PQresultStatus(result) != PGRES_TUPLES_OK)
546 strError = PQresultErrorMessage(result);
548 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
549 if (RollbackTransaction())
551 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
556 tuples = PQntuples(result);
558 if (tuples != DIR_NUM)
560 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Tariff params count and DIR_NUM does not feet (wanted %d, actually %d)'\n", DIR_NUM, tuples);
563 for (int i = 0; i < std::min(tuples, DIR_NUM); ++i)
568 std::stringstream tuple;
569 tuple << PQgetvalue(result, i, 0) << " ";
570 tuple << PQgetvalue(result, i, 1) << " ";
571 tuple << PQgetvalue(result, i, 2) << " ";
572 tuple << PQgetvalue(result, i, 3) << " ";
573 tuple << PQgetvalue(result, i, 4) << " ";
574 tuple << PQgetvalue(result, i, 5) << " ";
575 tuple << PQgetvalue(result, i, 6) << " ";
576 tuple << PQgetvalue(result, i, 7) << " ";
577 tuple << PQgetvalue(result, i, 8) << " ";
578 tuple << PQgetvalue(result, i, 9) << " ";
581 tuple >> td->dirPrice[dir].priceDayA;
582 td->dirPrice[dir].priceDayA /= 1024 * 1024;
583 tuple >> td->dirPrice[dir].priceDayB;
584 td->dirPrice[dir].priceDayB /= 1024 * 1024;
585 tuple >> td->dirPrice[dir].priceNightA;
586 td->dirPrice[dir].priceNightA /= 1024 * 1024;
587 tuple >> td->dirPrice[dir].priceNightB;
588 td->dirPrice[dir].priceNightB /= 1024 * 1024;
589 tuple >> td->dirPrice[dir].threshold;
590 tuple >> td->dirPrice[dir].hDay;
591 tuple >> td->dirPrice[dir].mDay;
592 tuple >> td->dirPrice[dir].hNight;
593 tuple >> td->dirPrice[dir].mNight;
596 if (std::fabs(td->dirPrice[dir].priceDayA - td->dirPrice[dir].priceNightA) < 1.0e-3 / pt_mega &&
597 std::fabs(td->dirPrice[dir].priceDayB - td->dirPrice[dir].priceNightB) < 1.0e-3 / pt_mega)
599 td->dirPrice[dir].singlePrice = true;
603 td->dirPrice[dir].singlePrice = false;
605 if (td->dirPrice[dir].threshold == static_cast<int>(0xffFFffFF))
607 td->dirPrice[dir].noDiscount = true;
612 td->dirPrice[dir].noDiscount = false;
619 if (CommitTransaction())
621 printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to commit transaction'\n");
627 //-----------------------------------------------------------------------------