]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Generic table loader for pqsql module
authorCruicky <redacted>
Sat, 2 Jun 2007 11:09:54 +0000 (12:09 +0100)
committerCruicky <redacted>
Sat, 2 Jun 2007 11:09:54 +0000 (12:09 +0100)
pqsql/pqsql.c
pqsql/pqsql.h

index 5928937002d0ac74faeb6541862208e6eca24497..838812754becec2cc36d572d9be5c38533b4fe2c 100644 (file)
@@ -9,6 +9,7 @@
 #include "../irc/irc_config.h"
 #include "../core/events.h"
 #include "../core/hooks.h"
+#include "../lib/irc_string.h"
 #include "../lib/version.h"
 #include "pqsql.h"
 
@@ -40,12 +41,19 @@ typedef struct pqasyncquery_s {
   struct pqasyncquery_s *next;
 } pqasyncquery_s;
 
+typedef struct pqtableloaderinfo_s
+{
+    sstring *tablename;
+    PQQueryHandler init, data, fini;
+} pqtableloaderinfo_s;
+
 pqasyncquery_s *queryhead = NULL, *querytail = NULL;
 
 int dbconnected = 0;
 PGconn *dbconn;
 
 void dbhandler(int fd, short revents);
+void pqstartloadtable(PGconn *dbconn, void *arg);
 void dbstatus(int hooknum, void *arg);
 void disconnectdb(void);
 void connectdb(void);
@@ -210,6 +218,57 @@ void pqasyncqueryf(PQQueryHandler handler, void *tag, int flags, char *format, .
   }
 }
 
+void pqloadtable(char *tablename, PQQueryHandler init, PQQueryHandler data, PQQueryHandler fini)
+{
+  pqtableloaderinfo_s *tli;
+
+  tli=(pqtableloaderinfo_s *)malloc(sizeof(pqtableloaderinfo_s));
+  tli->tablename=getsstring(tablename, 100);
+  tli->init=init;
+  tli->data=data;
+  tli->fini=fini;
+  pqasyncquery(pqstartloadtable, tli, "SELECT COUNT(*) FROM %s", tli->tablename->content);
+}
+
+void pqstartloadtable(PGconn *dbconn, void *arg)
+{
+  PGresult *res;
+  unsigned long i, count, tablecrc;
+  pqtableloaderinfo_s *tli = arg;
+
+  res = PQgetResult(dbconn);
+
+  if (PQresultStatus(res) != PGRES_TUPLES_OK && PQresultStatus(res) != PGRES_COMMAND_OK) {
+    Error("pqsql", ERR_ERROR, "Error getting row count for %s.", tli->tablename->content);
+    return;
+  }
+
+  if (PQnfields(res) != 1) {
+    Error("pqsql", ERR_ERROR, "Count query format error for %s.", tli->tablename->content);
+    return;
+  }
+
+  tablecrc=crc32(tli->tablename->content);
+  count=strtoul(PQgetvalue(res, 0, 0), NULL, 10);
+  PQclear(res);
+
+  Error("pqsql", ERR_INFO, "Found %lu entries in table %s, scheduling load.", count, tli->tablename->content);
+
+  pqasyncquery(tli->init, NULL, "BEGIN");
+  pqasyncquery(NULL, NULL, "DECLARE table%lx%lx CURSOR FOR SELECT * FROM %s", tablecrc, count, tli->tablename->content);
+
+  for (i=0;(count - i) > 1000; i+=1000)
+    pqasyncquery(tli->data, NULL, "FETCH 1000 FROM table%lx%lx", tablecrc, count);
+
+  pqasyncquery(tli->data, NULL, "FETCH ALL FROM table%lx%lx", tablecrc, count);
+
+  pqasyncquery(NULL, NULL, "CLOSE table%lx%lx", tablecrc, count);
+  pqasyncquery(tli->fini, NULL, "COMMIT");
+
+  freesstring(tli->tablename);
+  free(tli);
+}
+
 void disconnectdb(void) {
   pqasyncquery_s *qqp = queryhead, *nqqp;
 
index cf4e06cef72adeee9bd3dcedbc2f0175ca2c4f32..ec988bcc2cff88f43c0614213f753b4ad43255f3 100644 (file)
@@ -8,6 +8,7 @@
 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__)