]> jfr.im git - irc/quakenet/newserv.git/blame_incremental - dbapi2/dbapi2-adapter.inc
Merge.
[irc/quakenet/newserv.git] / dbapi2 / dbapi2-adapter.inc
... / ...
CommitLineData
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
12static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *);
13static void dbapi2_adapter_close(DBAPIConn *);
14
15static void dbapi2_adapter_query(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
16static void dbapi2_adapter_createtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
17static void dbapi2_adapter_loadtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIUserData data, const char *);
18
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);
21
22static char *dbapi2_adapter_tablename(const DBAPIConn *, const char *);
23
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,
33 .quotestring = dbapi2_adapter_quotestring,
34
35 .tablename = dbapi2_adapter_tablename,
36};
37
38struct DBAPI2AdapterQueryCallback {
39 const DBAPIConn *db;
40 DBAPIUserData data;
41 DBAPIQueryCallback callback;
42};
43
44struct DBAPI2AdapterLoadTableCallback {
45 const DBAPIConn *db;
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
60static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *db) {
61 long id = dbgetid();
62
63 dbattach(((DBAPIConn *)db)->name);
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
73static char *dbapi2_adapter_result_get(const DBAPIResult *r, unsigned int column) {
74 return dbgetvalue(r->handle, column);
75}
76
77static int dbapi2_adapter_result_next(const DBAPIResult *r) {
78 return dbfetchrow(r->handle);
79}
80
81static void dbapi2_adapter_result_clear(const DBAPIResult *r) {
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;
112 DBAPIResult r;
113
114 a->callback(wrapresult(&r, c), a->data);
115
116 free(a);
117}
118
119static void sqquery(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, int flags, const char *query) {
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
132 dbasyncqueryf((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, flags, "%s", query);
133}
134
135static void dbapi2_adapter_query(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
136 sqquery(db, cb, data, 0, query);
137}
138
139static void dbapi2_adapter_createtable(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
140 sqquery(db, cb, data, DB_CREATE, query);
141}
142
143static void dbapi2_adapter_loadtablewrapper_init(DBConn *c, void *data) {
144 struct DBAPI2AdapterLoadTableCallback *a = data;
145 DBAPIResult r;
146
147 a->init(wrapresult(&r, c), a->data);
148}
149
150static void dbapi2_adapter_loadtablewrapper_data(DBConn *c, void *data) {
151 struct DBAPI2AdapterLoadTableCallback *a = data;
152 DBAPIResult r;
153
154 a->callback(wrapresult(&r, c), a->data);
155}
156
157static void dbapi2_adapter_loadtablewrapper_fini(DBConn *c, void *data) {
158 struct DBAPI2AdapterLoadTableCallback *a = data;
159 DBAPIResult r;
160
161 if(a->fini)
162 a->fini(wrapresult(&r, c), a->data);
163
164 free(a);
165}
166
167static void dbapi2_adapter_loadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback cb, DBAPIQueryCallback final, DBAPIUserData data, const char *table) {
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
180static void dbapi2_adapter_escapestring(const DBAPIConn *db, char *buf, const char *data, size_t len) {
181 dbescapestring(buf, (char *)data, len);
182}
183
184#ifndef DBAPI2_CUSTOM_QUOTESTRING
185static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
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
203
204#ifndef DBAPI2_CUSTOM_TABLENAME
205static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename) {
206 static char buf[1024];
207
208 snprintf(buf, sizeof(buf), "%s.%s", db->name, tablename);
209
210 return buf;
211}
212#endif