X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/b729f732b5a089cf9073ecfadc49c967ded846af..440cd7e63ac2b059ea1a467a2e4e2244faf92cb3:/pqsql/pqsql.c diff --git a/pqsql/pqsql.c b/pqsql/pqsql.c index b0bbbb0a..ea9fd102 100644 --- a/pqsql/pqsql.c +++ b/pqsql/pqsql.c @@ -9,11 +9,15 @@ #include "../irc/irc_config.h" #include "../core/events.h" #include "../core/hooks.h" +#include "../core/nsmalloc.h" #include "../lib/irc_string.h" #include "../lib/version.h" #include "../lib/strlfunc.h" #include "pqsql.h" +#define BUILDING_DBAPI +#include "../dbapi/dbapi.h" + #include #include #include @@ -47,19 +51,21 @@ typedef struct pqtableloaderinfo_s { sstring *tablename; PQQueryHandler init, data, fini; + void *tag; } pqtableloaderinfo_s; pqasyncquery_s *queryhead = NULL, *querytail = NULL; -int dbconnected = 0; +static int dbconnected = 0; static PQModuleIdentifier moduleid = 0; -PGconn *dbconn; +static 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); +char* pqlasterror(PGconn * pgconn); void _init(void) { connectdb(); @@ -67,6 +73,8 @@ void _init(void) { void _fini(void) { disconnectdb(); + + nscheckfreeall(POOL_PQSQL); } PQModuleIdentifier pqgetid(void) { @@ -96,9 +104,9 @@ void pqfreeid(PQModuleIdentifier identifier) { if (q->query_ss) { freesstring(q->query_ss); } else { - free(q->query); + nsfree(POOL_PQSQL, q->query); } - free(q); + nsfree(POOL_PQSQL, q); q = p->next; } else { p = q; @@ -180,14 +188,15 @@ 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: 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); + if(!(queryhead->flags & DB_CREATE)) + Error("pqsql", ERR_WARNING, "Unhandled error response (query: %s): %s", queryhead->query, PQresultErrorMessage(res)); break; default: @@ -210,10 +219,10 @@ void dbhandler(int fd, short revents) { qqp->query_ss=NULL; qqp->query=NULL; } else if (qqp->query) { - free(qqp->query); + nsfree(POOL_PQSQL, qqp->query); qqp->query=NULL; } - free(qqp); + nsfree(POOL_PQSQL, qqp); if(queryhead) { /* Submit the next query */ PQsendQuery(dbconn, queryhead->query); @@ -226,9 +235,9 @@ void dbhandler(int fd, short revents) { /* sorry Q9 */ void pqasyncqueryf(int identifier, PQQueryHandler handler, void *tag, int flags, char *format, ...) { char querybuf[8192]; - va_list va; int len; pqasyncquery_s *qp; + va_list va; if(!pqconnected()) return; @@ -238,14 +247,14 @@ void pqasyncqueryf(int identifier, PQQueryHandler handler, void *tag, int flags, va_end(va); /* PPA: no check here... */ - qp = (pqasyncquery_s *)malloc(sizeof(pqasyncquery_s)); + qp = (pqasyncquery_s *)nsmalloc(POOL_PQSQL, sizeof(pqasyncquery_s)); if(!qp) Error("pqsql",ERR_STOP,"malloc() failed in pqsql.c"); /* Use sstring or allocate (see above rant) */ if (len > SSTRING_MAX) { - qp->query = (char *)malloc(len+1); + qp->query = (char *)nsmalloc(POOL_PQSQL, len+1); strcpy(qp->query,querybuf); qp->query_ss=NULL; } else { @@ -268,15 +277,16 @@ void pqasyncqueryf(int identifier, PQQueryHandler handler, void *tag, int flags, } } -void pqloadtable(char *tablename, PQQueryHandler init, PQQueryHandler data, PQQueryHandler fini) +void pqloadtable(char *tablename, PQQueryHandler init, PQQueryHandler data, PQQueryHandler fini, void *tag) { pqtableloaderinfo_s *tli; - tli=(pqtableloaderinfo_s *)malloc(sizeof(pqtableloaderinfo_s)); + tli=(pqtableloaderinfo_s *)nsmalloc(POOL_PQSQL, sizeof(pqtableloaderinfo_s)); tli->tablename=getsstring(tablename, 100); tli->init=init; tli->data=data; tli->fini=fini; + tli->tag=tag; pqasyncquery(pqstartloadtable, tli, "SELECT COUNT(*) FROM %s", tli->tablename->content); } @@ -304,19 +314,19 @@ void pqstartloadtable(PGconn *dbconn, void *arg) Error("pqsql", ERR_INFO, "Found %lu entries in table %s, scheduling load.", count, tli->tablename->content); - pqasyncquery(tli->init, NULL, "BEGIN"); + pqasyncquery(tli->init, tli->tag, "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, tli->tag, "FETCH 1000 FROM table%lx%lx", tablecrc, count); - pqasyncquery(tli->data, NULL, "FETCH ALL FROM table%lx%lx", tablecrc, count); + pqasyncquery(tli->data, tli->tag, "FETCH ALL FROM table%lx%lx", tablecrc, count); pqasyncquery(NULL, NULL, "CLOSE table%lx%lx", tablecrc, count); - pqasyncquery(tli->fini, NULL, "COMMIT"); + pqasyncquery(tli->fini, tli->tag, "COMMIT"); freesstring(tli->tablename); - free(tli); + nsfree(POOL_PQSQL, tli); } void disconnectdb(void) { @@ -336,10 +346,10 @@ void disconnectdb(void) { qqp->query_ss=NULL; qqp->query=NULL; } else if (qqp->query) { - free(qqp->query); + nsfree(POOL_PQSQL, qqp->query); qqp->query=NULL; } - free(qqp); + nsfree(POOL_PQSQL, qqp); qqp = nqqp; } @@ -384,3 +394,39 @@ char* pqlasterror(PGconn * pgconn) { } return errormsg; } + +PQResult *pqgetresult(PGconn *c) { + PQResult *r; + if(!c) + return NULL; + + r = (PQResult *)nsmalloc(POOL_PQSQL, sizeof(PQResult)); + r->row = -1; + r->result = PQgetResult(c); + r->rows = PQntuples(r->result); + + return r; +} + +int pqfetchrow(PQResult *res) { + if(res->row + 1 == res->rows) + return 0; + + res->row++; + + return 1; +} + +char *pqgetvalue(PQResult *res, int column) { + return PQgetvalue(res->result, res->row, column); +} + +void pqclear(PQResult *res) { + if(!res) + return; + + if(res->result) + PQclear(res->result); + + nsfree(POOL_PQSQL, res); +}