]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_mysql.cpp
Change the SQLutils and SQL providers to also use interfaces for proper unload order...
[user/henk/code/inspircd.git] / src / modules / extra / m_mysql.cpp
index 8b6efb2c6336d542c24fa0bdef204153f19cd61e..2449b523866292ff0fa606216b37dca05db07b91 100644 (file)
@@ -2,20 +2,15 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd is copyright (C) 2002-2004 ChatSpike-Dev.
- *                    E-mail:
- *             <brain@chatspike.net>
- *               <Craig@chatspike.net>
- *     
- * Written by Craig Edwards, Craig McLure, and others.
+ *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
  * This program is free but copyrighted software; see
- *         the file COPYING for details.
+ *            the file COPYING for details.
  *
  * ---------------------------------------------------
  */
 
-using namespace std;
-
 #include <stdio.h>
 #include <string>
 #include <mysql.h>
@@ -23,7 +18,6 @@ using namespace std;
 #include "users.h"
 #include "channels.h"
 #include "modules.h"
-
 #include "inspircd.h"
 #include "m_sqlv2.h"
 
@@ -32,6 +26,7 @@ using namespace std;
 /* $ModDesc: SQL Service Provider module for all other m_sql* modules */
 /* $CompileFlags: `mysql_config --include` */
 /* $LinkerFlags: `mysql_config --libs_r` `perl extra/mysql_rpath.pl` */
