]> jfr.im git - irc/quakenet/newserv.git/commitdiff
DBAPI2: add support for stored procedures
authorChris Porter <redacted>
Thu, 23 Feb 2012 14:39:26 +0000 (15:39 +0100)
committerChris Porter <redacted>
Thu, 23 Feb 2012 14:39:26 +0000 (15:39 +0100)
dbapi/dbapi.h
dbapi2/dbapi2-adapter.inc
dbapi2/dbapi2.c
dbapi2/dbapi2.h
pqsql/pqsql.c

index 07d888b91c83d52bd2844cb41fdd0681e250f76c..4b4453a5fe7b1fc2b7a5f6c766985e0d71b0550c 100644 (file)
@@ -7,6 +7,7 @@
 
 #define DB_NULLIDENTIFIER 0
 #define DB_CREATE 1
+#define DB_CALL 2
 
 #ifdef DBAPI_OVERRIDE
 #undef USE_DBAPI_PGSQL
@@ -43,6 +44,7 @@ typedef PQResult DBResult;
 #define dbgetvalue(result, column) pqgetvalue(result, column)
 
 #define dbclear(result) pqclear(result)
+#define dbcall(id, handler, tag, function, ...) pqasyncqueryf(id, handler, tag, (handler) == NULL ? DB_CALL : 0, "SELECT %s(%s)", function , ##__VA_ARGS__)
 
 #endif /* DBAPI_PGSQL */
 
@@ -75,6 +77,8 @@ typedef SQLiteResult DBResult;
 
 #define dbclear(result) sqliteclear(result)
 
+#define dbcall(...) abort() /* HA */
+
 #endif /* DBAPI_SQLITE */
 
 #endif /* BUILDING_DBAPI */
index 7e4c47da8f6d6fb361e3b4522f1119534a5ea498..cfb555a3d9e4ab90f04484cd5043ff42b2bd64cf 100644 (file)
@@ -22,6 +22,8 @@ static int dbapi2_adapter_quotestring(const DBAPIConn *, char *, size_t, const c
 
 static char *dbapi2_adapter_tablename(const DBAPIConn *, const char *);
 
+static void dbapi2_adapter_call(const DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *);
+
 static DBAPIProvider adapterprovider = {
   .new = dbapi2_adapter_new,
   .close = dbapi2_adapter_close,
@@ -34,6 +36,8 @@ static DBAPIProvider adapterprovider = {
   .quotestring = dbapi2_adapter_quotestring,
 
   .tablename = dbapi2_adapter_tablename,
+
+  .call = dbapi2_adapter_call,
 };
 
 struct DBAPI2AdapterQueryCallback {
@@ -209,3 +213,22 @@ static char *dbapi2_adapter_tablename(const DBAPIConn *db, const char *tablename
   return buf;
 }
 #endif
+
+static void dbapi2_adapter_call(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *query) {
+  struct DBAPI2AdapterQueryCallback *a;
+  char buf[512];
+
+  if(cb) {
+    a = malloc(sizeof(struct DBAPI2AdapterQueryCallback));
+
+    a->db = db;
+    a->data = data;
+    a->callback = cb;
+  } else {
+    a = NULL;
+  }
+
+  snprintf(buf, sizeof(buf), "%s", db->tablename(db, function));
+  dbcall((int)(long)db->handle, cb?dbapi2_adapter_querywrapper:NULL, a, buf, query);
+}
+
index 1f8da497c49dd29c4c2355c62940f210a0951aa8..212564806446436886d9b6a55f84c3a98562477c 100644 (file)
@@ -151,6 +151,28 @@ static void dbloadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQuery
   db->__loadtable(db, init, data, fini, tag, db->tablename(db, tablename));
 }
 
+static void dbcall(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *format, const char *types, ...) {
+  va_list ap;
+  char buf[QUERYBUFLEN];
+
+  va_start(ap, types);
+  dbvsnprintf(db, buf, sizeof(buf), format, types, ap);
+  va_end(ap);
+
+  db->__call(db, cb, data, function, buf);
+}
+
+static void dbsimplecall(const DBAPIConn *db, const char *function, const char *format, const char *types, ...) {
+  va_list ap;
+  char buf[QUERYBUFLEN];
+
+  va_start(ap, types);
+  dbvsnprintf(db, buf, sizeof(buf), format, types, ap);
+  va_end(ap);
+
+  db->__call(db, NULL, NULL, function, buf);
+}
+
 DBAPIConn *dbapi2open(const char *provider, const char *database) {
   int i, found = -1;
   DBAPIConn *db;
@@ -197,12 +219,15 @@ DBAPIConn *dbapi2open(const char *provider, const char *database) {
   db->unsafequery = dbunsafequery;
   db->unsafesquery = dbunsafesimplequery;
   db->unsafecreatetable = dbunsafecreatetable;
+  db->call = dbcall;
+  db->scall = dbsimplecall;
 
   db->__query = p->query;
   db->__close = p->close;
   db->__quotestring = p->quotestring;
   db->__createtable = p->createtable;
   db->__loadtable = p->loadtable;
+  db->__call = p->call;
 
   strlcpy(db->name, database, DBNAME_LEN);
 
index 0c3c8644623141c201429757f0d9f4f8faad9dcd..b7b71878c41fb5ec5501242561fb63949112bdfa 100644 (file)
@@ -32,6 +32,7 @@ typedef void (*DBAPIQueryCallback)(const struct DBAPIResult *, void *);
 typedef void (*DBAPIQuery)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, ...) __attribute__ ((format (printf, 4, 5)));
 typedef void (*DBAPISimpleQuery)(const struct DBAPIConn *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
 typedef void (*DBAPIQueryV)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
+typedef void (*DBAPICallV)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *);
 typedef void (*DBAPICreateTable)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, ...) __attribute__ ((format (printf, 4, 5)));
 typedef void (*DBAPICreateTableV)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *);
 typedef void (*DBAPILoadTable)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIQueryCallback, DBAPIUserData, const char *);
