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 DBAPIProvider adapterprovider = {
26 .new = dbapi2_adapter_new,
27 .close = dbapi2_adapter_close,
29 .query = dbapi2_adapter_query,
30 .createtable = dbapi2_adapter_createtable,
31 .loadtable = dbapi2_adapter_loadtable,
33 .escapestring = dbapi2_adapter_escapestring,
34 .quotestring = dbapi2_adapter_quotestring,
36 .tablename = dbapi2_adapter_tablename,
39 struct DBAPI2AdapterQueryCallback {
42 DBAPIQueryCallback callback;
45 struct DBAPI2AdapterLoadTableCallback {
48 DBAPIQueryCallback init, callback, fini;
51 static int adapterhandle;
53 static void registeradapterprovider(void) {
54 adapterhandle = registerdbprovider(DBAPI2_ADAPTER_NAME, &adapterprovider);
57 static void deregisteradapterprovider(void) {
58 deregisterdbprovider(adapterhandle);
61 static DBAPI2_HANDLE *dbapi2_adapter_new(const DBAPIConn *db) {
64 dbattach(((DBAPIConn *)db)->name);
69 static void dbapi2_adapter_close(DBAPIConn *db) {
70 dbfreeid((int)(long)db->handle);
74 static char *dbapi2_adapter_result_get(const DBAPIResult *r, unsigned int column) {
75 return dbgetvalue(r->handle, column);
78 static int dbapi2_adapter_result_next(const DBAPIResult *r) {
79 return dbfetchrow(r->handle);
82 static void dbapi2_adapter_result_clear(const DBAPIResult *r) {
89 static DBAPIResult *wrapresult(DBAPIResult *r, DBConn *c) {
94 r = calloc(1, sizeof(DBAPIResult));
96 r->clear = dbapi2_adapter_result_clear;
97 r->handle = dbgetresult(c);
99 if(!dbquerysuccessful(r->handle))
103 r->fields = dbnumfields(r->handle);
105 r->get = dbapi2_adapter_result_get;
106 r->next = dbapi2_adapter_result_next;
111 static void dbapi2_adapter_querywrapper(DBConn *c, void *data) {
112 struct DBAPI2AdapterQueryCallback *a = data;
115 a->callback(wrapresult(&r, c), a->data);
120 static void sqquery(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, int flags, const char *query) {
121 struct DBAPI2AdapterQueryCallback *a;
124 a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
133 dbasyncqueryf((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, flags, "%s", query);
136 static void dbapi2_adapter_query(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
137 sqquery(db, cb, data, 0, query);
140 static void dbapi2_adapter_createtable(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *query) {
141 sqquery(db, cb, data, DB_CREATE, query);
144 static void dbapi2_adapter_loadtablewrapper_init(DBConn *c, void *data) {
145 struct DBAPI2AdapterLoadTableCallback *a = data;
147 a->init(NULL, a->data);
150 static void dbapi2_adapter_loadtablewrapper_data(DBConn *c, void *data) {
151 struct DBAPI2AdapterLoadTableCallback *a = data;
154 a->callback(wrapresult(&r, c), a->data);
157 static void dbapi2_adapter_loadtablewrapper_fini(DBConn *c, void *data) {
158 struct DBAPI2AdapterLoadTableCallback *a = data;
161 a->fini(NULL, a->data);
166 static void dbapi2_adapter_loadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback cb, DBAPIQueryCallback final, DBAPIUserData data, const char *table) {
167 struct DBAPI2AdapterLoadTableCallback *a = malloc(sizeof(struct DBAPI2AdapterLoadTableCallback));
176 dbloadtable_tag((char *)table, init?dbapi2_adapter_loadtablewrapper_init:NULL, cb?dbapi2_adapter_loadtablewrapper_data:NULL, dbapi2_adapter_loadtablewrapper_fini, a);
179 static void dbapi2_adapter_escapestring(const DBAPIConn *db, char *buf, const char *data, size_t len) {
180 dbescapestring(buf, (char *)data, len);
183 #ifndef DBAPI2_CUSTOM_QUOTESTRING
184 static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
186 char xbuf[len * 2 + 5];
189 sbinit(&b, buf, buflen);
190 esclen = dbescapestring(xbuf, (char *)data, len);
193 sbaddstrlen(&b, xbuf, esclen);
203 #ifndef DBAPI2_CUSTOM_TABLENAME
204 static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename) {
205 static char buf[1024];
207 snprintf(buf, sizeof(buf), "%s.%s", db->name, tablename);