summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2017-02-07 17:20:07 -0500
committerAdam <Adam@anope.org>2017-02-07 17:20:07 -0500
commit09dca29c8898916772c2a2a6b86b625c812007ed (patch)
tree1b28f4751feec3ea2b46fa0afb061da7926f3a47
parent8b694bc392c36551e428b84454efb81cdbc8bcd3 (diff)
Normalize databases by not allowing generic Object references
Remove redis database support
-rw-r--r--data/anope.example.conf16
-rw-r--r--data/modules.example.conf25
-rw-r--r--docs/SQLite.md22
-rw-r--r--include/event.h2
-rw-r--r--include/modules/chanserv/chanaccess.h7
-rw-r--r--include/modules/chanserv/main/chanaccess.h8
-rw-r--r--include/modules/hostserv.h4
-rw-r--r--include/modules/memoserv.h7
-rw-r--r--include/modules/operserv/info.h7
-rw-r--r--include/modules/sql.h2
-rw-r--r--include/serialize.h9
-rw-r--r--modules/chanserv/access.cpp9
-rw-r--r--modules/chanserv/flags.cpp59
-rw-r--r--modules/chanserv/main/chanaccess.cpp16
-rw-r--r--modules/chanserv/main/chanaccesstype.h4
-rw-r--r--modules/chanserv/xop.cpp61
-rw-r--r--modules/database/flatfile.cpp14
-rw-r--r--modules/database/old.cpp2
-rw-r--r--modules/database/redis.cpp448
-rw-r--r--modules/database/sql.cpp32
-rw-r--r--modules/extra/mysql.cpp39
-rw-r--r--modules/hostserv/add.cpp2
-rw-r--r--modules/hostserv/main/vhost.cpp9
-rw-r--r--modules/hostserv/main/vhost.h6
-rw-r--r--modules/hostserv/main/vhosttype.cpp2
-rw-r--r--modules/hostserv/main/vhosttype.h2
-rw-r--r--modules/hostserv/request.cpp2
-rw-r--r--modules/memoserv/main/memoinfo.cpp19
-rw-r--r--modules/memoserv/main/memoinfo.h10
-rw-r--r--modules/memoserv/main/memoinfotype.cpp3
-rw-r--r--modules/memoserv/main/memoinfotype.h3
-rw-r--r--modules/memoserv/main/memoserv.cpp8
-rw-r--r--modules/operserv/info.cpp44
-rw-r--r--modules/redis.cpp608
-rw-r--r--modules/sqlite.cpp46
-rw-r--r--src/serialize.cpp63
36 files changed, 223 insertions, 1397 deletions
diff --git a/data/anope.example.conf b/data/anope.example.conf
index 89c63ebfd..f6abe70db 100644
--- a/data/anope.example.conf
+++ b/data/anope.example.conf
@@ -1087,22 +1087,6 @@ module
}
/*
- * db_redis.
- *
- * This module allows using Redis (http://redis.io) as a database backend.
- * This module requires the module redis to be loaded and configured properly.
- */
-#module
-{
- name = "database/redis"
-
- /*
- * Redis database to use. This must be configured with the module redis.
- */
- engine = "redis/main"
-}
-
-/*
* [RECOMMENDED] Encryption modules.
*
* The encryption modules are used when dealing with passwords. This determines how
diff --git a/data/modules.example.conf b/data/modules.example.conf
index 0f22a7c72..725130137 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -384,31 +384,6 @@ module { name = "help" }
}
/*
- * redis
- *
- * This module allows other modules to use Redis.
- */
-#module
-{
- name = "redis"
-
- /* A redis database */
- redis
- {
- /* The name of this service */
- name = "redis/main"
-
- /*
- * The redis database to use. New connections default to 0.
- */
- db = 0
-
- ip = "127.0.0.1"
- port = 6379
- }
-}
-
-/*
* rest [EXTRA]
*
* This module exposes a RESTful API using JSON via the httpd module.
diff --git a/docs/SQLite.md b/docs/SQLite.md
index be25bbb27..30e0d7b12 100644
--- a/docs/SQLite.md
+++ b/docs/SQLite.md
@@ -6,21 +6,21 @@ It does this by using SQLites support for having indexes on expressions https://
For example the account table could look like:
```
-CREATE TABLE `anope_db_account` (
+CREATE TABLE `anope_account` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT,
`display`,
`pass`,
`email`,
- `language`,
- `id` NOT NULL PRIMARY KEY,
- FOREIGN KEY (id) REFERENCES anope_db_objects(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
+ `language`
);
-CREATE INDEX idx_display ON `anope_db_account` (anope_canonicalize(display));
+
+CREATE INDEX idx_display ON `anope_account` (anope_canonicalize(display));
```
So, to do a SELECT which utilizes the indicies, Anope does something like:
```
-SELECT id FROM `anope_db_account` WHERE anope_canonicalize(display) = anope_canonicalize('Adam');
+SELECT id FROM `anope_account` WHERE anope_canonicalize(display) = anope_canonicalize('Adam');
```
If you are using your own SQLite instance, like the sqlite command line interface, the anope_canonicalize function
@@ -31,13 +31,13 @@ or libanope_sqlite_rfc1459.so into SQLite, depending on your casemap configurati
sqlite> .load lib/libanope_sqlite_ascii.so
```
-## Example of adding a new operator via SQLite
+## Example of registering a new user via SQLite
```
BEGIN TRANSACTION;
--- Allocate new ID and insert into objects table
-INSERT INTO anope_db_objects (id, type) SELECT MAX(id + 1), 'oper' FROM anope_db_objects;
--- Insert new operator using previously allocated id
-INSERT INTO anope_db_oper (name, type, require_oper, id) VALUES ('Adam', 'Services Root', 1, last_insert_rowid());
+-- Insert new account
+INSERT INTO anope_account (display, email, private, autoop, killprotect) VALUES ('Adam', 'adam@anope.org', 1, 1, 1);
+-- Insert nickname, linking it to the account
+INSERT INTO anope_nick (nick, account) VALUES ('Adam', last_insert_rowid());
COMMIT;
```
diff --git a/include/event.h b/include/event.h
index 85e406795..bcc04cc0a 100644
--- a/include/event.h
+++ b/include/event.h
@@ -1202,7 +1202,7 @@ namespace Event
virtual EventReturn OnSerializeDeref(Serialize::ID value, Serialize::TypeBase *type) anope_abstract;
- virtual EventReturn OnSerializableGetId(Serialize::ID &id) anope_abstract;
+ virtual EventReturn OnSerializableGetId(Serialize::TypeBase *type, Serialize::ID &id) anope_abstract;
virtual void OnSerializableDelete(Serialize::Object *) anope_abstract;
diff --git a/include/modules/chanserv/chanaccess.h b/include/modules/chanserv/chanaccess.h
index faaf48175..dff39c0f8 100644
--- a/include/modules/chanserv/chanaccess.h
+++ b/include/modules/chanserv/chanaccess.h
@@ -35,7 +35,7 @@ class CoreExport ChanAccess : public Serialize::Object
static constexpr const char *const NAME = "access";
Serialize::Storage<Channel *> channel;
- Serialize::Storage<Serialize::Object *> object;
+ Serialize::Storage<NickServ::Account *> account;
Serialize::Storage<Anope::string> creator, mask;
Serialize::Storage<time_t> last_seen, created;
@@ -56,11 +56,10 @@ class CoreExport ChanAccess : public Serialize::Object
virtual Anope::string GetMask() anope_abstract;
virtual void SetMask(const Anope::string &) anope_abstract;
- virtual Serialize::Object *GetObj() anope_abstract;
- virtual void SetObj(Serialize::Object *) anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
virtual Anope::string Mask() anope_abstract;
- virtual NickServ::Account *GetAccount() anope_abstract;
/** Check if this access entry matches the given user or account
* @param u The user
diff --git a/include/modules/chanserv/main/chanaccess.h b/include/modules/chanserv/main/chanaccess.h
index a126da685..fb78056ea 100644
--- a/include/modules/chanserv/main/chanaccess.h
+++ b/include/modules/chanserv/main/chanaccess.h
@@ -22,8 +22,7 @@
class ChanAccessImpl : public ChanServ::ChanAccess
{
public:
- ChanAccessImpl(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { }
- ChanAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { }
+ using ChanServ::ChanAccess::ChanAccess;
ChanServ::Channel *GetChannel() override;
void SetChannel(ChanServ::Channel *ci) override;
@@ -40,11 +39,10 @@ class ChanAccessImpl : public ChanServ::ChanAccess
Anope::string GetMask() override;
void SetMask(const Anope::string &) override;
- Serialize::Object *GetObj() override;
- void SetObj(Serialize::Object *) override;
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
Anope::string Mask() override;
- NickServ::Account *GetAccount() override;
bool Matches(const User *u, NickServ::Account *acc) override;
};
diff --git a/include/modules/hostserv.h b/include/modules/hostserv.h
index 6934c813e..f2ec9a187 100644
--- a/include/modules/hostserv.h
+++ b/include/modules/hostserv.h
@@ -31,8 +31,8 @@ namespace HostServ
public:
static constexpr const char *const NAME = "vhost";
- virtual Serialize::Object *GetOwner() anope_abstract;
- virtual void SetOwner(Serialize::Object *) anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
virtual Anope::string GetIdent() anope_abstract;
virtual void SetIdent(const Anope::string &) anope_abstract;
diff --git a/include/modules/memoserv.h b/include/modules/memoserv.h
index 8c39b5a5e..888f793fe 100644
--- a/include/modules/memoserv.h
+++ b/include/modules/memoserv.h
@@ -138,8 +138,11 @@ namespace MemoServ
virtual bool HasIgnore(User *u) anope_abstract;
- virtual Serialize::Object *GetOwner() anope_abstract;
- virtual void SetOwner(Serialize::Object *) anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
virtual int16_t GetMemoMax() anope_abstract;
virtual void SetMemoMax(const int16_t &) anope_abstract;
diff --git a/include/modules/operserv/info.h b/include/modules/operserv/info.h
index 0e2198880..0ab6d65b6 100644
--- a/include/modules/operserv/info.h
+++ b/include/modules/operserv/info.h
@@ -25,8 +25,11 @@ class OperInfo : public Serialize::Object
public:
static constexpr const char *const NAME = "operinfo";
- virtual Serialize::Object *GetTarget() anope_abstract;
- virtual void SetTarget(Serialize::Object *) anope_abstract;
+ virtual NickServ::Account *GetAccount() anope_abstract;
+ virtual void SetAccount(NickServ::Account *) anope_abstract;
+
+ virtual ChanServ::Channel *GetChannel() anope_abstract;
+ virtual void SetChannel(ChanServ::Channel *) anope_abstract;
virtual Anope::string GetInfo() anope_abstract;
virtual void SetInfo(const Anope::string &) anope_abstract;
diff --git a/include/modules/sql.h b/include/modules/sql.h
index 263b99fd1..31e7af0bf 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -210,7 +210,7 @@ namespace SQL
virtual Query BeginTransaction() anope_abstract;
virtual Query Commit() anope_abstract;
- virtual Serialize::ID GetID(const Anope::string &) anope_abstract;
+ virtual Serialize::ID GetID(const Anope::string &prefix, const Anope::string &type) anope_abstract;
virtual Query GetTables(const Anope::string &prefix) anope_abstract;
};
diff --git a/include/serialize.h b/include/serialize.h
index 90aedc7ae..10ec14d16 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -41,11 +41,9 @@ namespace Serialize
template<typename T, typename> class Type;
template<typename T> class Reference;
- // by id
- extern std::unordered_map<ID, Object *> objects;
extern std::vector<FieldBase *> serializableFields;
- extern Object *GetID(ID id);
+ extern Object *GetID(Serialize::TypeBase *type, ID id);
template<typename T>
inline T GetObject();
@@ -240,7 +238,6 @@ class CoreExport Serialize::TypeBase : public Service
std::set<Object *> objects;
TypeBase(Module *owner, const Anope::string &n);
- ~TypeBase();
void Unregister();
@@ -292,7 +289,7 @@ class Serialize::Type : public Base
T* RequireID(ID id)
{
- Object *s = Serialize::GetID(id);
+ Object *s = Serialize::GetID(this, id);
if (s == nullptr)
return new T(this, id);
@@ -353,7 +350,7 @@ class Serialize::Reference
if (!valid)
return nullptr;
- Object *targ = GetID(id);
+ Object *targ = GetID(type, id);
if (targ != nullptr && targ->GetSerializableType() == type)
return anope_dynamic_static_cast<T*>(targ);
diff --git a/modules/chanserv/access.cpp b/modules/chanserv/access.cpp
index 44d21734e..a29524a73 100644
--- a/modules/chanserv/access.cpp
+++ b/modules/chanserv/access.cpp
@@ -202,7 +202,7 @@ class CommandCSAccess : public Command
access = Serialize::New<AccessChanAccess *>();
if (na)
- access->SetObj(na->GetAccount());
+ access->SetAccount(na->GetAccount());
access->SetChannel(ci);
access->SetMask(mask);
access->SetCreator(source.GetNick());
@@ -263,7 +263,7 @@ class CommandCSAccess : public Command
ChanServ::AccessGroup ag = source.AccessFor(ci);
ChanServ::ChanAccess *u_highest = ag.Highest();
- if ((!u_highest || *u_highest <= *access) && !ag.founder && !source.IsOverride() && access->GetObj() != source.nc)
+ if ((!u_highest || *u_highest <= *access) && !ag.founder && !source.IsOverride() && access->GetAccount() != source.nc)
{
denied = true;
return;
@@ -305,7 +305,7 @@ class CommandCSAccess : public Command
ChanServ::ChanAccess *access = ci->GetAccess(i - 1);
if (mask.equals_ci(access->Mask()))
{
- if (access->GetObj() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasOverridePriv("chanserv/access/modify"))
+ if (access->GetAccount() != source.nc && !u_access.founder && (!highest || *highest <= *access) && !source.HasOverridePriv("chanserv/access/modify"))
{
source.Reply(_("Access denied. You do not have enough privileges on \002{0}\002 to remove the access of \002{1}\002."), ci->GetName(), access->Mask());
}
@@ -555,9 +555,6 @@ class CommandCSAccess : public Command
" Use of this command requires the \002{4}\002 privilege on \037channel\037."),
source.GetCommand(), ChanServ::ACCESS_INVALID + 1, ChanServ::ACCESS_FOUNDER - 1, "AUTOOP", "ACCESS_CHANGE");
- if (!Config->GetModule("chanserv/main")->Get<bool>("disallow_channel_access"))
- source.Reply(_("The given \037mask\037 may also be a channel, which will use the access list from the other channel up to the given \037level\037."));
-
//XXX show def levels
source.Reply(_("\n"
diff --git a/modules/chanserv/flags.cpp b/modules/chanserv/flags.cpp
index 6ec65d104..f535aa136 100644
--- a/modules/chanserv/flags.cpp
+++ b/modules/chanserv/flags.cpp
@@ -108,55 +108,28 @@ class CommandCSFlags : public Command
ChanServ::AccessGroup u_access = source.AccessFor(ci);
ChanServ::ChanAccess *highest = u_access.Highest();
- NickServ::Nick *na = nullptr;
- ChanServ::Channel *targ_ci = nullptr;
-
- if (IRCD->IsChannelValid(mask))
+ NickServ::Nick *na = NickServ::FindNick(mask);
+ if (!na && Config->GetModule("chanserv/main")->Get<bool>("disallow_hostmask_access"))
{
- if (Config->GetModule("chanserv/main")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- targ_ci = ChanServ::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(_("Channel \002{0}\002 isn't registered."), mask);
- return;
- }
- else if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->GetName();
+ source.Reply(_("Masks and unregistered users may not be on access lists."));
+ return;
}
- else
+
+ if (mask.find_first_of("!*@") == Anope::string::npos && !na)
{
- na = NickServ::FindNick(mask);
- if (!na && Config->GetModule("chanserv/main")->Get<bool>("disallow_hostmask_access"))
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
{
- source.Reply(_("Masks and unregistered users may not be on access lists."));
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
return;
}
- else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(_("\002{0}\002 isn't registered."), mask);
- return;
- }
- }
-
- if (na)
- mask = na->GetNick();
}
+ if (na)
+ mask = na->GetNick();
+
ChanServ::ChanAccess *current = NULL;
unsigned current_idx;
std::set<char> current_flags;
@@ -275,9 +248,7 @@ class CommandCSFlags : public Command
FlagsChanAccess *access = Serialize::New<FlagsChanAccess *>();
if (na)
- access->SetObj(na->GetAccount());
- else if (targ_ci)
- access->SetObj(targ_ci);
+ access->SetAccount(na->GetAccount());
access->SetChannel(ci);
access->SetMask(mask);
access->SetCreator(source.GetNick());
diff --git a/modules/chanserv/main/chanaccess.cpp b/modules/chanserv/main/chanaccess.cpp
index 75c70ed9c..f2b170989 100644
--- a/modules/chanserv/main/chanaccess.cpp
+++ b/modules/chanserv/main/chanaccess.cpp
@@ -71,14 +71,14 @@ void ChanAccessImpl::SetMask(const Anope::string &n)
Object::Set(&ChanAccessType<ChanServ::ChanAccess>::mask, n);
}
-Serialize::Object *ChanAccessImpl::GetObj()
+NickServ::Account *ChanAccessImpl::GetAccount()
{
- return Get(&ChanAccessType<ChanServ::ChanAccess>::obj);
+ return Get(&ChanAccessType<ChanServ::ChanAccess>::account);
}
-void ChanAccessImpl::SetObj(Serialize::Object *o)
+void ChanAccessImpl::SetAccount(NickServ::Account *acc)
{
- Object::Set(&ChanAccessType<ChanServ::ChanAccess>::obj, o);
+ Object::Set(&ChanAccessType<ChanServ::ChanAccess>::account, acc);
}
Anope::string ChanAccessImpl::Mask()
@@ -89,14 +89,6 @@ Anope::string ChanAccessImpl::Mask()
return GetMask();
}
-NickServ::Account *ChanAccessImpl::GetAccount()
-{
- if (!GetObj() || GetObj()->GetSerializableType()->GetName() != NickServ::Account::NAME)
- return nullptr;
-
- return anope_dynamic_static_cast<NickServ::Account *>(GetObj());
-}
-
bool ChanAccessImpl::Matches(const User *u, NickServ::Account *acc)
{
if (this->GetAccount())
diff --git a/modules/chanserv/main/chanaccesstype.h b/modules/chanserv/main/chanaccesstype.h
index b93747be7..4d95ee8b7 100644
--- a/modules/chanserv/main/chanaccesstype.h
+++ b/modules/chanserv/main/chanaccesstype.h
@@ -25,7 +25,7 @@ class ChanAccessType : public Serialize::Type<T>
public:
Serialize::ObjectField<ChanServ::ChanAccess, ChanServ::Channel *> channel;
Serialize::Field<ChanServ::ChanAccess, Anope::string> mask;
- Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj;
+ Serialize::ObjectField<ChanServ::ChanAccess, NickServ::Account *> account;
Serialize::Field<ChanServ::ChanAccess, Anope::string> creator;
Serialize::Field<ChanServ::ChanAccess, time_t> last_seen;
Serialize::Field<ChanServ::ChanAccess, time_t> created;
@@ -33,7 +33,7 @@ class ChanAccessType : public Serialize::Type<T>
ChanAccessType(Module *me) : Serialize::Type<T>(me)
, channel(this, "channel", &ChanServ::ChanAccess::channel, true)
, mask(this, "mask", &ChanServ::ChanAccess::mask)
- , obj(this, "obj", &ChanServ::ChanAccess::object, true)
+ , account(this, "account", &ChanServ::ChanAccess::account, true)
, creator(this, "creator", &ChanServ::ChanAccess::creator)
, last_seen(this, "last_seen", &ChanServ::ChanAccess::last_seen)
, created(this, "created", &ChanServ::ChanAccess::created)
diff --git a/modules/chanserv/xop.cpp b/modules/chanserv/xop.cpp
index 91fc7e4f1..d41ed7ae6 100644
--- a/modules/chanserv/xop.cpp
+++ b/modules/chanserv/xop.cpp
@@ -153,58 +153,29 @@ class CommandCSXOP : public Command
}
}
- NickServ::Nick *na = nullptr;
- ChanServ::Channel *targ_ci = nullptr;
+ NickServ::Nick *na = NickServ::FindNick(mask);
- if (IRCD->IsChannelValid(mask))
+ if (!na && Config->GetModule("chanserv/main")->Get<bool>("disallow_hostmask_access"))
{
- if (Config->GetModule("chanserv/main")->Get<bool>("disallow_channel_access"))
- {
- source.Reply(_("Channels may not be on access lists."));
- return;
- }
-
- targ_ci = ChanServ::Find(mask);
- if (targ_ci == NULL)
- {
- source.Reply(_("Channel \002{0}\002 isn't registered."), mask);
- return;
- }
-
- if (ci == targ_ci)
- {
- source.Reply(_("You can't add a channel to its own access list."));
- return;
- }
-
- mask = targ_ci->GetName();
+ source.Reply(_("Masks and unregistered users may not be on access lists."));
+ return;
}
- else
- {
- na = NickServ::FindNick(mask);
- if (!na && Config->GetModule("chanserv/main")->Get<bool>("disallow_hostmask_access"))
+ if (mask.find_first_of("!*@") == Anope::string::npos && !na)
+ {
+ User *targ = User::Find(mask, true);
+ if (targ != NULL)
+ mask = "*!*@" + targ->GetDisplayedHost();
+ else
{
- source.Reply(_("Masks and unregistered users may not be on access lists."));
+ source.Reply(_("\002{0}\002 isn't registered."), mask);
return;
}
-
- if (mask.find_first_of("!*@") == Anope::string::npos && !na)
- {
- User *targ = User::Find(mask, true);
- if (targ != NULL)
- mask = "*!*@" + targ->GetDisplayedHost();
- else
- {
- source.Reply(_("\002{0}\002 isn't registered."), mask);
- return;
- }
- }
-
- if (na)
- mask = na->GetNick();
}
+ if (na)
+ mask = na->GetNick();
+
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanServ::ChanAccess *a = ci->GetAccess(i);
@@ -231,9 +202,7 @@ class CommandCSXOP : public Command
XOPChanAccess *acc = Serialize::New<XOPChanAccess *>();
if (na)
- acc->SetObj(na->GetAccount());
- else if (targ_ci)
- acc->SetObj(targ_ci);
+ acc->SetAccount(na->GetAccount());
acc->SetChannel(ci);
acc->SetMask(mask);
acc->SetCreator(source.GetNick());
diff --git a/modules/database/flatfile.cpp b/modules/database/flatfile.cpp
index 27a51539c..ec6911ce2 100644
--- a/modules/database/flatfile.cpp
+++ b/modules/database/flatfile.cpp
@@ -129,7 +129,7 @@ class DBFlatFile : public Module
HostServ::VHost *vhost = Serialize::New<HostServ::VHost *>();
if (vhost != nullptr)
{
- vhost->SetOwner(acc);
+ vhost->SetAccount(acc);
vhost->SetIdent(data["vhost_ident"]);
vhost->SetHost(data["vhost_host"]);
vhost->SetCreator(data["vhost_creator"]);
@@ -352,7 +352,7 @@ class DBFlatFile : public Module
NickServ::Nick *nick = NickServ::FindNick(mask);
if (nick != nullptr)
- access->SetObj(nick->GetAccount());
+ access->SetAccount(nick->GetAccount());
access->AccessUnserialize(data["data"]);
}
@@ -557,18 +557,18 @@ class DBFlatFile : public Module
void LoadOperInfo(const Anope::string &type, std::map<Anope::string, Anope::string> &data)
{
- Serialize::Object *target = NickServ::FindAccount(data["target"]);
- if (target == nullptr)
- target = ChanServ::Find(data["target"]);
+ NickServ::Account *acc = NickServ::FindAccount(data["target"]);
+ ChanServ::Channel *chan = ChanServ::Find(data["target"]);
- if (target == nullptr)
+ if (acc == nullptr && chan == nullptr)
return;
OperInfo *o = Serialize::New<OperInfo *>();
if (o == nullptr)
return;
- o->SetTarget(target);
+ o->SetAccount(acc);
+ o->SetChannel(chan);
o->SetInfo(data["info"]);
o->SetCreator(data["adder"]);
try
diff --git a/modules/database/old.cpp b/modules/database/old.cpp
index 894b9125b..3a2b6ccb6 100644
--- a/modules/database/old.cpp
+++ b/modules/database/old.cpp
@@ -743,7 +743,7 @@ static void LoadVHosts()
if (vhost == nullptr)
continue;
- vhost->SetOwner(na->GetAccount());
+ vhost->SetAccount(na->GetAccount());
vhost->SetIdent(ident);
vhost->SetHost(host);
vhost->SetCreator(creator);
diff --git a/modules/database/redis.cpp b/modules/database/redis.cpp
deleted file mode 100644
index b6ce95241..000000000
--- a/modules/database/redis.cpp
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Anope IRC Services
- *
- * Copyright (C) 2013-2016 Anope Team <team@anope.org>
- *
- * This file is part of Anope. Anope is free software; you can
- * redistribute it and/or modify it under the terms of the GNU
- * General Public License as published by the Free Software
- * Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see see <http://www.gnu.org/licenses/>.
- */
-
-#include "module.h"
-#include "modules/redis.h"
-
-using namespace Redis;
-
-class DatabaseRedis;
-static DatabaseRedis *me;
-
-class TypeLoader : public Interface
-{
- Serialize::TypeBase *type;
-
- public:
- TypeLoader(Module *creator, Serialize::TypeBase *t) : Interface(creator), type(t) { }
-
- void OnResult(const Reply &r) override;
-};
-
-class ObjectLoader : public Interface
-{
- Serialize::Object *obj;
-
- public:
- ObjectLoader(Module *creator, Serialize::Object *s) : Interface(creator), obj(s) { }
-
- void OnResult(const Reply &r) override;
-};
-
-class FieldLoader : public Interface
-{
- Serialize::Object *obj;
- Serialize::FieldBase *field;
-
- public:
- FieldLoader(Module *creator, Serialize::Object *o, Serialize::FieldBase *f) : Interface(creator), obj(o), field(f) { }
-
- void OnResult(const Reply &) override;
-};
-
-class SubscriptionListener : public Interface
-{
- public:
- SubscriptionListener(Module *creator) : Interface(creator) { }
-
- void OnResult(const Reply &r) override;
-};
-
-class DatabaseRedis : public Module
- , public EventHook<Event::LoadDatabase>
- , public EventHook<Event::SerializeEvents>
-{
- SubscriptionListener sl;
-
- public:
- ServiceReference<Provider> redis;
-
- DatabaseRedis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR)
- , EventHook<Event::LoadDatabase>(this)
- , EventHook<Event::SerializeEvents>(this)
- , sl(this)
- {
- me = this;
- }
-
- void OnReload(Configuration::Conf *conf) override
- {
- Configuration::Block *block = conf->GetModule(this);
- this->redis = ServiceReference<Provider>(block->Get<Anope::string>("engine", "redis/main"));
- }
-
- EventReturn OnLoadDatabase() override
- {
- if (!redis)
- return EVENT_STOP;
-
- for (Serialize::TypeBase *type : Serialize::TypeBase::GetTypes())
- this->OnSerializeTypeCreate(type);
-
- while (redis->BlockAndProcess());
-
- redis->Subscribe(&this->sl, "anope");
-
- return EVENT_STOP;
- }
-
- void OnSerializeTypeCreate(Serialize::TypeBase *sb)
- {
- std::vector<Anope::string> args = { "SMEMBERS", "ids:" + sb->GetName() };
-
- redis->SendCommand(new TypeLoader(this, sb), args);
- }
-
- EventReturn OnSerializeList(Serialize::TypeBase *type, std::vector<Serialize::ID> &ids) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeFind(Serialize::TypeBase *type, Serialize::FieldBase *field, const Anope::string &value, Serialize::ID &id) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeGet(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &value) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeGetRefs(Serialize::Object *object, Serialize::TypeBase *type, std::vector<Serialize::Edge> &) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeDeref(Serialize::ID id, Serialize::TypeBase *type) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeGetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Anope::string &type, Serialize::ID &value) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeSet(Serialize::Object *object, Serialize::FieldBase *field, const Anope::string &value) override
- {
- std::vector<Anope::string> args;
-
- redis->StartTransaction();
-
- const Anope::string &old = field->SerializeToString(object);
- args = { "SREM", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + old, stringify(object->id) };
- redis->SendCommand(nullptr, args);
-
- // add object to type set
- args = { "SADD", "ids:" + object->GetSerializableType()->GetName(), stringify(object->id) };
- redis->SendCommand(nullptr, args);
-
- // add key to key set
- args = { "SADD", "keys:" + stringify(object->id), field->serialize_name };
- redis->SendCommand(nullptr, args);
-
- // set value
- args = { "SET", "values:" + stringify(object->id) + ":" + field->serialize_name, value };
- redis->SendCommand(nullptr, args);
-
- // lookup
- args = { "SADD", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + value, stringify(object->id) };
- redis->SendCommand(nullptr, args);
-
- redis->CommitTransaction();
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeSetSerializable(Serialize::Object *object, Serialize::FieldBase *field, Serialize::Object *value) override
- {
- return OnSerializeSet(object, field, stringify(value->id));
- }
-
- EventReturn OnSerializeUnset(Serialize::Object *object, Serialize::FieldBase *field) override
- {
- std::vector<Anope::string> args;
-
- redis->StartTransaction();
-
- const Anope::string &old = field->SerializeToString(object);
- args = { "SREM", "lookup:" + object->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + old, stringify(object->id) };
- redis->SendCommand(nullptr, args);
-
- // remove field from set
- args = { "SREM", "keys:" + stringify(object->id), field->serialize_name };
- redis->SendCommand(nullptr, args);
-
- redis->CommitTransaction();
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializeUnsetSerializable(Serialize::Object *object, Serialize::FieldBase *field) override
- {
- return OnSerializeUnset(object, field);
- }
-
- EventReturn OnSerializeHasField(Serialize::Object *object, Serialize::FieldBase *field) override
- {
- return EVENT_CONTINUE;
- }
-
- EventReturn OnSerializableGetId(Serialize::ID &id) override
- {
- std::vector<Anope::string> args = { "INCR", "id" };
-
- auto f = [&](const Reply &r)
- {
- id = r.i;
- };
-
- FInterface inter(this, f);
- redis->SendCommand(&inter, args);
- while (redis->BlockAndProcess());
- return EVENT_ALLOW;
- }
-
- void OnSerializableCreate(Serialize::Object *) override
- {
- }
-
- void OnSerializableDelete(Serialize::Object *obj) override
- {
- std::vector<Anope::string> args;
-
- redis->StartTransaction();
-
- for (Serialize::FieldBase *field : obj->GetSerializableType()->GetFields())
- {
- Anope::string value = field->SerializeToString(obj);
-
- args = { "SREM", "lookup:" + obj->GetSerializableType()->GetName() + ":" + field->serialize_name + ":" + value, stringify(obj->id) };
- redis->SendCommand(nullptr, args);
-
- args = { "DEL", "values:" + stringify(obj->id) + ":" + field->serialize_name };
- redis->SendCommand(nullptr, args);
-
- args = { "SREM", "keys:" + stringify(obj->id), field->serialize_name };
- redis->SendCommand(nullptr, args);
- }
-
- args = { "SREM", "ids:" + obj->GetSerializableType()->GetName(), stringify(obj->id) };
- redis->SendCommand(nullptr, args);
-
- redis->CommitTransaction();
- }
-};
-
-void TypeLoader::OnResult(const Reply &r)
-{
- if (r.type != Reply::MULTI_BULK || !me->redis)
- {
- delete this;
- return;
- }
-
- for (unsigned i = 0; i < r.multi_bulk.size(); ++i)
- {
- const Reply *reply = r.multi_bulk[i];
-
- if (reply->type != Reply::BULK)
- continue;
-
- int64_t id;
- try
- {
- id = convertTo<int64_t>(reply->bulk);
- }
- catch (const ConvertException &)
- {
- continue;
- }
-
- Serialize::Object *obj = type->Require(id);
- if (obj == nullptr)
- {
- Anope::Logger.Debug("Unable to require object #{0} of type {1}", id, type->GetName());
- continue;
- }
-
- std::vector<Anope::string> args = { "SMEMBERS", "keys:" + stringify(id) };
-
- me->redis->SendCommand(new ObjectLoader(me, obj), args);
- }
-
- delete this;
-}
-
-void ObjectLoader::OnResult(const Reply &r)
-{
- if (r.type != Reply::MULTI_BULK || r.multi_bulk.empty() || !me->redis)
- {
- delete this;
- return;
- }
-
- Serialize::TypeBase *type = obj->GetSerializableType();
-
- for (Reply *reply : r.multi_bulk)
- {
- const Anope::string &key = reply->bulk;
- Serialize::FieldBase *field = type->GetField(key);
-
- if (field == nullptr)
- continue;
-
- std::vector<Anope::string> args = { "GET", "values:" + stringify(obj->id) + ":" + key };
-
- me->redis->SendCommand(new FieldLoader(me, obj, field), args);
- }
-
- delete this;
-}
-
-void FieldLoader::OnResult(const Reply &r)
-{
- Anope::Logger.Debug2("Setting field {0} of object #{1} of type {2} to {3}", field->serialize_name, obj->id, obj->GetSerializableType()->GetName(), r.bulk);
- field->UnserializeFromString(obj, r.bulk);
-
- delete this;
-}
-
-void SubscriptionListener::OnResult(const Reply &r)
-{
- /*
- * message
- * anope
- * message
- *
- * set 4 email adam@anope.org
- * unset 4 email
- * create 4 NickCore
- * delete 4
- */
-
- const Anope::string &message = r.multi_bulk[2]->bulk;
- Anope::string command;
- spacesepstream sep(message);
-
- sep.GetToken(command);
-
- if (command == "set" || command == "unset")
- {
- Anope::string sid, key, value;
-
- sep.GetToken(sid);
- sep.GetToken(key);
- value = sep.GetRemaining();
-
- Serialize::ID id;
- try
- {
- id = convertTo<Serialize::ID>(sid);
- }
- catch (const ConvertException &ex)
- {
- this->GetOwner()->logger.Debug("unable to get id for SL update key {0}", sid);
- return;
- }
-
- Serialize::Object *obj = Serialize::GetID(id);
- if (obj == nullptr)
- {
- this->GetOwner()->logger.Debug("message for unknown object #{0}", id);
- return;
- }
-
- Serialize::FieldBase *field = obj->GetSerializableType()->GetField(key);
- if (field == nullptr)
- {
- this->GetOwner()->logger.Debug("message for unknown field of object #{0}: {1}", id, key);
- return;
- }
-
- this->GetOwner()->logger.Debug2("Setting field {0} of object #{1} of type {2} to {3}",
- field->serialize_name, obj->id, obj->GetSerializableType()->GetName(), value);
-
- field->UnserializeFromString(obj, value);
- }
- else if (command == "create")
- {
- Anope::string sid, stype;
-
- sep.GetToken(sid);
- sep.GetToken(stype);
-
- Serialize::ID id;
- try
- {
- id = convertTo<Serialize::ID>(sid);
- }
- catch (const ConvertException &ex)
- {
- this->GetOwner()->logger.Debug("unable to get id for SL update key {0}", sid);
- return;
- }
-
- Serialize::TypeBase *type = Serialize::TypeBase::Find(stype);
- if (type == nullptr)
- {
- this->GetOwner()->logger.Debug("message create for nonexistant type {0}", stype);
- return;
- }
-
- Serialize::Object *obj = type->Require(id);
- if (obj == nullptr)
- {
- this->GetOwner()->logger.Debug("require for message create type {0} id #{1} returned nullptr", type->GetName(), id);
- return;
- }
- }
- else if (command == "delete")
- {
- Anope::string sid;
-
- sep.GetToken(sid);
-
- Serialize::ID id;
- try
- {
- id = convertTo<Serialize::ID>(sid);
- }
- catch (const ConvertException &ex)
- {
- this->GetOwner()->logger.Debug("unable to get id for SL update key {0}", sid);
- return;
- }
-
- Serialize::Object *obj = Serialize::GetID(id);
- if (obj == nullptr)
- {
- this->GetOwner()->logger.Debug("message for unknown object #{0}", id);
- return;
- }
-
- obj->Delete();
- }
- else
- {
- this->GetOwner()->logger.Debug("unknown message: {0}", message);
- }
-}
-
-MODULE_INIT(DatabaseRedis)
diff --git a/modules/database/sql.cpp b/modules/database/sql.cpp
index 00c45a4bc..bd5a96b90 100644
--- a/modules/database/sql.cpp
+++ b/modules/database/sql.cpp
@@ -157,14 +157,12 @@ class DBSQL : public Module, public Pipe
{
for (Serialize::FieldBase *field : type->GetFields())
{
- if (field->is_object)
+ if (field->is_object && object->GetSerializableType()->GetName() == field->GetTypeName())
{
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 query = "SELECT id FROM " + table +
+ " WHERE " + field->serialize_name + " = @id@";
query.SetValue("id", object->id, false);
@@ -234,16 +232,15 @@ class DBSQL : public Module, public Pipe
{
StartTransaction();
- 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 query = "SELECT `" + field->serialize_name + "` FROM `" + prefix + object->GetSerializableType()->GetName() + "` "
+ "WHERE id = @id@";
query.SetValue("id", object->id, false);
Result res = Run(query);
if (res.Rows() == 0)
return EVENT_CONTINUE;
- type = res.Get(0, field->serialize_name + "_type");
+ type = field->GetTypeName();
try
{
value = convertTo<Serialize::ID>(res.Get(0, field->serialize_name));
@@ -350,32 +347,31 @@ class DBSQL : public Module, public Pipe
}
}
- EventReturn OnSerializableGetId(Serialize::ID &id) override
+ EventReturn OnSerializableGetId(Serialize::TypeBase *type, Serialize::ID &id) override
{
if (!SQL)
return EVENT_CONTINUE;
StartTransaction();
- id = SQL->GetID(prefix);
+ for (Query &q : SQL->CreateTable(prefix, type))
+ Run(q);
+
+ id = SQL->GetID(prefix, type->GetName());
return EVENT_ALLOW;
}
void OnSerializableCreate(Serialize::Object *object) override
{
- StartTransaction();
-
- Query q = Query("INSERT INTO `" + prefix + "objects` (`id`,`type`) VALUES (@id@, @type@)");
- q.SetValue("id", object->id, false);
- q.SetValue("type", object->GetSerializableType()->GetName());
- Run(q);
}
void OnSerializableDelete(Serialize::Object *object) override
{
StartTransaction();
- Query query("DELETE FROM `" + prefix + "objects` WHERE `id` = " + stringify(object->id));
+ Serialize::TypeBase *type = object->GetSerializableType();
+
+ Query query("DELETE FROM `" + prefix + type->GetName() + "` WHERE `id` = " + stringify(object->id));
Run(query);
}
};
diff --git a/modules/extra/mysql.cpp b/modules/extra/mysql.cpp
index 66b4ffa85..a61181f37 100644
--- a/modules/extra/mysql.cpp
+++ b/modules/extra/mysql.cpp
@@ -83,7 +83,7 @@ class MySQLResult : public Result
unsigned num_fields = mysql_num_fields(res);
MYSQL_FIELD *fields = mysql_fetch_fields(res);
- /* It is not thread safe to log anything here using Log(this->owner) now :( */
+ /* It is not thread safe to log anything here using the loggers now :( */
if (!num_fields || !fields)
return;
@@ -164,7 +164,7 @@ class MySQLService : public Provider
Query BeginTransaction() override;
Query Commit() override;
- Serialize::ID GetID(const Anope::string &) override;
+ Serialize::ID GetID(const Anope::string &prefix, const Anope::string &type) override;
Query GetTables(const Anope::string &prefix) override;
@@ -241,7 +241,7 @@ class ModuleSQL : public Module
if (i == config->CountBlock("mysql"))
{
- Log(LogType::NORMAL, "mysql") << "MySQL: Removing server connection " << cname;
+ logger.Log("Removing server connection {0}", cname);
delete s;
this->MySQLServices.erase(cname);
@@ -266,11 +266,11 @@ class ModuleSQL : public Module
MySQLService *ss = new MySQLService(this, connname, database, server, user, password, port);
this->MySQLServices.insert(std::make_pair(connname, ss));
- Log(LogType::NORMAL, "mysql") << "MySQL: Successfully connected to server " << connname << " (" << server << ")";
+ logger.Log(_("Successfully connected to server {0} ({1})"), connname, server);
}
catch (const SQL::Exception &ex)
{
- Log(LogType::NORMAL, "mysql") << "MySQL: " << ex.GetReason();
+ logger.Log(ex.GetReason());
}
}
}
@@ -394,8 +394,6 @@ std::vector<Query> MySQLService::InitSchema(const Anope::string &prefix)
{
std::vector<Query> queries;
- queries.push_back(Query("CREATE TABLE IF NOT EXISTS `" + prefix + "objects` (`id` bigint(20) NOT NULL PRIMARY KEY, `type` TINYTEXT) ENGINE=InnoDB"));
-
return queries;
}
@@ -431,11 +429,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &prefix, Serial
if (active_schema.find(prefix + base->GetName()) == active_schema.end())
{
- Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + base->GetName() + "` (`id` bigint(20) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB";
- queries.push_back(t);
-
- t = "ALTER TABLE `" + prefix + base->GetName() + "` "
- "ADD CONSTRAINT `" + base->GetName() + "_id_fk` FOREIGN KEY (`id`) REFERENCES `" + prefix + "objects` (`id`) ON DELETE CASCADE";
+ Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + base->GetName() + "` (`id` bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)) ENGINE=InnoDB";
queries.push_back(t);
active_schema[prefix + base->GetName()];
@@ -455,13 +449,13 @@ std::vector<Query> MySQLService::AlterTable(const Anope::string &prefix, Seriali
{
Anope::string buf = "ALTER TABLE `" + prefix + table + "` ADD COLUMN `" + field->serialize_name + "` ";
- if (!field->object)
+ if (!field->is_object)
{
buf += "TINYTEXT";
}
else
{
- buf += "bigint(20), ADD CONSTRAINT `" + table + "_" + field->serialize_name + "_fk` FOREIGN KEY (`" + field->serialize_name + "`) REFERENCES `" + prefix + "objects` (`id`) ON DELETE ";
+ buf += "bigint(20), ADD CONSTRAINT `" + table + "_" + field->serialize_name + "_fk` FOREIGN KEY (`" + field->serialize_name + "`) REFERENCES `" + prefix + field->GetTypeName() + "` (`id`) ON DELETE ";
if (field->depends)
buf += "CASCADE";
@@ -506,21 +500,12 @@ Query MySQLService::Commit()
return Query("COMMIT");
}
-Serialize::ID MySQLService::GetID(const Anope::string &prefix)
+Serialize::ID MySQLService::GetID(const Anope::string &prefix, const Anope::string &type)
{
- Query query = "SELECT `id` FROM `" + prefix + "objects` ORDER BY `id` DESC LIMIT 1";
- Serialize::ID id = 1;
-
+ Query query = "INSERT INTO `" + prefix + type + "` VALUES ()";
Result res = RunQuery(query);
- if (res.Rows())
- {
- id = convertTo<Serialize::ID>(res.Get(0, "id"));
-
- /* next id */
- ++id;
- }
- /* OnSerializableCreate is called immediately after this which does the insert */
+ Serialize::ID id = res.GetID();
return id;
}
@@ -542,7 +527,7 @@ void MySQLService::Connect()
if (!connect)
throw SQL::Exception("Unable to connect to MySQL service " + this->GetName() + ": " + mysql_error(this->sql));
- Log(LogType::DEBUG) << "Successfully connected to MySQL service " << this->GetName() << " at " << this->server << ":" << this->port;
+ this->GetOwner()->logger.Debug("Successfully connected to MySQL service {0} at {1}:{2}", this->GetName(), this->server, this->port);
}
diff --git a/modules/hostserv/add.cpp b/modules/hostserv/add.cpp
index 37de7d2bb..9960f407c 100644
--- a/modules/hostserv/add.cpp
+++ b/modules/hostserv/add.cpp
@@ -110,7 +110,7 @@ class CommandHSAdd : public Command
return;
}
- vhost->SetOwner(na->GetAccount());
+ vhost->SetAccount(na->GetAccount());
vhost->SetIdent(user);
vhost->SetHost(host);
vhost->SetCreator(source.GetNick());
diff --git a/modules/hostserv/main/vhost.cpp b/modules/hostserv/main/vhost.cpp
index 635e3a5b4..7c08fe838 100644
--- a/modules/hostserv/main/vhost.cpp
+++ b/modules/hostserv/main/vhost.cpp
@@ -18,15 +18,16 @@
*/
#include "vhosttype.h"
+#include "modules/nickserv.h"
-Serialize::Object *VHostImpl::GetOwner()
+NickServ::Account *VHostImpl::GetAccount()
{
- return Get(&VHostType::owner);
+ return Get(&VHostType::account);
}
-void VHostImpl::SetOwner(Serialize::Object *owner)
+void VHostImpl::SetAccount(NickServ::Account *acc)
{
- Set(&VHostType::owner, owner);
+ Set(&VHostType::account, acc);
}
Anope::string VHostImpl::GetIdent()
diff --git a/modules/hostserv/main/vhost.h b/modules/hostserv/main/vhost.h
index bdc6509d7..b96e20644 100644
--- a/modules/hostserv/main/vhost.h
+++ b/modules/hostserv/main/vhost.h
@@ -25,7 +25,7 @@ class VHostImpl : public HostServ::VHost
{
friend class VHostType;
- Serialize::Storage<Serialize::Object *> owner;
+ Serialize::Storage<NickServ::Account *> account;
Serialize::Storage<Anope::string> vident;
Serialize::Storage<Anope::string> vhost;
Serialize::Storage<Anope::string> creator;
@@ -35,8 +35,8 @@ class VHostImpl : public HostServ::VHost
public:
using HostServ::VHost::VHost;
- Serialize::Object *GetOwner() override;
- void SetOwner(Serialize::Object *) override;
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
Anope::string GetIdent() override;
void SetIdent(const Anope::string &) override;
diff --git a/modules/hostserv/main/vhosttype.cpp b/modules/hostserv/main/vhosttype.cpp
index ee73840bf..76ac5476b 100644
--- a/modules/hostserv/main/vhosttype.cpp
+++ b/modules/hostserv/main/vhosttype.cpp
@@ -21,7 +21,7 @@
#include "vhosttype.h"
VHostType::VHostType(Module *me) : Serialize::Type<VHostImpl>(me)
- , owner(this, "owner", &VHostImpl::owner, true)
+ , account(this, "account", &VHostImpl::account, true)
, vident(this, "vident", &VHostImpl::vident)
, vhost(this, "vhost", &VHostImpl::vhost)
, creator(this, "creator", &VHostImpl::creator)
diff --git a/modules/hostserv/main/vhosttype.h b/modules/hostserv/main/vhosttype.h
index 3be60f518..945110563 100644
--- a/modules/hostserv/main/vhosttype.h
+++ b/modules/hostserv/main/vhosttype.h
@@ -22,7 +22,7 @@
class VHostType : public Serialize::Type<VHostImpl>
{
public:
- Serialize::ObjectField<VHostImpl, Serialize::Object *> owner;
+ Serialize::ObjectField<VHostImpl, NickServ::Account *> account;
Serialize::Field<VHostImpl, Anope::string> vident;
Serialize::Field<VHostImpl, Anope::string> vhost;
Serialize::Field<VHostImpl, Anope::string> creator;
diff --git a/modules/hostserv/request.cpp b/modules/hostserv/request.cpp
index bef1f1548..a74dcacad 100644
--- a/modules/hostserv/request.cpp
+++ b/modules/hostserv/request.cpp
@@ -291,7 +291,7 @@ class CommandHSActivate : public Command
return;
}
- vhost->SetOwner(na->GetAccount());
+ vhost->SetAccount(na->GetAccount());
vhost->SetIdent(req->GetIdent());
vhost->SetHost(req->GetHost());
vhost->SetCreator(source.GetNick());
diff --git a/modules/memoserv/main/memoinfo.cpp b/modules/memoserv/main/memoinfo.cpp
index aa5ca71e4..8f5efc3fd 100644
--- a/modules/memoserv/main/memoinfo.cpp
+++ b/modules/memoserv/main/memoinfo.cpp
@@ -37,6 +37,7 @@ unsigned MemoInfoImpl::GetIndex(MemoServ::Memo *m)
void MemoInfoImpl::Del(unsigned index)
{
+#warning "delete on serializable"
delete GetMemo(index);
}
@@ -51,14 +52,24 @@ bool MemoInfoImpl::HasIgnore(User *u)
return false;
}
-Serialize::Object *MemoInfoImpl::GetOwner()
+NickServ::Account *MemoInfoImpl::GetAccount()
{
- return Get(&MemoInfoType::owner);
+ return Get(&MemoInfoType::account);
}
-void MemoInfoImpl::SetOwner(Serialize::Object *o)
+void MemoInfoImpl::SetAccount(NickServ::Account *account)
{
- Set(&MemoInfoType::owner, o);
+ Set(&MemoInfoType::account, account);
+}
+
+ChanServ::Channel *MemoInfoImpl::GetChannel()
+{
+ return Get(&MemoInfoType::channel);
+}
+
+void MemoInfoImpl::SetChannel(ChanServ::Channel *channel)
+{
+ Set(&MemoInfoType::channel, channel);
}
int16_t MemoInfoImpl::GetMemoMax()
diff --git a/modules/memoserv/main/memoinfo.h b/modules/memoserv/main/memoinfo.h
index cbe37e456..78d6f005b 100644
--- a/modules/memoserv/main/memoinfo.h
+++ b/modules/memoserv/main/memoinfo.h
@@ -23,7 +23,8 @@ class MemoInfoImpl : public MemoServ::MemoInfo
{
friend class MemoInfoType;
- Serialize::Storage<Serialize::Object *> owner;
+ Serialize::Storage<NickServ::Account *> account;
+ Serialize::Storage<ChanServ::Channel *> channel;
Serialize::Storage<int16_t> memomax;
Serialize::Storage<bool> hardmax;
@@ -35,8 +36,11 @@ class MemoInfoImpl : public MemoServ::MemoInfo
void Del(unsigned index) override;
bool HasIgnore(User *u) override;
- Serialize::Object *GetOwner() override;
- void SetOwner(Serialize::Object *) override;
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
int16_t GetMemoMax() override;
void SetMemoMax(const int16_t &) override;
diff --git a/modules/memoserv/main/memoinfotype.cpp b/modules/memoserv/main/memoinfotype.cpp
index 27e3bba75..1dcccec98 100644
--- a/modules/memoserv/main/memoinfotype.cpp
+++ b/modules/memoserv/main/memoinfotype.cpp
@@ -21,7 +21,8 @@
#include "memoinfotype.h"
MemoInfoType::MemoInfoType(Module *me) : Serialize::Type<MemoInfoImpl>(me)
- , owner(this, "owner", &MemoInfoImpl::owner, true)
+ , account(this, "account", &MemoInfoImpl::account, true)
+ , channel(this, "channel", &MemoInfoImpl::channel, true)
, memomax(this, "memomax", &MemoInfoImpl::memomax)
, hardmax(this, "hardmax", &MemoInfoImpl::hardmax)
{
diff --git a/modules/memoserv/main/memoinfotype.h b/modules/memoserv/main/memoinfotype.h
index 1a45b361a..94cc8fde4 100644
--- a/modules/memoserv/main/memoinfotype.h
+++ b/modules/memoserv/main/memoinfotype.h
@@ -22,7 +22,8 @@
class MemoInfoType : public Serialize::Type<MemoInfoImpl>
{
public:
- Serialize::ObjectField<MemoInfoImpl, Serialize::Object *> owner;
+ Serialize::ObjectField<MemoInfoImpl, NickServ::Account *> account;
+ Serialize::ObjectField<MemoInfoImpl, ChanServ::Channel *> channel;
Serialize::Field<MemoInfoImpl, int16_t> memomax;
Serialize::Field<MemoInfoImpl, bool> hardmax;
diff --git a/modules/memoserv/main/memoserv.cpp b/modules/memoserv/main/memoserv.cpp
index 3b2b7cd17..757b95563 100644
--- a/modules/memoserv/main/memoserv.cpp
+++ b/modules/memoserv/main/memoserv.cpp
@@ -189,7 +189,7 @@ class MemoServCore : public Module, public MemoServ::MemoServService
if (create && !ci->GetMemos())
{
MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
- mi->SetOwner(ci);
+ mi->SetChannel(ci);
}
return ci->GetMemos();
}
@@ -208,7 +208,7 @@ class MemoServCore : public Module, public MemoServ::MemoServService
if (create && !na->GetAccount()->GetMemos())
{
MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
- mi->SetOwner(na->GetAccount());
+ mi->SetAccount(na->GetAccount());
}
return na->GetAccount()->GetMemos();
}
@@ -238,14 +238,14 @@ class MemoServCore : public Module, public MemoServ::MemoServService
void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &) override
{
MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
- mi->SetOwner(na->GetAccount());
+ mi->SetAccount(na->GetAccount());
mi->SetMemoMax(Config->GetModule(this)->Get<int>("maxmemos"));
}
void OnChanRegistered(ChanServ::Channel *ci) override
{
MemoServ::MemoInfo *mi = Serialize::New<MemoServ::MemoInfo *>();
- mi->SetOwner(ci);
+ mi->SetChannel(ci);
mi->SetMemoMax(Config->GetModule(this)->Get<int>("maxmemos"));
}
diff --git a/modules/operserv/info.cpp b/modules/operserv/info.cpp
index c052c46ae..7a90c1bf6 100644
--- a/modules/operserv/info.cpp
+++ b/modules/operserv/info.cpp
@@ -27,15 +27,19 @@ class OperInfoImpl : public OperInfo
{
friend class OperInfoType;
- Serialize::Storage<Serialize::Object *> target;
+ Serialize::Storage<NickServ::Account *> account;
+ Serialize::Storage<ChanServ::Channel *> channel;
Serialize::Storage<Anope::string> info, creator;
Serialize::Storage<time_t> created;
public:
using OperInfo::OperInfo;
- Serialize::Object *GetTarget() override;
- void SetTarget(Serialize::Object *) override;
+ NickServ::Account *GetAccount() override;
+ void SetAccount(NickServ::Account *) override;
+
+ ChanServ::Channel *GetChannel() override;
+ void SetChannel(ChanServ::Channel *) override;
Anope::string GetInfo() override;
void SetInfo(const Anope::string &) override;
@@ -50,12 +54,14 @@ class OperInfoImpl : public OperInfo
class OperInfoType : public Serialize::Type<OperInfoImpl>
{
public:
- Serialize::ObjectField<OperInfoImpl, Serialize::Object *> target;
+ Serialize::ObjectField<OperInfoImpl, NickServ::Account *> account;
+ Serialize::ObjectField<OperInfoImpl, ChanServ::Channel *> channel;
Serialize::Field<OperInfoImpl, Anope::string> info, creator;
Serialize::Field<OperInfoImpl, time_t> created;
OperInfoType(Module *c) : Serialize::Type<OperInfoImpl>(c)
- , target(this, "target", &OperInfoImpl::target, true)
+ , account(this, "account", &OperInfoImpl::account, true)
+ , channel(this, "channel", &OperInfoImpl::channel, true)
, info(this, "info", &OperInfoImpl::info)
, creator(this, "adder", &OperInfoImpl::creator)
, created(this, "created", &OperInfoImpl::created)
@@ -63,14 +69,24 @@ class OperInfoType : public Serialize::Type<OperInfoImpl>
}
};
-Serialize::Object *OperInfoImpl::GetTarget()
+NickServ::Account *OperInfoImpl::GetAccount()
+{
+ return Get(&OperInfoType::account);
+}
+
+void OperInfoImpl::SetAccount(NickServ::Account *account)
{
- return Get(&OperInfoType::target);
+ Set(&OperInfoType::account, account);
}
-void OperInfoImpl::SetTarget(Serialize::Object *t)
+ChanServ::Channel *OperInfoImpl::GetChannel()
{
- Set(&OperInfoType::target, t);
+ return Get(&OperInfoType::channel);
+}
+
+void OperInfoImpl::SetChannel(ChanServ::Channel *channel)
+{
+ Set(&OperInfoType::channel, channel);
}
Anope::string OperInfoImpl::GetInfo()
@@ -118,7 +134,10 @@ class CommandOSInfo : public Command
{
const Anope::string &cmd = params[0], target = params[1], info = params.size() > 2 ? params[2] : "";
+ NickServ::Account *account = nullptr;
+ ChanServ::Channel *channel = nullptr;
Serialize::Object *e;
+
if (IRCD->IsChannelValid(target))
{
ChanServ::Channel *ci = ChanServ::Find(target);
@@ -128,6 +147,7 @@ class CommandOSInfo : public Command
return;
}
+ channel = ci;
e = ci;
}
else
@@ -139,7 +159,8 @@ class CommandOSInfo : public Command
return;
}
- e = na->GetAccount();
+ account = na->GetAccount();
+ e = account;
}
if (cmd.equals_ci("ADD"))
@@ -165,7 +186,8 @@ class CommandOSInfo : public Command
}
OperInfo *o = Serialize::New<OperInfo *>();
- o->SetTarget(e);
+ o->SetAccount(account);
+ o->SetChannel(channel);
o->SetInfo(info);
o->SetCreator(source.GetNick());
o->SetCreated(Anope::CurTime);
diff --git a/modules/redis.cpp b/modules/redis.cpp
deleted file mode 100644
index 47d89ef42..000000000
--- a/modules/redis.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Anope IRC Services
- *
- * Copyright (C) 2013-2016 Anope Team <team@anope.org>
- *
- * This file is part of Anope. Anope is free software; you can
- * redistribute it and/or modify it under the terms of the GNU
- * General Public License as published by the Free Software
- * Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see see <http://www.gnu.org/licenses/>.
- */
-
-#include "module.h"
-#include "modules/redis.h"
-
-using namespace Redis;
-
-class MyRedisService;
-
-class RedisSocket : public BinarySocket, public ConnectionSocket
-{
- size_t ParseReply(Reply &r, const char *buf, size_t l);
- public:
- MyRedisService *provider;
- std::deque<Interface *> interfaces;
- std::map<Anope::string, Interface *> subinterfaces;
-
- RedisSocket(MyRedisService *pro, bool v6) : Socket(-1, v6), provider(pro) { }
-
- ~RedisSocket();
-
- void OnConnect() override;
- void OnError(const Anope::string &error) override;
-
- bool Read(const char *buffer, size_t l) override;
-};
-
-class Transaction : public Interface
-{
- public:
- std::deque<Interface *> interfaces;
-
- Transaction(Module *creator) : Interface(creator) { }
-
- ~Transaction()
- {
- for (unsigned i = 0; i < interfaces.size(); ++i)
- {
- Interface *inter = interfaces[i];
-
- if (!inter)
- continue;
-
- inter->OnError("Interface going away");
- }
- }
-
- void OnResult(const Reply &r) override
- {
- /* This is a multi bulk reply of the results of the queued commands
- * in this transaction
- */
-
- this->GetOwner()->logger.Debug2("transaction complete with {0} results", r.multi_bulk.size());
-
- for (unsigned i = 0; i < r.multi_bulk.size(); ++i)
- {
- const Reply *reply = r.multi_bulk[i];
-
- if (interfaces.empty())
- break;
-
- Interface *inter = interfaces.front();
- interfaces.pop_front();
-
- if (inter)
- inter->OnResult(*reply);
- }
- }
-};
-
-class MyRedisService : public Provider
-{
- public:
- Anope::string host;
- int port;
- unsigned db;
-
- RedisSocket *sock, *sub;
-
- Transaction ti;
- bool in_transaction;
-
- MyRedisService(Module *c, const Anope::string &n, const Anope::string &h, int p, unsigned d) : Provider(c, n), host(h), port(p), db(d), sock(NULL), sub(NULL),
- ti(c), in_transaction(false)
- {
- sock = new RedisSocket(this, host.find(':') != Anope::string::npos);
- sock->Connect(host, port);
-
- sub = new RedisSocket(this, host.find(':') != Anope::string::npos);
- sub->Connect(host, port);
- }
-
- ~MyRedisService()
- {
- if (sock)
- {
- sock->flags[SF_DEAD] = true;
- sock->provider = NULL;
- }
-
- if (sub)
- {
- sub->flags[SF_DEAD] = true;
- sub->provider = NULL;
- }
- }
-
- private:
- inline void Pack(std::vector<char> &buffer, const char *buf, size_t sz = 0)
- {
- if (!sz)
- sz = strlen(buf);
-
- size_t old_size = buffer.size();
- buffer.resize(old_size + sz);
- std::copy(buf, buf + sz, buffer.begin() + old_size);
- }
-
- void Send(RedisSocket *s, Interface *i, const std::vector<std::pair<const char *, size_t> > &args)
- {
- std::vector<char> buffer;
-
- Pack(buffer, "*");
- Pack(buffer, stringify(args.size()).c_str());
- Pack(buffer, "\r\n");
-
- for (unsigned j = 0; j < args.size(); ++j)
- {
- const std::pair<const char *, size_t> &pair = args[j];
-
- Pack(buffer, "$");
- Pack(buffer, stringify(pair.second).c_str());
- Pack(buffer, "\r\n");
-
- Pack(buffer, pair.first, pair.second);
- Pack(buffer, "\r\n");
- }
-
- if (buffer.empty())
- return;
-
- s->Write(&buffer[0], buffer.size());
- if (in_transaction)
- {
- ti.interfaces.push_back(i);
- s->interfaces.push_back(NULL); // For the +Queued response
- }
- else
- s->interfaces.push_back(i);
- }
-
- public:
- void SendCommand(RedisSocket *s, Interface *i, const std::vector<Anope::string> &cmds)
- {
- std::vector<std::pair<const char *, size_t> > args;
- for (unsigned j = 0; j < cmds.size(); ++j)
- args.push_back(std::make_pair(cmds[j].c_str(), cmds[j].length()));
- this->Send(s, i, args);
- }
-
- void Send(Interface *i, const std::vector<std::pair<const char *, size_t> > &args)
- {
- if (!sock)
- {
- sock = new RedisSocket(this, host.find(':') != Anope::string::npos);
- sock->Connect(host, port);
- }
-
- this->Send(sock, i, args);
- }
-
- void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) override
- {
- std::vector<std::pair<const char *, size_t> > args;
- for (unsigned j = 0; j < cmds.size(); ++j)
- args.push_back(std::make_pair(cmds[j].c_str(), cmds[j].length()));
- this->Send(i, args);
- }
-
- void SendCommand(Interface *i, const Anope::string &str) override
- {
- std::vector<Anope::string> args;
- spacesepstream(str).GetTokens(args);
- this->SendCommand(i, args);
- }
-
- bool BlockAndProcess() override
- {
- this->sock->ProcessWrite();
- this->sock->SetBlocking(true);
- this->sock->ProcessRead();
- this->sock->SetBlocking(false);
- return !this->sock->interfaces.empty();
- }
-
- void Subscribe(Interface *i, const Anope::string &ch) override
- {
- if (sub == NULL)
- {
- sub = new RedisSocket(this, host.find(':') != Anope::string::npos);
- sub->Connect(host, port);
- }
-
- std::vector<Anope::string> args = { "SUBSCRIBE", ch };
- this->SendCommand(sub, NULL, args);
-
- sub->subinterfaces[ch] = i;
- }
-
- void Unsubscribe(const Anope::string &pattern) override
- {
- if (sub)
- sub->subinterfaces.erase(pattern);
- }
-
- void StartTransaction() override
- {
- if (in_transaction)
- throw CoreException();
-
- this->SendCommand(NULL, "MULTI");
- in_transaction = true;
- }
-
- void CommitTransaction() override
- {
- /* The result of the transaction comes back to the reply of EXEC as a multi bulk.
- * The reply to the individual commands that make up the transaction when executed
- * is a simple +QUEUED
- */
- in_transaction = false;
- this->SendCommand(&this->ti, "EXEC");
- }
-};
-
-RedisSocket::~RedisSocket()
-{
- if (provider)
- {
- if (provider->sock == this)
- provider->sock = NULL;
- else if (provider->sub == this)
- provider->sub = NULL;
- }
-
- for (unsigned i = 0; i < interfaces.size(); ++i)
- {
- Interface *inter = interfaces[i];
-
- if (!inter)
- continue;
-
- inter->OnError("Interface going away");
- }
-}
-
-void RedisSocket::OnConnect()
-{
- provider->GetOwner()->logger.Log(_("Successfully connected to {0}"), provider->GetName() + (this == this->provider->sub ? " (sub)" : ""));
-
- this->provider->SendCommand(NULL, "CLIENT SETNAME Anope");
- this->provider->SendCommand(NULL, "SELECT " + stringify(provider->db));
-}
-
-void RedisSocket::OnError(const Anope::string &error)
-{
- provider->GetOwner()->logger.Log(_("Error on {0}: {1}"), provider->GetName() + (this == this->provider->sub ? " (sub)" : ""), error);
-}
-
-size_t RedisSocket::ParseReply(Reply &r, const char *buffer, size_t l)
-{
- size_t used = 0;
-
- if (!l)
- return used;
-
- if (r.type == Reply::MULTI_BULK)
- goto multi_bulk_cont;
-
- switch (*buffer)
- {
- case '+':
- {
- Anope::string reason(buffer, 1, l - 1);
- size_t nl = reason.find("\r\n");
- provider->GetOwner()->logger.Debug2("status ok: {0}", reason.substr(0, nl));
- if (nl != Anope::string::npos)
- {
- r.type = Reply::OK;
- used = 1 + nl + 2;
- }
- break;
- }
- case '-':
- {
- Anope::string reason(buffer, 1, l - 1);
- size_t nl = reason.find("\r\n");
- provider->GetOwner()->logger.Debug2("status error: {0}", reason.substr(0, nl));
- if (nl != Anope::string::npos)
- {
- r.type = Reply::NOT_OK;
- used = 1 + nl + 2;
- }
- break;
- }
- case ':':
- {
- Anope::string ibuf(buffer, 1, l - 1);
- size_t nl = ibuf.find("\r\n");
- if (nl != Anope::string::npos)
- {
- try
- {
- r.i = convertTo<int64_t>(ibuf.substr(0, nl));
- }
- catch (const ConvertException &) { }
-
- r.type = Reply::INT;
- used = 1 + nl + 2;
- }
- break;
- }
- case '$':
- {
- Anope::string reply(buffer + 1, l - 1);
- /* This assumes one bulk can always fit in our recv buffer */
- size_t nl = reply.find("\r\n");
- if (nl != Anope::string::npos)
- {
- int len;
- try
- {
- len = convertTo<int>(reply.substr(0, nl));
- if (len >= 0)
- {
- if (1 + nl + 2 + len + 2 <= l)
- {
- used = 1 + nl + 2 + len + 2;
- r.bulk = reply.substr(nl + 2, len);
- r.type = Reply::BULK;
- }
- }
- else
- {
- used = 1 + nl + 2 + 2;
- r.type = Reply::BULK;
- }
- }
- catch (const ConvertException &) { }
- }
- break;
- }
- multi_bulk_cont:
- case '*':
- {
- if (r.type != Reply::MULTI_BULK)
- {
- Anope::string reply(buffer + 1, l - 1);
- size_t nl = reply.find("\r\n");
- if (nl != Anope::string::npos)
- {
- r.type = Reply::MULTI_BULK;
- try
- {
- r.multi_bulk_size = convertTo<int>(reply.substr(0, nl));
- }
- catch (const ConvertException &) { }
-
- used = 1 + nl + 2;
- }
- else
- break;
- }
- else if (r.multi_bulk_size >= 0 && r.multi_bulk.size() == static_cast<unsigned>(r.multi_bulk_size))
- {
- /* This multi bulk is already complete, so check the sub bulks */
- for (unsigned i = 0; i < r.multi_bulk.size(); ++i)
- if (r.multi_bulk[i]->type == Reply::MULTI_BULK)
- ParseReply(*r.multi_bulk[i], buffer + used, l - used);
- break;
- }
-
- for (int i = r.multi_bulk.size(); i < r.multi_bulk_size; ++i)
- {
- Reply *reply = new Reply();
- size_t u = ParseReply(*reply, buffer + used, l - used);
- if (!u)
- {
- provider->GetOwner()->logger.Debug("ran out of data to parse");
- delete reply;
- break;
- }
- r.multi_bulk.push_back(reply);
- used += u;
- }
- break;
- }
- default:
- provider->GetOwner()->logger.Debug("unknown reply {0}", *buffer);
- }
-
- return used;
-}
-
-bool RedisSocket::Read(const char *buffer, size_t l)
-{
- static std::vector<char> save;
- std::vector<char> copy;
-
- if (!save.empty())
- {
- std::copy(buffer, buffer + l, std::back_inserter(save));
-
- copy = save;
-
- buffer = &copy[0];
- l = copy.size();
- }
-
- while (l)
- {
- static Reply r;
-
- size_t used = this->ParseReply(r, buffer, l);
- if (!used)
- {
- provider->GetOwner()->logger.Debug("used == 0 ?");
- r.Clear();
- break;
- }
- else if (used > l)
- {
- provider->GetOwner()->logger.Debug("used > l ?");
- r.Clear();
- break;
- }
-
- /* Full result is not here yet */
- if (r.type == Reply::MULTI_BULK && static_cast<unsigned>(r.multi_bulk_size) != r.multi_bulk.size())
- {
- buffer += used;
- l -= used;
- break;
- }
-
- if (this == provider->sub)
- {
- std::map<Anope::string, Interface *>::iterator it = this->subinterfaces.find(r.multi_bulk[1]->bulk);
- if (it != this->subinterfaces.end())
- it->second->OnResult(r);
- }
- else
- {
- if (this->interfaces.empty())
- {
- provider->GetOwner()->logger.Debug("no interfaces?");
- }
- else
- {
- Interface *i = this->interfaces.front();
- this->interfaces.pop_front();
-
- if (i)
- {
- if (r.type != Reply::NOT_OK)
- i->OnResult(r);
- else
- i->OnError(r.bulk);
- }
- }
- }
-
- buffer += used;
- l -= used;
-
- r.Clear();
- }
-
- if (l)
- {
- save.resize(l);
- std::copy(buffer, buffer + l, save.begin());
- }
- else
- std::vector<char>().swap(save);
-
- return true;
-}
-
-
-class ModuleRedis : public Module
- , public EventHook<Event::ModuleUnload>
-{
- std::map<Anope::string, MyRedisService *> services;
-
- public:
- ModuleRedis(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
- , EventHook<Event::ModuleUnload>(this)
- {
- }
-
- ~ModuleRedis()
- {
- for (std::map<Anope::string, MyRedisService *>::iterator it = services.begin(); it != services.end(); ++it)
- {
- MyRedisService *p = it->second;
-
- delete p->sock;
- p->sock = NULL;
- delete p->sub;
- p->sub = NULL;
-
- delete p;
- }
- }
-
- void OnReload(Configuration::Conf *conf) override
- {
- Configuration::Block *block = conf->GetModule(this);
- std::vector<Anope::string> new_services;
-
- for (int i = 0; i < block->CountBlock("redis"); ++i)
- {
- Configuration::Block *redis = block->GetBlock("redis", i);
-
- const Anope::string &n = redis->Get<Anope::string>("name"),
- &ip = redis->Get<Anope::string>("ip");
- int port = redis->Get<int>("port");
- unsigned db = redis->Get<unsigned>("db");
-
- delete services[n];
- services[n] = new MyRedisService(this, n, ip, port, db);
- new_services.push_back(n);
- }
-
- for (std::map<Anope::string, MyRedisService *>::iterator it = services.begin(); it != services.end();)
- {
- Provider *p = it->second;
- ++it;
-
- if (std::find(new_services.begin(), new_services.end(), p->GetName()) == new_services.end())
- delete it->second;
- }
- }
-
- void OnModuleUnload(User *, Module *m) override
- {
- for (std::map<Anope::string, MyRedisService *>::iterator it = services.begin(); it != services.end(); ++it)
- {
- MyRedisService *p = it->second;
-
- if (p->sock)
- for (unsigned i = p->sock->interfaces.size(); i > 0; --i)
- {
- Interface *inter = p->sock->interfaces[i - 1];
-
- if (inter && inter->GetOwner() == m)
- {
- inter->OnError(m->name + " being unloaded");
- p->sock->interfaces.erase(p->sock->interfaces.begin() + i - 1);
- }
- }
-
- if (p->sub)
- for (unsigned i = p->sub->interfaces.size(); i > 0; --i)
- {
- Interface *inter = p->sub->interfaces[i - 1];
-
- if (inter && inter->GetOwner() == m)
- {
- inter->OnError(m->name + " being unloaded");
- p->sub->interfaces.erase(p->sub->interfaces.begin() + i - 1);
- }
- }
-
- for (unsigned i = p->ti.interfaces.size(); i > 0; --i)
- {
- Interface *inter = p->ti.interfaces[i - 1];
-
- if (inter && inter->GetOwner() == m)
- {
- inter->OnError(m->name + " being unloaded");
- p->ti.interfaces.erase(p->ti.interfaces.begin() + i - 1);
- }
- }
- }
- }
-};
-
-MODULE_INIT(ModuleRedis)
diff --git a/modules/sqlite.cpp b/modules/sqlite.cpp
index 3cc618e4c..b9bc063c5 100644
--- a/modules/sqlite.cpp
+++ b/modules/sqlite.cpp
@@ -96,7 +96,7 @@ class SQLiteService : public Provider
Query BeginTransaction() override;
Query Commit() override;
- Serialize::ID GetID(const Anope::string &) override;
+ Serialize::ID GetID(const Anope::string &prefix, const Anope::string &type) override;
Query GetTables(const Anope::string &prefix);
@@ -240,10 +240,6 @@ std::vector<Query> SQLiteService::InitSchema(const Anope::string &prefix)
queries.push_back(Query("PRAGMA foreign_keys = ON"));
- /* https://sqlite.org/lang_createtable.html#rowid, https://sqlite.org/autoinc.html */
- Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + "objects` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `type`)";
- queries.push_back(t);
-
return queries;
}
@@ -251,21 +247,7 @@ std::vector<Query> SQLiteService::Replace(const Anope::string &table, const Quer
{
std::vector<Query> queries;
- Anope::string query_text = "INSERT OR IGNORE INTO `" + table + "` (";
- for (const std::pair<Anope::string, QueryData> &p : q.parameters)
- query_text += "`" + p.first + "`,";
- query_text.erase(query_text.length() - 1);
- query_text += ") VALUES (";
- for (const std::pair<Anope::string, QueryData> &p : q.parameters)
- query_text += "@" + p.first + "@,";
- query_text.erase(query_text.length() - 1);
- query_text += ")";
-
- Query query(query_text);
- query.parameters = q.parameters;
- queries.push_back(query);
-
- query_text = "UPDATE `" + table + "` SET ";
+ Anope::string query_text = "UPDATE `" + table + "` SET ";
for (const std::pair<Anope::string, QueryData> &p : q.parameters)
if (!keys.count(p.first))
query_text += "`" + p.first + "` = @" + p.first + "@,";
@@ -280,7 +262,7 @@ std::vector<Query> SQLiteService::Replace(const Anope::string &table, const Quer
query_text += "`" + key + "` = @" + key + "@";
}
- query = query_text;
+ Query query(query_text);
query.parameters = q.parameters;
queries.push_back(query);
@@ -303,7 +285,7 @@ std::vector<Query> SQLiteService::CreateTable(const Anope::string &prefix, Seria
if (field->is_object)
{
- Anope::string refname = field->GetTypeName() == Serialize::Object::NAME ? "objects" : field->GetTypeName();
+ Anope::string refname = field->GetTypeName();
query += " REFERENCES " + prefix + refname + "(id) ON DELETE ";
if (field->depends)
@@ -321,7 +303,7 @@ std::vector<Query> SQLiteService::CreateTable(const Anope::string &prefix, Seria
query += ",";
}
- query += " `id` INTEGER PRIMARY KEY, FOREIGN KEY (id) REFERENCES " + prefix + "objects(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)";
+ query += " `id` INTEGER PRIMARY KEY AUTOINCREMENT)";
queries.push_back(query);
active_schema[prefix + base->GetName()] = fields;
@@ -343,7 +325,8 @@ std::vector<Query> SQLiteService::AlterTable(const Anope::string &prefix, Serial
if (field->is_object)
{
- buf += " REFERENCES " + prefix + "objects(id) ON DELETE ";
+ Anope::string refname = field->GetTypeName();
+ buf += " REFERENCES " + prefix + refname + "(id) ON DELETE ";
if (field->depends)
{
@@ -394,21 +377,12 @@ Query SQLiteService::Commit()
return Query("COMMIT");
}
-Serialize::ID SQLiteService::GetID(const Anope::string &prefix)
+Serialize::ID SQLiteService::GetID(const Anope::string &prefix, const Anope::string &type)
{
- Query query = "SELECT MAX(id) AS id FROM `" + prefix + "objects`";
- Serialize::ID id = 1;
-
+ Query query = "INSERT INTO `" + prefix + type + "` DEFAULT VALUES";
Result res = RunQuery(query);
- if (res.Rows() && !res.IsNull(0, "id"))
- {
- id = convertTo<Serialize::ID>(res.Get(0, "id"));
-
- /* next id */
- ++id;
- }
- /* OnSerializableCreate is called immediately after this which does the insert, within the same transaction */
+ Serialize::ID id = res.GetID();
return id;
}
diff --git a/src/serialize.cpp b/src/serialize.cpp
index d27950f36..5315a8469 100644
--- a/src/serialize.cpp
+++ b/src/serialize.cpp
@@ -25,7 +25,7 @@
using namespace Serialize;
-std::unordered_map<ID, Object *> Serialize::objects;
+static std::map<Serialize::TypeBase *, std::unordered_map<ID, Object *>> objects;
std::vector<FieldBase *> Serialize::serializableFields;
@@ -34,33 +34,34 @@ std::multimap<Anope::string, Anope::string> Serialize::child_types;
static ID curid;
-Object *Serialize::GetID(ID id)
+Object *Serialize::GetID(Serialize::TypeBase *type, ID id)
{
- auto it = objects.find(id);
- if (it != objects.end())
+ auto it = objects[type].find(id);
+ if (it != objects[type].end())
return it->second;
return nullptr;
}
void Serialize::GC()
{
- for (auto it = objects.begin(); it != objects.end();)
- {
- Object *o = it->second;
-
- if (!o->CanGC())
+ for (auto it = objects.begin(); it != objects.end(); ++it)
+ for (auto it2 = it->second.begin(); it2 != it->second.end();)
{
- // Wipe internal storage to force refetch
- o->Wipe();
- ++it;
- continue;
- }
+ Object *o = it2->second;
- Anope::Logger.Debug2("garbage collected object {0}", o->id);
+ if (!o->CanGC())
+ {
+ // Wipe internal storage to force refetch
+ o->Wipe();
+ ++it2;
+ continue;
+ }
- it = objects.erase(it);
- delete o;
- }
+ Anope::Logger.Debug2("garbage collected object {0}", o->id);
+
+ it2 = it->second.erase(it2);
+ delete o;
+ }
}
void Serialize::Unregister(Module *m)
@@ -109,15 +110,15 @@ std::vector<Edge> Object::GetEdges(TypeBase *type)
Object::Object(TypeBase *type)
{
ID i;
- EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializableGetId, i);
+ EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializableGetId, type, i);
if (result != EVENT_ALLOW)
{
- while (GetID(++curid));
+ while (GetID(type, ++curid));
i = curid;
}
id = i;
- objects[id] = this;
+ objects[type][id] = this;
this->s_type = type;
@@ -131,7 +132,7 @@ Object::Object(TypeBase *type)
Object::Object(TypeBase *type, ID i)
{
this->id = i;
- objects[i] = this;
+ objects[type][id] = this;
this->s_type = type;
@@ -142,7 +143,7 @@ Object::Object(TypeBase *type, ID i)
Object::~Object()
{
- Anope::Logger.Debug2("Destructing object id #{0} address {2} type {3}", id, static_cast<void *>(this), s_type->GetName());
+ Anope::Logger.Debug2("Destructing object id #{0} address {1} type {2}", id, static_cast<void *>(this), s_type->GetName());
/* Remove in memory edges */
std::map<TypeBase *, std::vector<Edge>> copy = edges;
@@ -161,7 +162,7 @@ Object::~Object()
}
}
- objects.erase(id);
+ objects[s_type].erase(id);
s_type->objects.erase(this);
}
@@ -230,18 +231,16 @@ TypeBase::TypeBase(Module *o, const Anope::string &n) : Service(o, TypeBase::NAM
{
}
-TypeBase::~TypeBase()
-{
- if (!Serialize::GetObjects<Object *>(this->GetName()).empty())
- throw CoreException("Type destructing with objects still alive");
-}
-
void TypeBase::Unregister()
{
Anope::Logger.Debug2("Unregistering type {0}", this->GetName());
- for (Object *obj : GetObjects<Object *>(this->GetName()))
- obj->Delete();
+ // Delete in memory objects
+ std::unordered_map<ID, Object *> objs = ::objects[this];
+ for (auto &pair : objs)
+ delete pair.second;
+
+ ::objects.erase(this);
for (FieldBase *field : serializableFields)
{