summaryrefslogtreecommitdiff
path: root/modules/extra
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-04-23 05:08:26 -0400
committerAdam <Adam@anope.org>2012-04-23 05:08:26 -0400
commit573e49a7ead331219eb6f0d3ca9cf83e793a5c9c (patch)
treee145e04fa3d041cf92ce46da4ac790b63231059c /modules/extra
parent63c639e108a00d7dbb0d7ac9891684fc83a3b207 (diff)
Reworked live SQL support yet again
Diffstat (limited to 'modules/extra')
-rw-r--r--modules/extra/m_dnsbl.cpp4
-rw-r--r--modules/extra/m_ldap_authentication.cpp9
-rw-r--r--modules/extra/m_ldap_oper.cpp22
-rw-r--r--modules/extra/m_mysql.cpp81
-rw-r--r--modules/extra/m_proxyscan.cpp4
-rw-r--r--modules/extra/m_sqlite.cpp82
-rw-r--r--modules/extra/m_xmlrpc_main.cpp14
-rw-r--r--modules/extra/ns_maxemail.cpp4
-rw-r--r--modules/extra/sql.h7
9 files changed, 137 insertions, 90 deletions
diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp
index d4c49501c..ed9776e84 100644
--- a/modules/extra/m_dnsbl.cpp
+++ b/modules/extra/m_dnsbl.cpp
@@ -61,7 +61,7 @@ class DNSBLResolver : public DNSRequest
reason = reason.replace_all_cs("%r", record_reason);
reason = reason.replace_all_cs("%N", Config->NetworkName);
- BotInfo *operserv = findbot(Config->OperServ);
+ const BotInfo *operserv = findbot(Config->OperServ);
Log(operserv) << "DNSBL: " << user->GetMask() << " (" << user->ip << ") appears in " << this->blacklist.name;
XLine *x = new XLine("*@" + user->ip, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID());
if (this->add_to_akill && akills)
@@ -72,7 +72,7 @@ class DNSBLResolver : public DNSRequest
else
{
ircdproto->SendAkill(NULL, x);
- delete x;
+ x->destroy();
}
}
};
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp
index a34e6a709..e3267f9e0 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -58,7 +58,7 @@ class IdentifyInterface : public LDAPInterface
if (Config->NSAddAccessOnReg)
na->nc->AddAccess(create_mask(u));
- BotInfo *bi = findbot(Config->NickServ);
+ const BotInfo *bi = findbot(Config->NickServ);
if (bi)
u->SendMessage(bi, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
@@ -123,10 +123,11 @@ class OnIdentifyInterface : public LDAPInterface
const LDAPAttributes &attr = r.get(0);
Anope::string email = attr.get(email_attribute);
- if (!email.equals_ci(u->Account()->email))
+ NickCore *nc = u->Account();
+ if (!email.equals_ci(nc->email))
{
- u->Account()->email = email;
- BotInfo *bi = findbot(Config->NickServ);
+ nc->email = email;
+ const BotInfo *bi = findbot(Config->NickServ);
if (bi)
u->SendMessage(bi, _("Your email has been updated to \002%s\002"), email.c_str());
Log() << "m_ldap_authentication: Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index 6a3bec89f..f432f35b8 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -31,6 +31,8 @@ class IdentifyInterface : public LDAPInterface
if (!u || !u->Account())
return;
+ NickCore *nc = u->Account();
+
try
{
const LDAPAttributes &attr = r.get(0);
@@ -38,9 +40,9 @@ class IdentifyInterface : public LDAPInterface
const Anope::string &opertype = attr.get(opertype_attribute);
OperType *ot = OperType::Find(opertype);
- if (ot != NULL && (u->Account()->o == NULL || ot != u->Account()->o->ot))
+ if (ot != NULL && (nc->o == NULL || ot != nc->o->ot))
{
- Oper *o = u->Account()->o;
+ Oper *o = nc->o;
if (o != NULL && my_opers.count(o) > 0)
{
my_opers.erase(o);
@@ -48,22 +50,22 @@ class IdentifyInterface : public LDAPInterface
}
o = new Oper(u->nick, ot);
my_opers.insert(o);
- u->Account()->o = o;
- Log() << "m_ldap_oper: Tied " << u->nick << " (" << u->Account()->display << ") to opertype " << ot->GetName();
+ nc->o = o;
+ Log() << "m_ldap_oper: Tied " << u->nick << " (" << nc->display << ") to opertype " << ot->GetName();
}
}
catch (const LDAPException &ex)
{
- if (u->Account()->o != NULL)
+ if (nc->o != NULL)
{
- if (my_opers.count(u->Account()->o) > 0)
+ if (my_opers.count(nc->o) > 0)
{
- my_opers.erase(u->Account()->o);
- delete u->Account()->o;
+ my_opers.erase(nc->o);
+ delete nc->o;
}
- u->Account()->o = NULL;
+ nc->o = NULL;
- Log() << "m_ldap_oper: Removed services operator from " << u->nick << " (" << u->Account()->display << ")";
+ Log() << "m_ldap_oper: Removed services operator from " << u->nick << " (" << nc->display << ")";
}
}
}
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp
index e83e78c7c..0696955cd 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/m_mysql.cpp
@@ -49,7 +49,7 @@ class MySQLResult : public SQLResult
MYSQL_RES *res;
public:
- MySQLResult(const SQLQuery &q, const Anope::string &fq, MYSQL_RES *r) : SQLResult(q, fq), res(r)
+ MySQLResult(unsigned int i, const SQLQuery &q, const Anope::string &fq, MYSQL_RES *r) : SQLResult(i, q, fq), res(r)
{
unsigned num_fields = res ? mysql_num_fields(res) : 0;
@@ -80,7 +80,7 @@ class MySQLResult : public SQLResult
}
}
- MySQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(q, fq, err), res(NULL)
+ MySQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(0, q, fq, err), res(NULL)
{
}
@@ -95,6 +95,8 @@ class MySQLResult : public SQLResult
*/
class MySQLService : public SQLProvider
{
+ std::map<Anope::string, std::set<Anope::string> > active_schema;
+
Anope::string database;
Anope::string server;
Anope::string user;
@@ -123,7 +125,7 @@ class MySQLService : public SQLProvider
SQLResult RunQuery(const SQLQuery &query) anope_override;
- SQLQuery CreateTable(const Anope::string &table, const Serializable::serialized_data &data) anope_override;
+ std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override;
SQLQuery GetTables() anope_override;
@@ -305,7 +307,7 @@ MySQLService::~MySQLService()
if (r.service == this)
{
if (r.sqlinterface)
- r.sqlinterface->OnError(SQLResult(r.query, "SQL Interface is going away"));
+ r.sqlinterface->OnError(SQLResult(0, r.query, "SQL Interface is going away"));
me->QueryRequests.erase(me->QueryRequests.begin() + i - 1);
}
}
@@ -329,10 +331,11 @@ SQLResult MySQLService::RunQuery(const SQLQuery &query)
if (this->CheckConnection() && !mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
{
- MYSQL_RES *res = mysql_use_result(this->sql);
+ MYSQL_RES *res = mysql_store_result(this->sql);
+ unsigned int id = mysql_insert_id(this->sql);
this->Lock.Unlock();
- return MySQLResult(query, real_query, res);
+ return MySQLResult(id, query, real_query, res);
}
else
{
@@ -342,38 +345,50 @@ SQLResult MySQLService::RunQuery(const SQLQuery &query)
}
}
-SQLQuery MySQLService::CreateTable(const Anope::string &table, const Serializable::serialized_data &data)
+std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, const Serialize::Data &data)
{
- Anope::string query_text = "CREATE TABLE `" + table + "` (", key_buf;
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
- {
- query_text += "`" + it->first + "` ";
- if (it->second.getType() == Serialize::DT_INT)
- query_text += "int(11)";
- else if (it->second.getMax() > 0)
- query_text += "varchar(" + stringify(it->second.getMax()) + ")";
- else
- query_text += "text";
- query_text += ",";
+ std::vector<SQLQuery> queries;
+ std::set<Anope::string> &known_cols = this->active_schema[table];
- if (it->second.getKey())
+ if (known_cols.empty())
+ {
+ Anope::string query_text = "CREATE TABLE IF NOT EXISTS `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
{
- if (key_buf.empty())
- key_buf = "UNIQUE KEY `ukey` (";
- key_buf += "`" + it->first + "`,";
+ known_cols.insert(it->first);
+
+ query_text += ", `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else if (it->second.getMax() > 0)
+ query_text += "varchar(" + stringify(it->second.getMax()) + ")";
+ else
+ query_text += "text";
}
- }
- if (!key_buf.empty())
- {
- key_buf.erase(key_buf.end() - 1);
- key_buf += ")";
- query_text += " " + key_buf;
+ query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))";
+ queries.push_back(query_text);
}
else
- query_text.erase(query_text.end() - 1);
- query_text += ")";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ {
+ if (known_cols.count(it->first) > 0)
+ continue;
+
+ known_cols.insert(it->first);
+
+ Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else if (it->second.getMax() > 0)
+ query_text += "varchar(" + stringify(it->second.getMax()) + ")";
+ else
+ query_text += "text";
+
+ queries.push_back(query_text);
+ }
- return SQLQuery(query_text);
+ return queries;
}
SQLQuery MySQLService::GetTables()
@@ -391,7 +406,9 @@ void MySQLService::Connect()
bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, NULL, 0);
if (!connect)
- throw SQLException("Unable to connect to SQL service " + this->name + ": " + mysql_error(this->sql));
+ throw SQLException("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql));
+
+ Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port;
}
diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp
index badc293fc..f7fa3fdad 100644
--- a/modules/extra/m_proxyscan.cpp
+++ b/modules/extra/m_proxyscan.cpp
@@ -98,7 +98,7 @@ class ProxyConnect : public ConnectionSocket
ircdproto->SendSZLine(NULL, x);
else
ircdproto->SendAkill(NULL, x);
- delete x;
+ x->destroy();
}
}
};
@@ -360,7 +360,7 @@ class ModuleProxyScan : public Module
if (!this->con_notice.empty() && !this->con_source.empty())
{
- BotInfo *bi = findbot(this->con_source);
+ const BotInfo *bi = findbot(this->con_source);
if (bi)
user->SendMessage(bi, this->con_notice);
}
diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp
index 2dd8ed148..1c82f3459 100644
--- a/modules/extra/m_sqlite.cpp
+++ b/modules/extra/m_sqlite.cpp
@@ -11,11 +11,11 @@
class SQLiteResult : public SQLResult
{
public:
- SQLiteResult(const SQLQuery &q, const Anope::string &fq) : SQLResult(q, fq)
+ SQLiteResult(unsigned int i, const SQLQuery &q, const Anope::string &fq) : SQLResult(i, q, fq)
{
}
- SQLiteResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(q, fq, err)
+ SQLiteResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(0, q, fq, err)
{
}
@@ -29,6 +29,8 @@ class SQLiteResult : public SQLResult
*/
class SQLiteService : public SQLProvider
{
+ std::map<Anope::string, std::set<Anope::string> > active_schema;
+
Anope::string database;
sqlite3 *sql;
@@ -44,7 +46,7 @@ class SQLiteService : public SQLProvider
SQLResult RunQuery(const SQLQuery &query);
- SQLQuery CreateTable(const Anope::string &table, const Serializable::serialized_data &data) anope_override;
+ std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override;
SQLQuery GetTables();
@@ -156,7 +158,7 @@ SQLResult SQLiteService::RunQuery(const SQLQuery &query)
for (int i = 0; i < cols; ++i)
columns[i] = sqlite3_column_name(stmt, i);
- SQLiteResult result(query, real_query);
+ SQLiteResult result(0, query, real_query);
while ((err = sqlite3_step(stmt)) == SQLITE_ROW)
{
@@ -170,6 +172,8 @@ SQLResult SQLiteService::RunQuery(const SQLQuery &query)
result.addRow(items);
}
+ result.id = sqlite3_last_insert_rowid(this->sql);
+
sqlite3_finalize(stmt);
if (err != SQLITE_DONE)
@@ -178,38 +182,58 @@ SQLResult SQLiteService::RunQuery(const SQLQuery &query)
return result;
}
-SQLQuery SQLiteService::CreateTable(const Anope::string &table, const Serializable::serialized_data &data)
+std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, const Serialize::Data &data)
{
- Anope::string query_text = "CREATE TABLE `" + table + "` (", key_buf;
- for (Serializable::serialized_data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ std::vector<SQLQuery> queries;
+ std::set<Anope::string> &known_cols = this->active_schema[table];
+
+ if (active_schema.empty())
{
- query_text += "`" + it->first + "` ";
- if (it->second.getType() == Serialize::DT_INT)
- query_text += "int(11)";
- else if (it->second.getMax() > 0)
- query_text += "varchar(" + stringify(it->second.getMax()) + ")";
- else
- query_text += "text";
- query_text += ",";
-
- if (it->second.getKey())
+ Anope::string query_text = "CREATE TABLE IF NOT EXISTS `" + table + "` (id INTEGER PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, ";
+
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
{
- if (key_buf.empty())
- key_buf = "UNIQUE (";
- key_buf += "`" + it->first + "`,";
+ known_cols.insert(it->first);
+
+ query_text += ", `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else
+ query_text += "text";
}
- }
- if (!key_buf.empty())
- {
- key_buf.erase(key_buf.end() - 1);
- key_buf += ")";
- query_text += " " + key_buf;
+
+ query_text.erase(query_text.end() - 1);
+ query_text += ")";
+
+ queries.push_back(query_text);
+
+ query_text = "CREATE UNIQUE INDEX IF NOT EXISTS `id_idx` ON `" + table + "` (`id`)";
+ queries.push_back(query_text);
+
+ query_text = "CREATE INDEX IF NOT EXISTS `timestamp_idx` ON `" + table + "` (`timestamp`)";
+ queries.push_back(query_text);
+
+ query_text = "CREATE TRIGGER `" + table + "_trigger` AFTER UPDATE ON `" + table + "` FOR EACH ROW BEGIN UPDATE `" + table + "` SET `timestamp` = CURRENT_TIMESTAMP WHERE `id` = `old.id`; end;";
+ queries.push_back(query_text);
}
else
- query_text.erase(query_text.end() - 1);
- query_text += ")";
+ for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it)
+ {
+ if (known_cols.count(it->first) > 0)
+ continue;
+
+ known_cols.insert(it->first);
+
+ Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` ";
+ if (it->second.getType() == Serialize::DT_INT)
+ query_text += "int(11)";
+ else
+ query_text += "text";
+
+ queries.push_back(query_text);
+ }
- return SQLQuery(query_text);
+ return queries;
}
SQLQuery SQLiteService::GetTables()
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 06ed55c86..0dec9997a 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -5,7 +5,7 @@
class XMLRPCUser : public User
{
Anope::string out;
- dynamic_reference<NickAlias> na;
+ NickAlias *na;
public:
XMLRPCUser(const Anope::string &nnick) : User(nnick, Config->NSEnforcerUser, Config->NSEnforcerHost, ""), na(findnick(nick))
@@ -14,22 +14,22 @@ class XMLRPCUser : public User
this->server = Me;
}
- void SendMessage(BotInfo *, Anope::string msg) anope_override
+ void SendMessage(const BotInfo *, Anope::string msg) anope_override
{
this->out += msg + "\n";
}
- NickCore *Account() anope_override
+ NickCore *Account() const anope_override
{
- return (na ? na->nc : NULL);
+ return (na ? *na->nc : NULL);
}
- bool IsIdentified(bool CheckNick = false) anope_override
+ bool IsIdentified(bool CheckNick = false) const anope_override
{
return na;
}
- bool IsRecognized(bool CheckSecure = true) anope_override
+ bool IsRecognized(bool CheckSecure = true) const anope_override
{
return na;
}
@@ -111,7 +111,7 @@ class MyXMLRPCEvent : public XMLRPCEvent
request->reply("error", "Invalid parameters");
else
{
- NickAlias *na = findnick(username);
+ const NickAlias *na = findnick(username);
if (!na)
request->reply("error", "Invalid account");
diff --git a/modules/extra/ns_maxemail.cpp b/modules/extra/ns_maxemail.cpp
index 350913fab..d8d7d3ec6 100644
--- a/modules/extra/ns_maxemail.cpp
+++ b/modules/extra/ns_maxemail.cpp
@@ -42,9 +42,9 @@ class NSMaxEmail : public Module
if (email.empty())
return 0;
- for (nickcore_map::const_iterator it = NickCoreList.begin(), it_end = NickCoreList.end(); it != it_end; ++it)
+ for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
{
- NickCore *nc = it->second;
+ const NickCore *nc = it->second;
if (!(u->Account() && u->Account() == nc) && !nc->email.empty() && nc->email.equals_ci(email))
++count;
diff --git a/modules/extra/sql.h b/modules/extra/sql.h
index b23466dee..a986cf794 100644
--- a/modules/extra/sql.h
+++ b/modules/extra/sql.h
@@ -65,12 +65,15 @@ class SQLResult
SQLQuery query;
Anope::string error;
public:
+ unsigned int id;
Anope::string finished_query;
- SQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), finished_query(fq) { }
+ SQLResult() : id(0) { }
+ SQLResult(unsigned int i, const SQLQuery &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { }
inline operator bool() const { return this->error.empty(); }
+ inline const unsigned int GetID() const { return this->id; }
inline const SQLQuery &GetQuery() const { return this->query; }
inline const Anope::string &GetError() const { return this->error; }
@@ -124,7 +127,7 @@ class SQLProvider : public Service
virtual SQLResult RunQuery(const SQLQuery &query) = 0;
- virtual SQLQuery CreateTable(const Anope::string &table, const Serializable::serialized_data &data) = 0;
+ virtual std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) = 0;
virtual SQLQuery GetTables() = 0;
};