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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 sysadm 1.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