]> jfr.im git - irc/quakenet/newserv.git/blob - dbapi2/dbapi2-adapter.inc
CHANSERV: return channel id from relay addchan.
[irc/quakenet/newserv.git] / dbapi2 / dbapi2-adapter.inc
1 #include <stdarg.h>
2 #include <stdio.h>
3
4 #define DBAPI2_ADAPTER
5 #include "../dbapi/dbapi.h"
6
7 #define DBAPI2_RESULT_HANDLE DBResult
8
9 #include "../dbapi2/dbapi2.h"
10 #include "../lib/stringbuf.h"
11 #include "../lib/version.h"
12
13 #include <string.h>
14
15 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *);
16 static void dbapi2_adapter_close(DBAPIConn *);
17
18 static void dbapi2_adapter_query(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
19 static void dbapi2_adapter_createtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
20 static void dbapi2_adapter_loadtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIUserData data, const char *);
21
22 static void dbapi2_adapter_escapestring(const DBAPIConn *, char *, const char *, size_t);
23 static int dbapi2_adapter_quotestring(const DBAPIConn *, char *, size_t, const char *, size_t);
24
25 static char *dbapi2_adapter_tablename(const DBAPIConn *, const char *);
26
27 static void dbapi2_adapter_call(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *);
28
29 static DBAPIProvider adapterprovider = {
30 .new = dbapi2_adapter_new,
31 .close = dbapi2_adapter_close,
32
33 .query = dbapi2_adapter_query,
34 .createtable = dbapi2_adapter_createtable,
35 .loadtable = dbapi2_adapter_loadtable,
36
37 .escapestring = dbapi2_adapter_escapestring,
38 .quotestring = dbapi2_adapter_quotestring,
39
40 .tablename = dbapi2_adapter_tablename,
41
42 .call = dbapi2_adapter_call,
43 };
44
45 struct DBAPI2AdapterQueryCallback {
46 const DBAPIConn *db;
47 DBAPIUserData data;
48 DBAPIQueryCallback callback;
49 };
50
51 struct DBAPI2AdapterLoadTableCallback {
52 const DBAPIConn *db;
53 DBAPIUserData data;
54 DBAPIQueryCallback init, callback, fini;
55 };
56
57 static int adapterhandle;
58
59 static void registeradapterprovider(void) {
60 adapterhandle = registerdbprovider(DBAPI2_ADAPTER_NAME, &adapterprovider);
61 }
62
63 static void deregisteradapterprovider(void) {
64 deregisterdbprovider(adapterhandle);
65 }
66
67 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *db) {
68 long id = dbgetid();
69
70 dbattach(((DBAPIConn *)db)->name);
71
72 return (void *)id;
73 }
74
75 static void dbapi2_adapter_close(DBAPIConn *db) {
76 dbfreeid((int)(long)db->handle);
77 dbdetach(db->name);
78 }
79
80 static char *dbapi2_adapter_result_get(const DBAPIResult *r, unsigned int column) {
81 return dbgetvalue(r->handle, column);
82 }
83
84 static int dbapi2_adapter_result_next(const DBAPIResult *r) {
85 return dbfetchrow(r->handle);
86 }
87
88 static void dbapi2_adapter_result_clear(const DBAPIResult *r) {
89 if(!r)
90 return;
91
92 dbclear(r->handle);
93 }
94
95 static DBAPIResult *wrapresult(DBAPIResult *r, DBConn *c) {
96 if(!c)
97 return NULL;
98
99 if(!r) {
100 r = calloc(1, sizeof(DBAPIResult));
101 } else {
102 memset(r, 0, sizeof(DBAPIResult));
103 }
104
105 r->clear = dbapi2_adapter_result_clear;
106 r->handle = dbgetresult(c);
107
108 if(!dbquerysuccessful(r->handle))
109 return r;
110
111 r->success = 1;
112 r->fields = dbnumfields(r->handle);
113
114 r->get = dbapi2_adapter_result_get;
115 r->next = dbapi2_adapter_result_next;
116
117 return r;
118 }
119
120 static void dbapi2_adapter_querywrapper(DBConn *c, void *data) {
121 struct DBAPI2AdapterQueryCallback *a = data;
122 DBAPIResult r;
123
124 a->callback(wrapresult(&r, c), a->data);
125
126 free(a);
127 }
128
129 static void sqquery(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, int flags, const char *query) {
130 struct DBAPI2AdapterQueryCallback *a;
131
132 if(cb) {
133 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
134
135 a->db = db;
136 a->data = data;
137 a->callback = cb;
138 } else {
139 a = NULL;
140 }
141
142 dbasyncqueryf((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, flags, "%s", query);
143 }
144
145 static void dbapi2_adapter_query(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
146 sqquery(db, cb, data, 0, query);
147 }
148
149 static void dbapi2_adapter_createtable(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
150 sqquery(db, cb, data, DB_CREATE, query);
151 }
152
153 static void dbapi2_adapter_loadtablewrapper_init(DBConn *c, void *data) {
154 struct DBAPI2AdapterLoadTableCallback *a = data;
155
156 a->init(NULL, a->data);
157 }
158
159 static void dbapi2_adapter_loadtablewrapper_data(DBConn *c, void *data) {
160 struct DBAPI2AdapterLoadTableCallback *a = data;
161 DBAPIResult r;
162
163 a->callback(wrapresult(&r, c), a->data);
164 }
165
166 static void dbapi2_adapter_loadtablewrapper_fini(DBConn *c, void *data) {
167 struct DBAPI2AdapterLoadTableCallback *a = data;
168
169 if(a->fini)
170 a->fini(NULL, a->data);
171
172 free(a);
173 }
174
175 static void dbapi2_adapter_loadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback cb, DBAPIQueryCallback final, DBAPIUserData data, const char *table) {
176 struct DBAPI2AdapterLoadTableCallback *a = malloc(sizeof(struct DBAPI2AdapterLoadTableCallback));
177
178 a->db = db;
179 a->data = data;
180
181 a->init = init;
182 a->callback = cb;
183 a->fini = final;
184
185 dbloadtable_tag((char *)table, init?dbapi2_adapter_loadtablewrapper_init:NULL, cb?dbapi2_adapter_loadtablewrapper_data:NULL, dbapi2_adapter_loadtablewrapper_fini, a);
186 }
187
188 static void dbapi2_adapter_escapestring(const DBAPIConn *db, char *buf, const char *data, size_t len) {
189 dbescapestring(buf, (char *)data, len);
190 }
191
192 #ifndef DBAPI2_CUSTOM_QUOTESTRING
193 static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
194 StringBuf b;
195 char xbuf[len * 2 + 5];
196 size_t esclen;
197
198 sbinit(&b, buf, buflen);
199 esclen = dbescapestring(xbuf, (char *)data, len);
200
201 sbaddchar(&b, '\'');
202 sbaddstrlen(&b, xbuf, esclen);
203 sbaddchar(&b, '\'');
204
205 if(!sbterminate(&b))
206 return 0;
207
208 return 1;
209 }
210 #endif
211
212 #ifndef DBAPI2_CUSTOM_TABLENAME
213 static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename) {
214 static char buf[1024];
215
216 snprintf(buf, sizeof(buf), "%s.%s", db->name, tablename);
217
218 return buf;
219 }
220 #endif
221
222 static void dbapi2_adapter_call(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *query) {
223 struct DBAPI2AdapterQueryCallback *a;
224 char buf[512];
225
226 if(cb) {
227 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
228
229 a->db = db;
230 a->data = data;
231 a->callback = cb;
232 } else {
233 a = NULL;
234 }
235
236 snprintf(buf, sizeof(buf), "%s", db->tablename(db, function));
237 dbcall((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, buf, query);
238 }
239