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