anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
sql.h (5080B)
1 /* 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 */ 8 9 namespace SQL 10 { 11 12 class Data : public Serialize::Data 13 { 14 public: 15 typedef std::map<Anope::string, std::stringstream *> Map; 16 Map data; 17 std::map<Anope::string, Type> types; 18 19 ~Data() 20 { 21 Clear(); 22 } 23 24 std::iostream& operator[](const Anope::string &key) anope_override 25 { 26 std::stringstream *&ss = data[key]; 27 if (!ss) 28 ss = new std::stringstream(); 29 return *ss; 30 } 31 32 std::set<Anope::string> KeySet() const anope_override 33 { 34 std::set<Anope::string> keys; 35 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) 36 keys.insert(it->first); 37 return keys; 38 } 39 40 size_t Hash() const anope_override 41 { 42 size_t hash = 0; 43 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) 44 if (!it->second->str().empty()) 45 hash ^= Anope::hash_cs()(it->second->str()); 46 return hash; 47 } 48 49 std::map<Anope::string, std::iostream *> GetData() const 50 { 51 std::map<Anope::string, std::iostream *> d; 52 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) 53 d[it->first] = it->second; 54 return d; 55 } 56 57 void Clear() 58 { 59 for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) 60 delete it->second; 61 this->data.clear(); 62 } 63 64 void SetType(const Anope::string &key, Type t) anope_override 65 { 66 this->types[key] = t; 67 } 68 69 Type GetType(const Anope::string &key) const anope_override 70 { 71 std::map<Anope::string, Type>::const_iterator it = this->types.find(key); 72 if (it != this->types.end()) 73 return it->second; 74 return DT_TEXT; 75 } 76 }; 77 78 /** A SQL exception, can be thrown at various points 79 */ 80 class Exception : public ModuleException 81 { 82 public: 83 Exception(const Anope::string &reason) : ModuleException(reason) { } 84 85 virtual ~Exception() throw() { } 86 }; 87 88 /** A SQL query 89 */ 90 91 struct QueryData 92 { 93 Anope::string data; 94 bool escape; 95 }; 96 97 struct Query 98 { 99 Anope::string query; 100 std::map<Anope::string, QueryData> parameters; 101 102 Query() { } 103 Query(const Anope::string &q) : query(q) { } 104 105 Query& operator=(const Anope::string &q) 106 { 107 this->query = q; 108 this->parameters.clear(); 109 return *this; 110 } 111 112 bool operator==(const Query &other) const 113 { 114 return this->query == other.query; 115 } 116 117 inline bool operator!=(const Query &other) const 118 { 119 return !(*this == other); 120 } 121 122 template<typename T> void SetValue(const Anope::string &key, const T& value, bool escape = true) 123 { 124 try 125 { 126 Anope::string string_value = stringify(value); 127 this->parameters[key].data = string_value; 128 this->parameters[key].escape = escape; 129 } 130 catch (const ConvertException &ex) { } 131 } 132 }; 133 134 /** A result from a SQL query 135 */ 136 class Result 137 { 138 protected: 139 /* Rows, column, item */ 140 std::vector<std::map<Anope::string, Anope::string> > entries; 141 Query query; 142 Anope::string error; 143 public: 144 unsigned int id; 145 Anope::string finished_query; 146 147 Result() : id(0) { } 148 Result(unsigned int i, const Query &q, const Anope::string &fq, const Anope::string &err = "") : query(q), error(err), id(i), finished_query(fq) { } 149 150 inline operator bool() const { return this->error.empty(); } 151 152 inline unsigned int GetID() const { return this->id; } 153 inline const Query &GetQuery() const { return this->query; } 154 inline const Anope::string &GetError() const { return this->error; } 155 156 int Rows() const { return this->entries.size(); } 157 158 const std::map<Anope::string, Anope::string> &Row(size_t index) const 159 { 160 try 161 { 162 return this->entries.at(index); 163 } 164 catch (const std::out_of_range &) 165 { 166 throw Exception("Out of bounds access to SQLResult"); 167 } 168 } 169 170 const Anope::string Get(size_t index, const Anope::string &col) const 171 { 172 const std::map<Anope::string, Anope::string> rows = this->Row(index); 173 174 std::map<Anope::string, Anope::string>::const_iterator it = rows.find(col); 175 if (it == rows.end()) 176 throw Exception("Unknown column name in SQLResult: " + col); 177 178 return it->second; 179 } 180 }; 181 182 /* An interface used by modules to retrieve the results 183 */ 184 class Interface 185 { 186 public: 187 Module *owner; 188 189 Interface(Module *m) : owner(m) { } 190 virtual ~Interface() { } 191 192 virtual void OnResult(const Result &r) = 0; 193 virtual void OnError(const Result &r) = 0; 194 }; 195 196 /** Class providing the SQL service, modules call this to execute queries 197 */ 198 class Provider : public Service 199 { 200 public: 201 Provider(Module *c, const Anope::string &n) : Service(c, "SQL::Provider", n) { } 202 203 virtual void Run(Interface *i, const Query &query) = 0; 204 205 virtual Result RunQuery(const Query &query) = 0; 206 207 virtual std::vector<Query> CreateTable(const Anope::string &table, const Data &data) = 0; 208 209 virtual Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) = 0; 210 211 virtual Query GetTables(const Anope::string &prefix) = 0; 212 213 virtual Anope::string FromUnixtime(time_t) = 0; 214 }; 215 216 }