]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/extra/m_sql.h
Updates, should be able to safely unload client modules with queries in progress...
[user/henk/code/inspircd.git] / src / modules / extra / m_sql.h
1 #ifndef __M_SQL_H__
2 #define __M_SQL_H__
3
4 using namespace std;
5
6 #include <string>
7 #include <vector>
8
9 #define SQL_RESULT 1
10 #define SQL_COUNT  2
11 #define SQL_ROW    3
12 #define SQL_ERROR  4
13 #define SQL_END    5
14 #define SQL_DONE   6
15 #define SQL_OK     7
16
17 // SQLRequest is inherited from a basic Request object
18 // so that we can neatly pass information around the
19 // system.
20
21 class SQLRequest : public classbase
22 {
23  protected:
24         long conn_id;
25         int request_type;
26         std::string thisquery;
27  public:
28         SQLRequest(int qt, long cid, std::string query)
29         {
30                 this->SetQueryType(qt);
31                 this->SetConnID(cid);
32                 this->SetQuery(query);
33         }
34
35         void SetConnID(long id)
36         {
37                 conn_id = id;
38         }
39
40         long GetConnID()
41         {
42                 return conn_id;
43         }
44
45         void SetQueryType(int t)
46         {
47                 request_type = t;
48         }
49
50         int GetQueryType()
51         {
52                 return request_type;
53         }
54
55         void SetQuery(std::string query)
56         {
57                 thisquery = query;
58         }
59
60         std::string GetQuery()
61         {
62                 return thisquery;
63         }
64 };
65
66 // Upon completion, an SQLRequest returns an SQLResponse.
67
68 class SQLResult : public classbase
69 {
70  protected:
71         int resptype;
72         long count;
73         std::string error;
74         std::map<std::string,std::string> row;
75  public:
76
77         void SetRow(std::map<std::string,std::string> r)
78         {
79                 row = r;
80         }
81
82         std::string GetField(std::string field)
83         {
84                 std::map<std::string,std::string>::iterator iter = row.find(field);
85                 if (iter == row.end()) return "";
86                 return iter->second;
87         }
88
89         void SetType(int rt)
90         {
91                 resptype = rt;
92         }
93
94         void SetError(std::string err)
95         {
96                 error = err;
97         }
98
99         int GetType()
100         {
101                 return resptype;
102         }
103
104         std::string GetError()
105         {
106                 return error;
107         }
108
109         void SetCount(long c)
110         {
111                 count = c;
112         }
113
114         /* This will return a negative value of the SQL server is down */
115         long GetCount()
116         {
117                 return count;
118         }
119 };
120
121 class SQLQuery : public classbase
122 {
123  private:
124         SQLRequest* rowrequest;
125         SQLRequest* query;
126         SQLResult* result;
127         SQLResult* rowresult;
128         Request* rowquery;
129         unsigned long dbid;
130         Module* parent;
131         Module* SQLModule;
132         Server* Srv;
133         std::string error;
134
135         bool MakeQueryGoNow(std::string qry)
136         {
137                 // Insert Lack of More Original Name here.
138                 Request queryrequest((char*)query, parent, SQLModule);
139                 result = (SQLResult*)queryrequest.Send();
140                 if (result->GetType() != SQL_ERROR)
141                 {
142                         // Query Is fine.. Prepare to get first row...
143                         rowrequest = new SQLRequest(SQL_ROW,dbid,"");
144                         rowquery = new Request((char*)rowrequest, parent, SQLModule);
145                         return true;
146                 }
147                 // Query Failed. - Coder Fucked up! (Probably me too :/)
148                 Srv->Log(DEBUG, " ============= SQL Error, Query And Error Follow. ============= ");
149                 Srv->Log(DEBUG, "Query: "+ qry);
150                 Srv->Log(DEBUG, "Error: "+ result->GetError());
151                 Srv->Log(DEBUG, " ============================================================== ");
152                 error = result->GetError();
153                 // Destroy Variables that were set..
154                 delete query;
155                 query = NULL;
156                 result = NULL;
157                 return false;
158         }
159
160  public:
161
162         SQLQuery(Server* S) : Srv(S)
163         {
164         }
165
166         SQLQuery(Module* a, unsigned long b, Server* S) : dbid(b), parent(a), Srv(S)
167         {
168                 // Make a few useful variables..
169                 SQLModule = Srv->FindModule("m_sql.so");
170         }
171
172         ~SQLQuery()
173         {
174         }
175
176         bool Query(std::string qry)
177         {
178                 query = new SQLRequest(SQL_RESULT, dbid, qry);
179                 return MakeQueryGoNow(qry);
180         }
181
182         bool QueryCount(std::string qry)
183         {
184                 query = new SQLRequest(SQL_COUNT, dbid, qry);
185                 return MakeQueryGoNow(qry);
186         }
187
188         bool GetRow()
189         {
190                 rowresult = (SQLResult*)rowquery->Send();
191                 if (rowresult->GetType() == SQL_ROW)
192                 {
193                         // We have got a row.. thats all for now.
194                         return true;
195                 }
196                 // No Row, Error, or end. KILL CALLER! *BANG*
197                 return false;
198         }
199
200         std::string GetField(std::string fname)
201         {
202                 return rowresult->GetField(fname);
203         }
204
205         long GetCount()
206         {
207                 rowresult = (SQLResult*)rowquery->Send();
208                 if (rowresult->GetType() == SQL_COUNT)
209                 {
210                         return rowresult->GetCount();
211                 }
212                 else
213                 {
214                         return 0;
215                 }
216         }
217
218         const std::string &GetError()
219         {
220                 return error;
221         }
222
223         void SQLDone()
224         {
225                 // Tell m_sql we are finished..
226                 query->SetQueryType(SQL_DONE);
227                 query->SetConnID(dbid);
228                 Request donerequest((char*)query, parent, SQLModule);
229                 donerequest.Send();
230
231                 // Do Some Clearing up.
232                 delete query;
233                 delete rowrequest;
234                 // Null the variables, so they can be re-used without confusion..
235                 result = NULL;
236                 query = NULL;
237                 rowrequest = NULL;
238                 rowresult = NULL;
239         }
240
241         static std::string Sanitise(const std::string& crap)
242         {
243                 std::string temp = "";
244                 for (unsigned int q = 0; q < crap.length(); q++)
245                 {
246                         if (crap[q] == '\'')
247                         {
248                                 temp += "\\'";
249                         }
250                         else if (crap[q] == '"')
251                         {
252                                 temp += "\\\"";
253                         }
254                         else if (crap[q] == '\\')
255                         {
256                                 temp += "\\\\";
257                         }
258                         else
259                         {
260                                 temp += crap[q];
261                         }
262                 }
263                 return temp;
264         }
265 };
266
267
268 #endif