+/* $ModDep: m_sqlv2.h */
 
 /* THE NONBLOCKING MYSQL API!
  * 
@@ -85,6 +80,8 @@ int QueueFD = -1;
 
 typedef std::deque<SQLresult*> ResultQueue;
 
+/** Represents a mysql query queue
+ */
 class QueryQueue : public classbase
 {
 private:
@@ -198,6 +195,10 @@ pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 pthread_mutex_t results_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+pthread_mutex_t logging_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/** Represents a mysql result set
+ */
 class MySQLresult : public SQLresult
 {
        int currentrow;
@@ -383,6 +384,8 @@ class SQLConnection;
 
 void NotifyMainThread(SQLConnection* connection_with_new_result);
 
+/** Represents a connection to a mysql database
+ */
 class SQLConnection : public classbase
 {
  protected:
@@ -403,16 +406,9 @@ class SQLConnection : public classbase
        QueryQueue queue;
        ResultQueue rq;
 
-       // This constructor creates an SQLConnection object with the given credentials, and creates the underlying
-       // MYSQL struct, but does not connect yet.
-       SQLConnection(std::string thishost, std::string thisuser, std::string thispass, std::string thisdb, const std::string &myid)
+       // This constructor creates an SQLConnection object with the given credentials, but does not connect yet.
+       SQLConnection(const std::string &thishost, const std::string &thisuser, const std::string &thispass, const std::string &thisdb, const std::string &myid) : host(thishost), user(thisuser), pass(thispass), db(thisdb), Enabled(true), id(myid)
        {
-               this->Enabled = true;
-               this->host = thishost;
-               this->user = thisuser;
-               this->pass = thispass;
-               this->db = thisdb;
-               this->id = myid;
        }
 
        // This method connects to the database using the credentials supplied to the constructor, and returns
@@ -532,6 +528,8 @@ class SQLConnection : public classbase
                 * Pass them this connection id as what to examine
                 */
 
+               delete[] query;
+
                NotifyMainThread(this);
        }
 
@@ -585,24 +583,30 @@ void ConnectDatabases(InspIRCd* ServerInstance)
        for (ConnMap::iterator i = Connections.begin(); i != Connections.end(); i++)
        {
                i->second->SetEnable(true);
-               if (i->second->Connect())
-               {
-                       ServerInstance->Log(DEFAULT,"SQL: Successfully connected database "+i->second->GetHost());
-               }
-               else
+               if (!i->second->Connect())
                {
+                       /* XXX: MUTEX */
+                       pthread_mutex_lock(&logging_mutex);
                        ServerInstance->Log(DEFAULT,"SQL: Failed to connect database "+i->second->GetHost()+": Error: "+i->second->GetError());
                        i->second->SetEnable(false);
+                       pthread_mutex_unlock(&logging_mutex);
                }
        }
 }
 
+void ClearDatabases()
+{
+       ConnMap::iterator i;
+       while ((i = Connections.begin()) != Connections.end())
+       {
+               Connections.erase(i);
+               delete i->second;
+       }
+}
 
 void LoadDatabases(ConfigReader* ThisConf, InspIRCd* ServerInstance)
 {
-       ServerInstance->Log(DEFAULT,"SQL: Loading database settings");
-       Connections.clear();
-       ServerInstance->Log(DEBUG,"Cleared connections");
+       ClearDatabases();
        for (int j =0; j < ThisConf->Enumerate("database"); j++)
        {
                std::string db = ThisConf->ReadValue("database","name",j);
@@ -610,13 +614,10 @@ void LoadDatabases(ConfigReader* ThisConf, InspIRCd* ServerInstance)
                std::string pass = ThisConf->ReadValue("database","password",j);
                std::string host = ThisConf->ReadValue("database","hostname",j);
                std::string id = ThisConf->ReadValue("database","id",j);
-               ServerInstance->Log(DEBUG,"Read database settings");
                if ((db != "") && (host != "") && (user != "") && (id != "") && (pass != ""))
                {
                        SQLConnection* ThisSQL = new SQLConnection(host,user,pass,db,id);
-                       ServerInstance->Log(DEFAULT,"Loaded database: "+ThisSQL->GetHost());
                        Connections[id] = ThisSQL;
-                       ServerInstance->Log(DEBUG,"Pushed back connection");
                }
        }
        ConnectDatabases(ServerInstance);
@@ -638,6 +639,8 @@ void NotifyMainThread(SQLConnection* connection_with_new_result)
 
 void* DispatcherThread(void* arg);
 
+/** Used by m_mysql to notify one thread when the other has a result
+ */
 class Notifier : public InspSocket
 {
        insp_sockaddr sock_us;
@@ -711,6 +714,8 @@ class Notifier : public InspSocket
        }
 };
 
+/** MySQL module
+ */
 class ModuleSQL : public Module
 {
  public:
@@ -720,6 +725,47 @@ class ModuleSQL : public Module
        pthread_t Dispatcher;
        int currid;
 
+       ModuleSQL(InspIRCd* Me)
+       : Module::Module(Me)
+       {
+               ServerInstance->UseInterface("SQLutils");
+
+               Conf = new ConfigReader(ServerInstance);
+               PublicServerInstance = ServerInstance;
+               currid = 0;
+               SQLModule = this;
+
+               MessagePipe = new Notifier(ServerInstance);
+               ServerInstance->Log(DEBUG,"Bound notifier to 127.0.0.1:%d",MessagePipe->GetPort());
+               
+               pthread_attr_t attribs;
+               pthread_attr_init(&attribs);
+               pthread_attr_setdetachstate(&attribs, PTHREAD_CREATE_DETACHED);
+               if (pthread_create(&this->Dispatcher, &attribs, DispatcherThread, (void *)this) != 0)
+               {
+                       throw ModuleException("m_mysql: Failed to create dispatcher thread: " + std::string(strerror(errno)));
+               }
+
+               if (!ServerInstance->PublishFeature("SQL", this))
+               {
+                       /* Tell worker thread to exit NOW */
+                       giveup = true;
+                       throw ModuleException("m_mysql: Unable to publish feature 'SQL'");
+               }
+
+               ServerInstance->PublishInterface("SQL", this);
+       }
+
+       virtual ~ModuleSQL()
+       {
+               giveup = true;
+               ClearDatabases();
+               DELETE(Conf);
+               ServerInstance->UnpublishInterface("SQL", this);
+               ServerInstance->DoneWithInterface("SQLutils");
+       }
+
+
        void Implements(char* List)
        {
                List[I_OnRehash] = List[I_OnRequest] = 1;
@@ -769,38 +815,6 @@ class ModuleSQL : public Module
                return NULL;
        }
 
-       ModuleSQL(InspIRCd* Me)
-               : Module::Module(Me)
-       {
-               
-               Conf = new ConfigReader(ServerInstance);
-               PublicServerInstance = ServerInstance;
-               currid = 0;
-               SQLModule = this;
-
-               MessagePipe = new Notifier(ServerInstance);
-               ServerInstance->Log(DEBUG,"Bound notifier to 127.0.0.1:%d",MessagePipe->GetPort());
-               
-               pthread_attr_t attribs;
-               pthread_attr_init(&attribs);
-               pthread_attr_setdetachstate(&attribs, PTHREAD_CREATE_DETACHED);
-               if (pthread_create(&this->Dispatcher, &attribs, DispatcherThread, (void *)this) != 0)
-               {
-                       throw ModuleException("m_mysql: Failed to create dispatcher thread: " + std::string(strerror(errno)));
-               }
-               if (!ServerInstance->PublishFeature("SQL", this))
-               {
-                       /* Tell worker thread to exit NOW */
-                       giveup = true;
-                       throw ModuleException("m_mysql: Unable to publish feature 'SQL'");
-               }
-       }
-       
-       virtual ~ModuleSQL()
-       {
-               DELETE(Conf);
-       }
-       
        virtual void OnRehash(const std::string &parameter)
        {
                /* TODO: set rehash bool here, which makes the dispatcher thread rehash at next opportunity */
@@ -808,7 +822,7 @@ class ModuleSQL : public Module
        
        virtual Version GetVersion()
        {
-               return Version(1,1,0,0,VF_VENDOR|VF_SERVICEPROVIDER);
+               return Version(1,1,0,0,VF_VENDOR|VF_SERVICEPROVIDER,API_VERSION);
        }
        
 };