]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Add a way of doing 'clean' unloads in pqsql.
authorChris Porter <redacted>
Tue, 11 Mar 2008 01:58:27 +0000 (01:58 +0000)
committerChris Porter <redacted>
Tue, 11 Mar 2008 01:58:27 +0000 (01:58 +0000)
Doesn't cover table stuff at the moment.

pqsql/pqsql.c
pqsql/pqsql.h

index 687cdee9159c12589563668e0755cfb1fd4e1c46..b0bbbb0a64658720d9d0da1e6887fee1273a8940 100644 (file)
@@ -39,6 +39,7 @@ typedef struct pqasyncquery_s {
   void *tag;
   PQQueryHandler handler;
   int flags;
+  PQModuleIdentifier identifier;
   struct pqasyncquery_s *next;
 } pqasyncquery_s;
 
@@ -51,6 +52,7 @@ typedef struct pqtableloaderinfo_s
 pqasyncquery_s *queryhead = NULL, *querytail = NULL;
 
 int dbconnected = 0;
+static PQModuleIdentifier moduleid = 0;
 PGconn *dbconn;
 
 void dbhandler(int fd, short revents);
@@ -67,6 +69,46 @@ void _fini(void) {
   disconnectdb();
 }
 
+PQModuleIdentifier pqgetid(void) {
+  moduleid++;
+  if(moduleid < 10)
+    moduleid = 10;
+
+  return moduleid;
+}
+
+void pqfreeid(PQModuleIdentifier identifier) {
+  pqasyncquery_s *q, *p;
+  
+  if(identifier == 0 || !queryhead)
+    return;
+
+  if(queryhead->identifier == identifier) {
+    (queryhead->handler)(NULL, queryhead->tag);
+    queryhead->identifier = QH_ALREADYFIRED;
+  }
+
+  for(p=queryhead,q=queryhead->next;q;) {
+    if(q->identifier == identifier) {
+      (q->handler)(NULL, q->tag);
+      p->next = q->next;
+
+      if (q->query_ss) {
+        freesstring(q->query_ss);
+      } else {
+        free(q->query);
+      }
+      free(q);
+      q = p->next;
+    } else {
+      p = q;
+      q = q->next;
+    }
+  }
+
+  querytail = p;
+}
+
 void connectdb(void) {
   sstring *dbhost, *dbusername, *dbpassword, *dbdatabase, *dbport;
   char connectstr[1024];
@@ -131,24 +173,26 @@ void dbhandler(int fd, short revents) {
     PQconsumeInput(dbconn);
     
     if(!PQisBusy(dbconn)) { /* query is complete */
-      if(queryhead->handler)
+      if(queryhead->handler && queryhead->identifier != QH_ALREADYFIRED)
         (queryhead->handler)(dbconn, queryhead->tag);
 
       while((res = PQgetResult(dbconn))) {
-        switch(PQresultStatus(res)) {
-          case PGRES_TUPLES_OK:
-            Error("pqsql", ERR_WARNING, "Unhandled tuples output (query: %s)", queryhead->query);
-            break;
-
-          case PGRES_NONFATAL_ERROR:
-          case PGRES_FATAL_ERROR:
-            /* if a create query returns an error assume it went ok, paul will winge about this */
-            if(!(queryhead->flags & QH_CREATE))
-              Error("pqsql", ERR_WARNING, "Unhandled error response (query: %s)", queryhead->query);
-            break;
+        if(queryhead->identifier != QH_ALREADYFIRED) {
+          switch(PQresultStatus(res)) {
+            case PGRES_TUPLES_OK:
+              Error("pqsql", ERR_WARNING, "Unhandled tuples output (query: %s)", queryhead->query);
+              break;
+
+            case PGRES_NONFATAL_ERROR:
+            case PGRES_FATAL_ERROR:
+              /* if a create query returns an error assume it went ok, paul will winge about this */
+              if(!(queryhead->flags & QH_CREATE))
+                Error("pqsql", ERR_WARNING, "Unhandled error response (query: %s)", queryhead->query);
+              break;
          
-          default:
-            break;
+            default:
+              break;
+          }
         }
        
         PQclear(res);
@@ -180,7 +224,7 @@ void dbhandler(int fd, short revents) {
 }
 
 /* sorry Q9 */
-void pqasyncqueryf(PQQueryHandler handler, void *tag, int flags, char *format, ...) {
+void pqasyncqueryf(int identifier, PQQueryHandler handler, void *tag, int flags, char *format, ...) {
   char querybuf[8192];
   va_list va;
   int len;
@@ -212,6 +256,7 @@ void pqasyncqueryf(PQQueryHandler handler, void *tag, int flags, char *format, .
   qp->handler = handler;
   qp->next = NULL; /* shove them at the end */
   qp->flags = flags;
+  qp->identifier = identifier;
 
   if(querytail) {
     querytail->next = qp;
index 8eb2608f6eb042c925178e92e3e1ac1510a880d6..b43eb676a8e4344fd094477b7813b4417ae97efc 100644 (file)
@@ -6,16 +6,24 @@
 #define QH_CREATE 0x01
 #define PQ_ERRORMSG_LENGTH 1024
 
+#define QH_NULLIDENTIFIER 0
+#define QH_ALREADYFIRED 1
+
+typedef int PQModuleIdentifier;
 typedef void (*PQQueryHandler)(PGconn *, void *);
 
-void pqasyncqueryf(PQQueryHandler handler, void *tag, int flags, char *format, ...);
 void pqloadtable(char *tablename, PQQueryHandler init, PQQueryHandler data, PQQueryHandler fini);
 
-#define pqasyncquery(handler, tag, format, ...) pqasyncqueryf(handler, tag, 0, format , ##__VA_ARGS__)
-#define pqcreatequery(format, ...) pqasyncqueryf(NULL, NULL, QH_CREATE, format , ##__VA_ARGS__)
-#define pqquery(format, ...) pqasyncqueryf(NULL, NULL, 0, format , ##__VA_ARGS__)
+void pqasyncqueryf(PQModuleIdentifier identifier, PQQueryHandler handler, void *tag, int flags, char *format, ...);
+#define pqasyncqueryi(identifier, handler, tag, format, ...) pqasyncqueryf(identifier, handler, tag, 0, format , ##__VA_ARGS__)
+#define pqasyncquery(handler, tag, format, ...) pqasyncqueryf(QH_NULLIDENTIFIER, handler, tag, 0, format , ##__VA_ARGS__)
+#define pqcreatequery(format, ...) pqasyncqueryf(QH_NULLIDENTIFIER, NULL, NULL, QH_CREATE, format , ##__VA_ARGS__)
+#define pqquery(format, ...) pqasyncqueryf(QH_NULLIDENTIFIER, NULL, NULL, 0, format , ##__VA_ARGS__)
 
 int pqconnected(void);
-char* pqlasterror(PGconn * pgconn);
+char* pqlasterror(PGconn *pgconn);
+
+PQModuleIdentifier pqgetid(void);
+void pqfreeid(PQModuleIdentifier identifier);
 
 #endif