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