summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2016-10-15 16:25:57 -0400
committerAdam <Adam@anope.org>2016-10-15 16:25:57 -0400
commit1ba242179fee46583098f48421af39ce9a8985a1 (patch)
treea276cd7bd53e7270c86ab3744bd6a568a016501b
parent696239e93391f3dfd6459857fb02a6006048093a (diff)
Various improvements/bugfixes to extdb stuff
-rw-r--r--include/config.h8
-rw-r--r--include/modules/sql.h4
-rw-r--r--include/serialize.h76
-rw-r--r--include/users.h1
-rw-r--r--include/xline.h2
-rw-r--r--modules/botserv/assign.cpp4
-rw-r--r--modules/botserv/bot.cpp26
-rw-r--r--modules/botserv/info.cpp7
-rw-r--r--modules/botserv/set.cpp2
-rw-r--r--modules/chanserv/main/channeltype.cpp8
-rw-r--r--modules/chanserv/main/channeltype.h2
-rw-r--r--modules/chanserv/main/chanserv.cpp16
-rw-r--r--modules/database/old.cpp4
-rw-r--r--modules/database/sql.cpp184
-rw-r--r--modules/extra/mysql.cpp82
-rw-r--r--modules/extra/sqlite.cpp124
-rw-r--r--modules/nickserv/cert.cpp19
-rw-r--r--modules/nickserv/main/accounttype.cpp13
-rw-r--r--modules/nickserv/main/accounttype.h2
-rw-r--r--modules/nickserv/main/nickserv.cpp9
-rw-r--r--modules/nickserv/main/nicktype.cpp9
-rw-r--r--modules/nickserv/main/nicktype.h2
-rw-r--r--src/bots.cpp21
-rw-r--r--src/config.cpp169
-rw-r--r--src/init.cpp3
-rw-r--r--src/service_manager.cpp8
-rw-r--r--src/xline.cpp3
27 files changed, 426 insertions, 382 deletions
diff --git a/include/config.h b/include/config.h
index dccadbe79..b6b36b726 100644
--- a/include/config.h
+++ b/include/config.h
@@ -102,8 +102,9 @@ namespace Configuration
struct Usermode;
struct Channelmode;
- struct CoreExport Conf : Block
+ class CoreExport Conf : public Block
{
+ public:
/* options:readtimeout */
time_t ReadTimeout;
/* options:useprivmsg */
@@ -162,6 +163,11 @@ namespace Configuration
ServiceBot *GetClient(const Anope::string &name);
Block *GetCommand(CommandSource &);
+
+ void LoadBots();
+ void ApplyBots();
+
+ void LoadOpers();
};
struct Uplink
diff --git a/include/modules/sql.h b/include/modules/sql.h
index 2e84db152..6770f407e 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -202,8 +202,8 @@ namespace SQL
virtual std::vector<Query> InitSchema(const Anope::string &prefix) anope_abstract;
virtual std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) anope_abstract;
- virtual std::vector<Query> CreateTable(const Anope::string &prefix, const Anope::string &table) anope_abstract;
- virtual std::vector<Query> AlterTable(const Anope::string &, const Anope::string &table, const Anope::string &field, bool object) anope_abstract;
+ virtual std::vector<Query> CreateTable(const Anope::string &prefix, Serialize::TypeBase *) anope_abstract;
+ virtual std::vector<Query> AlterTable(const Anope::string &, Serialize::TypeBase *, Serialize::FieldBase *) anope_abstract;
virtual std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) anope_abstract;
virtual Query BeginTransaction() anope_abstract;
diff --git a/include/serialize.h b/include/serialize.h
index 1d0fb9400..8f35e61c6 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -49,6 +49,9 @@ namespace Serialize
inline T GetObject();
template<typename T>
+ inline std::vector<T> GetObjects_(TypeBase *);
+
+ template<typename T>
inline std::vector<T> GetObjects(const Anope::string &name);
template<typename T>
@@ -235,29 +238,6 @@ class CoreExport Serialize::TypeBase : public Service
*/
const Anope::string &GetName() { return this->name; }
- /**
- * Get all objects of the given type
- */
- template<typename T>
- std::vector<T> List()
- {
- std::vector<ID> ids;
- EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeList, this, ids);
- if (result == EVENT_ALLOW)
- {
- std::vector<T> o;
- for (ID id : ids)
- {
- Object *s = Require(id);
- if (s)
- o.push_back(anope_dynamic_static_cast<T>(s));
- }
- return o;
- }
-
- return GetObjects<T>();
- }
-
/** Create a new object of this type.
*/
virtual Object *Create() anope_abstract;
@@ -306,7 +286,10 @@ class Serialize::Type : public Base
return new T(this, id);
if (s->GetSerializableType() != this)
+ {
+ Log(LOG_DEBUG) << "Mismatch for required id " << id << ", is of type " << s->GetSerializableType()->GetName() << " but wants " << this->GetName();
return nullptr;
+ }
return static_cast<T *>(s);
}
@@ -387,6 +370,8 @@ class Serialize::FieldBase : public Service
*/
bool depends;
+ bool object = false;
+
FieldBase(Module *, const Anope::string &, const Anope::string &, bool);
virtual ~FieldBase();
void Unregister();
@@ -592,7 +577,10 @@ class Serialize::Field : public CommonFieldBase<TypeImpl, T>
// module returned us data, so we unserialize it
T t2 = this->Unserialize(value);
+ // should cache the default value somehow, but can't differentiate not cached from cached and default
+
// Cache
+ OnSet(s, t2);
this->Set_(s, t2);
return t2;
@@ -609,11 +597,18 @@ class Serialize::Field : public CommonFieldBase<TypeImpl, T>
SetField(this->Upcast(s), value);
}
- virtual void SetField(TypeImpl *s, const T &value)
+ /**
+ * Override to hook to changes in the internally
+ * cached value
+ */
+ virtual void OnSet(TypeImpl *s, const T &value) { }
+
+ void SetField(TypeImpl *s, const T &value)
{
Anope::string strvalue = this->Serialize(value);
EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeSet, s, this, strvalue);
+ OnSet(s, value);
this->Set_(s, value);
}
@@ -697,10 +692,12 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
public:
ObjectField(TypeBase *t, const Anope::string &n, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, d)
{
+ this->object = true;
}
ObjectField(TypeBase *t, const Anope::string &n, T TypeImpl::*field, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, field, d)
{
+ this->object = true;
}
T GetField(TypeImpl *s)
@@ -723,6 +720,7 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
T t2 = result == EVENT_ALLOW ? static_cast<T>(base->Require(sid)) : nullptr;
+ OnSet(s, t2);
this->Set_(s, t2);
return t2;
@@ -739,7 +737,9 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
SetField(this->Upcast(s), value);
}
- virtual void SetField(TypeImpl *s, T value)
+ virtual void OnSet(TypeImpl *s, T value) { }
+
+ void SetField(TypeImpl *s, T value)
{
EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeSetSerializable, s, this, value);
@@ -747,6 +747,7 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
if (old != nullptr && *old != nullptr)
s->RemoveEdge(*old, this);
+ OnSet(s, value);
this->Set_(s, value);
if (value != nullptr)
@@ -812,13 +813,34 @@ T Serialize::GetObject()
}
template<typename T>
+std::vector<T> Serialize::GetObjects_(TypeBase *type)
+{
+ std::vector<T> o;
+ std::vector<ID> ids;
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeList, type, ids);
+ if (result == EVENT_ALLOW)
+ {
+ for (ID id : ids)
+ {
+ Object *s = type->Require(id);
+ if (s)
+ o.push_back(anope_dynamic_static_cast<T>(s));
+ }
+ return o;
+ }
+
+ std::transform(type->objects.begin(), type->objects.end(), std::back_inserter(o), [](Object *e) { return anope_dynamic_static_cast<T>(e); });
+ return o;
+}
+
+template<typename T>
std::vector<T> Serialize::GetObjects(const Anope::string &name)
{
std::vector<T> objs;
for (TypeBase *t : GetTypes(name))
- for (Object *s : t->objects)
- objs.push_back(anope_dynamic_static_cast<T>(s));
+ for (T obj : GetObjects_<T>(t))
+ objs.push_back(obj);
return objs;
}
diff --git a/include/users.h b/include/users.h
index dacb7045e..be4ee2a39 100644
--- a/include/users.h
+++ b/include/users.h
@@ -38,7 +38,6 @@ extern CoreExport int OperCount;
enum class UserType
{
USER,
- //LOCAL_USER,
BOT
};
diff --git a/include/xline.h b/include/xline.h
index 87b64d1da..05ddbe2d3 100644
--- a/include/xline.h
+++ b/include/xline.h
@@ -87,7 +87,7 @@ class XLineType : public Serialize::Type<XLine>
{
using Serialize::Field<XLine, Anope::string>::Field;
- void SetField(XLine *s, const Anope::string &value) override;
+ void OnSet(XLine *s, const Anope::string &value) override;
} mask;
Serialize::Field<XLine, Anope::string> by, reason, id;
Serialize::Field<XLine, time_t> created, expires;
diff --git a/modules/botserv/assign.cpp b/modules/botserv/assign.cpp
index eb6b8da10..a26b869fe 100644
--- a/modules/botserv/assign.cpp
+++ b/modules/botserv/assign.cpp
@@ -67,7 +67,7 @@ class CommandBSAssign : public Command
return;
}
- if (bi->bi->GetOperOnly() && !source.HasPriv("botserv/administration"))
+ if (bi->bi && bi->bi->GetOperOnly() && !source.HasPriv("botserv/administration"))
{
source.Reply(_("Access denied. Bot \002{0}\002 is for operators only."), bi->nick);
return;
@@ -265,7 +265,7 @@ class BSAssign : public Module
return;
}
- if (bi->bi->GetOperOnly() && !source->HasPriv("botserv/administration"))
+ if (bi->bi && bi->bi->GetOperOnly() && !source->HasPriv("botserv/administration"))
{
targ->SendMessage(bi, _("Access denied. Bot \002{0}\002 is for operators only."), bi->nick);
return;
diff --git a/modules/botserv/bot.cpp b/modules/botserv/bot.cpp
index c93c4cf50..2e33b7ccb 100644
--- a/modules/botserv/bot.cpp
+++ b/modules/botserv/bot.cpp
@@ -93,6 +93,16 @@ class CommandBSBot : public Command
ServiceBot *bi = new ServiceBot(nick, user, host, real);
+ BotInfo *botinfo = Serialize::New<BotInfo *>();
+ botinfo->SetNick(nick);
+ botinfo->SetUser(user);
+ botinfo->SetHost(host);
+ botinfo->SetRealName(real);
+ botinfo->SetCreated(Anope::CurTime);
+
+ bi->bi = botinfo;
+ botinfo->bot = bi;
+
Log(LOG_ADMIN, source, this) << "ADD " << bi->GetMask() << " " << bi->realname;
source.Reply(_("\002{0}!{1}@{2}\002 (\002{3}\002) added to the bot list."), bi->nick, bi->GetIdent(), bi->host, bi->realname);
@@ -121,7 +131,7 @@ class CommandBSBot : public Command
return;
}
- if (bi->bi->conf)
+ if (bi->bi && bi->bi->conf)
{
source.Reply(_("Bot \002{0}\002 is not changeable because it is configured in services configuration."), bi->nick.c_str());
return;
@@ -226,23 +236,27 @@ class CommandBSBot : public Command
if (!nick.equals_cs(bi->nick))
{
bi->SetNewNick(nick);
- bi->bi->SetNick(nick);
+ if (bi->bi != nullptr)
+ bi->bi->SetNick(nick);
}
if (!user.equals_cs(bi->GetIdent()))
{
bi->SetIdent(user);
- bi->bi->SetUser(user);
+ if (bi->bi != nullptr)
+ bi->bi->SetUser(user);
}
if (!host.equals_cs(bi->host))
{
bi->host = host;
- bi->bi->SetHost(host);
+ if (bi->bi != nullptr)
+ bi->bi->SetHost(host);
}
if (real.equals_cs(bi->realname))
{
bi->realname = real;
- bi->bi->SetRealName(real);
+ if (bi->bi != nullptr)
+ bi->bi->SetRealName(real);
}
if (!user.empty())
@@ -271,7 +285,7 @@ class CommandBSBot : public Command
return;
}
- if (bi->bi->conf)
+ if (bi->bi && bi->bi->conf)
{
source.Reply(_("Bot \002{0}\002 is can not be deleted because it is configured in services configuration."), bi->nick);
return;
diff --git a/modules/botserv/info.cpp b/modules/botserv/info.cpp
index 94b1bbbd7..4de86643f 100644
--- a/modules/botserv/info.cpp
+++ b/modules/botserv/info.cpp
@@ -41,8 +41,11 @@ class CommandBSInfo : public Command
source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
info[_("Real name")] = bi->realname;
- info[_("Created")] = Anope::strftime(bi->bi->GetCreated(), source.GetAccount());
- info[_("Options")] = bi->bi->GetOperOnly() ? _("Private") : _("None");
+ if (bi->bi)
+ {
+ info[_("Created")] = Anope::strftime(bi->bi->GetCreated(), source.GetAccount());
+ info[_("Options")] = bi->bi->GetOperOnly() ? _("Private") : _("None");
+ }
info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
EventManager::Get()->Dispatch(&Event::ServiceBotEvent::OnServiceBot, source, bi, ci, info);
diff --git a/modules/botserv/set.cpp b/modules/botserv/set.cpp
index 47c5337d2..bb432e3f0 100644
--- a/modules/botserv/set.cpp
+++ b/modules/botserv/set.cpp
@@ -174,7 +174,7 @@ class CommandBSSetPrivate : public Command
source.Reply(_("Services are in read-only mode. Any changes made may not persist."));
ServiceBot *bi = ServiceBot::Find(nick, true);
- if (bi == NULL)
+ if (bi == NULL || !bi->bi)
{
source.Reply(_("Bot \002{0}\002 does not exist."), nick);
return;
diff --git a/modules/chanserv/main/channeltype.cpp b/modules/chanserv/main/channeltype.cpp
index fa5e03e4c..37c290ef1 100644
--- a/modules/chanserv/main/channeltype.cpp
+++ b/modules/chanserv/main/channeltype.cpp
@@ -37,12 +37,12 @@ ChannelType::ChannelType(Module *me) : Serialize::Type<ChannelImpl>(me)
}
-void ChannelType::Name::SetField(ChannelImpl *c, const Anope::string &value)
+void ChannelType::Name::OnSet(ChannelImpl *c, const Anope::string &value)
{
ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
- map.erase(GetField(c));
-
- Serialize::Field<ChannelImpl, Anope::string>::SetField(c, value);
+ Anope::string *old = this->Get_(c);
+ if (old != nullptr)
+ map.erase(*old);
map[value] = c;
}
diff --git a/modules/chanserv/main/channeltype.h b/modules/chanserv/main/channeltype.h
index 95158427a..1f1c92201 100644
--- a/modules/chanserv/main/channeltype.h
+++ b/modules/chanserv/main/channeltype.h
@@ -27,7 +27,7 @@ class ChannelType : public Serialize::Type<ChannelImpl>
{
using Serialize::Field<ChannelImpl, Anope::string>::Field;
- void SetField(ChannelImpl *c, const Anope::string &value) override;
+ void OnSet(ChannelImpl *c, const Anope::string &value) override;
} name;
Serialize::Field<ChannelImpl, Anope::string> desc;
Serialize::Field<ChannelImpl, time_t> time_registered;
diff --git a/modules/chanserv/main/chanserv.cpp b/modules/chanserv/main/chanserv.cpp
index ec2e8a623..dc44173a0 100644
--- a/modules/chanserv/main/chanserv.cpp
+++ b/modules/chanserv/main/chanserv.cpp
@@ -322,7 +322,7 @@ class ChanServCore : public Module
{
::Log(LOG_NORMAL, "chanserv/drop", ChanServ) << "Deleting channel " << ci->GetName() << " owned by deleted nick " << nc->GetDisplay();
- delete ci;
+ ci->Delete();
continue;
}
}
@@ -330,6 +330,7 @@ class ChanServCore : public Module
if (ci->GetSuccessor() == nc)
ci->SetSuccessor(NULL);
+#warning "these arent necessary?"
/* are these necessary? */
for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
{
@@ -338,7 +339,7 @@ class ChanServCore : public Module
if (anc && anc == nc)
{
- delete ca;
+ ca->Delete();
break;
}
}
@@ -348,7 +349,7 @@ class ChanServCore : public Module
AutoKick *ak = ci->GetAkick(j);
if (ak->GetAccount() == nc)
{
- delete ak;
+ ak->Delete();
break;
}
}
@@ -359,6 +360,7 @@ class ChanServCore : public Module
{
/* remove access entries that are this channel */
+#warning "also not necessary?"
for (ChanServ::Channel *c : ci->GetRefs<ChanServ::Channel *>())
{
for (unsigned j = 0; j < c->GetAccessCount(); ++j)
@@ -367,7 +369,7 @@ class ChanServCore : public Module
if (a->Mask().equals_ci(ci->GetName()))
{
- delete a;
+ a->Delete();
break;
}
}
@@ -465,7 +467,7 @@ class ChanServCore : public Module
if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly)
return;
- for (ChanServ::Channel *ci : channel_type.List<ChanServ::Channel *>())
+ for (ChanServ::Channel *ci : Serialize::GetObjects<ChanServ::Channel *>())
{
bool expire = false;
@@ -488,7 +490,7 @@ class ChanServCore : public Module
{
::Log(LOG_NORMAL, "chanserv/expire", ChanServ) << "Expiring channel " << ci->GetName() << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->GetDisplay() : "(none)") << ")";
EventManager::Get()->Dispatch(&ChanServ::Event::ChanExpire::OnChanExpire, ci);
- delete ci;
+ ci->Delete();
}
}
}
@@ -505,7 +507,7 @@ class ChanServCore : public Module
void OnPreUplinkSync(Server *serv) override
{
/* Find all persistent channels and create them, as we are about to finish burst to our uplink */
- for (ChanServ::Channel *ci : channel_type.List<ChanServ::Channel *>())
+ for (ChanServ::Channel *ci : Serialize::GetObjects<ChanServ::Channel *>())
{
if (ci->HasFieldS("PERSIST"))
{
diff --git a/modules/database/old.cpp b/modules/database/old.cpp
index d63b2c4d8..61be22e9d 100644
--- a/modules/database/old.cpp
+++ b/modules/database/old.cpp
@@ -777,6 +777,10 @@ static void LoadBots()
ServiceBot *bi = ServiceBot::Find(nick, true);
if (!bi)
bi = new ServiceBot(nick, user, host, real);
+
+ if (bi->bi == nullptr)
+ bi->bi = Serialize::New<BotInfo *>();
+
bi->bi->SetCreated(created);
if (flags & OLD_BI_PRIVATE)
diff --git a/modules/database/sql.cpp b/modules/database/sql.cpp
index d7ed1963a..aa1c94bc0 100644
--- a/modules/database/sql.cpp
+++ b/modules/database/sql.cpp
@@ -22,7 +22,7 @@
using namespace SQL;
-class DBMySQL : public Module, public Pipe
+class DBSQL : public Module, public Pipe
, public EventHook<Event::SerializeEvents>
{
private:
@@ -58,8 +58,6 @@ class DBMySQL : public Module, public Pipe
SQL->RunQuery(q);
}
- Log(LOG_DEBUG_2) << query.Unsafe();
-
return SQL->RunQuery(query);
}
@@ -85,7 +83,7 @@ class DBMySQL : public Module, public Pipe
}
public:
- DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
+ DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
, EventHook<Event::SerializeEvents>(this)
{
}
@@ -129,10 +127,10 @@ class DBMySQL : public Module, public Pipe
StartTransaction();
- for (Query &q : SQL->CreateTable(prefix, type->GetName()))
+ for (Query &q : SQL->CreateTable(prefix, type))
Run(q);
- for (Query &q : SQL->AlterTable(prefix, type->GetName(), field->serialize_name, false))
+ for (Query &q : SQL->AlterTable(prefix, type, field))
Run(q);
for (const Query &q : SQL->CreateIndex(prefix + type->GetName(), field->serialize_name))
@@ -150,6 +148,7 @@ class DBMySQL : public Module, public Pipe
catch (const ConvertException &)
{
}
+
return EVENT_CONTINUE;
}
@@ -159,7 +158,7 @@ class DBMySQL : public Module, public Pipe
StartTransaction();
Query query = "SELECT `" + field->serialize_name + "` FROM `" + prefix + object->GetSerializableType()->GetName() + "` WHERE `id` = @id@";
- query.SetValue("id", object->id);
+ query.SetValue("id", object->id, false);
Result res = Run(query);
if (res.Rows() == 0)
@@ -169,6 +168,40 @@ class DBMySQL : public Module, public Pipe
return true;
}
+ void GetRefs(Serialize::Object *object, Serialize::TypeBase *type, std::vector<Serialize::Edge> &edges)
+ {
+ for (Serialize::FieldBase *field : type->GetFields())
+ {
+ if (field->object)
+ {
+ Anope::string table = prefix + type->GetName();
+
+ Query query = "SELECT " + table + ".id FROM " + table +
+ " INNER JOIN " + prefix + "objects AS o ON " +
+ table + "." + field->serialize_name + " = o.id "
+ "WHERE o.id = @id@";
+
+ query.SetValue("id", object->id, false);
+
+ Result res = Run(query);
+ for (int i = 0; i < res.Rows(); ++i)
+ {
+ Serialize::ID id = convertTo<Serialize::ID>(res.Get(i, "id"));
+
+ Serialize::Object *other = type->Require(id);
+ if (other == nullptr)
+ {
+ Log(LOG_DEBUG) << "Unable to require id " << id << " type " << type->GetName();
+ continue;
+ }
+
+ // other type, other field, direction
+ edges.emplace_back(other, field, false);
+ }
+ }
+ }
+ }
+
public:
EventReturn OnSerializeGet(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &value) override
{
@@ -193,93 +226,16 @@ class DBMySQL : public Module, public Pipe
edges.clear();
- Query query;
- if (type)
- query = "SELECT field," + prefix + "edges.id,other_id,j1.type,j2.type AS other_type FROM `" + prefix + "edges` "
- "JOIN `" + prefix + "objects` AS j1 ON " + prefix + "edges.id = j1.id "
- "JOIN `" + prefix + "objects` AS j2 ON " + prefix + "edges.other_id = j2.id "
- "WHERE "
- " (" + prefix + "edges.id = @id@ AND j2.type = @other_type@) "
- "OR"
- " (other_id = @id@ AND j1.type = @other_type@)";
+ if (type == nullptr)
+ {
+ for (Serialize::TypeBase *type : Serialize::TypeBase::GetTypes())
+ GetRefs(object, type, edges);
+ }
else
- query = "SELECT field," + prefix + "edges.id,other_id,j1.type,j2.type AS other_type FROM `" + prefix + "edges` "
- "JOIN `" + prefix + "objects` AS j1 ON " + prefix + "edges.id = j1.id "
- "JOIN `" + prefix + "objects` AS j2 ON " + prefix + "edges.other_id = j2.id "
- "WHERE " + prefix + "edges.id = @id@ OR other_id = @id@";
-
- query.SetValue("type", object->GetSerializableType()->GetName());
- query.SetValue("id", object->id);
- if (type)
- query.SetValue("other_type", type->GetName());
-
- Result res = Run(query);
- for (int i = 0; i < res.Rows(); ++i)
{
- Serialize::ID id = convertTo<Serialize::ID>(res.Get(i, "id")); // object edge is on
-
- if (id == object->id)
- {
- // we want other type, this is my edge
- Anope::string t = res.Get(i, "other_type");
- Anope::string f = res.Get(i, "field");
- id = convertTo<Serialize::ID>(res.Get(i, "other_id"));
-
- Serialize::FieldBase *obj_field = object->GetSerializableType()->GetField(f);
- if (obj_field == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to find field " << f << " on " << object->GetSerializableType()->GetName();
- continue;
- }
-
- Serialize::TypeBase *obj_type = Serialize::TypeBase::Find(t);
- if (obj_type == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to find type " << t;
- continue;
- }
-
- Serialize::Object *other = obj_type->Require(id);
- if (other == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to require id " << id << " type " << obj_type->GetName();
- continue;
- }
-
- edges.emplace_back(other, obj_field, true);
- }
- else
- {
- // edge to me
- Anope::string t = res.Get(i, "type");
- Anope::string f = res.Get(i, "field");
-
- Serialize::TypeBase *obj_type = Serialize::TypeBase::Find(t);
- if (obj_type == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to find type " << t;
- continue;
- }
-
- Serialize::FieldBase *obj_field = obj_type->GetField(f);
- if (obj_field == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to find field " << f << " on " << obj_type->GetName();
- continue;
- }
-
- Serialize::Object *other = obj_type->Require(id);
- if (other == nullptr)
- {
- Log(LOG_DEBUG) << "Unable to require id " << id << " type " << obj_type->GetName();
- continue;
- }
-
- // other type, other field,
- edges.emplace_back(other, obj_field, false);
- }
+ GetRefs(object, type, edges);
}
-
+
return EVENT_ALLOW;
}
@@ -288,7 +244,7 @@ class DBMySQL : public Module, public Pipe
StartTransaction();
Query query = "SELECT `id` FROM `" + prefix + type->GetName() + "` WHERE `id` = @id@";
- query.SetValue("id", id);
+ query.SetValue("id", id, false);
Result res = Run(query);
if (res.Rows() == 0)
return EVENT_CONTINUE;
@@ -302,7 +258,7 @@ class DBMySQL : public Module, public Pipe
Query query = "SELECT `" + field->serialize_name + "`,j1.type AS " + field->serialize_name + "_type FROM `" + prefix + object->GetSerializableType()->GetName() + "` "
"JOIN `" + prefix + "objects` AS j1 ON " + prefix + object->GetSerializableType()->GetName() + "." + field->serialize_name + " = j1.id "
"WHERE " + prefix + object->GetSerializableType()->GetName() + ".id = @id@";
- query.SetValue("id", object->id);
+ query.SetValue("id", object->id, false);
Result res = Run(query);
if (res.Rows() == 0)
@@ -329,16 +285,16 @@ class DBMySQL : public Module, public Pipe
StartTransaction();
- for (Query &q : SQL->CreateTable(prefix, object->GetSerializableType()->GetName()))
+ for (Query &q : SQL->CreateTable(prefix, object->GetSerializableType()))
Run(q);
- for (Query &q : SQL->AlterTable(prefix, object->GetSerializableType()->GetName(), field->serialize_name, is_object))
+ for (Query &q : SQL->AlterTable(prefix, object->GetSerializableType(), field))
Run(q);
Query q;
- q.SetValue("id", object->id);
+ q.SetValue("id", object->id, false);
if (value)
- q.SetValue(field->serialize_name, *value);
+ q.SetValue(field->serialize_name, *value, !is_object);
else
q.SetNull(field->serialize_name);
@@ -364,23 +320,10 @@ class DBMySQL : public Module, public Pipe
{
Anope::string v = stringify(value->id);
DoSet(object, field, true, &v);
-
- Query query;
- query.SetValue("field", field->serialize_name);
- query.SetValue("id", object->id);
- query.SetValue("other_id", value->id);
-
- for (Query &q : SQL->Replace(prefix + "edges", query, { "id", "field" }))
- Run(q);
}
else
{
DoSet(object, field, true, nullptr);
-
- Query query("DELETE FROM `" + prefix + "edges` WHERE `id` = @id@ AND `field` = @field@");
- query.SetValue("id", object->id);
- query.SetValue("field", field->serialize_name);
- Run(query);
}
return EVENT_STOP;
@@ -395,12 +338,6 @@ class DBMySQL : public Module, public Pipe
EventReturn OnSerializeUnsetSerializable(Serialize::Object *object, Serialize::FieldBase *field) override
{
DoSet(object, field, true, nullptr);
-
- Query query("DELETE FROM `" + prefix + "edges` WHERE `id` = @id@ AND `field` = @field@");
- query.SetValue("id", object->id);
- query.SetValue("field", field->serialize_name);
- Run(query);
-
return EVENT_STOP;
}
@@ -408,7 +345,14 @@ class DBMySQL : public Module, public Pipe
{
SQL::Result::Value v;
- return GetValue(object, field, v) && !v.null ? EVENT_STOP : EVENT_CONTINUE;
+ if (!GetValue(object, field, v))
+ return EVENT_CONTINUE;
+
+ if (v.null)
+ return EVENT_CONTINUE;
+
+ field->UnserializeFromString(object, v.value);
+ return EVENT_STOP;
}
EventReturn OnSerializableGetId(Serialize::ID &id) override
@@ -427,7 +371,7 @@ class DBMySQL : public Module, public Pipe
StartTransaction();
Query q = Query("INSERT INTO `" + prefix + "objects` (`id`,`type`) VALUES (@id@, @type@)");
- q.SetValue("id", object->id);
+ q.SetValue("id", object->id, false);
q.SetValue("type", object->GetSerializableType()->GetName());
Run(q);
}
@@ -436,10 +380,10 @@ class DBMySQL : public Module, public Pipe
{
StartTransaction();
- Query query("DELETE FROM `" + prefix + object->GetSerializableType()->GetName() + "` WHERE `id` = " + stringify(object->id));
+ Query query("DELETE FROM `" + prefix + "objects` WHERE `id` = " + stringify(object->id));
Run(query);
}
};
-MODULE_INIT(DBMySQL)
+MODULE_INIT(DBSQL)
diff --git a/modules/extra/mysql.cpp b/modules/extra/mysql.cpp
index b0aec1f6d..b5ff0c3d9 100644
--- a/modules/extra/mysql.cpp
+++ b/modules/extra/mysql.cpp
@@ -156,8 +156,8 @@ class MySQLService : public Provider
std::vector<Query> InitSchema(const Anope::string &prefix) override;
std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) override;
- std::ve