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