summaryrefslogtreecommitdiff
path: root/include/modules/sql.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/modules/sql.h')
-rw-r--r--include/modules/sql.h183
1 files changed, 93 insertions, 90 deletions
diff --git a/include/modules/sql.h b/include/modules/sql.h
index 375de14b6..31e7af0bf 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -1,80 +1,24 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2016 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2010-2016 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
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
@@ -92,6 +36,7 @@ namespace SQL
{
Anope::string data;
bool escape;
+ bool null;
};
struct Query
@@ -129,15 +74,41 @@ namespace SQL
}
catch (const ConvertException &ex) { }
}
+
+ void SetNull(const Anope::string &key)
+ {
+ QueryData &qd = this->parameters[key];
+
+ qd.data = "";
+ qd.escape = false;
+ qd.null = true;
+ }
+
+ Anope::string Unsafe() const
+ {
+ Anope::string q = query;
+ for (auto it = parameters.begin(); it != parameters.end(); ++it)
+ q = q.replace_all_cs("@" + it->first + "@", it->second.data);
+ return q;
+ }
};
/** A result from a SQL query
*/
class Result
{
+ public:
+ struct Value
+ {
+ bool null = false;
+ Anope::string value;
+ };
+
protected:
- /* Rows, column, item */
- std::vector<std::map<Anope::string, Anope::string> > entries;
+ std::vector<Anope::string> columns;
+ // row, column
+ std::vector<std::vector<Value>> values;
+
Query query;
Anope::string error;
public:
@@ -149,17 +120,20 @@ namespace SQL
inline operator bool() const { return this->error.empty(); }
- inline const unsigned int GetID() const { return this->id; }
+ inline 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(); }
+ int Rows() const
+ {
+ return this->values.size();
+ }
- const std::map<Anope::string, Anope::string> &Row(size_t index) const
+ const std::vector<Value> &Row(size_t index) const
{
try
{
- return this->entries.at(index);
+ return this->values.at(index);
}
catch (const std::out_of_range &)
{
@@ -167,15 +141,35 @@ namespace SQL
}
}
- const Anope::string Get(size_t index, const Anope::string &col) const
+ const Value &GetValue(size_t index, const Anope::string &col) const
{
- const std::map<Anope::string, Anope::string> rows = this->Row(index);
+ const std::vector<Value> &v = this->Row(index);
- std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col);
- if (it == rows.end())
+ auto it = std::find(this->columns.begin(), this->columns.end(), col);
+ if (it == this->columns.end())
throw Exception("Unknown column name in SQLResult: " + col);
+ unsigned int col_idx = it - this->columns.begin();
- return it->second;
+ try
+ {
+ return v[col_idx];
+ }
+ 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 Value &value = GetValue(index, col);
+ return value.value;
+ }
+
+ bool IsNull(size_t index, const Anope::string &col) const
+ {
+ const Value &value = GetValue(index, col);
+ return value.null;
}
};
@@ -189,8 +183,8 @@ namespace SQL
Interface(Module *m) : owner(m) { }
virtual ~Interface() { }
- virtual void OnResult(const Result &r) = 0;
- virtual void OnError(const Result &r) = 0;
+ virtual void OnResult(const Result &r) anope_abstract;
+ virtual void OnError(const Result &r) anope_abstract;
};
/** Class providing the SQL service, modules call this to execute queries
@@ -198,19 +192,28 @@ namespace SQL
class Provider : public Service
{
public:
- Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { }
+ static constexpr const char *NAME = "sql";
+
+ Provider(Module *c, const Anope::string &n) : Service(c, NAME, n) { }
- virtual void Run(Interface *i, const Query &query) = 0;
+ virtual void Run(Interface *i, const Query &query) anope_abstract;
- virtual Result RunQuery(const Query &query) = 0;
+ virtual Result RunQuery(const Query &query) anope_abstract;
- virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0;
+ virtual std::vector<Query> InitSchema(const Anope::string &prefix) anope_abstract;
+ virtual std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) anope_abstract;
+ virtual std::vector<Query> CreateTable(const Anope::string &prefix, Serialize::TypeBase *) anope_abstract;
+ virtual std::vector<Query> AlterTable(const Anope::string &, Serialize::TypeBase *, Serialize::FieldBase *) anope_abstract;
+ virtual std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) anope_abstract;
+ virtual Query SelectFind(const Anope::string &table, const Anope::string &field) anope_abstract;
- virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0;
+ virtual Query BeginTransaction() anope_abstract;
+ virtual Query Commit() anope_abstract;
- virtual Query GetTables(const Anope::string &prefix) = 0;
+ virtual Serialize::ID GetID(const Anope::string &prefix, const Anope::string &type) anope_abstract;
- virtual Anope::string FromUnixtime(time_t) = 0;
+ virtual Query GetTables(const Anope::string &prefix) anope_abstract;
};
}
+