]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/modules/sql.h
Fix building on Windows (mostly).
[user/henk/code/inspircd.git] / include / modules / sql.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
5  *   Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #pragma once
22
23
24 namespace SQL
25 {
26         class Error;
27         class Field;
28         class Provider;
29         class Query;
30         class Result;
31
32         /** A list of parameter replacement values. */
33         typedef std::vector<std::string> ParamList;
34
35         /** A map of parameter replacement values. */
36         typedef std::map<std::string, std::string> ParamMap;
37
38         /** A list of SQL fields from a specific row. */
39         typedef std::vector<Field> Row;
40
41         /** An enumeration of possible error codes. */
42         enum ErrorCode
43         {
44                 /** No error has occurred. */
45                 SUCCESS,
46
47                 /** The database identifier is invalid. */
48                 BAD_DBID,
49
50                 /** The database connection has failed. */
51                 BAD_CONN,
52
53                 /** Executing the query failed. */
54                 QSEND_FAIL,
55
56                 /** Reading the response failed. */
57                 QREPLY_FAIL
58         };
59
60         /** Populates a parameter map with information about a user.
61          * @param user The user to collect information from.
62          * @param userinfo The map to populate.
63          */
64         void PopulateUserInfo(User* user, ParamMap& userinfo);
65 }
66
67 /** Represents a single SQL field. */
68 class SQL::Field
69 {
70  private:
71         /** Whether this SQL field is NULL. */
72         bool null;
73
74         /** The underlying SQL value. */
75         std::string value;
76
77  public:
78         /** Creates a new NULL SQL field. */
79         Field()
80                 : null(true)
81         {
82         }
83
84         /** Creates a new non-NULL SQL field.
85          * @param v The value of the field.
86          */
87         Field(const std::string& v)
88                 : null(false)
89                 , value(v)
90         {
91         }
92
93         /** Determines whether this SQL entry is NULL. */
94         inline bool IsNull() const { return null; }
95
96         /** Retrieves the underlying value. */
97         inline operator const std::string&() const { return value; }
98 };
99
100 /** Represents the result of an SQL query. */
101 class SQL::Result : public classbase
102 {
103  public:
104         /**
105          * Return the number of rows in the result.
106          *
107          * Note that if you have perfomed an INSERT or UPDATE query or other
108          * query which will not return rows, this will return the number of
109          * affected rows. In this case you SHOULD NEVER access any of the result
110          * set rows, as there aren't any!
111          * @returns Number of rows in the result set.
112          */
113         virtual int Rows() = 0;
114
115         /** Retrieves the next available row from the database.
116          * @param result A list to store the fields from this row in.
117          * @return True if a row could be retrieved; otherwise, false.
118          */
119         virtual bool GetRow(Row& result) = 0;
120
121         /** Retrieves a list of SQL columns in the result.
122          * @param result A reference to the vector to store column names in.
123          */
124         virtual void GetCols(std::vector<std::string>& result) = 0;
125 };
126
127 /** SQL::Error holds the error state of a request.
128  * The error string varies from database software to database software
129  * and should be used to display informational error messages to users.
130  */
131 class SQL::Error
132 {
133  private:
134         /** The custom error message if one has been specified. */
135         const std::string message;
136
137  public:
138         /** The code which represents this error. */
139         const ErrorCode code;
140
141         /** Initialize an SQL::Error from an error code.
142          * @param c A code which represents this error.
143          */
144         Error(ErrorCode c)
145                 : code(c)
146         {
147         }
148
149         /** Initialize an SQL::Error from an error code and a custom error message.
150          * @param c A code which represents this error.
151          * @param m A custom error message.
152          */
153         Error(ErrorCode c, const std::string m)
154                 : message(m)
155                 , code(c)
156         {
157         }
158
159         /** Retrieves the error message. */
160         const char* ToString() const
161         {
162                 if (!message.empty())
163                         return message.c_str();
164
165                 switch (code)
166                 {
167                         case BAD_DBID:
168                                 return "Invalid database identifier";
169                         case BAD_CONN:
170                                 return "Invalid connection";
171                         case QSEND_FAIL:
172                                 return "Sending query failed";
173                         case QREPLY_FAIL:
174                                 return "Getting query result failed";
175                         default:
176                                 return "Unknown error";
177                 }
178         }
179 };
180
181 /**
182  * Object representing an SQL query. This should be allocated on the heap and
183  * passed to an SQL::Provider, which will free it when the query is complete or
184  * when the querying module is unloaded.
185  *
186  * You should store whatever information is needed to have the callbacks work in
187  * this object (UID of user, channel name, etc).
188  */
189 class SQL::Query : public classbase
190 {
191  protected:
192         /** Creates a new SQL query. */
193         Query(Module* Creator)
194                 : creator(Creator)
195         {
196         }
197
198  public:
199         const ModuleRef creator;
200
201         /* Destroys this Query instance. */
202         virtual ~Query()
203         {
204         }
205
206         /** Called when an SQL error happens.
207          * @param error The error that occurred.
208          */
209         virtual void OnError(Error& error) = 0;
210
211         /** Called when a SQL result is received.
212          * @param result The result of the SQL query.
213          */
214         virtual void OnResult(Result& result) = 0;
215 };
216
217 /**
218  * Provider object for SQL servers
219  */
220 class SQL::Provider : public DataProvider
221 {
222  public:
223         Provider(Module* Creator, const std::string& Name)
224                 : DataProvider(Creator, Name)
225         {
226         }
227
228         /** Submit an asynchronous SQL query.
229          * @param callback The result reporting point
230          * @param query The hardcoded query string. If you have parameters to substitute, see below.
231          */
232         virtual void Submit(Query* callback, const std::string& query) = 0;
233
234         /** Submit an asynchronous SQL query.
235          * @param callback The result reporting point
236          * @param format The simple parameterized query string ('?' parameters)
237          * @param p Parameters to fill in for the '?' entries
238          */
239         virtual void Submit(Query* callback, const std::string& format, const SQL::ParamList& p) = 0;
240
241         /** Submit an asynchronous SQL query.
242          * @param callback The result reporting point
243          * @param format The parameterized query string ('$name' parameters)
244          * @param p Parameters to fill in for the '$name' entries
245          */
246         virtual void Submit(Query* callback, const std::string& format, const ParamMap& p) = 0;
247 };
248
249 inline void SQL::PopulateUserInfo(User* user, ParamMap& userinfo)
250 {
251         userinfo["nick"] = user->nick;
252         userinfo["host"] = user->GetRealHost();
253         userinfo["ip"] = user->GetIPString();
254         userinfo["gecos"] = user->fullname;
255         userinfo["ident"] = user->ident;
256         userinfo["server"] = user->server->GetName();
257         userinfo["uuid"] = user->uuid;
258 }