@@ -42,6 +43,8 @@ typedef void (*DBAPISafeCreateTable)(const struct DBAPIConn *, DBAPIQueryCallbac
 
 typedef void (*DBAPIEscapeString)(const struct DBAPIConn *, char *, const char *, size_t);
 typedef int (*DBAPIQuoteString)(const struct DBAPIConn *, char *, size_t, const char *, size_t);
+typedef void (*DBAPICall)(const struct DBAPIConn *, DBAPIQueryCallback, DBAPIUserData, const char *, const char *, const char *, ...);
+typedef void (*DBAPISimpleCall)(const struct DBAPIConn *, const char *, const char *, const char *, ...);
 
 typedef char *(*DBAPITableName)(const struct DBAPIConn *, const char *);
 
@@ -59,6 +62,7 @@ typedef struct DBAPIProvider {
 
   DBAPIEscapeString escapestring;
   DBAPIQuoteString quotestring;
+  DBAPICallV call;
 
 /* private members */
   struct DBAPIProviderData *__providerdata;
@@ -78,6 +82,9 @@ typedef struct DBAPIConn {
   DBAPISafeSimpleQuery squery;
   DBAPISafeCreateTable createtable;
 
+  DBAPICall call;
+  DBAPISimpleCall scall;
+
   char name[DBNAME_LEN+1];
 
   void *handle;
@@ -88,6 +95,7 @@ typedef struct DBAPIConn {
   DBAPIQueryV __query;
   DBAPICreateTableV __createtable;
   DBAPILoadTable __loadtable;
+  DBAPICallV __call;
 } DBAPIConn;
 
 typedef char *(*DBAPIResultGet)(const struct DBAPIResult *, unsigned int);
index c0eb002cedbb6ce040cb3acc33af34081559311d..ea9fd102df9a9cf1aa18951bf22f6de1c55d3089 100644 (file)
@@ -188,7 +188,8 @@ void dbhandler(int fd, short revents) {
         if(queryhead->identifier != QH_ALREADYFIRED) {
           switch(PQresultStatus(res)) {
             case PGRES_TUPLES_OK:
-              Error("pqsql", ERR_WARNING, "Unhandled tuples output (query: %s)", queryhead->query);
+              if(!(queryhead->flags & DB_CALL))
+                Error("pqsql", ERR_WARNING, "Unhandled tuples output (query: %s)", queryhead->query);
               break;
 
             case PGRES_NONFATAL_ERROR: