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