summaryrefslogtreecommitdiff
path: root/include/modules/sql.h
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-05 03:30:08 -0400
committerAdam <Adam@anope.org>2013-05-05 03:30:08 -0400
commit57c2b65f08c9c0658003a74a32c6506829e12b0b (patch)
tree49883b790ed9f7cd395e0c6f2f62cc946d743635 /include/modules/sql.h
parenta118946e657b8a137502ff60c1f21c608cb44495 (diff)
Move module header files to include/modules to fix naming conflicts with system headers
Diffstat (limited to 'include/modules/sql.h')
-rw-r--r--include/modules/sql.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/include/modules/sql.h b/include/modules/sql.h
new file mode 100644
index 000000000..1c8fdd3aa
--- /dev/null
+++ b/include/modules/sql.h
@@ -0,0 +1,216 @@
+/*
+ * (C) 2003-2013 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+namespace SQL
+{
+
+ class Data : public Serialize::Data
+ {
+ public:
+ typedef std::map<Anope::string, std::stringstream *> Map;
+ Map data;
+ std::map<Anope::string, Type> types;
+
+ ~Data()
+ {
+ Clear();
+ }
+
+ std::iostream& operator[](const Anope::string &key) anope_override
+ {
+ std::stringstream *&ss = data[key];
+ if (!ss)
+ ss = new std::stringstream();
+ return *ss;
+ }
+
+ std::set<Anope::string> KeySet() const anope_override
+ {
+ std::set<Anope::string> keys;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ keys.insert(it->first);
+ return keys;
+ }
+
+ size_t Hash() const anope_override
+ {
+ size_t hash = 0;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ if (!it->second->str().empty())
+ hash ^= Anope::hash_cs()(it->second->str());
+ return hash;
+ }
+
+ std::map<Anope::string, std::iostream *> GetData() const
+ {
+ std::map<Anope::string, std::iostream *> d;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ d[it->first] = it->second;
+ return d;
+ }
+
+ void Clear()
+ {
+ for (Map::const_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;
+ }
+ };
+
+ /** A SQL exception, can be thrown at various points
+ */
+ class Exception : public ModuleException
+ {
+ public:
+ Exception(const Anope::string &reason) : ModuleException(reason) { }
+
+ virtual ~Exception() throw() { }
+ };
+
+ /** A SQL query
+ */
+
+ struct QueryData
+ {
+ Anope::string data;
+ bool escape;
+ };
+
+ struct Query
+ {
+ Anope::string query;
+ std::map<Anope::string, QueryData> parameters;
+
+ Query() { }
+ Query(const Anope::string &q) : query(q) { }
+
+ Query& operator=(const Anope::string &q)
+ {
+ this->query = q;
+ this->parameters.clear();
+ return *this;
+ }
+
+ bool operator==(const Query &other) const
+ {
+ return this->query == other.query;
+ }
+
+ 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) { }
+ }
+ };
+
+ /** 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;
+
+ 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) { }
+
+ inline operator bool() const { return this->error.empty(); }
+
+ 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
+ {
+ try
+ {
+ return this->entries.at(index);
+ }
+ catch (const std::out_of_range &)
+ {
+ throw Exception("Out of bounds access to SQLResult");
+ }
+ }
+
+ 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);
+
+ return it->second;
+ }
+ };
+
+ /* An interface used by modules to retrieve the results
+ */
+ class Interface
+ {
+ public:
+ Module *owner;
+
+ Interface(Module *m) : owner(m) { }
+ virtual ~Interface() { }
+
+ virtual void OnResult(const Result &r) = 0;
+ virtual void OnError(const Result &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) { }
+
+ virtual void Run(Interface *i, const Query &query) = 0;
+
+ virtual Result RunQuery(const Query &query) = 0;
+
+ virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0;
+
+ virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0;
+
+ virtual Query GetTables(const Anope::string &prefix) = 0;
+
+ virtual Anope::string FromUnixtime(time_t) = 0;
+ };
+
+}
+