summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h3
-rw-r--r--include/serialize.h35
-rw-r--r--modules/commands/os_dns.cpp83
-rw-r--r--modules/database/db_flatfile.cpp40
-rw-r--r--modules/database/db_sql.cpp69
-rw-r--r--src/serialize.cpp53
6 files changed, 146 insertions, 137 deletions
diff --git a/include/modules.h b/include/modules.h
index 09df6617e..eba0138b8 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -935,6 +935,7 @@ class CoreExport Module : public Extensible
virtual void OnSerializableConstruct(Serializable *) { }
virtual void OnSerializableDestruct(Serializable *) { }
virtual void OnSerializableUpdate(Serializable *) { }
+ virtual void OnSerializeTypeCreate(Serialize::Type *) { }
/** Called when a chanserv/set command is used
* @param source The source of the command
@@ -1013,7 +1014,7 @@ enum Implementation
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnLog, I_OnDnsRequest,
I_OnMessage,
- I_OnSerializeCheck, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate,
+ I_OnSerializeCheck, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate, I_OnSerializeTypeCreate,
I_END
};
diff --git a/include/serialize.h b/include/serialize.h
index 1a16e5b35..edbf1facf 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -188,52 +188,49 @@ class Serialize::Checker
{
Anope::string name;
T obj;
+ mutable Serialize::Type *type;
+
+ inline void Check() const
+ {
+ if (!type)
+ type = Serialize::Type::Find(this->name);
+ if (type)
+ type->Check();
+ }
public:
- Checker(const Anope::string &n) : name(n) { }
+ Checker(const Anope::string &n) : name(n), type(NULL) { }
inline const T* operator->() const
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return &this->obj;
}
inline T* operator->()
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return &this->obj;
}
inline const T& operator*() const
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return this->obj;
}
inline T& operator*()
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return this->obj;
}
inline operator const T&() const
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return this->obj;
}
inline operator T&()
{
- static Serialize::Type *type = Serialize::Type::Find(this->name);
- if (type)
- type->Check();
+ this->Check();
return this->obj;
}
};
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp
index d825851f3..ab8e412be 100644
--- a/modules/commands/os_dns.cpp
+++ b/modules/commands/os_dns.cpp
@@ -13,8 +13,8 @@ static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager");
class DNSZone;
class DNSServer;
-static std::vector<DNSZone *> zones;
-static std::vector<DNSServer *> dns_servers;
+static Serialize::Checker<std::vector<DNSZone *> > zones("DNSZone");
+static Serialize::Checker<std::vector<DNSServer *> > dns_servers("DNSServer");
static std::map<Anope::string, std::list<time_t> > server_quit_times;
@@ -25,14 +25,14 @@ struct DNSZone : Serializable
DNSZone(const Anope::string &n) : Serializable("DNSZone"), name(n)
{
- zones.push_back(this);
+ zones->push_back(this);
}
~DNSZone()
{
- std::vector<DNSZone *>::iterator it = std::find(zones.begin(), zones.end(), this);
- if (it != zones.end())
- zones.erase(it);
+ std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this);
+ if (it != zones->end())
+ zones->erase(it);
}
void Serialize(Serialize::Data &data) const anope_override
@@ -73,9 +73,13 @@ struct DNSZone : Serializable
static DNSZone *Find(const Anope::string &name)
{
- for (unsigned i = 0; i < zones.size(); ++i)
- if (zones[i]->name.equals_ci(name))
- return zones[i];
+ for (unsigned i = 0; i < zones->size(); ++i)
+ if (zones->at(i)->name.equals_ci(name))
+ {
+ DNSZone *z = zones->at(i);
+ z->QueueUpdate();
+ return z;
+ }
return NULL;
}
};
@@ -96,14 +100,14 @@ class DNSServer : public Serializable
DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), active(false), repool(0)
{
- dns_servers.push_back(this);
+ dns_servers->push_back(this);
}
~DNSServer()
{
- std::vector<DNSServer *>::iterator it = std::find(dns_servers.begin(), dns_servers.end(), this);
- if (it != dns_servers.end())
- dns_servers.erase(it);
+ std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this);
+ if (it != dns_servers->end())
+ dns_servers->erase(it);
}
const Anope::string &GetName() const { return server_name; }
@@ -177,9 +181,13 @@ class DNSServer : public Serializable
static DNSServer *Find(const Anope::string &s)
{
- for (unsigned i = 0; i < dns_servers.size(); ++i)
- if (dns_servers[i]->GetName() == s)
- return dns_servers[i];
+ for (unsigned i = 0; i < dns_servers->size(); ++i)
+ if (dns_servers->at(i)->GetName() == s)
+ {
+ DNSServer *serv = dns_servers->at(i);
+ serv->QueueUpdate();
+ return serv;
+ }
return NULL;
}
};
@@ -188,7 +196,7 @@ class CommandOSDNS : public Command
{
void DisplayPoolState(CommandSource &source)
{
- if (dns_servers.empty())
+ if (dns_servers->empty())
{
source.Reply(_("There are no configured servers."));
return;
@@ -196,9 +204,9 @@ class CommandOSDNS : public Command
ListFormatter lf;
lf.AddColumn("Server").AddColumn("IP").AddColumn("Limit").AddColumn("State");
- for (unsigned i = 0; i < dns_servers.size(); ++i)
+ for (unsigned i = 0; i < dns_servers->size(); ++i)
{
- DNSServer *s = dns_servers[i];
+ DNSServer *s = dns_servers->at(i);
Server *srv = Server::Find(s->GetName());
ListFormatter::ListEntry entry;
@@ -228,14 +236,14 @@ class CommandOSDNS : public Command
std::vector<Anope::string> replies;
lf.Process(replies);
- if (!zones.empty())
+ if (!zones->empty())
{
ListFormatter lf2;
lf2.AddColumn("Zone").AddColumn("Servers");
- for (unsigned i = 0; i < zones.size(); ++i)
+ for (unsigned i = 0; i < zones->size(); ++i)
{
- DNSZone *z = zones[i];
+ const DNSZone *z = zones->at(i);
ListFormatter::ListEntry entry;
entry["Zone"] = z->name;
@@ -297,7 +305,7 @@ class CommandOSDNS : public Command
}
source.Reply(_("Zone %s removed."), z->name.c_str());
- delete z;
+ z->Destroy();
}
void AddServer(CommandSource &source, const std::vector<Anope::string> &params)
@@ -355,7 +363,7 @@ class CommandOSDNS : public Command
if (!z)
{
source.Reply(_("Zone %s does not exist."), zone.c_str());
- delete s;
+ s->Destroy();
return;
}
@@ -411,7 +419,7 @@ class CommandOSDNS : public Command
Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName();
source.Reply(_("Removed server %s."), s->GetName().c_str());
- delete s;
+ s->Destroy();
}
void AddIP(CommandSource &source, const std::vector<Anope::string> &params)
@@ -630,7 +638,7 @@ class CommandOSDNS : public Command
" \n"
"The \2ADDIP\2 command associates an IP with a server.\n"
" \n"
- "The \2POOL\2 and \2DEPOOL\2 commands actually add and remove servers to their given zones.\b"));
+ "The \2POOL\2 and \2DEPOOL\2 commands actually add and remove servers to their given zones."));
return true;
}
};
@@ -657,14 +665,21 @@ class ModuleDNS : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
this->OnReload();
+
+ for (unsigned j = 0; j < dns_servers->size(); ++j)
+ {
+ DNSServer *s = dns_servers->at(j);
+ if (s->Pooled() && Server::Find(s->GetName()))
+ s->SetActive(true);
+ }
}
~ModuleDNS()
{
- for (unsigned i = 0; i < zones.size(); ++i)
- delete zones[i];
- for (unsigned i = 0; i < dns_servers.size(); ++i)
- delete dns_servers[i];
+ for (unsigned i = zones->size(); i > 0; --i)
+ delete zones->at(i - 1);
+ for (unsigned i = dns_servers->size(); i > 0; --i)
+ delete dns_servers->at(i - 1);
}
void OnReload() anope_override
@@ -800,9 +815,9 @@ class ModuleDNS : public Module
if (packet->answers.size() == answer_size)
{
/* Default zone */
- for (unsigned i = 0; i < dns_servers.size(); ++i)
+ for (unsigned i = 0; i < dns_servers->size(); ++i)
{
- DNSServer *s = dns_servers[i];
+ DNSServer *s = dns_servers->at(i);
if (!s->Active())
continue;
@@ -831,9 +846,9 @@ class ModuleDNS : public Module
}
/* Something messed up, just return them all and hope one is available */
- for (unsigned i = 0; i < dns_servers.size(); ++i)
+ for (unsigned i = 0; i < dns_servers->size(); ++i)
{
- DNSServer *s = dns_servers[i];
+ DNSServer *s = dns_servers->at(i);
for (unsigned j = 0; j < s->GetIPs().size(); ++j)
{
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
index 66715b9f8..3aaadd7c0 100644
--- a/modules/database/db_flatfile.cpp
+++ b/modules/database/db_flatfile.cpp
@@ -73,6 +73,7 @@ class DBFlatFile : public Module, public Pipe
/* Backup file names */
std::map<Anope::string, std::list<Anope::string> > backups;
bool use_fork;
+ bool loaded;
void BackupDatabase()
{
@@ -128,11 +129,11 @@ class DBFlatFile : public Module, public Pipe
}
public:
- DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), last_day(0), use_fork(false)
+ DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), last_day(0), use_fork(false), loaded(false)
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase };
+ Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
OnReload();
@@ -208,6 +209,7 @@ class DBFlatFile : public Module, public Pipe
fd.close();
+ loaded = true;
return EVENT_STOP;
}
@@ -306,6 +308,40 @@ class DBFlatFile : public Module, public Pipe
return EVENT_CONTINUE;
}
+
+ /* Load just one type. Done if a module is reloaded during runtime */
+ void OnSerializeTypeCreate(Serialize::Type *stype) anope_override
+ {
+ if (!loaded)
+ return;
+
+ Anope::string db_name;
+ if (stype->GetOwner())
+ db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db";
+ else
+ db_name = Anope::DataDir + "/" + database_file;
+
+ std::fstream fd(db_name.c_str(), std::ios_base::in);
+ if (!fd.is_open())
+ {
+ Log(this) << "Unable to open " << db_name << " for reading!";
+ return;
+ }
+
+ LoadData ld;
+ ld.fs = &fd;
+
+ for (Anope::string buf; std::getline(fd, buf.str());)
+ {
+ if (buf == "OBJECT " + stype->GetName())
+ {
+ stype->Unserialize(NULL, ld);
+ ld.Reset();
+ }
+ }
+
+ fd.close();
+ }
};
MODULE_INIT(DBFlatFile)
diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp
index 56db7b8a0..457c6b304 100644
--- a/modules/database/db_sql.cpp
+++ b/modules/database/db_sql.cpp
@@ -62,6 +62,7 @@ class DBSQL : public Module, public Pipe
std::set<Reference<Serializable> > updated_items;
bool shutting_down;
bool loading_databases;
+ bool loaded;
void RunBackground(const Query &q, Interface *iface = NULL)
{
@@ -85,11 +86,11 @@ class DBSQL : public Module, public Pipe
}
public:
- DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false)
+ DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false), loaded(false)
{
this->SetAuthor("Anope");
- Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate };
+ Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate, I_OnSerializeTypeCreate };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
this->OnReload();
@@ -163,37 +164,11 @@ class DBSQL : public Module, public Pipe
for (unsigned i = 0; i < type_order.size(); ++i)
{
Serialize::Type *sb = Serialize::Type::Find(type_order[i]);
-
- Query query("SELECT * FROM `" + this->prefix + sb->GetName() + "`");
- Result res = this->sql->RunQuery(query);
-
- for (int j = 0; j < res.Rows(); ++j)
- {
- Data *data = new 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;
-
- Serializable *obj = sb->Unserialize(NULL, *data);
- try
- {
- if (obj)
- obj->id = convertTo<unsigned int>(res.Get(j, "id"));
- }
- catch (const ConvertException &)
- {
- Log(this) << "Unable to convert id for object #" << j << " of type " << sb->GetName();
- }
-
- if (obj)
- obj->UpdateCache(data); /* We know this is the most up to date copy */
- else
- delete data;
- }
+ this->OnSerializeTypeCreate(sb);
}
this->loading_databases = false;
+ this->loaded = true;
return EVENT_STOP;
}
@@ -221,6 +196,40 @@ class DBSQL : public Module, public Pipe
this->updated_items.insert(obj);
this->Notify();
}
+
+ void OnSerializeTypeCreate(Serialize::Type *sb) anope_override
+ {
+ if (!this->loading_databases && !this->loaded)
+ return;
+
+ Query query("SELECT * FROM `" + this->prefix + sb->GetName() + "`");
+ Result res = this->sql->RunQuery(query);
+
+ for (int j = 0; j < res.Rows(); ++j)
+ {
+ Data *data = new 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;
+
+ Serializable *obj = sb->Unserialize(NULL, *data);
+ try
+ {
+ if (obj)
+ obj->id = convertTo<unsigned int>(res.Get(j, "id"));
+ }
+ catch (const ConvertException &)
+ {
+ Log(this) << "Unable to convert id for object #" << j << " of type " << sb->GetName();
+ }
+
+ if (obj)
+ obj->UpdateCache(data); /* We know this is the most up to date copy */
+ else
+ delete data;
+ }
+ }
};
MODULE_INIT(DBSQL)
diff --git a/src/serialize.cpp b/src/serialize.cpp
index 0f3e6c7a6..0fff92fab 100644
--- a/src/serialize.cpp
+++ b/src/serialize.cpp
@@ -35,57 +35,6 @@ void Serialize::RegisterTypes()
memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize);
}
-/*stringstream::stringstream() : std::stringstream(), type(Serialize::DT_TEXT), _max(0)
-{
-}
-
-stringstream::stringstream(const stringstream &ss) : std::stringstream(ss.str()), type(Serialize::DT_TEXT), _max(0)
-{
-}
-
-Anope::string stringstream::astr() const
-{
- return this->str();
-}
-
-std::istream &stringstream::operator>>(Anope::string &val)
-{
- val = this->str();
- return *this;
-}
-
-bool stringstream::operator==(const stringstream &other) const
-{
- return this->astr() == other.astr();
-}
-
-bool stringstream::operator!=(const stringstream &other) const
-{
- return !(*this == other);
-}
-
-stringstream &stringstream::SetType(Serialize::DataType t)
-{
- this->type = t;
- return *this;
-}
-
-DataType Serialize::stringstream::GetType() const
-{
- return this->type;
-}
-
-stringstream &stringstream::SetMax(unsigned m)
-{
- this->_max = m;
- return *this;
-}
-
-unsigned stringstream::GetMax() const
-{
- return this->_max;
-}*/
-
Serializable::Serializable() : last_commit(NULL), last_commit_time(0), id(0)
{
throw CoreException("Default Serializable constructor?");
@@ -175,6 +124,8 @@ Type::Type(const Anope::string &n, unserialize_func f, Module *o) : name(n), un
{
TypeOrder.push_back(this->name);
Types[this->name] = this;
+
+ FOREACH_MOD(I_OnSerializeTypeCreate, OnSerializeTypeCreate(this));
}
Type::~Type()