1
0
mirror of https://github.com/anope/anope.git synced 2026-07-09 20:43:13 +02:00

Allow modules to store data in their own databases.

This commit is contained in:
Adam
2012-10-01 18:50:29 -04:00
parent f14a3dfb8a
commit a434baed91
33 changed files with 166 additions and 191 deletions
+1 -6
View File
@@ -20,7 +20,7 @@ struct EntryMsg : Serializable
Anope::string message;
time_t when;
EntryMsg(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime)
EntryMsg(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
{
this->ci = c;
this->creator = cname;
@@ -28,11 +28,6 @@ struct EntryMsg : Serializable
this->when = ct;
}
const Anope::string serialize_name() const anope_override
{
return "EntryMsg";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data data;
+1 -6
View File
@@ -33,15 +33,10 @@ struct SeenInfo : Serializable
Anope::string message; // for part/kick/quit
time_t last; // the time when the user was last seen
SeenInfo()
SeenInfo() : Serializable("SeenInfo")
{
}
const Anope::string serialize_name() const anope_override
{
return "SeenInfo";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data data;
+1 -6
View File
@@ -18,15 +18,10 @@ struct CSMiscData : ExtensibleItem, Serializable
Anope::string name;
Anope::string data;
CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : ci(c), name(n), data(d)
CSMiscData(ChannelInfo *c, const Anope::string &n, const Anope::string &d) : Serializable("CSMiscData"), ci(c), name(n), data(d)
{
}
const Anope::string serialize_name() const anope_override
{
return "CSMiscData";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data sdata;
+1 -6
View File
@@ -18,15 +18,10 @@ struct ChanSuspend : ExtensibleItem, Serializable
Anope::string chan;
time_t when;
ChanSuspend()
ChanSuspend() : Serializable("ChanSuspend")
{
}
const Anope::string serialize_name() const
{
return "ChanSuspend";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data sd;
+1 -4
View File
@@ -30,10 +30,7 @@ struct HostRequest : ExtensibleItem, Serializable
Anope::string host;
time_t time;
const Anope::string serialize_name() const anope_override
{
return "HostRequest";
}
HostRequest() : Serializable("HostRequest") { }
Serialize::Data serialize() const anope_override
{
+1 -4
View File
@@ -26,10 +26,7 @@ struct AJoinEntry : Serializable
Anope::string channel;
Anope::string key;
const Anope::string serialize_name() const anope_override
{
return "AJoinEntry";
}
AJoinEntry() : Serializable("AJoinEntry") { }
Serialize::Data serialize() const anope_override
{
+1 -6
View File
@@ -19,15 +19,10 @@ struct NSMiscData : ExtensibleItem, Serializable
Anope::string name;
Anope::string data;
NSMiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : nc(ncore), name(n), data(d)
NSMiscData(NickCore *ncore, const Anope::string &n, const Anope::string &d) : Serializable("NSMiscData"), nc(ncore), name(n), data(d)
{
}
const Anope::string serialize_name() const anope_override
{
return "NSMiscData";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data sdata;
+1 -6
View File
@@ -18,15 +18,10 @@ struct NickSuspend : ExtensibleItem, Serializable
Anope::string nick;
time_t when;
NickSuspend()
NickSuspend() : Serializable("NickSuspend")
{
}
const Anope::string serialize_name() const
{
return "NickSuspend";
}
Serialize::Data serialize() const anope_override
{
Serialize::Data sd;
+1 -1
View File
@@ -18,7 +18,7 @@ struct ForbidData : Serializable
time_t expires;
ForbidType type;
const Anope::string serialize_name() const anope_override { return "ForbidData"; }
ForbidData() : Serializable("ForbidData") { }
Serialize::Data serialize() const anope_override;
static Serializable* unserialize(Serializable *obj, Serialize::Data &data);
};
+1 -1
View File
@@ -17,7 +17,7 @@ struct IgnoreData : Serializable
Anope::string reason;
time_t time; /* When do we stop ignoring them? */
const Anope::string serialize_name() const anope_override { return "IgnoreData"; }
IgnoreData() : Serializable("IgnoreData") { }
Serialize::Data serialize() const anope_override;
static Serializable* unserialize(Serializable *obj, Serialize::Data &data);
};
+1 -1
View File
@@ -22,7 +22,7 @@ struct NewsItem : Serializable
Anope::string who;
time_t time;
const Anope::string serialize_name() const anope_override { return "NewsItem"; }
NewsItem() : Serializable("NewsItem") { }
Serialize::Data serialize() const anope_override;
static Serializable* unserialize(Serializable *obj, Serialize::Data &data);
};
+1 -6
View File
@@ -15,12 +15,7 @@
struct MyOper : Oper, Serializable
{
MyOper(const Anope::string &n, OperType *o) : Oper(n, o) { }
const Anope::string serialize_name() const anope_override
{
return "Oper";
}
MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { }
Serialize::Data serialize() const anope_override
{
+1 -1
View File
@@ -19,7 +19,7 @@ struct Exception : Serializable
time_t time; /* When this exception was added */
time_t expires; /* Time when it expires. 0 == no expiry */
const Anope::string serialize_name() const anope_override { return "Exception"; }
Exception() : Serializable("Exception") { }
Serialize::Data serialize() const anope_override;
static Serializable* unserialize(Serializable *obj, Serialize::Data &data);
};
+1 -4
View File
@@ -15,10 +15,7 @@
struct Stats : Serializable
{
const Anope::string serialize_name() const
{
return "Stats";
}
Stats() : Serializable("Stats") { }
Serialize::Data serialize() const anope_override
{
+73 -34
View File
@@ -82,42 +82,58 @@ class DBFlatFile : public Module
EventReturn OnLoadDatabase() anope_override
{
std::fstream db;
db.open(DatabaseFile.c_str(), std::ios_base::in);
std::map<Module *, std::fstream *> databases;
databases[NULL] = new std::fstream(DatabaseFile.c_str(), std::ios_base::in);
if (!db.is_open())
if (!databases[NULL]->is_open())
{
delete databases[NULL];
Log() << "Unable to open " << DatabaseFile << " for reading!";
return EVENT_CONTINUE;
}
SerializeType *st = NULL;
Serialize::Data data;
std::multimap<SerializeType *, Serialize::Data> objects;
for (Anope::string buf, token; std::getline(db, buf.str());)
const std::vector<Anope::string> type_order = SerializeType::GetTypeOrder();
for (unsigned i = 0; i < type_order.size(); ++i)
{
spacesepstream sep(buf);
if (!sep.GetToken(token))
continue;
if (token == "OBJECT" && sep.GetToken(token))
SerializeType *stype = SerializeType::Find(type_order[i]);
if (stype && !databases.count(stype->GetOwner()))
{
st = SerializeType::Find(token);
data.clear();
}
else if (token == "DATA" && st != NULL && sep.GetToken(token))
data[token] << sep.GetRemaining();
else if (token == "END" && st != NULL)
{
objects.insert(std::make_pair(st, data));
st = NULL;
data.clear();
Anope::string db_name = db_dir + "/module_" + stype->GetOwner()->name + ".db";
databases[stype->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::in);
}
}
std::multimap<SerializeType *, Serialize::Data> objects;
for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it)
{
std::fstream *db = it->second;
SerializeType *st = NULL;
Serialize::Data data;
for (Anope::string buf, token; std::getline(*db, buf.str());)
{
spacesepstream sep(buf);
if (!sep.GetToken(token))
continue;
if (token == "OBJECT" && sep.GetToken(token))
{
st = SerializeType::Find(token);
data.clear();
}
else if (token == "DATA" && st != NULL && sep.GetToken(token))
data[token] << sep.GetRemaining();
else if (token == "END" && st != NULL)
{
objects.insert(std::make_pair(st, data));
st = NULL;
data.clear();
}
}
}
const std::vector<Anope::string> type_order = SerializeType::GetTypeOrder();
for (unsigned i = 0; i < type_order.size(); ++i)
{
SerializeType *stype = SerializeType::Find(type_order[i]);
@@ -129,7 +145,11 @@ class DBFlatFile : public Module
it->first->Unserialize(NULL, it->second);
}
db.close();
for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it)
{
it->second->close();
delete it->second;
}
return EVENT_STOP;
}
@@ -143,9 +163,11 @@ class DBFlatFile : public Module
if (IsFile(DatabaseFile))
rename(DatabaseFile.c_str(), tmp_db.c_str());
std::fstream db(DatabaseFile.c_str(), std::ios_base::out | std::ios_base::trunc);
if (!db.is_open())
std::map<Module *, std::fstream *> databases;
databases[NULL] = new std::fstream(DatabaseFile.c_str(), std::ios_base::out | std::ios_base::trunc);
if (!databases[NULL]->is_open())
{
delete databases[NULL];
Log() << "Unable to open " << DatabaseFile << " for writing";
if (IsFile(tmp_db))
rename(tmp_db.c_str(), DatabaseFile.c_str());
@@ -156,19 +178,30 @@ class DBFlatFile : public Module
for (std::list<Serializable *>::const_iterator it = items.begin(), it_end = items.end(); it != it_end; ++it)
{
Serializable *base = *it;
SerializeType *s_type = base->GetSerializableType();
if (!s_type)
continue;
Serialize::Data data = base->serialize();
if (!databases.count(s_type->GetOwner()))
{
Anope::string db_name = db_dir + "/module_" + s_type->GetOwner()->name + ".db";
databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc);
}
std::fstream *fd = databases[s_type->GetOwner()];
db << "OBJECT " << base->serialize_name() << "\n";
*fd << "OBJECT " << s_type->GetName() << "\n";
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";
*fd << "DATA " << dit->first << " " << dit->second.astr() << "\n";
*fd << "END\n";
}
db.close();
if (db.good() == false)
if (databases[NULL]->good() == false)
{
Log() << "Unable to write database";
databases[NULL]->close();
if (!Config->NoBackupOkay)
quitting = true;
if (IsFile(tmp_db))
@@ -177,6 +210,12 @@ class DBFlatFile : public Module
else
unlink(tmp_db.c_str());
for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it)
{
it->second->close();
delete it->second;
}
return EVENT_CONTINUE;
}
};
+9 -3
View File
@@ -105,13 +105,17 @@ class DBSQL : public Module, public Pipe
continue;
obj->UpdateCache();
SerializeType *s_type = obj->GetSerializableType();
if (!s_type)
continue;
Serialize::Data data = obj->serialize();
std::vector<SQLQuery> create = this->sql->CreateTable(this->prefix + obj->serialize_name(), data);
std::vector<SQLQuery> create = this->sql->CreateTable(this->prefix + s_type->GetName(), data);
for (unsigned i = 0; i < create.size(); ++i)
this->RunBackground(create[i]);
SQLQuery insert = this->sql->BuildInsert(this->prefix + obj->serialize_name(), obj->id, data);
SQLQuery insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, data);
this->RunBackground(insert, new ResultSQLSQLInterface(this, obj));
}
}
@@ -188,7 +192,9 @@ class DBSQL : public Module, public Pipe
void OnSerializableDestruct(Serializable *obj) anope_override
{
this->RunBackground("DELETE FROM `" + this->prefix + obj->serialize_name() + "` WHERE `id` = " + stringify(obj->id));
SerializeType *s_type = obj->GetSerializableType();
if (s_type)
this->RunBackground("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id));
}
void OnSerializableUpdate(Serializable *obj) anope_override
+14 -11
View File
@@ -95,18 +95,20 @@ class DBMySQL : public Module, public Pipe
continue;
obj->UpdateCache();
SerializeType *s_type = obj->GetSerializableType();
if (!s_type)
continue;
Serialize::Data data = obj->serialize();
std::vector<SQLQuery> create = this->SQL->CreateTable(this->prefix + obj->serialize_name(), data);
std::vector<SQLQuery> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), data);
for (unsigned i = 0; i < create.size(); ++i)
this->RunQueryResult(create[i]);
SQLResult res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + obj->serialize_name(), obj->id, data));
SQLResult res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, data));
if (res.GetID() > 0)
obj->id = res.GetID();
SerializeType *stype = SerializeType::Find(obj->serialize_name());
if (stype)
stype->objects.erase(obj->id);
s_type->objects.erase(obj->id);
}
}
@@ -144,15 +146,16 @@ class DBMySQL : public Module, public Pipe
{
if (!this->CheckInit())
return;
this->RunQuery("DELETE FROM `" + this->prefix + obj->serialize_name() + "` WHERE `id` = " + stringify(obj->id));
SerializeType *stype = SerializeType::Find(obj->serialize_name());
if (stype)
stype->objects.erase(obj->id);
SerializeType *s_type = obj->GetSerializableType();
if (!s_type)
return;
this->RunQuery("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id));
s_type->objects.erase(obj->id);
}
void OnSerializePtrAssign(Serializable *obj) anope_override
{
SerializeType *stype = SerializeType::Find(obj->serialize_name());
SerializeType *stype = obj->GetSerializableType();
if (stype == NULL || !this->CheckInit() || stype->GetTimestamp() == Anope::CurTime)
return;
@@ -160,7 +163,7 @@ class DBMySQL : public Module, public Pipe
return;
obj->UpdateCache();
SQLResult res = this->RunQueryResult("SELECT * FROM `" + this->prefix + obj->serialize_name() + "` WHERE `id` = " + stringify(obj->id));
SQLResult res = this->RunQueryResult("SELECT * FROM `" + this->prefix + stype->GetName() + "` WHERE `id` = " + stringify(obj->id));
if (res.Rows() == 0)
obj->destroy();
+1 -1
View File
@@ -875,7 +875,7 @@ struct IRCDMessageRSQuit : IRCDMessage
else
s = Server::Find(params[0]);
source.GetServer()->Delete(source.GetServer()->GetName() + " " + source.GetServer()->GetUplink()->GetName());
source.GetServer()->Delete(source.GetServer()->GetName() + " " + (s ? s->GetName() : "<unknown>"));
return true;
}