]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/store/postgresql/postgresql_store_services.cpp
Use std::lock_guard instead of STG_LOCKER.
[stg.git] / projects / stargazer / plugins / store / postgresql / postgresql_store_services.cpp
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21
22 /*
23  *  Services manipulation methods
24  *
25  *  $Revision: 1.2 $
26  *  $Date: 2009/06/09 12:32:40 $
27  *
28  */
29
30 #include "postgresql_store.h"
31
32 #include "stg/service_conf.h"
33 #include "stg/common.h"
34
35 #include <string>
36 #include <vector>
37 #include <sstream>
38
39 #include <libpq-fe.h>
40
41 //-----------------------------------------------------------------------------
42 int POSTGRESQL_STORE::GetServicesList(std::vector<std::string> * servicesList) const
43 {
44 std::lock_guard lock(m_mutex);
45
46 if (PQstatus(connection) != CONNECTION_OK)
47     {
48     printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
49     if (Reset())
50         {
51         strError = "Connection lost";
52         printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): '%s'\n", strError.c_str());
53         return -1;
54         }
55     }
56
57 PGresult * result;
58
59 if (StartTransaction())
60     {
61     printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): 'Failed to start transaction'\n");
62     return -1;
63     }
64
65 result = PQexec(connection, "SELECT name FROM tb_services");
66
67 if (PQresultStatus(result) != PGRES_TUPLES_OK)
68     {
69     strError = PQresultErrorMessage(result);
70     PQclear(result);
71     printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): '%s'\n", strError.c_str());
72     if (RollbackTransaction())
73         {
74         printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): 'Failed to rollback transaction'\n");
75         }
76     return -1;
77     }
78
79 int tuples = PQntuples(result);
80
81 for (int i = 0; i < tuples; ++i)
82     {
83     servicesList->push_back(PQgetvalue(result, i, 0));
84     }
85
86 PQclear(result);
87
88 if (CommitTransaction())
89     {
90     printfd(__FILE__, "POSTGRESQL_STORE::GetServicesList(): 'Failed to commit transaction'\n");
91     return -1;
92     }
93
94 return 0;
95 }
96
97 //-----------------------------------------------------------------------------
98 int POSTGRESQL_STORE::SaveService(const STG::ServiceConf & sc) const
99 {
100 std::lock_guard lock(m_mutex);
101
102 if (PQstatus(connection) != CONNECTION_OK)
103     {
104     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
105     if (Reset())
106         {
107         strError = "Connection lost";
108         printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): '%s'\n", strError.c_str());
109         return -1;
110         }
111     }
112
113 PGresult * result;
114
115 if (StartTransaction())
116     {
117     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to start transaction'\n");
118     return -1;
119     }
120
121 std::string ename = sc.name;
122 std::string ecomment = sc.comment;
123
124 if (EscapeString(ename))
125     {
126     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to escape name'\n");
127     if (RollbackTransaction())
128         {
129         printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to rollback transaction'\n");
130         }
131     return -1;
132     }
133
134 if (EscapeString(ecomment))
135     {
136     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to escape comment'\n");
137     if (RollbackTransaction())
138         {
139         printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to rollback transaction'\n");
140         }
141     return -1;
142     }
143
144 std::ostringstream query;
145 query << "UPDATE tb_services SET "
146           << "comment = '" << ecomment << "', "
147           << "cost = " << sc.cost << ", "
148           << "pay_day = " << sc.payDay << " "
149       << "WHERE name = '" << ename << "'";
150
151 result = PQexec(connection, query.str().c_str());
152
153 if (PQresultStatus(result) != PGRES_COMMAND_OK)
154     {
155     strError = PQresultErrorMessage(result);
156     PQclear(result);
157     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): '%s'\n", strError.c_str());
158     if (RollbackTransaction())
159         {
160         printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to rollback transaction'\n");
161         }
162     return -1;
163     }
164
165 PQclear(result);
166
167 if (CommitTransaction())
168     {
169     printfd(__FILE__, "POSTGRESQL_STORE::SaveService(): 'Failed to commit transaction'\n");
170     return -1;
171     }
172
173 return 0;
174 }
175
176 //-----------------------------------------------------------------------------
177 int POSTGRESQL_STORE::RestoreService(STG::ServiceConf * sc,
178                                      const std::string & name) const
179 {
180 std::lock_guard lock(m_mutex);
181
182 if (PQstatus(connection) != CONNECTION_OK)
183     {
184     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
185     if (Reset())
186         {
187         strError = "Connection lost";
188         printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): '%s'\n", strError.c_str());
189         return -1;
190         }
191     }
192
193 PGresult * result;
194
195 if (StartTransaction())
196     {
197     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to start transaction'\n");
198     return -1;
199     }
200
201 std::string ename = name;
202
203 if (EscapeString(ename))
204     {
205     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to escape name'\n");
206     if (RollbackTransaction())
207         {
208         printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to rollback transaction'\n");
209         }
210     return -1;
211     }
212
213 std::ostringstream query;
214 query << "SELECT comment, cost, pay_day FROM tb_services WHERE name = '" << ename << "'";
215
216 result = PQexec(connection, query.str().c_str());
217
218 if (PQresultStatus(result) != PGRES_TUPLES_OK)
219     {
220     strError = PQresultErrorMessage(result);
221     PQclear(result);
222     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): '%s'\n", strError.c_str());
223     if (RollbackTransaction())
224         {
225         printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to rollback transaction'\n");
226         }
227     return -1;
228     }
229
230 int tuples = PQntuples(result);
231
232 if (tuples != 1)
233     {
234     strError = "Failed to fetch service's data";
235     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
236     PQclear(result);
237     if (RollbackTransaction())
238         {
239         printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to rollback transaction'\n");
240         }
241     return -1;
242     }
243
244 std::stringstream tuple;
245 tuple << PQgetvalue(result, 0, 0) << " "
246       << PQgetvalue(result, 0, 1) << " "
247       << PQgetvalue(result, 0, 2);
248
249 PQclear(result);
250
251 tuple >> sc->comment
252       >> sc->cost
253       >> sc->payDay;
254
255 if (CommitTransaction())
256     {
257     printfd(__FILE__, "POSTGRESQL_STORE::RestoreService(): 'Failed to commit transaction'\n");
258     return -1;
259     }
260
261 return 0;
262 }
263
264 //-----------------------------------------------------------------------------
265 int POSTGRESQL_STORE::AddService(const std::string & name) const
266 {
267 std::lock_guard lock(m_mutex);
268
269 if (PQstatus(connection) != CONNECTION_OK)
270     {
271     printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
272     if (Reset())
273         {
274         strError = "Connection lost";
275         printfd(__FILE__, "POSTGRESQL_STORE::AddService(): '%s'\n", strError.c_str());
276         return -1;
277         }
278     }
279
280 PGresult * result;
281
282 if (StartTransaction())
283     {
284     printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Failed to start transaction'\n");
285     return -1;
286     }
287
288 std::string ename = name;
289
290 if (EscapeString(ename))
291     {
292     printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Failed to escape name'\n");
293     if (RollbackTransaction())
294         {
295         printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Failed to rollback transaction'\n");
296         }
297     return -1;
298     }
299
300 std::ostringstream query;
301 query << "INSERT INTO tb_services \
302               (name, comment, cost, pay_day) \
303           VALUES \
304               ('" << ename << "', '', 0, 0)";
305
306 result = PQexec(connection, query.str().c_str());
307
308 if (PQresultStatus(result) != PGRES_COMMAND_OK)
309     {
310     strError = PQresultErrorMessage(result);
311     PQclear(result);
312     printfd(__FILE__, "POSTGRESQL_STORE::AddService(): '%s'\n", strError.c_str());
313     if (RollbackTransaction())
314         {
315         printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Failed to rollback transaction'\n");
316         }
317     return -1;
318     }
319
320 PQclear(result);
321
322 if (CommitTransaction())
323     {
324     printfd(__FILE__, "POSTGRESQL_STORE::AddService(): 'Failed to commit transaction'\n");
325     return -1;
326     }
327
328 return 0;
329 }
330
331 //-----------------------------------------------------------------------------
332 int POSTGRESQL_STORE::DelService(const std::string & name) const
333 {
334 std::lock_guard lock(m_mutex);
335
336 if (PQstatus(connection) != CONNECTION_OK)
337     {
338     printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Connection lost. Trying to reconnect...'\n", strError.c_str());
339     if (Reset())
340         {
341         strError = "Connection lost";
342         printfd(__FILE__, "POSTGRESQL_STORE::DelService(): '%s'\n", strError.c_str());
343         return -1;
344         }
345     }
346
347 PGresult * result;
348
349 if (StartTransaction())
350     {
351     printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Failed to start transaction'\n");
352     return -1;
353     }
354
355 std::string ename = name;
356
357 if (EscapeString(ename))
358     {
359     printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Failed to escape name'\n");
360     if (RollbackTransaction())
361         {
362         printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Failed to rollback transaction'\n");
363         }
364     return -1;
365     }
366
367 std::ostringstream query;
368 query << "DELETE FROM tb_services WHERE name = '" << ename << "'";
369
370 result = PQexec(connection, query.str().c_str());
371
372 if (PQresultStatus(result) != PGRES_COMMAND_OK)
373     {
374     strError = PQresultErrorMessage(result);
375     PQclear(result);
376     printfd(__FILE__, "POSTGRESQL_STORE::DelService(): '%s'\n", strError.c_str());
377     if (RollbackTransaction())
378         {
379         printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Failed to rollback transaction'\n");
380         }
381     return -1;
382     }
383
384 PQclear(result);
385
386 if (CommitTransaction())
387     {
388     printfd(__FILE__, "POSTGRESQL_STORE::DelService(): 'Failed to commit transaction'\n");
389     return -1;
390     }
391
392 return 0;
393 }
394 //-----------------------------------------------------------------------------
395