summaryrefslogtreecommitdiff
path: root/modules/database/db_sql_live_read.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-12-22 03:46:35 -0500
committerAdam <Adam@anope.org>2011-12-22 03:46:35 -0500
commit3bcb2856909ea8637b28b526a2afd8cf8f801f88 (patch)
tree198db81df53b05bb3254bdfdc6980f00219b4607 /modules/database/db_sql_live_read.cpp
parent704dbe27bf4a01ee10851a6181c1da3ab44a1b87 (diff)
Somehow these two modules got mixed up..
Diffstat (limited to 'modules/database/db_sql_live_read.cpp')
-rw-r--r--modules/database/db_sql_live_read.cpp523
1 files changed, 168 insertions, 355 deletions
diff --git a/modules/database/db_sql_live_read.cpp b/modules/database/db_sql_live_read.cpp
index 6bb9b93d5..4dfe01ef9 100644
--- a/modules/database/db_sql_live_read.cpp
+++ b/modules/database/db_sql_live_read.cpp
@@ -1,434 +1,247 @@
#include "module.h"
#include "../extra/sql.h"
-#include "../commands/os_session.h"
-class MySQLInterface : public SQLInterface
+class SQLCache : public Timer
{
+ typedef std::map<Anope::string, time_t, ci::less> cache_map;
+ cache_map cache;
public:
- MySQLInterface(Module *o) : SQLInterface(o) { }
- void OnResult(const SQLResult &r)
- {
- Log(LOG_DEBUG) << "SQL successfully executed query: " << r.finished_query;
- }
+ SQLCache() : Timer(300, Anope::CurTime, true) { }
- void OnError(const SQLResult &r)
+ bool Check(const Anope::string &item)
{
- if (!r.GetQuery().query.empty())
- Log(LOG_DEBUG) << "Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "Error executing query: " << r.GetError();
- }
-};
+ cache_map::iterator it = this->cache.find(item);
+ if (it != this->cache.end() && Anope::CurTime - it->second < 5)
+ return true;
-class DBMySQL : public Module
-{
- private:
- MySQLInterface sqlinterface;
- service_reference<SQLProvider, Base> SQL;
- std::set<Anope::string> tables;
-
- void RunQuery(const SQLQuery &query)
- {
- if (SQL)
- {
- if (readonly && this->ro)
- {
- readonly = this->ro = false;
- BotInfo *bi = findbot(Config->OperServ);
- if (bi)
- ircdproto->SendGlobops(bi, "Found SQL again, going out of readonly mode...");
- }
-
- SQL->Run(&sqlinterface, query);
- }
- else
- {
- if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
- {
- BotInfo *bi = findbot(Config->OperServ);
- if (bi)
- ircdproto->SendGlobops(bi, "Unable to locate SQL reference, going to readonly...");
- readonly = this->ro = true;
- this->lastwarn = Anope::CurTime;
- }
- }
+ this->cache[item] = Anope::CurTime;
+ return false;
}
- void Insert(const Anope::string &table, const Serializable::serialized_data &data)
+ void Tick(time_t)
{
- if (tables.count(table) == 0 && SQL)
+ for (cache_map::iterator it = this->cache.begin(), next_it; it != this->cache.end(); it = next_it)
{
- this->RunQuery(this->SQL->CreateTable(table, data));
- tables.insert(table);
- }
-
- Anope::string query_text = "INSERT INTO `" + table + "` (";
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query_text += "`" + it->first + "`,";
- query_text.erase(query_text.end() - 1);
- query_text += ") VALUES (";
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query_text += "@" + it->first + "@,";
- query_text.erase(query_text.end() - 1);
- query_text += ") ON DUPLICATE KEY UPDATE ";
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query_text += it->first + "=VALUES(" + it->first + "),";
- query_text.erase(query_text.end() - 1);
-
- SQLQuery query(query_text);
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query.setValue(it->first, it->second.astr());
-
- this->RunQuery(query);
- }
-
- void Delete(const Anope::string &table, const Serializable::serialized_data &data)
- {
- Anope::string query_text = "DELETE FROM `" + table + "` WHERE ";
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query_text += "`" + it->first + "` = @" + it->first + "@";
-
- SQLQuery query(query_text);
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- query.setValue(it->first, it->second.astr());
+ next_it = it;
+ ++next_it;
- this->RunQuery(query);
- }
-
- public:
- time_t lastwarn;
- bool ro;
-
- DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sqlinterface(this), SQL("")
- {
- this->lastwarn = 0;
- this->ro = false;
-
- Implementation i[] = { I_OnReload, I_OnServerConnect };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
-
- OnReload();
-
- if (CurrentUplink)
- OnServerConnect();
- }
-
- void OnReload()
- {
- ConfigReader config;
- Anope::string engine = config.ReadValue("db_sql", "engine", "", 0);
- this->SQL = engine;
+ if (Anope::CurTime - it->second > 5)
+ this->cache.erase(it);
+ }
}
+};
- void OnServerConnect()
+static void ChanInfoUpdate(const Anope::string &name, const SQLResult &res)
+{
+ ChannelInfo *ci = cs_findchan(name);
+ if (res.Rows() == 0)
{
- Implementation i[] = {
- /* Misc */
- I_OnPostCommand,
- /* NickServ */
- I_OnNickAddAccess, I_OnNickEraseAccess, I_OnNickClearAccess,
- I_OnDelCore, I_OnNickForbidden, I_OnNickGroup,
- I_OnNickRegister, I_OnChangeCoreDisplay,
- I_OnNickSuspended, I_OnDelNick,
- /* ChanServ */
- I_OnAccessAdd, I_OnAccessDel, I_OnAccessClear, I_OnLevelChange,
- I_OnDelChan, I_OnChanRegistered, I_OnChanSuspend,
- I_OnAkickAdd, I_OnAkickDel, I_OnMLock, I_OnUnMLock,
- /* BotServ */
- I_OnBotCreate, I_OnBotChange, I_OnBotDelete,
- I_OnBotAssign, I_OnBotUnAssign,
- I_OnBadWordAdd, I_OnBadWordDel,
- /* MemoServ */
- I_OnMemoSend, I_OnMemoDel,
- /* OperServ */
- I_OnExceptionAdd, I_OnExceptionDel,
- I_OnAddXLine, I_OnDelXLine,
- /* HostServ */
- I_OnSetVhost, I_OnDeleteVhost
- };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ delete ci;
+ return;
}
- void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
+ try
{
- User *u = source.u;
-
- if (command->name.find("nickserv/set/") == 0)
- {
- NickAlias *na = findnick(source.u->nick);
- if (!na)
- this->Insert(na->nc->serialize_name(), na->nc->serialize());
+ if (!ci)
+ ci = new ChannelInfo(name);
+ ci->SetFounder(findcore(res.Get(0, "founder")));
+ ci->successor = findcore(res.Get(0, "successor"));
+ ci->desc = res.Get(0, "description");
+ ci->time_registered = convertTo<time_t>(res.Get(0, "time_registered"));
+ ci->ClearFlags();
+ ci->FromString(res.Get(0, "flags"));
+ ci->bantype = convertTo<int>(res.Get(0, "bantype"));
+ ci->memos.memomax = convertTo<unsigned>(res.Get(0, "memomax"));
- }
- else if (command->name.find("nickserv/saset/") == 0)
- {
- NickAlias *na = findnick(params[0]);
- if (!na)
- this->Insert(na->nc->serialize_name(), na->nc->serialize());
- }
- else if (command->name.find("chanserv/set") == 0 || command->name.find("chanserv/saset") == 0)
- {
- ChannelInfo *ci = params.size() > 0 ? cs_findchan(params[0]) : NULL;
- if (!ci)
- this->Insert(ci->serialize_name(), ci->serialize());
- }
- else if (command->name == "botserv/kick" && params.size() > 2)
- {
- ChannelInfo *ci = cs_findchan(params[0]);
- if (!ci)
- return;
- if (!ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
- return;
- this->Insert(ci->serialize_name(), ci->serialize());
- }
- else if (command->name == "botserv/set" && params.size() > 1)
- {
- ChannelInfo *ci = cs_findchan(params[0]);
- BotInfo *bi = NULL;
- if (!ci)
- bi = findbot(params[0]);
- if (bi && params[1].equals_ci("PRIVATE") && u->HasPriv("botserv/set/private"))
- this->Insert(bi->serialize_name(), bi->serialize());
- else if (ci && !ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
- this->Insert(ci->serialize_name(), ci->serialize());
- }
- else if (command->name == "memoserv/ignore" && params.size() > 0)
+ if (res.Get(0, "bi").equals_cs(ci->bi ? ci->bi->nick : "") == false)
{
- Anope::string target = params[0];
- if (target[0] != '#')
- {
- NickCore *nc = u->Account();
- if (nc)
- this->Insert(nc->serialize_name(), nc->serialize());
- }
- else
- {
- ChannelInfo *ci = cs_findchan(target);
- if (ci && ci->AccessFor(u).HasPriv("MEMO"))
- this->Insert(ci->serialize_name(), ci->serialize());
- }
+ if (ci->bi)
+ ci->bi->UnAssign(NULL, ci);
+ BotInfo *bi = findbot(res.Get(0, "bi"));
+ if (bi)
+ bi->Assign(NULL, ci);
}
- }
- void OnNickAddAccess(NickCore *nc, const Anope::string &entry)
- {
- this->Insert(nc->serialize_name(), nc->serialize());
- }
+ ci->capsmin = convertTo<int16_t>(res.Get(0, "capsmin"));
+ ci->capspercent = convertTo<int16_t>(res.Get(0, "capspercent"));
+ ci->floodlines = convertTo<int16_t>(res.Get(0, "floodlines"));
+ ci->floodsecs = convertTo<int16_t>(res.Get(0, "floodsecs"));
+ ci->repeattimes = convertTo<int16_t>(res.Get(0, "repeattimes"));
- void OnNickEraseAccess(NickCore *nc, const Anope::string &entry)
- {
- this->Insert(nc->serialize_name(), nc->serialize());
+ if (ci->c)
+ check_modes(ci->c);
}
-
- void OnNickClearAccess(NickCore *nc)
+ catch (const SQLException &ex)
{
- this->Insert(nc->serialize_name(), nc->serialize());
+ Log() << ex.GetReason();
}
+ catch (const ConvertException &) { }
+}
- void OnDelCore(NickCore *nc)
- {
- this->Delete(nc->serialize_name(), nc->serialize());
- }
-
- void OnNickForbidden(NickAlias *na)
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void OnNickGroup(User *u, NickAlias *)
- {
- OnNickRegister(findnick(u->nick));
- }
-
- void InsertAlias(NickAlias *na)
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void InsertCore(NickCore *nc)
+static void NickInfoUpdate(const Anope::string &name, const SQLResult &res)
+{
+ NickAlias *na = findnick(name);
+ if (res.Rows() == 0)
{
- this->Insert(nc->serialize_name(), nc->serialize());
+ delete na;
+ return;
}
- void OnNickRegister(NickAlias *na)
+ try
{
- this->InsertCore(na->nc);
- this->InsertAlias(na);
- }
+ NickCore *nc = findcore(res.Get(0, "nick"));
+ if (!nc)
+ return;
+ if (!na)
+ na = new NickAlias(name, nc);
- void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay)
- {
- Serializable::serialized_data data = nc->serialize();
- this->Delete(nc->serialize_name(), data);
- data.erase("display");
- data["display"] << newdisplay;
- this->Insert(nc->serialize_name(), data);
+ na->last_quit = res.Get(0, "last_quit");
+ na->last_realname = res.Get(0, "last_realname");
+ na->last_usermask = res.Get(0, "last_usermask");
+ na->last_realhost = res.Get(0, "last_realhost");
+ na->time_registered = convertTo<time_t>(res.Get(0, "time_registered"));
+ na->last_seen = convertTo<time_t>(res.Get(0, "last_seen"));
+ na->ClearFlags();
+ na->FromString(res.Get(0, "flags"));
- for (std::list<NickAlias *>::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it)
+ if (na->nc != nc)
{
- NickAlias *na = *it;
- data = na->serialize();
+ std::list<NickAlias *>::iterator it = std::find(na->nc->aliases.begin(), na->nc->aliases.end(), na);
+ if (it != na->nc->aliases.end())
+ na->nc->aliases.erase(it);
- this->Delete(na->serialize_name(), data);
- data.erase("nc");
- data["nc"] << newdisplay;
- this->Insert(na->serialize_name(), data);
+ na->nc = nc;
+ na->nc->aliases.push_back(na);
}
}
-
- void OnNickSuspend(NickAlias *na)
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void OnDelNick(NickAlias *na)
- {
- this->Delete(na->serialize_name(), na->serialize());
- }
-
- void OnAccessAdd(ChannelInfo *ci, User *, ChanAccess *access)
- {
- this->Insert(access->serialize_name(), access->serialize());
- }
-
- void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access)
- {
- this->Delete(access->serialize_name(), access->serialize());
- }
-
- void OnAccessClear(ChannelInfo *ci, User *u)
- {
- for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
- this->OnAccessDel(ci, NULL, ci->GetAccess(i));
- }
-
- void OnLevelChange(User *u, ChannelInfo *ci, const Anope::string &priv, int16_t what)
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnDelChan(ChannelInfo *ci)
+ catch (const SQLException &ex)
{
- this->Delete(ci->serialize_name(), ci->serialize());
+ Log() << ex.GetReason();
}
+ catch (const ConvertException &) { }
+}
- void OnChanRegistered(ChannelInfo *ci)
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnChanSuspend(ChannelInfo *ci)
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnAkickAdd(ChannelInfo *ci, AutoKick *ak)
- {
- this->Insert(ak->serialize_name(), ak->serialize());
- }
-
- void OnAkickDel(ChannelInfo *ci, AutoKick *ak)
- {
- this->Delete(ak->serialize_name(), ak->serialize());
- }
-
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock)
- {
- this->Insert(lock->serialize_name(), lock->serialize());
- return EVENT_CONTINUE;
- }
-
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock)
+static void NickCoreUpdate(const Anope::string &name, const SQLResult &res)
+{
+ NickCore *nc = findcore(name);
+ if (res.Rows() == 0)
{
- this->Delete(lock->serialize_name(), lock->serialize());
- return EVENT_CONTINUE;
+ delete nc;
+ return;
}
- void OnBotCreate(BotInfo *bi)
+ try
{
- this->Insert(bi->serialize_name(), bi->serialize());
- }
+ if (!nc)
+ nc = new NickCore(name);
- void OnBotChange(BotInfo *bi)
- {
- OnBotCreate(bi);
+ nc->pass = res.Get(0, "pass");
+ nc->email = res.Get(0, "email");
+ nc->greet = res.Get(0, "greet");
+ nc->ClearFlags();
+ nc->FromString(res.Get(0, "flags"));
+ nc->language = res.Get(0, "language");
}
-
- void OnBotDelete(BotInfo *bi)
+ catch (const SQLException &ex)
{
- this->Delete(bi->serialize_name(), bi->serialize());
+ Log() << ex.GetReason();
}
+ catch (const ConvertException &) { }
+}
- EventReturn OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi)
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- return EVENT_CONTINUE;
- }
+class MySQLLiveModule : public Module
+{
+ service_reference<SQLProvider, Base> SQL;
- EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci)
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- return EVENT_CONTINUE;
- }
+ SQLCache chan_cache, nick_cache, core_cache;
- void OnBadWordAdd(ChannelInfo *ci, BadWord *bw)
+ SQLResult RunQuery(const SQLQuery &query)
{
- this->Insert(bw->serialize_name(), bw->serialize());
- }
+ if (!this->SQL)
+ throw SQLException("Unable to locate SQL reference, is db_sql loaded and configured correctly?");
- void OnBadWordDel(ChannelInfo *ci, BadWord *bw)
- {
- this->Delete(bw->serialize_name(), bw->serialize());
+ SQLResult res = SQL->RunQuery(query);
+ if (!res.GetError().empty())
+ throw SQLException(res.GetError());
+ return res;
}
- void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m)
+ public:
+ MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) :
+ Module(modname, creator, DATABASE), SQL("")
{
- this->Insert(m->serialize_name(), m->serialize());
+ Implementation i[] = { I_OnReload, I_OnFindChan, I_OnFindNick, I_OnFindCore, I_OnShutdown };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnMemoDel(const NickCore *nc, MemoInfo *mi, Memo *m)
+ void OnReload()
{
- this->Delete(m->serialize_name(), m->serialize());
+ ConfigReader config;
+ Anope::string engine = config.ReadValue("db_sql", "engine", "", 0);
+ this->SQL = engine;
}
- void OnMemoDel(ChannelInfo *ci, MemoInfo *mi, Memo *m)
+ void OnShutdown()
{
- this->Delete(m->serialize_name(), m->serialize());
+ Implementation i[] = { I_OnFindChan, I_OnFindNick, I_OnFindCore };
+ for (size_t j = 0; j < 3; ++j)
+ ModuleManager::Detach(i[j], this);
}
- EventReturn OnExceptionAdd(Exception *ex)
+ void OnFindChan(const Anope::string &chname)
{
- this->Insert(ex->serialize_name(), ex->serialize());
- return EVENT_CONTINUE;
- }
+ if (chan_cache.Check(chname))
+ return;
- void OnExceptionDel(User *, Exception *ex)
- {
- this->Delete(ex->serialize_name(), ex->serialize());
+ try
+ {
+ SQLQuery query("SELECT * FROM `ChannelInfo` WHERE `name` = @name@");
+ query.setValue("name", chname);
+ SQLResult res = this->RunQuery(query);
+ ChanInfoUpdate(chname, res);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindChan: " << ex.GetReason();
+ }
}
- EventReturn OnAddXLine(XLine *x, XLineManager *xlm)
+ void OnFindNick(const Anope::string &nick)
{
- this->Insert(x->serialize_name(), x->serialize());
- return EVENT_CONTINUE;
- }
+ if (nick_cache.Check(nick))
+ return;
- void OnDelXLine(User *, XLine *x, XLineManager *xlm)
- {
- this->Delete(x->serialize_name(), x->serialize());
+ try
+ {
+ SQLQuery query("SELECT * FROM `NickAlias` WHERE `nick` = @nick@");
+ query.setValue("nick", nick);
+ SQLResult res = this->RunQuery(query);
+ NickInfoUpdate(nick, res);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindNick: " << ex.GetReason();
+ }
}
- void OnDeleteVhost(NickAlias *na)
+ void OnFindCore(const Anope::string &nick)
{
- this->Insert(na->serialize_name(), na->serialize());
- }
+ if (core_cache.Check(nick))
+ return;
- void OnSetVhost(NickAlias *na)
- {
- this->Insert(na->serialize_name(), na->serialize());
+ try
+ {
+ SQLQuery query("SELECT * FROM `NickCore` WHERE `display` = @display@");
+ query.setValue("display", nick);
+ SQLResult res = this->RunQuery(query);
+ NickCoreUpdate(nick, res);
+ }
+ catch (const SQLException &ex)
+ {
+ Log(LOG_DEBUG) << "OnFindCore: " << ex.GetReason();
+ }
}
};
-MODULE_INIT(DBMySQL)
-
+MODULE_INIT(MySQLLiveModule)