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