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"
15 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *);
16 static void dbapi2_adapter_close(DBAPIConn *);
18 static void dbapi2_adapter_query(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
19 static void dbapi2_adapter_createtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
20 static void dbapi2_adapter_loadtable(const DBAPIConn *, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIUserData data, const char *);
22 static void dbapi2_adapter_escapestring(const DBAPIConn *, char *, const char *, size_t);
23 static int dbapi2_adapter_quotestring(const DBAPIConn *, char *, size_t, const char *, size_t);
25 static char *dbapi2_adapter_tablename(const DBAPIConn *, const char *);
27 static void dbapi2_adapter_call(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *);
29 static DBAPIProvider adapterprovider = {
30 .new = dbapi2_adapter_new,
31 .close = dbapi2_adapter_close,
33 .query = dbapi2_adapter_query,
34 .createtable = dbapi2_adapter_createtable,
35 .loadtable = dbapi2_adapter_loadtable,
37 .escapestring = dbapi2_adapter_escapestring,
38 .quotestring = dbapi2_adapter_quotestring,
40 .tablename = dbapi2_adapter_tablename,
42 .call = dbapi2_adapter_call,
45 struct DBAPI2AdapterQueryCallback {
48 DBAPIQueryCallback callback;
51 struct DBAPI2AdapterLoadTableCallback {
54 DBAPIQueryCallback init, callback, fini;
57 static int adapterhandle;
59 static void registeradapterprovider(void) {
60 adapterhandle = registerdbprovider(DBAPI2_ADAPTER_NAME, &adapterprovider);
63 static void deregisteradapterprovider(void) {
64 deregisterdbprovider(adapterhandle);
67 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *db) {
70 dbattach(((DBAPIConn *)db)->name);
75 static void dbapi2_adapter_close(DBAPIConn *db) {
76 dbfreeid((int)(long)db->handle);
80 static char *dbapi2_adapter_result_get(const DBAPIResult *r, unsigned int column) {
81 return dbgetvalue(r->handle, column);
84 static int dbapi2_adapter_result_next(const DBAPIResult *r) {
85 return dbfetchrow(r->handle);
88 static void dbapi2_adapter_result_clear(const DBAPIResult *r) {
95 static DBAPIResult *wrapresult(DBAPIResult *r, DBConn *c) {
100 r = calloc(1, sizeof(DBAPIResult));
102 memset(r, 0, sizeof(DBAPIResult));
105 r->clear = dbapi2_adapter_result_clear;
106 r->handle = dbgetresult(c);
108 r->affected = dbnumaffected(c, r->handle);
110 if(!dbquerysuccessful(r->handle))
114 r->fields = dbnumfields(r->handle);
116 r->get = dbapi2_adapter_result_get;
117 r->next = dbapi2_adapter_result_next;
122 static void dbapi2_adapter_querywrapper(DBConn *c, void *data) {
123 struct DBAPI2AdapterQueryCallback *a = data;
126 a->callback(wrapresult(&r, c), a->data);
131 static void sqquery(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, int flags, const char *query) {
132 struct DBAPI2AdapterQueryCallback *a;
135 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
144 dbasyncqueryf((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, flags, "%s", query);
147 static void dbapi2_adapter_query(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
148 sqquery(db, cb, data, 0, query);
151 static void dbapi2_adapter_createtable(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
152 sqquery(db, cb, data, DB_CREATE, query);
155 static void dbapi2_adapter_loadtablewrapper_init(DBConn *c, void *data) {
156 struct DBAPI2AdapterLoadTableCallback *a = data;
158 a->init(NULL, a->data);
161 static void dbapi2_adapter_loadtablewrapper_data(DBConn *c, void *data) {
162 struct DBAPI2AdapterLoadTableCallback *a = data;
165 a->callback(wrapresult(&r, c), a->data);
168 static void dbapi2_adapter_loadtablewrapper_fini(DBConn *c, void *data) {
169 struct DBAPI2AdapterLoadTableCallback *a = data;
172 a->fini(NULL, a->data);
177 static void dbapi2_adapter_loadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback cb, DBAPIQueryCallback final, DBAPIUserData data, const char *table) {
178 struct DBAPI2AdapterLoadTableCallback *a = malloc(sizeof(struct DBAPI2AdapterLoadTableCallback));
187 dbloadtable_tag((char *)table, init?dbapi2_adapter_loadtablewrapper_init:NULL, cb?dbapi2_adapter_loadtablewrapper_data:NULL, dbapi2_adapter_loadtablewrapper_fini, a);
190 static void dbapi2_adapter_escapestring(const DBAPIConn *db, char *buf, const char *data, size_t len) {
191 dbescapestring(buf, (char *)data, len);
194 #ifndef DBAPI2_CUSTOM_QUOTESTRING
195 static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
197 char xbuf[len * 2 + 5];
200 sbinit(&b, buf, buflen);
201 esclen = dbescapestring(xbuf, (char *)data, len);
204 sbaddstrlen(&b, xbuf, esclen);
214 #ifndef DBAPI2_CUSTOM_TABLENAME
215 static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename) {
216 static char buf[1024];
218 snprintf(buf, sizeof(buf), "%s.%s", db->name, tablename);
224 static void dbapi2_adapter_call(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *query) {
225 struct DBAPI2AdapterQueryCallback *a;
229 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
238 snprintf(buf, sizeof(buf), "%s", db->tablename(db, function));
239 dbcall((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, buf, query);