diff options
| author | Adam <Adam@anope.org> | 2012-12-13 06:12:56 -0500 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2012-12-13 06:12:56 -0500 |
| commit | c1077faa281c5635f85b892e605e23bd6c8fcc3b (patch) | |
| tree | 213b5f87a19f182e1efd6110f03ff10d5b10ebf6 /modules/extra/sql.h | |
| parent | 76ba147c22944b67e8522cd2bb7b6e1bae498ced (diff) | |
Optimize much of the database code and serialize code.
Diffstat (limited to 'modules/extra/sql.h')
| -rw-r--r-- | modules/extra/sql.h | 280 |
1 files changed, 180 insertions, 100 deletions
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; -}; +} |
