Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 namespace SQL
00009 {
00010
00011 class Data : public Serialize::Data
00012 {
00013 public:
00014 typedef std::map<Anope::string, std::stringstream *> Map;
00015 Map data;
00016 std::map<Anope::string, Type> types;
00017
00018 ~Data()
00019 {
00020 Clear();
00021 }
00022
00023 std::iostream& operator[](const Anope::string &key) anope_override
00024 {
00025 std::stringstream *&ss = data[key];
00026 if (!ss)
00027 ss = new std::stringstream();
00028 return *ss;
00029 }
00030
00031 std::set<Anope::string> KeySet() const anope_override
00032 {
00033 std::set<Anope::string> keys;
00034 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
00035 keys.insert(it->first);
00036 return keys;
00037 }
00038
00039 size_t Hash() const anope_override
00040 {
00041 size_t hash = 0;
00042 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
00043 if (!it->second->str().empty())
00044 hash ^= Anope::hash_cs()(it->second->str());
00045 return hash;
00046 }
00047
00048 std::map<Anope::string, std::iostream *> GetData() const
00049 {
00050 std::map<Anope::string, std::iostream *> d;
00051 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
00052 d[it->first] = it->second;
00053 return d;
00054 }
00055
00056 void Clear()
00057 {
00058 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
00059 delete it->second;
00060 this->data.clear();
00061 }
00062
00063 void SetType(const Anope::string &key, Type t) anope_override
00064 {
00065 this->types[key] = t;
00066 }
00067
00068 Type GetType(const Anope::string &key) const anope_override
00069 {
00070 std::map<Anope::string, Type>::const_iterator it = this->types.find(key);
00071 if (it != this->types.end())
00072 return it->second;
00073 return DT_TEXT;
00074 }
00075 };
00076
00079 class Exception : public ModuleException
00080 {
00081 public:
00082 Exception(const Anope::string &reason) : ModuleException(reason) { }
00083
00084 virtual ~Exception() throw() { }
00085 };
00086
00090 struct QueryData
00091 {
00092 Anope::string data;
00093 bool escape;
00094 };
00095
00096 struct Query
00097 {
00098 Anope::string query;
00099 std::map<Anope::string, QueryData> parameters;
00100
00101 Query() { }
00102 Query(const Anope::string &q) : query(q) { }
00103
00104 Query& operator=(const Anope::string &q)
00105 {
00106 this->query = q;
00107 this->parameters.clear();
00108 return *this;
00109 }
00110
00111 bool operator==(const Query &other) const
00112 {
00113 return this->query == other.query;
00114 }
00115
00116 inline bool operator!=(const Query &other) const
00117 {
00118 return !(*this == other);
00119 }
00120
00121 template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true)
00122 {
00123 try
00124 {
00125 Anope::string string_value = stringify(value);
00126 this->parameters[key].data = string_value;
00127 this->parameters[key].escape = escape;
00128 }
00129 catch (const ConvertException &ex) { }
00130 }
00131 };
00132
00135 class Result
00136 {
00137 protected:
00138
00139 std::vector<std::map<Anope::string, Anope::string> > entries;
00140 Query query;
00141 Anope::string error;
00142 public:
00143 unsigned int id;
00144 Anope::string finished_query;
00145
00146 Result() : id(0) { }
00147 Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { }
00148
00149 inline operator bool() const { return this->error.empty(); }
00150
00151 inline const unsigned int GetID() const { return this->id; }
00152 inline const Query &GetQuery() const { return this->query; }
00153 inline const Anope::string &GetError() const { return this->error; }
00154
00155 int Rows() const { return this->entries.size(); }
00156
00157 const std::map<Anope::string, Anope::string> &Row(size_t index) const
00158 {
00159 try
00160 {
00161 return this->entries.at(index);
00162 }
00163 catch (const std::out_of_range &)
00164 {
00165 throw Exception("Out of bounds access to SQLResult");
00166 }
00167 }
00168
00169 const Anope::string Get(size_t index, const Anope::string &col) const
00170 {
00171 const std::map<Anope::string, Anope::string> rows = this->Row(index);
00172
00173 std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col);
00174 if (it == rows.end())
00175 throw Exception("Unknown column name in SQLResult: " + col);
00176
00177 return it->second;
00178 }
00179 };
00180
00181
00182
00183 class Interface
00184 {
00185 public:
00186 Module *owner;
00187
00188 Interface(Module *m) : owner(m) { }
00189 virtual ~Interface() { }
00190
00191 virtual void OnResult(const Result &r) = 0;
00192 virtual void OnError(const Result &r) = 0;
00193 };
00194
00197 class Provider : public Service
00198 {
00199 public:
00200 Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { }
00201
00202 virtual void Run(Interface *i, const Query &query) = 0;
00203
00204 virtual Result RunQuery(const Query &query) = 0;
00205
00206 virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0;
00207
00208 virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0;
00209
00210 virtual Query GetTables(const Anope::string &prefix) = 0;
00211
00212 virtual Anope::string FromUnixtime(time_t) = 0;
00213 };
00214
00215 }
00216