summaryrefslogtreecommitdiff
path: root/modules/database
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-04-23 05:08:26 -0400
committerAdam <Adam@anope.org>2012-04-23 05:08:26 -0400
commit573e49a7ead331219eb6f0d3ca9cf83e793a5c9c (patch)
treee145e04fa3d041cf92ce46da4ac790b63231059c /modules/database
parent63c639e108a00d7dbb0d7ac9891684fc83a3b207 (diff)
Reworked live SQL support yet again
Diffstat (limited to 'modules/database')
-rw-r--r--modules/database/db_flatfile.cpp12
-rw-r--r--modules/database/db_old.cpp4
-rw-r--r--modules/database/db_plain.cpp101
-rw-r--r--modules/database/db_sql.cpp50
-rw-r--r--modules/database/db_sql_live.cpp311
-rw-r--r--modules/database/db_sql_live_read.cpp179
-rw-r--r--modules/database/db_sql_live_write.cpp440
7 files changed, 384 insertions, 713 deletions
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
index 259851b18..14e894e0c 100644
--- a/modules/database/db_flatfile.cpp
+++ b/modules/database/db_flatfile.cpp
@@ -91,8 +91,8 @@ class DBFlatFile : public Module
}
SerializeType *st = NULL;
- Serializable::serialized_data data;
- std::multimap<SerializeType *, Serializable::serialized_data> objects;
+ Serialize::Data data;
+ std::multimap<SerializeType *, Serialize::Data> objects;
for (Anope::string buf, token; std::getline(db, buf.str());)
{
spacesepstream sep(buf);
@@ -121,11 +121,11 @@ class DBFlatFile : public Module
{
SerializeType *stype = SerializeType::Find(type_order[i]);
- std::multimap<SerializeType *, Serializable::serialized_data>::iterator it = objects.find(stype), it_end = objects.upper_bound(stype);
+ std::multimap<SerializeType *, Serialize::Data>::iterator it = objects.find(stype), it_end = objects.upper_bound(stype);
if (it == objects.end())
continue;
for (; it != it_end; ++it)
- it->first->Create(it->second);
+ it->first->Unserialize(NULL, it->second);
}
db.close();
@@ -155,10 +155,10 @@ class DBFlatFile : public Module
for (std::list<Serializable *>::const_iterator it = items.begin(), it_end = items.end(); it != it_end; ++it)
{
Serializable *base = *it;
- Serializable::serialized_data data = base->serialize();
+ Serialize::Data data = base->serialize();
db << "OBJECT " << base->serialize_name() << "\n";
- for (Serializable::serialized_data::iterator dit = data.begin(), dit_end = data.end(); dit != dit_end; ++dit)
+ for (Serialize::Data::iterator dit = data.begin(), dit_end = data.end(); dit != dit_end; ++dit)
db << "DATA " << dit->first << " " << dit->second.astr() << "\n";
db << "END\n";
}
diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp
index c455aa265..2783a29b2 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/db_old.cpp
@@ -516,7 +516,7 @@ static void LoadNicks()
m->sender = sbuf;
READ(read_string(m->text, f));
m->owner = nc->display;
- nc->memos.memos.push_back(m);
+ nc->memos.memos->push_back(m);
}
READ(read_uint16(&u16, f));
READ(read_int16(&i16, f));
@@ -798,7 +798,7 @@ static void LoadChannels()
m->sender = sbuf;
READ(read_string(m->text, f));
m->owner = ci->name;
- ci->memos.memos.push_back(m);
+ ci->memos.memos->push_back(m);
}
READ(read_string(buffer, f));
diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp
index edf41c7f0..935ef95a2 100644
--- a/modules/database/db_plain.cpp
+++ b/modules/database/db_plain.cpp
@@ -17,6 +17,11 @@
Anope::string DatabaseFile;
std::stringstream db_buffer;
+struct ExtensibleString : Anope::string, ExtensibleItem
+{
+ ExtensibleString(const Anope::string &s) : Anope::string(s) { }
+};
+
class DatabaseException : public CoreException
{
public:
@@ -60,7 +65,7 @@ EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
LoadOperInfo(otherparams);
return EVENT_CONTINUE;
- }
+}
EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const std::vector<Anope::string> &params)
{
@@ -93,7 +98,7 @@ EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const
m->SetFlag(MF_RECEIPT);
}
m->text = params[params.size() - 1];
- nc->memos.memos.push_back(m);
+ nc->memos.memos->push_back(m);
}
else if (key.equals_ci("MIG"))
nc->memos.ignores.push_back(params[0].ci_str());
@@ -173,7 +178,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
if (!provider)
throw DatabaseException("Old access entry for nonexistant provider");
- ChanAccess *access = provider->Create();
+ ChanAccess *access = const_cast<ChanAccess *>(provider->Create());
access->ci = ci;
access->mask = params[0];
access->Unserialize(params[1]);
@@ -189,7 +194,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
if (!provider)
throw DatabaseException("Access entry for nonexistant provider " + params[0]);
- ChanAccess *access = provider->Create();
+ ChanAccess *access = const_cast<ChanAccess *>(provider->Create());
access->ci = ci;
access->mask = params[1];
access->Unserialize(params[2]);
@@ -222,18 +227,18 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
}
else if (key.equals_ci("LOG"))
{
- LogSetting l;
-
- l.ci = ci;
- l.service_name = params[0];
- l.command_service = params[1];
- l.command_name = params[2];
- l.method = params[3];
- l.creator = params[4];
- l.created = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : Anope::CurTime;
- l.extra = params.size() > 6 ? params[6] : "";
-
- ci->log_settings.push_back(l);
+ LogSetting *l = new LogSetting();
+
+ l->ci = ci;
+ l->service_name = params[0];
+ l->command_service = params[1];
+ l->command_name = params[2];
+ l->method = params[3];
+ l->creator = params[4];
+ l->created = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : Anope::CurTime;
+ l->extra = params.size() > 6 ? params[6] : "";
+
+ ci->log_settings->push_back(l);
}
else if (key.equals_ci("MLOCK"))
{
@@ -241,12 +246,12 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
Anope::string mode_name = params[1];
Anope::string setter = params[2];
time_t mcreated = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : Anope::CurTime;
- Anope::string param = params.size() > 4 ? params[4] : "";
- for (size_t i = CMODE_BEGIN + 1; i < CMODE_END; ++i)
+ Anope::string param = params.size() > 4 ? params[4] : "";
+ for (size_t i = CMODE_BEGIN + 1; i < CMODE_END; ++i)
if (ChannelModeNameStrings[i] == mode_name)
{
ChannelModeName n = static_cast<ChannelModeName>(i);
- ci->mode_locks.insert(std::make_pair(n, ModeLock(ci, set, n, param, setter, mcreated)));
+ ci->mode_locks->insert(std::make_pair(n, new ModeLock(ci, set, n, param, setter, mcreated)));
break;
}
}
@@ -263,7 +268,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
m->SetFlag(MF_RECEIPT);
}
m->text = params[params.size() - 1];
- ci->memos.memos.push_back(m);
+ ci->memos.memos->push_back(m);
}
else if (key.equals_ci("MIG"))
ci->memos.ignores.push_back(params[0].ci_str());
@@ -666,9 +671,9 @@ class DBPlain : public Module
db_buffer << "VER 2" << endl;
- for (nickcore_map::const_iterator nit = NickCoreList.begin(), nit_end = NickCoreList.end(); nit != nit_end; ++nit)
+ for (nickcore_map::const_iterator nit = NickCoreList->begin(), nit_end = NickCoreList->end(); nit != nit_end; ++nit)
{
- NickCore *nc = nit->second;
+ const NickCore *nc = nit->second;
db_buffer << "NC " << nc->display << " " << nc->pass << endl;
@@ -683,34 +688,35 @@ class DBPlain : public Module
if (!nc->access.empty())
{
- for (std::vector<Anope::string>::iterator it = nc->access.begin(), it_end = nc->access.end(); it != it_end; ++it)
+ for (std::vector<Anope::string>::const_iterator it = nc->access.begin(), it_end = nc->access.end(); it != it_end; ++it)
db_buffer << "MD ACCESS " << *it << endl;
}
if (!nc->cert.empty())
{
- for (std::vector<Anope::string>::iterator it = nc->cert.begin(), it_end = nc->cert.end(); it != it_end; ++it)
+ for (std::vector<Anope::string>::const_iterator it = nc->cert.begin(), it_end = nc->cert.end(); it != it_end; ++it)
db_buffer << "MD CERT " << *it << endl;
}
if (nc->FlagCount())
db_buffer << "MD FLAGS " << nc->ToString() << endl;
- MemoInfo *mi = &nc->memos;
- for (unsigned k = 0, end = mi->memos.size(); k < end; ++k)
+ const MemoInfo *mi = &nc->memos;
+ for (unsigned k = 0, end = mi->memos->size(); k < end; ++k)
{
- db_buffer << "MD MI " << mi->memos[k]->time << " " << mi->memos[k]->sender;
- if (mi->memos[k]->HasFlag(MF_UNREAD))
+ const Memo *m = mi->GetMemo(k);
+ db_buffer << "MD MI " << m->time << " " << m->sender;
+ if (m->HasFlag(MF_UNREAD))
db_buffer << " UNREAD";
- if (mi->memos[k]->HasFlag(MF_RECEIPT))
+ if (m->HasFlag(MF_RECEIPT))
db_buffer << " RECEIPT";
- db_buffer << " :" << mi->memos[k]->text << endl;
+ db_buffer << " :" << m->text << endl;
}
for (unsigned k = 0, end = mi->ignores.size(); k < end; ++k)
db_buffer << "MD MIG " << Anope::string(mi->ignores[k]) << endl;
//FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
}
- for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it)
+ for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
{
- NickAlias *na = it->second;
+ const NickAlias *na = it->second;
db_buffer << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl;
if (!na->last_usermask.empty())
@@ -729,7 +735,7 @@ class DBPlain : public Module
//FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, na));
}
- for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
{
BotInfo *bi = it->second;
@@ -741,9 +747,9 @@ class DBPlain : public Module
db_buffer << "MD FLAGS " << bi->ToString() << endl;
}
- for (registered_channel_map::const_iterator cit = RegisteredChannelList.begin(), cit_end = RegisteredChannelList.end(); cit != cit_end; ++cit)
+ for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit)
{
- ChannelInfo *ci = cit->second;
+ const ChannelInfo *ci = cit->second;
db_buffer << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used << endl;
db_buffer << "MD BANTYPE " << ci->bantype << endl;
@@ -774,7 +780,7 @@ class DBPlain : public Module
}
for (unsigned k = 0, end = ci->GetAccessCount(); k < end; ++k)
{
- ChanAccess *access = ci->GetAccess(k);
+ const ChanAccess *access = ci->GetAccess(k);
db_buffer << "MD ACCESS2 " << access->provider->name << " " << access->mask << " " << access->Serialize() << " " << access->last_seen << " " << access->creator << " " << access->created << endl;
}
for (unsigned k = 0, end = ci->GetAkickCount(); k < end; ++k)
@@ -785,28 +791,29 @@ class DBPlain : public Module
db_buffer << ci->GetAkick(k)->reason;
db_buffer << endl;
}
- for (unsigned k = 0, end = ci->log_settings.size(); k < end; ++k)
+ for (unsigned k = 0, end = ci->log_settings->size(); k < end; ++k)
{
- LogSetting &l = ci->log_settings[k];
+ const LogSetting &l = *ci->log_settings->at(k);
db_buffer << "MD LOG " << l.service_name << " " << l.command_service << " " << l.command_name << " " << l.method << " " << l.creator << " " << l.created << " " << l.extra << endl;
}
- for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it)
+ for (ChannelInfo::ModeList::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it)
{
- const ModeLock &ml = it->second;
+ const ModeLock &ml = *it->second;
ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
if (cm != NULL)
db_buffer << "MD MLOCK " << (ml.set ? 1 : 0) << " " << cm->NameAsString() << " " << ml.setter << " " << ml.created << " " << ml.param << endl;
}
- MemoInfo *memos = &ci->memos;
- for (unsigned k = 0, end = memos->memos.size(); k < end; ++k)
+ const MemoInfo *memos = &ci->memos;
+ for (unsigned k = 0, end = memos->memos->size(); k < end; ++k)
{
- db_buffer << "MD MI " << memos->memos[k]->time << " " << memos->memos[k]->sender;
- if (memos->memos[k]->HasFlag(MF_UNREAD))
+ const Memo *m = memos->GetMemo(k);
+ db_buffer << "MD MI " << m->time << " " << m->sender;
+ if (m->HasFlag(MF_UNREAD))
db_buffer << " UNREAD";
- if (memos->memos[k]->HasFlag(MF_RECEIPT))
+ if (m->HasFlag(MF_RECEIPT))
db_buffer << " RECEIPT";
- db_buffer << " :" << memos->memos[k]->text << endl;
+ db_buffer << " :" << m->text << endl;
}
for (unsigned k = 0, end = memos->ignores.size(); k < end; ++k)
db_buffer << "MD MIG " << Anope::string(memos->ignores[k]) << endl;
@@ -839,7 +846,7 @@ class DBPlain : public Module
XLineManager *xl = *it;
for (unsigned i = 0, end = xl->GetCount(); i < end; ++i)
{
- XLine *x = xl->GetEntry(i);
+ const XLine *x = xl->GetEntry(i);
db_buffer << "OS SXLINE " << xl->Type() << " " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
}
diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp
index c8379ca12..c2ba84a5f 100644
--- a/modules/database/db_sql.cpp
+++ b/modules/database/db_sql.cpp
@@ -60,41 +60,20 @@ class DBSQL : public Module
}
}
- void AlterTable(const Anope::string &table, std::set<Anope::string> &data, const Serializable::serialized_data &newd)
- {
- for (Serializable::serialized_data::const_iterator it = newd.begin(), it_end = newd.end(); it != it_end; ++it)
- {
- if (data.count(it->first) > 0)
- continue;
-
- data.insert(it->first);
-
- Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
- if (it->second.getType() == Serialize::DT_INT)
- query_text += "int(11)";
- else if (it->second.getMax() > 0)
- query_text += "varchar(" + stringify(it->second.getMax()) + ")";
- else
- query_text += "text";
-
- this->RunBackground(SQLQuery(query_text));
- }
- }
-
- void Insert(const Anope::string &table, const Serializable::serialized_data &data)
+ void Insert(const Anope::string &table, const Serialize::Data &data)
{
Anope::string query_text = "INSERT INTO `" + table + "` (";
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ for (Serialize::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)
+ for (Serialize::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 += ")";
SQLQuery query(query_text);
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
query.setValue(it->first, it->second.astr());
this->RunBackground(query);
@@ -132,28 +111,21 @@ class DBSQL : public Module
this->DropAll();
- std::map<Anope::string, std::set<Anope::string> > table_layout;
for (std::list<Serializable *>::const_iterator it = items.begin(), it_end = items.end(); it != it_end; ++it)
{
Serializable *base = *it;
- Serializable::serialized_data data = base->serialize();
+ Serialize::Data data = base->serialize();
if (data.empty())
continue;
- std::set<Anope::string> &layout = table_layout[base->serialize_name()];
- if (layout.empty())
- {
- this->RunBackground(this->sql->CreateTable(base->serialize_name(), data));
-
- for (Serializable::serialized_data::iterator it2 = data.begin(), it2_end = data.end(); it2 != it2_end; ++it2)
- layout.insert(it2->first);
- }
- else
- this->AlterTable(base->serialize_name(), layout, data);
+ std::vector<SQLQuery> create_queries = this->sql->CreateTable(base->serialize_name(), data);
+ for (unsigned i = 0; i < create_queries.size(); ++i)
+ this->RunBackground(create_queries[i]);
this->Insert(base->serialize_name(), data);
}
+
return EVENT_CONTINUE;
}
@@ -174,12 +146,12 @@ class DBSQL : public Module
SQLResult res = this->sql->RunQuery(query);
for (int j = 0; j < res.Rows(); ++j)
{
- Serializable::serialized_data data;
+ Serialize::Data data;
const std::map<Anope::string, Anope::string> &row = res.Row(j);
for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
data[rit->first] << rit->second;
- sb->Create(data);
+ sb->Unserialize(NULL, data);
}
}
diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp
new file mode 100644
index 000000000..4b939e23b
--- /dev/null
+++ b/modules/database/db_sql_live.cpp
@@ -0,0 +1,311 @@
+#include "module.h"
+#include "../extra/sql.h"
+#include "../commands/os_session.h"
+
+class MySQLInterface : public SQLInterface
+{
+ public:
+ MySQLInterface(Module *o) : SQLInterface(o) { }
+
+ void OnResult(const SQLResult &r) anope_override
+ {
+ Log(LOG_DEBUG) << "SQLive successfully executed query: " << r.finished_query;
+ }
+
+ void OnError(const SQLResult &r) anope_override
+ {
+ 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();
+ }
+};
+
+class DBMySQL : public Module, public Pipe
+{
+ private:
+ MySQLInterface sqlinterface;
+ Anope::string engine;
+ service_reference<SQLProvider> SQL;
+ time_t lastwarn;
+ bool ro;
+ bool init;
+ std::set<dynamic_reference<Serializable> > updated_items;
+
+ bool CheckSQL()
+ {
+ if (SQL)
+ {
+ if (readonly && this->ro)
+ {
+ readonly = this->ro = false;
+ const BotInfo *bi = findbot(Config->OperServ);
+ if (bi)
+ ircdproto->SendGlobops(bi, "Found SQL again, going out of readonly mode...");
+ }
+
+ return true;
+ }
+ else
+ {
+ if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
+ {
+ const 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;
+ }
+
+ return false;
+ }
+ }
+
+ bool CheckInit()
+ {
+ return init && SQL;
+ }
+
+ void RunQuery(const SQLQuery &query)
+ {
+ /* Can this be threaded? */
+ this->RunQueryResult(query);
+ }
+
+ SQLResult RunQueryResult(const SQLQuery &query)
+ {
+ if (this->CheckSQL())
+ {
+ SQLResult res = SQL->RunQuery(query);
+ if (!res.GetError().empty())
+ Log(LOG_DEBUG) << "SQlive got error " << res.GetError() << " for " + res.finished_query;
+ else
+ Log(LOG_DEBUG) << "SQLive got " << res.Rows() << " rows for " << res.finished_query;
+ return res;
+ }
+ throw SQLException("No SQL!");
+ }
+
+ SQLQuery BuildInsert(const Anope::string &table, unsigned int id, const Serialize::Data &data)
+ {
+ if (this->SQL)
+ {
+ std::vector<SQLQuery> create_queries = this->SQL->CreateTable(table, data);
+ for (unsigned i = 0; i < create_queries.size(); ++i)
+ this->RunQuery(create_queries[i]);
+ }
+
+ Anope::string query_text = "INSERT INTO `" + table + "` (`id`";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ query_text += ",`" + it->first + "`";
+ query_text += ") VALUES (" + stringify(id);
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ query_text += ",@" + it->first + "@";
+ query_text += ") ON DUPLICATE KEY UPDATE ";
+ for (Serialize::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 (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ query.setValue(it->first, it->second.astr());
+
+ return query;
+ }
+
+ public:
+ DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sqlinterface(this), SQL("", "")
+ {
+ this->lastwarn = 0;
+ this->ro = false;
+ this->init = false;
+
+ Implementation i[] = { I_OnReload, I_OnShutdown, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializePtrAssign, I_OnSerializeCheck, I_OnSerializableUpdate };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+
+ OnReload();
+ }
+
+ void OnNotify() anope_override
+ {
+ if (!this->CheckInit())
+ return;
+
+ for (std::set<dynamic_reference<Serializable> >::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it)
+ {
+ dynamic_reference<Serializable> obj = *it;
+
+ if (obj)
+ {
+ if (obj->IsCached())
+ continue;
+ obj->UpdateCache();
+
+ static std::set<Serializable *> working_objects; // XXX
+ if (working_objects.count(obj))
+ continue;
+ working_objects.insert(obj);
+
+ SQLResult res = this->RunQueryResult(BuildInsert(obj->serialize_name(), obj->id, obj->serialize()));
+ if (res.GetID() > 0)
+ obj->id = res.GetID();
+ SerializeType *type = SerializeType::Find(obj->serialize_name());
+ if (type)
+ type->objects.erase(obj->id);
+
+ working_objects.erase(obj);
+ }
+ }
+
+ this->updated_items.clear();
+ }
+
+ EventReturn OnLoadDatabase() anope_override
+ {
+ init = true;
+ return EVENT_STOP;
+ }
+
+ void OnShutdown() anope_override
+ {
+ init = false;
+ }
+
+ void OnReload() anope_override
+ {
+ ConfigReader config;
+ this->engine = config.ReadValue("db_sql", "engine", "", 0);
+ this->SQL = service_reference<SQLProvider>("SQLProvider", this->engine);
+ }
+
+ void OnSerializableConstruct(Serializable *obj) anope_override
+ {
+ if (!this->CheckInit())
+ return;
+ this->updated_items.insert(obj);
+ this->Notify();
+ }
+
+ void OnSerializableDestruct(Serializable *obj) anope_override
+ {
+ if (!this->CheckInit())
+ return;
+ this->RunQuery("DELETE FROM `" + obj->serialize_name() + "` WHERE `id` = " + stringify(obj->id));
+ SerializeType *type = SerializeType::Find(obj->serialize_name());
+ if (type)
+ type->objects.erase(obj->id);
+ }
+
+ void OnSerializePtrAssign(Serializable *obj) anope_override
+ {
+ SerializeType *stype = SerializeType::Find(obj->serialize_name());
+ if (stype == NULL || !this->CheckInit() || stype->GetTimestamp() == Anope::CurTime)
+ return;
+
+ if (obj->IsCached())
+ return;
+ obj->UpdateCache();
+
+ SQLResult res = this->RunQueryResult("SELECT * FROM `" + obj->serialize_name() + "` WHERE `id` = " + stringify(obj->id));
+
+ if (res.Rows() == 0)
+ obj->destroy();
+ else
+ {
+ const std::map<Anope::string, Anope::string> &row = res.Row(0);
+
+ if (res.Get(0, "timestamp").empty())
+ {
+ obj->destroy();
+ stype->objects.erase(obj->id);
+ }
+ else
+ {
+ Serialize::Data data;
+
+ for (std::map<Anope::string, Anope::string>::const_iterator it = row.begin(), it_end = row.end(); it != it_end; ++it)
+ data[it->first] << it->second;
+
+ if (stype->Unserialize(obj, data) == NULL)
+ obj->destroy();
+ }
+ }
+ }
+
+ void OnSerializeCheck(SerializeType *obj)
+ {
+ if (!this->CheckInit() || obj->GetTimestamp() == Anope::CurTime)
+ return;
+
+ SQLQuery query("SELECT * FROM `" + obj->GetName() + "` WHERE (`timestamp` > FROM_UNIXTIME(@ts@) OR `timestamp` IS NULL)");
+ query.setValue("ts", obj->GetTimestamp());
+
+ obj->UpdateTimestamp();
+
+ SQLResult res = this->RunQueryResult(query);
+
+ bool clear_null = false;
+ for (int i = 0; i < res.Rows(); ++i)
+ {
+ const std::map<Anope::string, Anope::string> &row = res.Row(i);
+
+ unsigned int id;
+ try
+ {
+ id = convertTo<unsigned int>(res.Get(i, "id"));
+ }
+ catch (const ConvertException &)
+ {
+ Log(LOG_DEBUG) << "Unable to convert id from " << obj->GetName();
+ continue;
+ }
+
+ if (res.Get(i, "timestamp").empty())
+ {
+ clear_null = true;
+ std::map<unsigned int, Serializable *>::iterator it = obj->objects.find(id);
+ if (it != obj->objects.end())
+ {
+ it->second->destroy();
+ obj->objects.erase(it);
+ }
+ }
+ else
+ {
+ Serialize::Data data;
+
+ for (std::map<Anope::string, Anope::string>::const_iterator it = row.begin(), it_end = row.end(); it != it_end; ++it)
+ data[it->first] << it->second;
+
+ Serializable *s = NULL;
+ std::map<unsigned int, Serializable *>::iterator it = obj->objects.find(id);
+ if (it != obj->objects.end())
+ s = it->second;
+
+ Serializable *new_s = obj->Unserialize(s, data);
+ if (new_s)
+ {
+ new_s->id = id;
+ obj->objects[id] = new_s;
+ }
+ else
+ s->destroy();
+ }
+ }
+
+ if (clear_null)
+ {
+ query = "DELETE FROM `" + obj->GetName() + "` WHERE `timestamp` IS NULL";
+ this->RunQuery(query);
+ }
+ }
+
+ void OnSerializableUpdate(Serializable *obj)
+ {
+ this->updated_items.insert(obj);
+ this->Notify();
+ }
+};
+
+MODULE_INIT(DBMySQL)
+
diff --git a/modules/database/db_sql_live_read.cpp b/modules/database/db_sql_live_read.cpp
deleted file mode 100644
index 38e5f6fef..000000000
--- a/modules/database/db_sql_live_read.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "module.h"
-#include "../extra/sql.h"
-
-class SQLCache : public Timer
-{
- typedef std::map<Anope::string, time_t, ci::less> cache_map;
- cache_map cache;
- public:
-
- SQLCache() : Timer(300, Anope::CurTime, true) { }
-
- bool Check(const Anope::string &item)
- {
- cache_map::iterator it = this->cache.find(item);
- if (it != this->cache.end() && Anope::CurTime - it->second < 5)
- return true;
-
- this->cache[item] = Anope::CurTime;
- return false;
- }
-
- void Tick(time_t) anope_override
- {
- for (cache_map::iterator it = this->cache.begin(), next_it; it != this->cache.end(); it = next_it)
- {
- next_it = it;
- ++next_it;
-
- if (Anope::CurTime - it->second > 5)
- this->cache.erase(it);
- }
- }
-};
-
-class MySQLLiveModule : public Module
-{
- service_reference<SQLProvider> SQL;
-
- SQLCache chan_cache, nick_cache, core_cache;
-
- SQLResult RunQuery(const SQLQuery &query)
- {
- if (!this->SQL)
- throw SQLException("Unable to locate SQL reference, is db_sql loaded and configured correctly?");
-
- SQLResult res = SQL->RunQuery(query);
- if (!res.GetError().empty())
- throw SQLException(res.GetError());
- return res;
- }
-
- public:
- MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) :
- Module(modname, creator, DATABASE), SQL("", "")
- {
- this->OnReload();
-
- Implementation i[] = { I_OnReload, I_OnFindChan, I_OnFindNick, I_OnFindCore, I_OnShutdown };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- void OnReload() anope_override
- {
- ConfigReader config;
- Anope::string engine = config.ReadValue("db_sql", "engine", "", 0);
- this->SQL = service_reference<SQLProvider>("SQLProvider", engine);
- }
-
- void OnShutdown() anope_override
- {
- Implementation i[] = { I_OnFindChan, I_OnFindNick, I_OnFindCore };
- for (size_t j = 0; j < 3; ++j)
- ModuleManager::Detach(i[j], this);
- }
-
- void OnFindChan(const Anope::string &chname) anope_override
- {
- if (chan_cache.Check(chname))
- return;
-
- try
- {
- SQLQuery query("SELECT * FROM `ChannelInfo` WHERE `name` = @name@");
- query.setValue("name", chname);
- SQLResult res = this->RunQuery(query);
-
- if (res.Rows() == 0)
- {
- delete cs_findchan(chname);
- return;
- }
-
- SerializeType *sb = SerializeType::Find("ChannelInfo");
- if (sb == NULL)
- return;
-
- Serializable::serialized_data data;
- const std::map<Anope::string, Anope::string> &row = res.Row(0);
- for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
- data[rit->first] << rit->second;
-
- sb->Create(data);
- }
- catch (const SQLException &ex)
- {
- Log(LOG_DEBUG) << "OnFindChan: " << ex.GetReason();
- }
- }
-
- void OnFindNick(const Anope::string &nick) anope_override
- {
- if (nick_cache.Check(nick))
- return;
-
- try
- {
- SQLQuery query("SELECT * FROM `NickAlias` WHERE `nick` = @nick@");
- query.setValue("nick", nick);
- SQLResult res = this->RunQuery(query);
-
- if (res.Rows() == 0)
- {
- delete findnick(nick);
- return;
- }
-
- SerializeType *sb = SerializeType::Find("NickAlias");
- if (sb == NULL)
- return;
-
- Serializable::serialized_data data;
- const std::map<Anope::string, Anope::string> &row = res.Row(0);
- for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
- data[rit->first] << rit->second;
-
- sb->Create(data);
- }
- catch (const SQLException &ex)
- {
- Log(LOG_DEBUG) << "OnFindNick: " << ex.GetReason();
- }
- }
-
- void OnFindCore(const Anope::string &nick) anope_override
- {
- if (core_cache.Check(nick))
- return;
-
- try
- {
- SQLQuery query("SELECT * FROM `NickCore` WHERE `display` = @display@");
- query.setValue("display", nick);
- SQLResult res = this->RunQuery(query);
-
- if (res.Rows() == 0)
- {
- delete findcore(nick);
- return;
- }
-
- SerializeType *sb = SerializeType::Find("NickCore");
- if (sb == NULL)
- return;
-
- Serializable::serialized_data data;
- const std::map<Anope::string, Anope::string> &row = res.Row(0);
- for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
- data[rit->first] << rit->second;
-
- sb->Create(data);
- }
- catch (const SQLException &ex)
- {
- Log(LOG_DEBUG) << "OnFindCore: " << ex.GetReason();
- }
- }
-};
-
-MODULE_INIT(MySQLLiveModule)
diff --git a/modules/database/db_sql_live_write.cpp b/modules/database/db_sql_live_write.cpp
deleted file mode 100644
index 0692f7f30..000000000
--- a/modules/database/db_sql_live_write.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-#include "module.h"
-#include "../extra/sql.h"
-#include "../commands/os_session.h"
-
-class MySQLInterface : public SQLInterface
-{
- public:
- MySQLInterface(Module *o) : SQLInterface(o) { }
-
- void OnResult(const SQLResult &r) anope_override
- {
- Log(LOG_DEBUG) << "SQL successfully executed query: " << r.finished_query;
- }
-
- void OnError(const SQLResult &r) anope_override
- {
- 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();
- }
-};
-
-class DBMySQL : public Module
-{
- private:
- MySQLInterface sqlinterface;
- service_reference<SQLProvider> 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;
- }
- }
- }
-
- void Insert(const Anope::string &table, const Serializable::serialized_data &data)
- {
- if (tables.count(table) == 0 && SQL)
- {
- 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 ", arg_text;
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- {
- if (!arg_text.empty())
- arg_text += " AND ";
- arg_text += "`" + it->first + "` = @" + it->first + "@";
- }
-
- query_text += arg_text;
-
- 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);
- }
-
- 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() anope_override
- {
- ConfigReader config;
- Anope::string engine = config.ReadValue("db_sql", "engine", "", 0);
- this->SQL = service_reference<SQLProvider>("SQLProvider", engine);
- }
-
- void OnServerConnect() anope_override
- {
- 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));
- }
-
- void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) anope_override
- {
- 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());
-
- }
- 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)
- {
- 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());
- }
- }
- }
-
- void OnNickAddAccess(NickCore *nc, const Anope::string &entry) anope_override
- {
- this->Insert(nc->serialize_name(), nc->serialize());
- }
-
- void OnNickEraseAccess(NickCore *nc, const Anope::string &entry) anope_override
- {
- this->Insert(nc->serialize_name(), nc->serialize());
- }
-
- void OnNickClearAccess(NickCore *nc) anope_override
- {
- this->Insert(nc->serialize_name(), nc->serialize());
- }
-
- void OnDelCore(NickCore *nc) anope_override
- {
- this->Delete(nc->serialize_name(), nc->serialize());
- }
-
- void OnNickForbidden(NickAlias *na) anope_override
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void OnNickGroup(User *u, NickAlias *) anope_override
- {
- OnNickRegister(findnick(u->nick));
- }
-
- void InsertAlias(NickAlias *na)
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void InsertCore(NickCore *nc)
- {
- this->Insert(nc->serialize_name(), nc->serialize());
- }
-
- void OnNickRegister(NickAlias *na) anope_override
- {
- this->InsertCore(na->nc);
- this->InsertAlias(na);
- }
-
- void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override
- {
- Serializable::serialized_data data = nc->serialize();
- this->Delete(nc->serialize_name(), data);
- data.erase("display");
- data["display"] << newdisplay;
- this->Insert(nc->serialize_name(), data);
-
- for (std::list<NickAlias *>::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it)
- {
- NickAlias *na = *it;
- data = na->serialize();
-
- this->Delete(na->serialize_name(), data);
- data.erase("nc");
- data["nc"] << newdisplay;
- this->Insert(na->serialize_name(), data);
- }
- }
-
- void OnNickSuspend(NickAlias *na) anope_override
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void OnDelNick(NickAlias *na) anope_override
- {
- this->Delete(na->serialize_name(), na->serialize());
- }
-
- void OnAccessAdd(ChannelInfo *ci, User *, ChanAccess *access) anope_override
- {
- this->Insert(access->serialize_name(), access->serialize());
- }
-
- void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) anope_override
- {
- this->Delete(access->serialize_name(), access->serialize());
- }
-
- void OnAccessClear(ChannelInfo *ci, User *u) anope_override
- {
- 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) anope_override
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnDelChan(ChannelInfo *ci) anope_override
- {
- this->Delete(ci->serialize_name(), ci->serialize());
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnChanSuspend(ChannelInfo *ci) anope_override
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- }
-
- void OnAkickAdd(User *u, ChannelInfo *ci, AutoKick *ak) anope_override
- {
- this->Insert(ak->serialize_name(), ak->serialize());
- }
-
- void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) anope_override
- {
- this->Delete(ak->serialize_name(), ak->serialize());
- }
-
- EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
- {
- this->Insert(lock->serialize_name(), lock->serialize());
- return EVENT_CONTINUE;
- }
-
- EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
- {
- this->Delete(lock->serialize_name(), lock->serialize());
- return EVENT_CONTINUE;
- }
-
- void OnBotCreate(BotInfo *bi) anope_override
- {
- this->Insert(bi->serialize_name(), bi->serialize());
- }
-
- void OnBotChange(BotInfo *bi) anope_override
- {
- OnBotCreate(bi);
- }
-
- void OnBotDelete(BotInfo *bi) anope_override
- {
- this->Delete(bi->serialize_name(), bi->serialize());
- }
-
- EventReturn OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- return EVENT_CONTINUE;
- }
-
- EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) anope_override
- {
- this->Insert(ci->serialize_name(), ci->serialize());
- return EVENT_CONTINUE;
- }
-
- void OnBadWordAdd(ChannelInfo *ci, BadWord *bw) anope_override
- {
- this->Insert(bw->serialize_name(), bw->serialize());
- }
-
- void OnBadWordDel(ChannelInfo *ci, BadWord *bw) anope_override
- {
- this->Delete(bw->serialize_name(), bw->serialize());
- }
-
- void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) anope_override
- {
- this->Insert(m->serialize_name(), m->serialize());
- }
-
- void OnMemoDel(const NickCore *nc, MemoInfo *mi, Memo *m) anope_override
- {
- this->Delete(m->serialize_name(), m->serialize());
- }
-
- void OnMemoDel(ChannelInfo *ci, MemoInfo *mi, Memo *m) anope_override
- {
- this->Delete(m->serialize_name(), m->serialize());
- }
-
- EventReturn OnExceptionAdd(Exception *ex) anope_override
- {
- this->Insert(ex->serialize_name(), ex->serialize());
- return EVENT_CONTINUE;
- }
-
- void OnExceptionDel(User *, Exception *ex) anope_override
- {
- this->Delete(ex->serialize_name(), ex->serialize());
- }
-
- EventReturn OnAddXLine(User *u, XLine *x, XLineManager *xlm) anope_override
- {
- this->Insert(x->serialize_name(), x->serialize());
- return EVENT_CONTINUE;
- }
-
- void OnDelXLine(User *, XLine *x, XLineManager *xlm) anope_override
- {
- this->Delete(x->serialize_name(), x->serialize());
- }
-
- void OnDeleteVhost(NickAlias *na) anope_override
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-
- void OnSetVhost(NickAlias *na) anope_override
- {
- this->Insert(na->serialize_name(), na->serialize());
- }
-};
-
-MODULE_INIT(DBMySQL)
-