]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_pgsql.cpp
Merge pull request #1185 from SaberUK/master+lockserv
[user/henk/code/inspircd.git] / src / modules / extra / m_pgsql.cpp
index 84f159be1763e14e5d7b47fd01b2c8bf545073cb..5f6f6e30faa0615c5d9c80eb37c306a59109571b 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/// $CompilerFlags: -Iexecute("pg_config --includedir" "POSTGRESQL_INCLUDE_DIR")
+/// $LinkerFlags: -Lexecute("pg_config --libdir" "POSTGRESQL_LIBRARY_DIR") -lpq
+
+/// $PackageInfo: require_system("centos") postgresql-devel
+/// $PackageInfo: require_system("darwin") postgresql
+/// $PackageInfo: require_system("ubuntu") libpq-dev
+
 
 #include "inspircd.h"
 #include <cstdlib>
-#include <sstream>
 #include <libpq-fe.h>
-#include "sql.h"
-
-/* $ModDesc: PostgreSQL Service Provider module for all other m_sql* modules, uses v2 of the SQL API */
-/* $CompileFlags: -Iexec("pg_config --includedir") eval("my $s = `pg_config --version`;$s =~ /^.*?(\d+)\.(\d+)\.(\d+).*?$/;my $v = hex(sprintf("0x%02x%02x%02x", $1, $2, $3));print "-DPGSQL_HAS_ESCAPECONN" if(($v >= 0x080104) || ($v >= 0x07030F && $v < 0x070400) || ($v >= 0x07040D && $v < 0x080000) || ($v >= 0x080008 && $v < 0x080100));") */
-/* $LinkerFlags: -Lexec("pg_config --libdir") -lpq */
+#include "modules/sql.h"
 
 /* SQLConn rewritten by peavey to
  * use EventHandler instead of
@@ -43,7 +45,7 @@
 class SQLConn;
 class ModulePgSQL;
 
-typedef std::map<std::string, SQLConn*> ConnMap;
+typedef insp::flat_map<std::string, SQLConn*> ConnMap;
 
 /* CREAD,      Connecting and wants read event
  * CWRITE,     Connecting and wants write event
@@ -59,10 +61,10 @@ class ReconnectTimer : public Timer
  private:
        ModulePgSQL* mod;
  public:
-       ReconnectTimer(ModulePgSQL* m) : Timer(5, ServerInstance->Time(), false), mod(m)
+       ReconnectTimer(ModulePgSQL* m) : Timer(5, false), mod(m)
        {
        }
-       virtual void Tick(time_t TIME);
+       bool Tick(time_t TIME);
 };
 
 struct QueueItem
@@ -97,12 +99,12 @@ class PgSQLresult : public SQLResult
                PQclear(res);
        }
 
-       virtual int Rows()
+       int Rows()
        {
                return rows;
        }
 
-       virtual void GetCols(std::vector<std::string>& result)
+       void GetCols(std::vector<std::string>& result)
        {
                result.resize(PQnfields(res));
                for(unsigned int i=0; i < result.size(); i++)
@@ -111,7 +113,7 @@ class PgSQLresult : public SQLResult
                }
        }
 
-       virtual SQLEntry GetValue(int row, int column)
+       SQLEntry GetValue(int row, int column)
        {
                char* v = PQgetvalue(res, row, column);
                if (!v || PQgetisnull(res, row, column))
@@ -120,7 +122,7 @@ class PgSQLresult : public SQLResult
                return SQLEntry(std::string(v, PQgetlength(res, row, column)));
        }
 
-       virtual bool GetRow(SQLEntries& result)
+       bool GetRow(SQLEntries& result)
        {
                if (currentrow >= PQntuples(res))
                        return false;
@@ -152,7 +154,7 @@ class SQLConn : public SQLProvider, public EventHandler
        {
                if (!DoConnect())
                {
-                       ServerInstance->Logs->Log("m_pgsql",DEFAULT, "WARNING: Could not connect to database " + tag->getString("id"));
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "WARNING: Could not connect to database " + tag->getString("id"));
                        DelayReconnect();
                }
        }
@@ -180,18 +182,19 @@ class SQLConn : public SQLProvider, public EventHandler
                }
        }
 
-       virtual void HandleEvent(EventType et, int errornum)
+       void OnEventHandlerRead() CXX11_OVERRIDE
        {
-               switch (et)
-               {
-                       case EVENT_READ:
-                       case EVENT_WRITE:
-                               DoEvent();
-                       break;
+               DoEvent();
+       }
 
-                       case EVENT_ERROR:
-                               DelayReconnect();
-               }
+       void OnEventHandlerWrite() CXX11_OVERRIDE
+       {
+               DoEvent();
+       }
+
+       void OnEventHandlerError(int errornum) CXX11_OVERRIDE
+       {
+               DelayReconnect();
        }
 
        std::string GetDSN()
@@ -242,9 +245,9 @@ class SQLConn : public SQLProvider, public EventHandler
                if(this->fd <= -1)
                        return false;
 
-               if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_WRITE | FD_WANT_NO_READ))
+               if (!SocketEngine::AddFd(this, FD_WANT_NO_WRITE | FD_WANT_NO_READ))
                {
-                       ServerInstance->Logs->Log("m_pgsql",DEBUG, "BUG: Couldn't add pgsql socket to socket engine");
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "BUG: Couldn't add pgsql socket to socket engine");
                        return false;
                }
 
@@ -257,17 +260,17 @@ class SQLConn : public SQLProvider, public EventHandler
                switch(PQconnectPoll(sql))
                {
                        case PGRES_POLLING_WRITING:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
                                status = CWRITE;
                                return true;
                        case PGRES_POLLING_READING:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
                                status = CREAD;
                                return true;
                        case PGRES_POLLING_FAILED:
                                return false;
                        case PGRES_POLLING_OK:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
                                status = WWRITE;
                                DoConnectedPoll();
                        default:
@@ -350,17 +353,17 @@ restart:
                switch(PQresetPoll(sql))
                {
                        case PGRES_POLLING_WRITING:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
                                status = CWRITE;
                                return DoPoll();
                        case PGRES_POLLING_READING:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
                                status = CREAD;
                                return true;
                        case PGRES_POLLING_FAILED:
                                return false;
                        case PGRES_POLLING_OK:
-                               ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
+                               SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
                                status = WWRITE;
                                DoConnectedPoll();
                        default:
@@ -412,16 +415,12 @@ restart:
                                if (param < p.size())
                                {
                                        std::string parm = p[param++];
-                                       char buffer[MAXBUF];
-#ifdef PGSQL_HAS_ESCAPECONN
+                                       std::vector<char> buffer(parm.length() * 2 + 1);
                                        int error;
-                                       PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error);
+                                       size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error);
                                        if (error)
-                                               ServerInstance->Logs->Log("m_pgsql", DEBUG, "BUG: Apparently PQescapeStringConn() failed");
-#else
-                                       PQescapeString         (buffer, parm.c_str(), parm.length());
-#endif
-                                       res.append(buffer);
+                                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed");
+                                       res.append(&buffer[0], escapedsize);
                                }
                        }
                }
@@ -447,16 +446,12 @@ restart:
                                if (it != p.end())
                                {
                                        std::string parm = it->second;
-                                       char buffer[MAXBUF];
-#ifdef PGSQL_HAS_ESCAPECONN
+                                       std::vector<char> buffer(parm.length() * 2 + 1);
                                        int error;
-                                       PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error);
+                                       size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error);
                                        if (error)
-                                               ServerInstance->Logs->Log("m_pgsql", DEBUG, "BUG: Apparently PQescapeStringConn() failed");
-#else
-                                       PQescapeString         (buffer, parm.c_str(), parm.length());
-#endif
-                                       res.append(buffer);
+                                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed");
+                                       res.append(&buffer[0], escapedsize);
                                }
                        }
                }
@@ -488,7 +483,7 @@ restart:
 
        void Close()
        {
-               ServerInstance->SE->DelFd(this);
+               SocketEngine::DelFd(this);
 
                if(sql)
                {
@@ -504,22 +499,18 @@ class ModulePgSQL : public Module
        ConnMap connections;
        ReconnectTimer* retimer;
 
-       void init()
+       ModulePgSQL()
+               : retimer(NULL)
        {
-               ReadConf();
-
-               Implementation eventlist[] = { I_OnUnloadModule, I_OnRehash };
-               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
        }
 
-       virtual ~ModulePgSQL()
+       ~ModulePgSQL()
        {
-               if (retimer)
-                       ServerInstance->Timers->DelTimer(retimer);
+               delete retimer;
                ClearAllConnections();
        }
 
-       virtual void OnRehash(User* user)
+       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
        {
                ReadConf();
        }
@@ -560,7 +551,7 @@ class ModulePgSQL : public Module
                connections.clear();
        }
 
-       void OnUnloadModule(Module* mod)
+       void OnUnloadModule(Module* mod) CXX11_OVERRIDE
        {
                SQLerror err(SQL_BAD_DBID);
                for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++)
@@ -588,16 +579,18 @@ class ModulePgSQL : public Module
                }
        }
 
-       Version GetVersion()
+       Version GetVersion() CXX11_OVERRIDE
        {
                return Version("PostgreSQL Service Provider module for all other m_sql* modules, uses v2 of the SQL API", VF_VENDOR);
        }
 };
 
-void ReconnectTimer::Tick(time_t time)
+bool ReconnectTimer::Tick(time_t time)
 {
        mod->retimer = NULL;
        mod->ReadConf();
+       delete this;
+       return false;
 }
 
 void SQLConn::DelayReconnect()
@@ -611,7 +604,7 @@ void SQLConn::DelayReconnect()
                if (!mod->retimer)
                {
                        mod->retimer = new ReconnectTimer(mod);
-                       ServerInstance->Timers->AddTimer(mod->retimer);
+                       ServerInstance->Timers.AddTimer(mod->retimer);
                }
        }
 }