X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fextra%2Fm_mysql.cpp;h=2449b523866292ff0fa606216b37dca05db07b91;hb=59bd18f2a0b43b71ee32124add9d40d1d3a54919;hp=8b6efb2c6336d542c24fa0bdef204153f19cd61e;hpb=104cf9cbee8ae0c6994060b565fe410e8f140ed7;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index 8b6efb2c6..2449b5238 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -2,20 +2,15 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd is copyright (C) 2002-2004 ChatSpike-Dev. - * E-mail: - * - * - * - * 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 #include #include @@ -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 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 ¶meter) { /* 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); } };