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 }