/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/sql_pgsql.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/sql_pgsql.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 /*
2 * Copyright (C) 2002,2003 Mihai RUSU (dizzy@rdsnet.ro)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #ifdef WITH_SQL_PGSQL
19
20 #include "common/setup_before.h"
21 #include <libpq-fe.h>
22 #include <stdlib.h>
23 #include "common/eventlog.h"
24 #include "common/xalloc.h"
25 #include "storage_sql.h"
26 #include "sql_pgsql.h"
27 #include "common/setup_after.h"
28
29 static int sql_pgsql_init(const char *, const char *, const char *, const char *, const char *, const char *);
30 static int sql_pgsql_close(void);
31 static t_sql_res * sql_pgsql_query_res(const char *);
32 static int sql_pgsql_query(const char *);
33 static t_sql_row * sql_pgsql_fetch_row(t_sql_res *);
34 static void sql_pgsql_free_result(t_sql_res *);
35 static unsigned int sql_pgsql_num_rows(t_sql_res *);
36 static unsigned int sql_pgsql_num_fields(t_sql_res *);
37 static unsigned int sql_pgsql_affected_rows(void);
38 static t_sql_field * sql_pgsql_fetch_fields(t_sql_res *);
39 static int sql_pgsql_free_fields(t_sql_field *);
40 static void sql_pgsql_escape_string(char *, const char *, int);
41
42 t_sql_engine sql_pgsql = {
43 sql_pgsql_init,
44 sql_pgsql_close,
45 sql_pgsql_query_res,
46 sql_pgsql_query,
47 sql_pgsql_fetch_row,
48 sql_pgsql_free_result,
49 sql_pgsql_num_rows,
50 sql_pgsql_num_fields,
51 sql_pgsql_affected_rows,
52 sql_pgsql_fetch_fields,
53 sql_pgsql_free_fields,
54 sql_pgsql_escape_string
55 };
56
57 static PGconn *pgsql = NULL;
58 static unsigned int lastarows = 0;
59
60 typedef struct {
61 int crow;
62 char ** rowbuf;
63 PGresult *pgres;
64 } t_pgsql_res;
65
66 static int sql_pgsql_init(const char *host, const char *port, const char *socket, const char *name, const char *user, const char *pass)
67 {
68 const char *tmphost;
69
70 if (name == NULL || user == NULL) {
71 eventlog(eventlog_level_error, __FUNCTION__, "got NULL parameter");
72 return -1;
73 }
74
75 tmphost = host != NULL ? host : socket;
76
77 if ((pgsql = PQsetdbLogin(host, port, NULL, NULL, name, user, pass)) == NULL) {
78 eventlog(eventlog_level_error, __FUNCTION__, "not enougn memory for new pgsql connection");
79 return -1;
80 }
81
82 if (PQstatus(pgsql) != CONNECTION_OK) {
83 eventlog(eventlog_level_error, __FUNCTION__, "error connecting to database (db said: '%s')", PQerrorMessage(pgsql));
84 PQfinish(pgsql);
85 pgsql = NULL;
86 return -1;
87 }
88
89 return 0;
90 }
91
92 static int sql_pgsql_close(void)
93 {
94 if (pgsql) {
95 PQfinish(pgsql);
96 pgsql = NULL;
97 }
98
99 return 0;
100 }
101
102 static t_sql_res * sql_pgsql_query_res(const char * query)
103 {
104 t_pgsql_res *res;
105 PGresult *pgres;
106
107 if (pgsql == NULL) {
108 eventlog(eventlog_level_error, __FUNCTION__, "pgsql driver not initilized");
109 return NULL;
110 }
111
112 if (query == NULL) {
113 eventlog(eventlog_level_error, __FUNCTION__, "got NULL query");
114 return NULL;
115 }
116
117 if ((pgres = PQexec(pgsql, query)) == NULL) {
118 eventlog(eventlog_level_error, __FUNCTION__, "not enough memory for query (%s)", query);
119 return NULL;
120 }
121
122 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
123 /* eventlog(eventlog_level_debug, __FUNCTION__, "got error from query (%s)", query); */
124 PQclear(pgres);
125 return NULL;
126 }
127
128 res = (t_pgsql_res *)xmalloc(sizeof(t_pgsql_res));
129 res->rowbuf = xmalloc(sizeof(char *) * PQnfields(pgres));
130 res->pgres = pgres;
131 res->crow = 0;
132
133 /* eventlog(eventlog_level_debug, __FUNCTION__, "res: %p res->rowbuf: %p res->crow: %d res->pgres: %p", res, res->rowbuf, res->crow, res->pgres); */
134 return res;
135 }
136
137 static void _pgsql_update_arows (const char *str)
138 {
139 if (!str || str[0] == '\0') lastarows = 0;
140 lastarows = (unsigned int)atoi(str);
141 }
142
143 static int sql_pgsql_query(const char * query)
144 {
145 PGresult *pgres;
146 int res;
147
148 if (pgsql == NULL) {
149 eventlog(eventlog_level_error, __FUNCTION__, "pgsql driver not initilized");
150 return -1;
151 }
152
153 if (query == NULL) {
154 eventlog(eventlog_level_error, __FUNCTION__, "got NULL query");
155 return -1;
156 }
157
158 if ((pgres = PQexec(pgsql, query)) == NULL) {
159 eventlog(eventlog_level_error, __FUNCTION__, "not enough memory for result");
160 return -1;
161 }
162
163 res = PQresultStatus(pgres) == PGRES_COMMAND_OK ? 0 : -1;
164 /* Dizzy: HACK ALERT! cache affected rows here before destroying result */
165 if (!res) _pgsql_update_arows(PQcmdTuples(pgres));
166 PQclear(pgres);
167
168 return res;
169 }
170
171 static t_sql_row * sql_pgsql_fetch_row(t_sql_res *result)
172 {
173 int nofields, i;
174 t_pgsql_res *res = (t_pgsql_res *) result;
175
176 if (res == NULL) {
177 eventlog(eventlog_level_error, __FUNCTION__, "got NULL result");
178 return NULL;
179 }
180
181 if (res->crow < 0) {
182 eventlog(eventlog_level_error, __FUNCTION__, "got called without a proper res query");
183 return NULL;
184 }
185
186 if (res->crow >= PQntuples(res->pgres)) return NULL; /* end of result */
187
188 nofields = PQnfields(res->pgres);
189 for(i = 0; i < nofields; i++) {
190 res->rowbuf[i] = PQgetvalue(res->pgres, res->crow, i);
191 /* the next line emulates the mysql way where NULL containing fields return NULL */
192 if (res->rowbuf[i] && res->rowbuf[i][0] == '\0') res->rowbuf[i] = NULL;
193 }
194
195 res->crow++;
196
197 /* eventlog(eventlog_level_debug, __FUNCTION__, "res: %p res->rowbuf: %p res->crow: %d res->pgres: %p", res, res->rowbuf, res->crow, res->pgres); */
198 return res->rowbuf;
199 }
200
201 static void sql_pgsql_free_result(t_sql_res *result)
202 {
203 t_pgsql_res *res = (t_pgsql_res *) result;
204
205 if (res == NULL) return;
206 /* eventlog(eventlog_level_debug, __FUNCTION__, "res: %p res->rowbuf: %p res->crow: %d res->pgres: %p", res, res->rowbuf, res->crow, res->pgres); */
207
208 if (res->pgres) PQclear(res->pgres);
209 if (res->rowbuf) xfree((void*)res->rowbuf);
210 xfree((void*)res);
211 }
212
213 static unsigned int sql_pgsql_num_rows(t_sql_res *result)
214 {
215 if (result == NULL) {
216 eventlog(eventlog_level_error, __FUNCTION__, "got NULL result");
217 return 0;
218 }
219
220 return PQntuples(((t_pgsql_res *)result)->pgres);
221 }
222
223 static unsigned int sql_pgsql_num_fields(t_sql_res *result)
224 {
225 if (result == NULL) {
226 eventlog(eventlog_level_error, __FUNCTION__, "got NULL result");
227 return 0;
228 }
229
230 return PQnfields(((t_pgsql_res *)result)->pgres);
231 }
232
233 static unsigned int sql_pgsql_affected_rows(void)
234 {
235 return lastarows;
236 }
237
238 static t_sql_field * sql_pgsql_fetch_fields(t_sql_res *result)
239 {
240 t_pgsql_res *res = (t_pgsql_res *) result;
241 unsigned fieldno, i;
242 t_sql_field *rfields;
243
244 if (result == NULL) {
245 eventlog(eventlog_level_error, __FUNCTION__, "got NULL result");
246 return NULL;
247 }
248
249 fieldno = PQnfields(res->pgres);
250
251 rfields = xmalloc(sizeof(t_sql_field) * (fieldno + 1));
252 for(i = 0; i < fieldno; i++)
253 rfields[i] = PQfname(res->pgres, i);
254 rfields[i] = NULL;
255
256 return rfields;
257 }
258
259 static int sql_pgsql_free_fields(t_sql_field *fields)
260 {
261 if (fields == NULL) {
262 eventlog(eventlog_level_error, __FUNCTION__, "got NULL fields");
263 return -1;
264 }
265
266 xfree((void*)fields);
267 return 0; /* PQclear() should free the rest properly */
268 }
269
270 static void sql_pgsql_escape_string(char *escape, const char *from, int len)
271 {
272 PQescapeString(escape, from, len);
273 }
274
275 #endif /* WITH_SQL_PGSQL */

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1