5 #include "../dbapi/dbapi.h"
7 #define DBAPI2_RESULT_HANDLE DBResult
9 #include "../dbapi2/dbapi2.h"
10 #include "../lib/stringbuf.h"
11 #include "../lib/version.h"
13 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *);
14 static void dbapi2_adapter_close(DBAPIConn *);
16 static void dbapi2_adapter_query(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
17 static void dbapi2_adapter_createtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
18 static void dbapi2_adapter_loadtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIUserData data, const char *);
20 static void dbapi2_adapter_escapestring(const DBAPIConn *, char *, const char *, size_t);
21 static int dbapi2_adapter_quotestring(const DBAPIConn *, char *, size_t, const char *, size_t);
23 static char *dbapi2_adapter_tablename(const DBAPIConn *, const char *);
25 static void dbapi2_adapter_call(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *);
27 static DBAPIProvider adapterprovider = {
28 .new = dbapi2_adapter_new,
29 .close = dbapi2_adapter_close,
31 .query = dbapi2_adapter_query,
32 .createtable = dbapi2_adapter_createtable,
33 .loadtable = dbapi2_adapter_loadtable,
35 .escapestring = dbapi2_adapter_escapestring,
36 .quotestring = dbapi2_adapter_quotestring,
38 .tablename = dbapi2_adapter_tablename,
40 .call = dbapi2_adapter_call,
43 struct DBAPI2AdapterQueryCallback {
46 DBAPIQueryCallback callback;
49 struct DBAPI2AdapterLoadTableCallback {
52 DBAPIQueryCallback init, callback, fini;
55 static int adapterhandle;
57 static void registeradapterprovider(void) {
58 adapterhandle = registerdbprovider(DBAPI2_ADAPTER_NAME, &adapterprovider);
61 static void deregisteradapterprovider(void) {
62 deregisterdbprovider(adapterhandle);
65 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *db) {
68 dbattach(((DBAPIConn *)db)->name);
73 static void dbapi2_adapter_close(DBAPIConn *db) {
74 dbfreeid((int)(long)db->handle);
78 static char *dbapi2_adapter_result_get(const DBAPIResult *r, unsigned int column) {
79 return dbgetvalue(r->handle, column);
82 static int dbapi2_adapter_result_next(const DBAPIResult *r) {
83 return dbfetchrow(r->handle);
86 static void dbapi2_adapter_result_clear(const DBAPIResult *r) {
93 static DBAPIResult *wrapresult(DBAPIResult *r, DBConn *c) {
98 r = calloc(1, sizeof(DBAPIResult));
100 r->clear = dbapi2_adapter_result_clear;
101 r->handle = dbgetresult(c);
103 if(!dbquerysuccessful(r->handle))
107 r->fields = dbnumfields(r->handle);
109 r->get = dbapi2_adapter_result_get;
110 r->next = dbapi2_adapter_result_next;
115 static void dbapi2_adapter_querywrapper(DBConn *c, void *data) {
116 struct DBAPI2AdapterQueryCallback *a = data;
119 a->callback(wrapresult(&r, c), a->data);
124 static void sqquery(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, int flags, const char *query) {
125 struct DBAPI2AdapterQueryCallback *a;
128 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
137 dbasyncqueryf((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, flags, "%s", query);
140 static void dbapi2_adapter_query(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
141 sqquery(db, cb, data, 0, query);
144 static void dbapi2_adapter_createtable(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
145 sqquery(db, cb, data, DB_CREATE, query);
148 static void dbapi2_adapter_loadtablewrapper_init(DBConn *c, void *data) {
149 struct DBAPI2AdapterLoadTableCallback *a = data;
151 a->init(NULL, a->data);
154 static void dbapi2_adapter_loadtablewrapper_data(DBConn *c, void *data) {
155 struct DBAPI2AdapterLoadTableCallback *a = data;
158 a->callback(wrapresult(&r, c), a->data);
161 static void dbapi2_adapter_loadtablewrapper_fini(DBConn *c, void *data) {
162 struct DBAPI2AdapterLoadTableCallback *a = data;
165 a->fini(NULL, a->data);
170 static void dbapi2_adapter_loadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback cb, DBAPIQueryCallback final, DBAPIUserData data, const char *table) {
171 struct DBAPI2AdapterLoadTableCallback *a = malloc(sizeof(struct DBAPI2AdapterLoadTableCallback));
180 dbloadtable_tag((char *)table, init?dbapi2_adapter_loadtablewrapper_init:NULL, cb?dbapi2_adapter_loadtablewrapper_data:NULL, dbapi2_adapter_loadtablewrapper_fini, a);
183 static void dbapi2_adapter_escapestring(const DBAPIConn *db, char *buf, const char *data, size_t len) {
184 dbescapestring(buf, (char *)data, len);
187 #ifndef DBAPI2_CUSTOM_QUOTESTRING
188 static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
190 char xbuf[len * 2 + 5];
193 sbinit(&b, buf, buflen);
194 esclen = dbescapestring(xbuf, (char *)data, len);
197 sbaddstrlen(&b, xbuf, esclen);
207 #ifndef DBAPI2_CUSTOM_TABLENAME
208 static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename) {
209 static char buf[1024];
211 snprintf(buf, sizeof(buf), "%s.%s", db->name, tablename);
217 static void dbapi2_adapter_call(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *query) {
218 struct DBAPI2AdapterQueryCallback *a;
222 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
231 snprintf(buf, sizeof(buf), "%s", db->tablename(db, function));
232 dbcall((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, buf, query);