diff options
Diffstat (limited to 'modules/extra')
-rw-r--r-- | modules/extra/m_chanstats.cpp | 58 | ||||
-rw-r--r-- | modules/extra/m_mysql.cpp | 96 | ||||
-rw-r--r-- | modules/extra/m_sql_authentication.cpp | 28 | ||||
-rw-r--r-- | modules/extra/m_sql_oper.cpp | 22 | ||||
-rw-r--r-- | modules/extra/m_sqlite.cpp | 76 | ||||
-rw-r--r-- | modules/extra/sql.h | 280 | ||||
-rw-r--r-- | modules/extra/webcpanel/pages/chanserv/access.cpp | 2 |
7 files changed, 325 insertions, 237 deletions
diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp index b50592b0f..7096b39a5 100644 --- a/modules/extra/m_chanstats.cpp +++ b/modules/extra/m_chanstats.cpp @@ -1,16 +1,16 @@ #include "module.h" #include "../extra/sql.h" -class MySQLInterface : public SQLInterface +class MySQLInterface : public SQL::Interface { public: - MySQLInterface(Module *o) : SQLInterface(o) { } + MySQLInterface(Module *o) : SQL::Interface(o) { } - void OnResult(const SQLResult &r) anope_override + void OnResult(const SQL::Result &r) anope_override { } - void OnError(const SQLResult &r) anope_override + void OnError(const SQL::Result &r) anope_override { if (!r.GetQuery().query.empty()) Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); @@ -21,13 +21,13 @@ class MySQLInterface : public SQLInterface class MChanstats : public Module { - ServiceReference<SQLProvider> sql; + ServiceReference<SQL::Provider> sql; MySQLInterface sqlinterface; - SQLQuery query; + SQL::Query query; Anope::string SmileysHappy, SmileysSad, SmileysOther, prefix; std::vector<Anope::string> TableList, ProcedureList, EventList; - void RunQuery(const SQLQuery &q) + void RunQuery(const SQL::Query &q) { if (sql) sql->Run(&sqlinterface, q); @@ -70,7 +70,7 @@ class MChanstats : public Module if (!sql) return; - SQLResult r = this->sql->RunQuery(this->sql->GetTables(prefix)); + SQL::Result r = this->sql->RunQuery(this->sql->GetTables(prefix)); for (int i = 0; i < r.Rows(); ++i) { const std::map<Anope::string, Anope::string> &map = r.Row(i); @@ -359,7 +359,7 @@ class MChanstats : public Module SmileysOther = config.ReadValue("chanstats", "SmileysOther", ":/", 0); Anope::string engine = config.ReadValue("chanstats", "engine", "", 0); - this->sql = ServiceReference<SQLProvider>("SQLProvider", engine); + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); if (sql) this->CheckTables(); else @@ -371,8 +371,8 @@ class MChanstats : public Module if (!u || !u->Account() || !c->ci || !c->ci->HasFlag(CI_STATS)) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);"; - query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(u)); + query.SetValue("channel", c->name); + query.SetValue("nick", GetDisplay(u)); this->RunQuery(query); } EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override @@ -392,8 +392,8 @@ class MChanstats : public Module return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);"; - query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(u)); + query.SetValue("channel", c->name); + query.SetValue("nick", GetDisplay(u)); this->RunQuery(query); } public: @@ -403,13 +403,13 @@ class MChanstats : public Module return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);"; - query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(target)); + query.SetValue("channel", c->name); + query.SetValue("nick", GetDisplay(target)); this->RunQuery(query); query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);"; - query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(source.GetUser())); + query.SetValue("channel", c->name); + query.SetValue("nick", GetDisplay(source.GetUser())); this->RunQuery(query); } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override @@ -437,33 +437,33 @@ class MChanstats : public Module words = words - smileys_happy - smileys_sad - smileys_other; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 1, @letters@, @words@, @action@, " "@smileys_happy@, @smileys_sad@, @smileys_other@, '0', '0', '0', '0');"; - query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(u)); - query.setValue("letters", letters); - query.setValue("words", words); - query.setValue("action", action); - query.setValue("smileys_happy", smileys_happy); - query.setValue("smileys_sad", smileys_sad); - query.setValue("smileys_other", smileys_other); + query.SetValue("channel", c->name); + query.SetValue("nick", GetDisplay(u)); + query.SetValue("letters", letters); + query.SetValue("words", words); + query.SetValue("action", action); + query.SetValue("smileys_happy", smileys_happy); + query.SetValue("smileys_sad", smileys_sad); + query.SetValue("smileys_other", smileys_other); this->RunQuery(query); } void OnDelCore(NickCore *nc) anope_override { query = "DELETE FROM `" + prefix + "chanstats` WHERE `nick` = @nick@;"; - query.setValue("nick", nc->display); + query.SetValue("nick", nc->display); this->RunQuery(query); } void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override { query = "CALL " + prefix + "chanstats_proc_chgdisplay(@old_display@, @new_display@);"; - query.setValue("old_display", nc->display); - query.setValue("new_display", newdisplay); + query.SetValue("old_display", nc->display); + query.SetValue("new_display", newdisplay); this->RunQuery(query); } void OnChanDrop(ChannelInfo *ci) anope_override { query = "DELETE FROM `" + prefix + "chanstats` WHERE `chan` = @channel@;"; - query.setValue("channel", ci->name); + query.SetValue("channel", ci->name); this->RunQuery(query); } }; diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index 47f6f41de..a8433fd38 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -5,6 +5,8 @@ #include <mysql/mysql.h> #include "sql.h" +using namespace SQL; + /** Non blocking threaded MySQL API, based loosely from InspIRCd's m_mysql.cpp * * This module spawns a single thread that is used to execute blocking MySQL queries. @@ -24,32 +26,32 @@ struct QueryRequest /* The connection to the database */ MySQLService *service; /* The interface to use once we have the result to send the data back */ - SQLInterface *sqlinterface; + Interface *sqlinterface; /* The actual query */ - SQLQuery query; + Query query; - QueryRequest(MySQLService *s, SQLInterface *i, const SQLQuery &q) : service(s), sqlinterface(i), query(q) { } + QueryRequest(MySQLService *s, Interface *i, const Query &q) : service(s), sqlinterface(i), query(q) { } }; /** A query result */ struct QueryResult { /* The interface to send the data back on */ - SQLInterface *sqlinterface; + Interface *sqlinterface; /* The result */ - SQLResult result; + Result result; - QueryResult(SQLInterface *i, SQLResult &r) : sqlinterface(i), result(r) { } + QueryResult(Interface *i, Result &r) : sqlinterface(i), result(r) { } }; /** A MySQL result */ -class MySQLResult : public SQLResult +class MySQLResult : public Result { MYSQL_RES *res; public: - MySQLResult(unsigned int i, const SQLQuery &q, const Anope::string &fq, MYSQL_RES *r) : SQLResult(i, q, fq), res(r) + MySQLResult(unsigned int i, const Query &q, const Anope::string &fq, MYSQL_RES *r) : Result(i, q, fq), res(r) { unsigned num_fields = res ? mysql_num_fields(res) : 0; @@ -79,7 +81,7 @@ class MySQLResult : public SQLResult } } - MySQLResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(0, q, fq, err), res(NULL) + MySQLResult(const Query &q, const Anope::string &fq, const Anope::string &err) : Result(0, q, fq, err), res(NULL) { } @@ -92,7 +94,7 @@ class MySQLResult : public SQLResult /** A MySQL connection, there can be multiple */ -class MySQLService : public SQLProvider +class MySQLService : public Provider { std::map<Anope::string, std::set<Anope::string> > active_schema; @@ -120,21 +122,21 @@ class MySQLService : public SQLProvider ~MySQLService(); - void Run(SQLInterface *i, const SQLQuery &query) anope_override; + void Run(Interface *i, const Query &query) anope_override; - SQLResult RunQuery(const SQLQuery &query) anope_override; + Result RunQuery(const Query &query) anope_override; - std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override; + std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override; - SQLQuery BuildInsert(const Anope::string &table, unsigned int id, Serialize::Data &data); + Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) anope_override; - SQLQuery GetTables(const Anope::string &prefix) anope_override; + Query GetTables(const Anope::string &prefix) anope_override; void Connect(); bool CheckConnection(); - Anope::string BuildQuery(const SQLQuery &q); + Anope::string BuildQuery(const Query &q); Anope::string FromUnixtime(time_t); }; @@ -235,7 +237,7 @@ class ModuleSQL : public Module, public Pipe Log(LOG_NORMAL, "mysql") << "MySQL: Successfully connected to server " << connname << " (" << server << ")"; } - catch (const SQLException &ex) + catch (const SQL::Exception &ex) { Log(LOG_NORMAL, "mysql") << "MySQL: " << ex.GetReason(); } @@ -280,7 +282,7 @@ class ModuleSQL : public Module, public Pipe const QueryResult &qr = *it; if (!qr.sqlinterface) - throw SQLException("NULL qr.sqlinterface in MySQLPipe::OnNotify() ?"); + throw SQL::Exception("NULL qr.sqlinterface in MySQLPipe::OnNotify() ?"); if (qr.result.GetError().empty()) qr.sqlinterface->OnResult(qr.result); @@ -291,7 +293,7 @@ class ModuleSQL : public Module, public Pipe }; MySQLService::MySQLService(Module *o, const Anope::string &n, const Anope::string &d, const Anope::string &s, const Anope::string &u, const Anope::string &p, int po) -: SQLProvider(o, n), database(d), server(s), user(u), password(p), port(po), sql(NULL) +: Provider(o, n), database(d), server(s), user(u), password(p), port(po), sql(NULL) { Connect(); } @@ -310,7 +312,7 @@ MySQLService::~MySQLService() if (r.service == this) { if (r.sqlinterface) - r.sqlinterface->OnError(SQLResult(0, r.query, "SQL Interface is going away")); + r.sqlinterface->OnError(Result(0, r.query, "SQL Interface is going away")); me->QueryRequests.erase(me->QueryRequests.begin() + i - 1); } } @@ -318,7 +320,7 @@ MySQLService::~MySQLService() me->DThread->Unlock(); } -void MySQLService::Run(SQLInterface *i, const SQLQuery &query) +void MySQLService::Run(Interface *i, const Query &query) { me->DThread->Lock(); me->QueryRequests.push_back(QueryRequest(this, i, query)); @@ -326,7 +328,7 @@ void MySQLService::Run(SQLInterface *i, const SQLQuery &query) me->DThread->Wakeup(); } -SQLResult MySQLService::RunQuery(const SQLQuery &query) +Result MySQLService::RunQuery(const Query &query) { this->Lock.Lock(); @@ -348,16 +350,16 @@ SQLResult MySQLService::RunQuery(const SQLQuery &query) } } -std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, const Serialize::Data &data) +std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const Data &data) { - std::vector<SQLQuery> queries; + std::vector<Query> queries; std::set<Anope::string> &known_cols = this->active_schema[table]; if (known_cols.empty()) { Log(LOG_DEBUG) << "m_mysql: Fetching columns for " << table; - SQLResult columns = this->RunQuery("SHOW COLUMNS FROM `" + table + "`"); + Result columns = this->RunQuery("SHOW COLUMNS FROM `" + table + "`"); for (int i = 0; i < columns.Rows(); ++i) { const Anope::string &column = columns.Get(i, "Field"); @@ -371,15 +373,13 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons { Anope::string query_text = "CREATE TABLE `" + 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) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { known_cols.insert(it->first); query_text += ", `" + it->first + "` "; - if (it->second.GetType() == Serialize::DT_INT) + if (data.GetType(it->first) == Serialize::Data::DT_INT) query_text += "int(11)"; - else if (it->second.GetMax() > 0) - query_text += "varchar(" + stringify(it->second.GetMax()) + ")"; else query_text += "text"; } @@ -387,7 +387,7 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons queries.push_back(query_text); } else - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { if (known_cols.count(it->first) > 0) continue; @@ -395,10 +395,8 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons known_cols.insert(it->first); Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` "; - if (it->second.GetType() == Serialize::DT_INT) + if (data.GetType(it->first) == Serialize::Data::DT_INT) query_text += "int(11)"; - else if (it->second.GetMax() > 0) - query_text += "varchar(" + stringify(it->second.GetMax()) + ")"; else query_text += "text"; @@ -408,35 +406,39 @@ std::vector<SQLQuery> MySQLService::CreateTable(const Anope::string &table, cons return queries; } -SQLQuery MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Serialize::Data &data) +Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) anope_override { /* Empty columns not present in the data set */ const std::set<Anope::string> &known_cols = this->active_schema[table]; for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it) - if (*it != "id" && *it != "timestamp" && data.count(*it) == 0) + if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0) data[*it] << ""; Anope::string query_text = "INSERT INTO `" + table + "` (`id`"; - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) query_text += ",`" + it->first + "`"; query_text += ") VALUES (" + stringify(id); - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) query_text += ",@" + it->first + "@"; query_text += ") ON DUPLICATE KEY UPDATE "; - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) query_text += "`" + it->first + "`=VALUES(`" + it->first + "`),"; query_text.erase(query_text.end() - 1); - SQLQuery query(query_text); - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) - query.setValue(it->first, it->second.astr()); + Query query(query_text); + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) + { + Anope::string buf; + *it->second >> buf; + query.SetValue(it->first, buf); + } return query; } -SQLQuery MySQLService::GetTables(const Anope::string &prefix) +Query MySQLService::GetTables(const Anope::string &prefix) { - return SQLQuery("SHOW TABLES LIKE '" + prefix + "%';"); + return Query("SHOW TABLES LIKE '" + prefix + "%';"); } void MySQLService::Connect() @@ -449,7 +451,7 @@ 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, CLIENT_MULTI_RESULTS); if (!connect) - throw SQLException("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql)); + throw SQL::Exception("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; } @@ -463,7 +465,7 @@ bool MySQLService::CheckConnection() { this->Connect(); } - catch (const SQLException &) + catch (const SQL::Exception &) { return false; } @@ -479,7 +481,7 @@ Anope::string MySQLService::Escape(const Anope::string &query) return buffer; } -Anope::string MySQLService::BuildQuery(const SQLQuery &q) +Anope::string MySQLService::BuildQuery(const Query &q) { Anope::string real_query = q.query; @@ -505,7 +507,7 @@ void DispatcherThread::Run() QueryRequest &r = me->QueryRequests.front(); this->Unlock(); - SQLResult sresult = r.service->RunQuery(r.query); + Result sresult = r.service->RunQuery(r.query); this->Lock(); if (!me->QueryRequests.empty() && me->QueryRequests.front().query == r.query) diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp index ce7a275b3..e1afbc923 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/m_sql_authentication.cpp @@ -3,13 +3,13 @@ static Module *me; -class SQLAuthenticationResult : public SQLInterface +class SQLAuthenticationResult : public SQL::Interface { Reference<User> user; IdentifyRequest *req; public: - SQLAuthenticationResult(User *u, IdentifyRequest *r) : SQLInterface(me), user(u), req(r) + SQLAuthenticationResult(User *u, IdentifyRequest *r) : SQL::Interface(me), user(u), req(r) { req->Hold(me); } @@ -19,7 +19,7 @@ class SQLAuthenticationResult : public SQLInterface req->Release(me); } - void OnResult(const SQLResult &r) anope_override + void OnResult(const SQL::Result &r) anope_override { if (r.Rows() == 0) { @@ -35,7 +35,7 @@ class SQLAuthenticationResult : public SQLInterface { email = r.Get(0, "email"); } - catch (const SQLException &) { } + catch (const SQL::Exception &) { } NickAlias *na = NickAlias::Find(req->GetAccount()); if (na == NULL) @@ -62,7 +62,7 @@ class SQLAuthenticationResult : public SQLInterface delete this; } - void OnError(const SQLResult &r) anope_override + void OnError(const SQL::Result &r) anope_override { Log(this->owner) << "m_sql_authentication: Error executing query " << r.GetQuery().query << ": " << r.GetError(); delete this; @@ -76,7 +76,7 @@ class ModuleSQLAuthentication : public Module bool disable_register; Anope::string disable_reason; - ServiceReference<SQLProvider> SQL; + ServiceReference<SQL::Provider> SQL; public: ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) @@ -100,7 +100,7 @@ class ModuleSQLAuthentication : public Module this->disable_register = config.ReadFlag("m_sql_authentication", "disable_ns_register", "false", 0); this->disable_reason = config.ReadValue("m_sql_authentication", "disable_reason", "", 0); - this->SQL = ServiceReference<SQLProvider>("SQLProvider", this->engine); + this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override @@ -122,18 +122,18 @@ class ModuleSQLAuthentication : public Module return; } - SQLQuery q(this->query); - q.setValue("a", req->GetAccount()); - q.setValue("p", req->GetPassword()); + SQL::Query q(this->query); + q.SetValue("a", req->GetAccount()); + q.SetValue("p", req->GetPassword()); if (u) { - q.setValue("n", u->nick); - q.setValue("i", u->ip); + q.SetValue("n", u->nick); + q.SetValue("i", u->ip); } else { - q.setValue("n", ""); - q.setValue("i", ""); + q.SetValue("n", ""); + q.SetValue("i", ""); } diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp index 523272a49..dd1f13b74 100644 --- a/modules/extra/m_sql_oper.cpp +++ b/modules/extra/m_sql_oper.cpp @@ -1,7 +1,7 @@ #include "module.h" #include "sql.h" -class SQLOperResult : public SQLInterface +class SQLOperResult : public SQL::Interface { Reference<User> user; @@ -13,9 +13,9 @@ class SQLOperResult : public SQLInterface }; public: - SQLOperResult(Module *m, User *u) : SQLInterface(m), user(u) { } + SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { } - void OnResult(const SQLResult &r) anope_override + void OnResult(const SQL::Result &r) anope_override { SQLOperResultDeleter d(this); @@ -27,7 +27,7 @@ class SQLOperResult : public SQLInterface { opertype = r.Get(0, "opertype"); } - catch (const SQLException &) + catch (const SQL::Exception &) { return; } @@ -39,7 +39,7 @@ class SQLOperResult : public SQLInterface { modes = r.Get(0, "modes"); } - catch (const SQLException &) { } + catch (const SQL::Exception &) { } if (opertype.empty()) { @@ -79,7 +79,7 @@ class SQLOperResult : public SQLInterface } } - void OnError(const SQLResult &r) anope_override + void OnError(const SQL::Result &r) anope_override { SQLOperResultDeleter d(this); Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError(); @@ -91,7 +91,7 @@ class ModuleSQLOper : public Module Anope::string engine; Anope::string query; - ServiceReference<SQLProvider> SQL; + ServiceReference<SQL::Provider> SQL; public: ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) @@ -111,7 +111,7 @@ class ModuleSQLOper : public Module this->engine = config.ReadValue("m_sql_oper", "engine", "", 0); this->query = config.ReadValue("m_sql_oper", "query", "", 0); - this->SQL = ServiceReference<SQLProvider>("SQLProvider", this->engine); + this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } void OnNickIdentify(User *u) anope_override @@ -122,9 +122,9 @@ class ModuleSQLOper : public Module return; } - SQLQuery q(this->query); - q.setValue("a", u->Account()->display); - q.setValue("i", u->ip); + SQL::Query q(this->query); + q.SetValue("a", u->Account()->display); + q.SetValue("i", u->ip); this->SQL->Run(new SQLOperResult(this, u), q); diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 971345475..5d59c3eb9 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -4,22 +4,24 @@ #include <sqlite3.h> #include "sql.h" +using namespace SQL; + /* SQLite3 API, based from InspiRCd */ /** A SQLite result */ -class SQLiteResult : public SQLResult +class SQLiteResult : public Result { public: - SQLiteResult(unsigned int i, const SQLQuery &q, const Anope::string &fq) : SQLResult(i, q, fq) + SQLiteResult(unsigned int i, const Query &q, const Anope::string &fq) : Result(i, q, fq) { } - SQLiteResult(const SQLQuery &q, const Anope::string &fq, const Anope::string &err) : SQLResult(0, q, fq, err) + SQLiteResult(const Query &q, const Anope::string &fq, const Anope::string &err) : Result(0, q, fq, err) { } - void addRow(const std::map<Anope::string, Anope::string> &data) + void AddRow(const std::map<Anope::string, Anope::string> &data) { this->entries.push_back(data); } @@ -27,7 +29,7 @@ class SQLiteResult : public SQLResult /** A SQLite database, there can be multiple */ -class SQLiteService : public SQLProvider +class SQLiteService : public Provider { std::map<Anope::string, std::set<Anope::string> > active_schema; @@ -42,17 +44,17 @@ class SQLiteService : public SQLProvider ~SQLiteService(); - void Run(SQLInterface *i, const SQLQuery &query) anope_override; + void Run(Interface *i, const Query &query) anope_override; - SQLResult RunQuery(const SQLQuery &query); + Result RunQuery(const Query &query); - std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) anope_override; + std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override; - SQLQuery BuildInsert(const Anope::string &table, unsigned int id, Serialize::Data &data); + Query BuildInsert(const Anope::string &table, unsigned int id, Data &data); - SQLQuery GetTables(const Anope::string &prefix); + Query GetTables(const Anope::string &prefix); - Anope::string BuildQuery(const SQLQuery &q); + Anope::string BuildQuery(const Query &q); Anope::string FromUnixtime(time_t); }; @@ -116,7 +118,7 @@ class ModuleSQLite : public Module Log(LOG_NORMAL, "sqlite") << "SQLite: Successfully added database " << database; } - catch (const SQLException &ex) + catch (const SQL::Exception &ex) { Log(LOG_NORMAL, "sqlite") << "SQLite: " << ex.GetReason(); } @@ -126,11 +128,11 @@ class ModuleSQLite : public Module }; SQLiteService::SQLiteService(Module *o, const Anope::string &n, const Anope::string &d) -: SQLProvider(o, n), database(d), sql(NULL) +: Provider(o, n), database(d), sql(NULL) { int db = sqlite3_open_v2(database.c_str(), &this->sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); if (db != SQLITE_OK) - throw SQLException("Unable to open SQLite database " + database + ": " + sqlite3_errmsg(this->sql)); + throw SQL::Exception("Unable to open SQLite database " + database + ": " + sqlite3_errmsg(this->sql)); } SQLiteService::~SQLiteService() @@ -139,16 +141,16 @@ SQLiteService::~SQLiteService() sqlite3_close(this->sql); } -void SQLiteService::Run(SQLInterface *i, const SQLQuery &query) +void SQLiteService::Run(Interface *i, const Query &query) { - SQLResult res = this->RunQuery(query); + Result res = this->RunQuery(query); if (!res.GetError().empty()) i->OnError(res); else i->OnResult(res); } -SQLResult SQLiteService::RunQuery(const SQLQuery &query) +Result SQLiteService::RunQuery(const Query &query) { Anope::string real_query = this->BuildQuery(query); sqlite3_stmt *stmt; @@ -173,7 +175,7 @@ SQLResult SQLiteService::RunQuery(const SQLQuery &query) if (data && *data) items[columns[i]] = data; } - result.addRow(items); + result.AddRow(items); } result.id = sqlite3_last_insert_rowid(this->sql); @@ -186,16 +188,16 @@ SQLResult SQLiteService::RunQuery(const SQLQuery &query) return result; } -std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, const Serialize::Data &data) +std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const Data &data) { - std::vector<SQLQuery> queries; + std::vector<Query> queries; std::set<Anope::string> &known_cols = this->active_schema[table]; if (known_cols.empty()) { Log(LOG_DEBUG) << "m_sqlite: Fetching columns for " << table; - SQLResult columns = this->RunQuery("PRAGMA table_info(" + table + ")"); + Result columns = this->RunQuery("PRAGMA table_info(" + table + ")"); for (int i = 0; i < columns.Rows(); ++i) { const Anope::string &column = columns.Get(i, "name"); @@ -209,12 +211,12 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con { Anope::string query_text = "CREATE TABLE `" + 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) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { known_cols.insert(it->first); query_text += ", `" + it->first + "` "; - if (it->second.GetType() == Serialize::DT_INT) + if (data.GetType(it->first) == Serialize::Data::DT_INT) query_text += "int(11)"; else query_text += "text"; @@ -234,7 +236,7 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con queries.push_back(query_text); } else - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { if (known_cols.count(it->first) > 0) continue; @@ -242,7 +244,7 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con known_cols.insert(it->first); Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` "; - if (it->second.GetType() == Serialize::DT_INT) + if (data.GetType(it->first) == Serialize::Data::DT_INT) query_text += "int(11)"; else query_text += "text"; @@ -253,38 +255,42 @@ std::vector<SQLQuery> SQLiteService::CreateTable(const Anope::string &table, con return queries; } -SQLQuery SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, Serialize::Data &data) +Query SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) { /* Empty columns not present in the data set */ const std::set<Anope::string> &known_cols = this->active_schema[table]; for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it) - if (*it != "id" && *it != "timestamp" && data.count(*it) == 0) + if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0) data[*it] << ""; Anope::string query_text = "REPLACE INTO `" + table + "` ("; if (id > 0) query_text += "`id`,"; - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) query_text += "`" + it->first + "`,"; query_text.erase(query_text.length() - 1); query_text += ") VALUES ("; if (id > 0) query_text += stringify(id) + ","; - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) query_text += "@" + it->first + "@,"; query_text.erase(query_text.length() - 1); query_text += ")"; - SQLQuery query(query_text); - for (Serialize::Data::const_iterator it = data.begin(), it_end = data.end(); it != it_end; ++it) - query.setValue(it->first, it->second.astr()); + Query query(query_text); + for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) + { + Anope::string buf; + *it->second >> buf; + query.SetValue(it->first, buf); + } return query; } -SQLQuery SQLiteService::GetTables(const Anope::string &prefix) +Query SQLiteService::GetTables(const Anope::string &prefix) { - return SQLQuery("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';"); + return Query("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';"); } Anope::string SQLiteService::Escape(const Anope::string &query) @@ -295,7 +301,7 @@ Anope::string SQLiteService::Escape(const Anope::string &query) return buffer; } -Anope::string SQLiteService::BuildQuery(const SQLQuery &q) +Anope::string SQLiteService::BuildQuery(const Query &q) { Anope::string real_query = q.query; diff --git a/modules/extra/sql.h b/modules/extra/sql.h index 89686bfe8..f8c7a5961 100644 --- a/modules/extra/sql.h +++ b/modules/extra/sql.h @@ -1,139 +1,219 @@ - -/** A SQL exception, can be thrown at various points +/* + * (C) 2003-2012 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. */ -class SQLException : public ModuleException + +namespace SQL { - public: - SQLException(const Anope::string &reason) : ModuleException(reason) { } - virtual ~SQLException() throw() { } -}; + class Data : public Serialize::Data + { + public: + typedef std::map<Anope::string, std::stringstream *> Map; + Map data; + std::map<Anope::string, Type> types; -/** A SQL query - */ + ~Data() + { + Clear(); + } -struct QueryData -{ - Anope::string data; - bool escape; -}; + std::iostream& operator[](const Anope::string &key) anope_override + { + std::stringstream *&ss = data[key]; + if (!ss) + ss = new std::stringstream(); + return *ss; + } -struct SQLQuery -{ - Anope::string query; - std::map<Anope::string, QueryData> parameters; + bool IsEqual(Serialize::Data *other) anope_override + { + try + { + Data *o = anope_dynamic_static_cast<Data *>(other); + + for (std::map<Anope::string, std::stringstream *>::const_iterator it = o->data.begin(), it_end = o->data.end(); it != it_end; ++it) + if (!this->data.count(it->first) || it->second->str() != this->data[it->first]->str()) + return false; + + return true; + } + catch (const CoreException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + + return false; + } - SQLQuery() { } - SQLQuery(const Anope::string &q) : query(q) { } + std::map<Anope::string, std::iostream *> GetData() const + { + std::map<Anope::string, std::iostream *> d; + for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + d[it->first] = it->second; + return d; + } - SQLQuery& operator=(const Anope::string &q) - { - this->query = q; - this->parameters.clear(); - return *this; - } + void Clear() + { + for (std::map<Anope::string, std::stringstream *>::iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + delete it->second; + this->data.clear(); + } + + void SetType(const Anope::string &key, Type t) anope_override + { + this->types[key] = t; + } + + Type GetType(const Anope::string &key) const anope_override + { + std::map<Anope::string, Type>::const_iterator it = this->types.find(key); + if (it != this->types.end()) + return it->second; + return DT_TEXT; + } + }; - bool operator==(const SQLQuery &other) const + /** A SQL exception, can be thrown at various points + */ + class Exception : public ModuleException { - return this->query == other.query; - } + public: + Exception(const Anope::string &reason) : ModuleException(reason) { } + + virtual ~Exception() throw() { } + }; + + /** A SQL query + */ - inline bool operator!=(const SQLQuery &other) const + struct QueryData { - return !(*this == other); - } + Anope::string data; + bool escape; + }; - template<typename T> void setValue(const Anope::string &key, const T& value, bool escape = true) + struct Query { - try + Anope::string query; + std::map<Anope::string, QueryData> parameters; + + Query() { } + Query(const Anope::string &q) : query(q) { } + + Query& operator=(const Anope::string &q) { - Anope::string string_value = stringify(value); - this->parameters[key].data = string_value; - this->parameters[key].escape = escape; + this->query = q; + this->parameters.clear(); + return *this; } - catch (const ConvertException &ex) { } - } -}; -/** A result from a SQL query - */ -class SQLResult -{ - protected: - /* Rows, column, item */ - std::vector<std::map<Anope::string, Anope::string> > entries; - SQLQuery query; - Anope::string error; - public: - unsigned int id; - Anope::string finished_query; + bool operator==(const Query &other) const + { + return this->query == other.query; + } - 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 bool operator!=(const Query &other) const + { + return !(*this == other); + } + + template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true) + { + try + { + Anope::string string_value = stringify(value); + this->parameters[key].data = string_value; + this->parameters[key].escape = escape; + } + catch (const ConvertException &ex) { } + } + }; - inline operator bool() const { return this->error.empty(); } + /** A result from a SQL query + */ + class Result + { + protected: + /* Rows, column, item */ + std::vector<std::map<Anope::string, Anope::string> > entries; + Query query; + Anope::string error; + public: + unsigned int id; + Anope::string finished_query; - 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; } + Result() : id(0) { } + Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { } - int Rows() const { return this->entries.size(); } + inline operator bool() const { return this->error.empty(); } - const std::map<Anope::string, Anope::string> &Row(size_t index) const - { - try + inline const unsigned int GetID() const { return this->id; } + inline const Query &GetQuery() const { return this->query; } + inline const Anope::string &GetError() const { return this->error; } + + int Rows() const { return this->entries.size(); } + + const std::map<Anope::string, Anope::string> &Row(size_t index) const { - return this->entries.at(index); + try + { + return this->entries.at(index); + } + catch (const std::out_of_range &) + { + throw Exception("Out of bounds access to SQLResult"); + } } - catch (const std::out_of_range &) + + const Anope::string Get(size_t index, const Anope::string &col) const { - throw SQLException("Out of bounds access to SQLResult"); - } - } + const std::map<Anope::string, Anope::string> rows = this->Row(index); - const Anope::string Get(size_t index, const Anope::string &col) const - { - const std::map<Anope::string, Anope::string> rows = this->Row(index); + std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col); + if (it == rows.end()) + throw Exception("Unknown column name in SQLResult: " + col); - std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col); - if (it == rows.end()) - throw SQLException("Unknown column name in SQLResult: " + col); + return it->second; + } + }; - return it->second; - } -}; + /* An interface used by modules to retrieve the results + */ + class Interface + { + public: + Module *owner; -/* An interface used by modules to retrieve the results - */ -class SQLInterface -{ - public: - Module *owner; + Interface(Module *m) : owner(m) { } + virtual ~Interface() { } - SQLInterface(Module *m) : owner(m) { } - virtual ~SQLInterface() { } + virtual void OnResult(const Result &r) = 0; + virtual void OnError(const Result &r) = 0; + }; - virtual void OnResult(const SQLResult &r) = 0; - virtual void OnError(const SQLResult &r) = 0; -}; + /** Class providing the SQL service, modules call this to execute queries + */ + class Provider : public Service + { + public: + Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { } -/** Class providing the SQL service, modules call this to execute queries - */ -class SQLProvider : public Service -{ - public: - SQLProvider(Module *c, const Anope::string &n) : Service(c, "SQLProvider", n) { } + virtual void Run(Interface *i, const Query &query) = 0; - virtual void Run(SQLInterface *i, const SQLQuery &query) = 0; + virtual Result RunQuery(const Query &query) = 0; - virtual SQLResult RunQuery(const SQLQuery &query) = 0; + virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0; - virtual std::vector<SQLQuery> CreateTable(const Anope::string &table, const Serialize::Data &data) = 0; + virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0; - virtual SQLQuery BuildInsert(const Anope::string &table, unsigned int id, Serialize::Data &data) = 0; + virtual Query GetTables(const Anope::string &prefix) = 0; - virtual SQLQuery GetTables(const Anope::string &prefix) = 0; + virtual Anope::string FromUnixtime(time_t) = 0; + }; - virtual Anope::string FromUnixtime(time_t) = 0; -}; +} diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp index d21546c3a..96fa3dca5 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.cpp +++ b/modules/extra/webcpanel/pages/chanserv/access.cpp @@ -100,7 +100,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s if ((!highest || *highest <= *new_acc) && !u_access.founder && !has_priv) delete new_acc; - else if (new_acc->Serialize().empty()) + else if (new_acc->AccessSerialize().empty()) { replacements["MESSAGES"] = "Invalid access expression for the given type"; delete new_acc; |