summaryrefslogtreecommitdiff
path: root/modules/extra/sql.h
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-12-13 06:12:56 -0500
committerAdam <Adam@anope.org>2012-12-13 06:12:56 -0500
commitc1077faa281c5635f85b892e605e23bd6c8fcc3b (patch)
tree213b5f87a19f182e1efd6110f03ff10d5b10ebf6 /modules/extra/sql.h
parent76ba147c22944b67e8522cd2bb7b6e1bae498ced (diff)
Optimize much of the database code and serialize code.
Diffstat (limited to 'modules/extra/sql.h')
-rw-r--r--modules/extra/sql.h280
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;
-};
+}