From 2c6c072c1f5f19d1471feb43fa94bba0030e5fb6 Mon Sep 17 00:00:00 2001 From: om Date: Fri, 21 Jul 2006 08:37:42 +0000 Subject: API header and client module updates for new multi-parameter query request. Needs proper implementation in m_pgsql and documentation git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4471 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/extra/m_pgsql.cpp | 42 ++++++++++++++++++++++------ src/modules/extra/m_sqlv2.h | 56 +++++++++++++++++++++++++++++++++----- src/modules/extra/m_testclient.cpp | 2 +- 3 files changed, 84 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index c67ca0854..39849271d 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -101,7 +101,7 @@ public: void push(const SQLrequest &q) { - log(DEBUG, "QueryQueue::push(): Adding %s query to queue: %s", ((q.pri) ? "priority" : "non-priority"), q.query.c_str()); + log(DEBUG, "QueryQueue::push(): Adding %s query to queue: %s", ((q.pri) ? "priority" : "non-priority"), q.query.q.c_str()); if(q.pri) priority.push_back(q); @@ -506,7 +506,7 @@ public: SQLrequest* req = (SQLrequest*)request; ConnMap::iterator iter; - log(DEBUG, "Got query: '%s' on id '%s'", req->query.c_str(), req->dbid.c_str()); + log(DEBUG, "Got query: '%s' with %d replacement parameters on id '%s'", req->query.q.c_str(), req->query.p.size(), req->dbid.c_str()); if((iter = connections.find(req->dbid)) != connections.end()) { @@ -941,16 +941,42 @@ SQLerror SQLConn::DoQuery(const SQLrequest &req) { if(!qinprog) { - if(PQsendQuery(sql, req.query.c_str())) + /* Parse the command string and dispatch it */ + + /* A list of offsets into the original string of the '?' characters we're substituting */ + std::vector insertlocs; + + for(unsigned int i = 0; i < req.query.q.length(); i++) + { + if(req.query.q[i] == '?') + { + insertlocs.push_back(i); + } + } + + char* query = new char[(req.query.q.length()*2)+1]; + int error = 0; + + // PQescapeStringConn(sql, query, req.query.q.c_str(), req.query.q.length(), error); + + if(error == 0) { - log(DEBUG, "Dispatched query: %s", req.query.c_str()); - qinprog = true; - return SQLerror(); + if(PQsendQuery(sql, query)) + { + log(DEBUG, "Dispatched query: %s", query); + qinprog = true; + return SQLerror(); + } + else + { + log(DEBUG, "Failed to dispatch query: %s", PQerrorMessage(sql)); + return SQLerror(QSEND_FAIL, PQerrorMessage(sql)); + } } else { - log(DEBUG, "Failed to dispatch query: %s", PQerrorMessage(sql)); - return SQLerror(QSEND_FAIL, PQerrorMessage(sql)); + log(DEBUG, "Failed to escape query string"); + return SQLerror(QSEND_FAIL, "Couldn't escape query string"); } } } diff --git a/src/modules/extra/m_sqlv2.h b/src/modules/extra/m_sqlv2.h index 714af2db6..aa90c7b95 100644 --- a/src/modules/extra/m_sqlv2.h +++ b/src/modules/extra/m_sqlv2.h @@ -1,16 +1,22 @@ #ifndef INSPIRCD_SQLAPI_2 #define INSPIRCD_SQLAPI_2 -#define SQLREQID "SQLv2 Request" -#define SQLRESID "SQLv2 Result" -#define SQLSUCCESS "You shouldn't be reading this (success)" - #include #include #include #include "modules.h" +/* This is the voodoo magic which lets us pass multiple parameters + * to the SQLrequest constructor..voodoo... + */ +#define SQLreq(a, b, c, d, e...) SQLrequest(a, b, c, (SQLquery(d), ##e)) + +#define SQLREQID "SQLv2 Request" +#define SQLRESID "SQLv2 Result" +#define SQLSUCCESS "You shouldn't be reading this (success)" + enum SQLerrorNum { NO_ERROR, BAD_DBID, BAD_CONN, QSEND_FAIL }; +typedef std::vector ParamL; class SQLexception : public ModuleException { @@ -69,18 +75,54 @@ public: } }; +class SQLquery +{ +public: + std::string q; + ParamL p; + + SQLquery(const std::string &query) + : q(query) + { + log(DEBUG, "SQLquery constructor: %s", q.c_str()); + } + + SQLquery(const std::string &query, const ParamL ¶ms) + : q(query), p(params) + { + log(DEBUG, "SQLquery constructor with %d params: %s", p.size(), q.c_str()); + } + + SQLquery& operator,(const std::string &foo) + { + p.push_back(foo); + return *this; + } + + SQLquery& operator%(const std::string &foo) + { + p.push_back(foo); + return *this; + } +}; + class SQLrequest : public Request { public: - std::string query; + SQLquery query; std::string dbid; bool pri; unsigned long id; SQLerror error; - SQLrequest(Module* s, Module* d, const std::string &q, const std::string &id, bool p = false) - : Request(SQLREQID, s, d), query(q), dbid(id), pri(p), id(0) + SQLrequest(Module* s, Module* d, const std::string &databaseid, const SQLquery &q) + : Request(SQLREQID, s, d), query(q), dbid(databaseid), pri(false), id(0) + { + } + + void Priority(bool p = true) { + pri = p; } void SetSource(Module* mod) diff --git a/src/modules/extra/m_testclient.cpp b/src/modules/extra/m_testclient.cpp index 3cd4742c9..069c21c0b 100644 --- a/src/modules/extra/m_testclient.cpp +++ b/src/modules/extra/m_testclient.cpp @@ -35,7 +35,7 @@ public: if(target) { - SQLrequest foo(this, target, "SELECT foo, bar FROM rawr", "foo"); + SQLrequest foo = SQLreq(this, target, "foo", "SELECT foo, bar FROM ?", "rawr"); if(foo.Send()) { -- cgit v1.2.3