summaryrefslogtreecommitdiff
path: root/modules/extra/db_mysql_live.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/extra/db_mysql_live.cpp')
-rw-r--r--modules/extra/db_mysql_live.cpp355
1 files changed, 267 insertions, 88 deletions
diff --git a/modules/extra/db_mysql_live.cpp b/modules/extra/db_mysql_live.cpp
index 8f14f3998..c5e645be6 100644
--- a/modules/extra/db_mysql_live.cpp
+++ b/modules/extra/db_mysql_live.cpp
@@ -2,59 +2,51 @@
#include "async_commands.h"
#include "sql.h"
-class MySQLLiveModule : public Module
+class SQLCache : public Timer
{
- service_reference<SQLProvider> SQL;
- service_reference<AsynchCommandsService> ACS;
+ typedef std::map<Anope::string, time_t, std::less<ci::string> > cache_map;
+ cache_map cache;
+ public:
- SQLResult RunQuery(const Anope::string &query)
+ SQLCache() : Timer(300, Anope::CurTime, true) { }
+
+ bool Check(const Anope::string &item)
{
- if (!this->SQL)
- throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
+ cache_map::iterator it = this->cache.find(item);
+ if (it != this->cache.end() && Anope::CurTime - it->second < 5)
+ return true;
- return SQL->RunQuery(query);
+ this->cache[item] = Anope::CurTime;
+ return false;
}
- const Anope::string Escape(const Anope::string &query)
+ void Tick(time_t)
{
- return SQL ? SQL->Escape(query) : query;
- }
+ for (cache_map::iterator it = this->cache.begin(), next_it; it != this->cache.end(); it = next_it)
+ {
+ next_it = it;
+ ++next_it;
- CommandMutex *CurrentCommand()
- {
- if (this->ACS)
- return this->ACS->CurrentCommand();
- return NULL;
+ if (Anope::CurTime - it->second > 5)
+ this->cache.erase(it);
+ }
}
+};
+class BotInfoUpdater : public SQLInterface, public SQLCache
+{
public:
- MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) :
- Module(modname, creator), SQL("mysql/main"), ACS("asynch_commands")
+ BotInfoUpdater(Module *m) : SQLInterface(m) { }
+
+ void OnResult(const SQLResult &r)
{
- Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore };
- ModuleManager::Attach(i, this, 4);
+ BotInfoUpdater::Process(r);
}
- void OnFindBot(const Anope::string &nick)
+ static void Process(const SQLResult &res)
{
- static bool lookup = true;
- if (lookup == false)
- {
- lookup = true;
- return;
- }
-
try
{
- CommandMutex *current_command = this->CurrentCommand();
-
- if (current_command)
- current_command->Unlock();
- SQLResult res = this->RunQuery("SELECT * FROM `anope_bs_core` WHERE `nick` = '" + this->Escape(nick) + "'");
- if (current_command)
- current_command->Lock();
-
- lookup = false;
BotInfo *bi = findbot(res.Get(0, "nick"));
if (!bi)
bi = new BotInfo(res.Get(0, "nick"), res.Get(0, "user"), res.Get(0, "host"), res.Get(0, "rname"));
@@ -70,30 +62,28 @@ class MySQLLiveModule : public Module
bi->created = convertTo<time_t>(res.Get(0, "created"));
bi->chancount = convertTo<uint32>(res.Get(0, "chancount"));
}
- catch (const SQLException &) { }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << ex.GetReason();
+ }
catch (const ConvertException &) { }
}
+};
- void OnFindChan(const Anope::string &chname)
+class ChanInfoUpdater : public SQLInterface, public SQLCache
+{
+ public:
+ ChanInfoUpdater(Module *m) : SQLInterface(m) { }
+
+ void OnResult(const SQLResult &r)
{
- static bool lookup = true;
- if (lookup == false)
- {
- lookup = true;
- return;
- }
+ ChanInfoUpdater::Process(r);
+ }
+ static void Process(const SQLResult &res)
+ {
try
{
- CommandMutex *current_command = this->CurrentCommand();
-
- if (current_command)
- current_command->Unlock();
- SQLResult res = this->RunQuery("SELECT * FROM `anope_cs_info` WHERE `name` = '" + this->Escape(chname) + "'");
- if (current_command)
- current_command->Lock();
-
- lookup = false;
ChannelInfo *ci = cs_findchan(res.Get(0, "name"));
if (!ci)
ci = new ChannelInfo(res.Get(0, "name"));
@@ -159,33 +149,31 @@ class MySQLLiveModule : public Module
if (ci->c)
check_modes(ci->c);
}
- catch (const SQLException &) { }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << ex.GetReason();
+ }
catch (const ConvertException &) { }
}
+};
- void OnFindNick(const Anope::string &nick)
+class NickInfoUpdater : public SQLInterface, public SQLCache
+{
+ public:
+ NickInfoUpdater(Module *m) : SQLInterface(m) { }
+
+ void OnResult(const SQLResult &r)
{
- static bool lookup = true;
- if (lookup == false)
- {
- lookup = true;
- return;
- }
+ NickInfoUpdater::Process(r);
+ }
+ static void Process(const SQLResult &res)
+ {
try
{
- CommandMutex *current_command = this->CurrentCommand();
-
- if (current_command)
- current_command->Unlock();
- SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_alias` WHERE `nick` = '" + this->Escape(nick) + "'");
- if (current_command)
- current_command->Lock();
-
NickCore *nc = findcore(res.Get(0, "display"));
if (!nc)
return;
- lookup = false;
NickAlias *na = findnick(res.Get(0, "nick"));
if (!na)
na = new NickAlias(res.Get(0, "nick"), nc);
@@ -208,30 +196,28 @@ class MySQLLiveModule : public Module
na->nc->aliases.push_back(na);
}
}
- catch (const SQLException &) { }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << ex.GetReason();
+ }
catch (const ConvertException &) { }
}
+};
- void OnFindCore(const Anope::string &nick)
+class NickCoreUpdater : public SQLInterface, public SQLCache
+{
+ public:
+ NickCoreUpdater(Module *m) : SQLInterface(m) { }
+
+ void OnResult(const SQLResult &r)
{
- static bool lookup = true;
- if (lookup == false)
- {
- lookup = true;
- return;
- }
+ NickCoreUpdater::Process(r);
+ }
+ static void Process(const SQLResult &res)
+ {
try
{
- CommandMutex *current_command = this->CurrentCommand();
-
- if (current_command)
- current_command->Unlock();
- SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_core` WHERE `name` = '" + this->Escape(nick) + "'");
- if (current_command)
- current_command->Lock();
-
- lookup = false;
NickCore *nc = findcore(res.Get(0, "display"));
if (!nc)
nc = new NickCore(res.Get(0, "display"));
@@ -243,9 +229,202 @@ class MySQLLiveModule : public Module
nc->FromString(BuildStringVector(res.Get(0, "flags")));
nc->language = res.Get(0, "language");
}
- catch (const SQLException &) { }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << ex.GetReason();
+ }
catch (const ConvertException &) { }
}
};
+class MySQLLiveModule : public Module
+{
+ service_reference<SQLProvider> SQL;
+ service_reference<AsynchCommandsService> ACS;
+
+ BotInfoUpdater botinfoupdater;
+ ChanInfoUpdater chaninfoupdater;
+ NickInfoUpdater nickinfoupdater;
+ NickCoreUpdater nickcoreupdater;
+
+ SQLResult RunQuery(const Anope::string &query)
+ {
+ if (!this->SQL)
+ throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
+
+ SQLResult res = SQL->RunQuery(query);
+ if (!res.GetError().empty())
+ throw SQLException(res.GetError());
+ return res;
+ }
+
+ void RunQuery(SQLInterface *i, const Anope::string &query)
+ {
+ if (!this->SQL)
+ throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
+
+ return SQL->Run(i, query);
+ }
+
+ const Anope::string Escape(const Anope::string &query)
+ {
+ return SQL ? SQL->Escape(query) : query;
+ }
+
+ CommandMutex *CurrentCommand()
+ {
+ if (this->ACS)
+ return this->ACS->CurrentCommand();
+ return NULL;
+ }
+
+ public:
+ MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) :
+ Module(modname, creator), SQL("mysql/main"), ACS("asynch_commands"), botinfoupdater(this),
+ chaninfoupdater(this), nickinfoupdater(this), nickcoreupdater(this)
+ {
+ Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore, I_OnPreShutdown };
+ ModuleManager::Attach(i, this, 5);
+ }
+
+ void OnPreShutdown()
+ {
+ Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore };
+ for (size_t j = 0; j < 4; ++j)
+ ModuleManager::Detach(i[j], this);
+ }
+
+ void OnFindBot(const Anope::string &nick)
+ {
+ if (botinfoupdater.Check(nick))
+ return;
+
+ try
+ {
+ Anope::string query = "SELECT * FROM `anope_bs_core` WHERE `nick` = '" + this->Escape(nick) + "'";
+ CommandMutex *current_command = this->CurrentCommand();
+ if (current_command)
+ {
+ current_command->Unlock();
+ try
+ {
+ SQLResult res = this->RunQuery(query);
+ current_command->Lock();
+ BotInfoUpdater::Process(res);
+ }
+ catch (const SQLException &ex)
+ {
+ current_command->Lock();
+ throw;
+ }
+ }
+ else
+ this->RunQuery(&botinfoupdater, query);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnBotChan: " << ex.GetReason();
+ }
+ }
+
+ void OnFindChan(const Anope::string &chname)
+ {
+ if (chaninfoupdater.Check(chname))
+ return;
+
+ try
+ {
+ Anope::string query = "SELECT * FROM `anope_cs_info` WHERE `name` = '" + this->Escape(chname) + "'";
+ CommandMutex *current_command = this->CurrentCommand();
+ if (current_command)
+ {
+ current_command->Unlock();
+ try
+ {
+ SQLResult res = this->RunQuery(query);
+ current_command->Lock();
+ ChanInfoUpdater::Process(res);
+ }
+ catch (const SQLException &)
+ {
+ current_command->Lock();
+ throw;
+ }
+ }
+ else
+ this->RunQuery(&chaninfoupdater, query);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindChan: " << ex.GetReason();
+ }
+ }
+
+ void OnFindNick(const Anope::string &nick)
+ {
+ if (nickinfoupdater.Check(nick))
+ return;
+
+ try
+ {
+ Anope::string query = "SELECT * FROM `anope_ns_alias` WHERE `nick` = '" + this->Escape(nick) + "'";
+ CommandMutex *current_command = this->CurrentCommand();
+ if (current_command)
+ {
+ current_command->Unlock();
+ try
+ {
+ SQLResult res = this->RunQuery(query);
+ current_command->Lock();
+ NickInfoUpdater::Process(res);
+ }
+ catch (const SQLException &)
+ {
+ current_command->Lock();
+ throw;
+ }
+ }
+ else
+ this->RunQuery(&nickinfoupdater, query);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindNick: " << ex.GetReason();
+ }
+ }
+
+ void OnFindCore(const Anope::string &nick)
+ {
+ if (nickcoreupdater.Check(nick))
+ return;
+
+ try
+ {
+ Anope::string query = "SELECT * FROM `anope_ns_core` WHERE `display` = '" + this->Escape(nick) + "'";
+ CommandMutex *current_command = this->CurrentCommand();
+ if (current_command)
+ {
+ current_command->Unlock();
+ try
+ {
+ SQLResult res = this->RunQuery(query);
+ current_command->Lock();
+ NickCoreUpdater::Process(res);
+ }
+ catch (const SQLException &)
+ {
+ current_command->Lock();
+ throw;
+ }
+ }
+ else
+ this->RunQuery(&nickcoreupdater, query);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindCore: " << ex.GetReason();
+ }
+ }
+};
+
MODULE_INIT(MySQLLiveModule)