2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
5 * Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
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.
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
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/>.
32 /** A list of parameter replacement values. */
33 typedef std::vector<std::string> ParamList;
35 /** A map of parameter replacement values. */
36 typedef std::map<std::string, std::string> ParamMap;
38 /** A list of SQL fields from a specific row. */
39 typedef std::vector<Field> Row;
41 /** An enumeration of possible error codes. */
44 /** No error has occurred. */
47 /** The database identifier is invalid. */
50 /** The database connection has failed. */
53 /** Executing the query failed. */
56 /** Reading the response failed. */
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.
64 void PopulateUserInfo(User* user, ParamMap& userinfo);
67 /** Represents a single SQL field. */
71 /** Whether this SQL field is NULL. */
74 /** The underlying SQL value. */
78 /** Creates a new NULL SQL field. */
84 /** Creates a new non-NULL SQL field.
85 * @param v The value of the field.
87 Field(const std::string& v)
93 /** Determines whether this SQL entry is NULL. */
94 inline bool IsNull() const { return null; }
96 /** Retrieves the underlying value. */
97 inline operator const std::string&() const { return value; }
100 /** Represents the result of an SQL query. */
101 class SQL::Result : public classbase
105 * Return the number of rows in the result.
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.
113 virtual int Rows() = 0;
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.
119 virtual bool GetRow(Row& result) = 0;
121 /** Retrieves a list of SQL columns in the result.
122 * @param result A reference to the vector to store column names in.
124 virtual void GetCols(std::vector<std::string>& result) = 0;
127 * Check if there's a column with the specified name in the result
129 * @param the column name
130 * @param on success, this is the column index
131 * @returns true, or false if the column is not found
133 virtual bool HasColumn(const std::string& column, size_t& index) = 0;
136 /** SQL::Error holds the error state of a request.
137 * The error string varies from database software to database software
138 * and should be used to display informational error messages to users.
143 /** The custom error message if one has been specified. */
144 const std::string message;
147 /** The code which represents this error. */
148 const ErrorCode code;
150 /** Initialize an SQL::Error from an error code.
151 * @param c A code which represents this error.
158 /** Initialize an SQL::Error from an error code and a custom error message.
159 * @param c A code which represents this error.
160 * @param m A custom error message.
162 Error(ErrorCode c, const std::string m)
168 /** Retrieves the error message. */
169 const char* ToString() const
171 if (!message.empty())
172 return message.c_str();
177 return "Invalid database identifier";
179 return "Invalid connection";
181 return "Sending query failed";
183 return "Getting query result failed";
185 return "Unknown error";
191 * Object representing an SQL query. This should be allocated on the heap and
192 * passed to an SQL::Provider, which will free it when the query is complete or
193 * when the querying module is unloaded.
195 * You should store whatever information is needed to have the callbacks work in
196 * this object (UID of user, channel name, etc).
198 class SQL::Query : public classbase
201 /** Creates a new SQL query. */
202 Query(Module* Creator)
208 const ModuleRef creator;
210 /* Destroys this Query instance. */
215 /** Called when an SQL error happens.
216 * @param error The error that occurred.
218 virtual void OnError(Error& error) = 0;
220 /** Called when a SQL result is received.
221 * @param result The result of the SQL query.
223 virtual void OnResult(Result& result) = 0;
227 * Provider object for SQL servers
229 class SQL::Provider : public DataProvider
232 /** The name of the database tag in the config. */
233 const std::string dbid;
236 Provider(Module* Creator, const std::string& Name)
237 : DataProvider(Creator, "SQL/" + Name)
241 /** Retrieves the name of the database tag in the config. */
242 const std::string& GetId() const { return dbid; }
244 /** Submit an asynchronous SQL query.
245 * @param callback The result reporting point
246 * @param query The hardcoded query string. If you have parameters to substitute, see below.
248 virtual void Submit(Query* callback, const std::string& query) = 0;
250 /** Submit an asynchronous SQL query.
251 * @param callback The result reporting point
252 * @param format The simple parameterized query string ('?' parameters)
253 * @param p Parameters to fill in for the '?' entries
255 virtual void Submit(Query* callback, const std::string& format, const SQL::ParamList& p) = 0;
257 /** Submit an asynchronous SQL query.
258 * @param callback The result reporting point
259 * @param format The parameterized query string ('$name' parameters)
260 * @param p Parameters to fill in for the '$name' entries
262 virtual void Submit(Query* callback, const std::string& format, const ParamMap& p) = 0;
265 inline void SQL::PopulateUserInfo(User* user, ParamMap& userinfo)
267 userinfo["nick"] = user->nick;
268 userinfo["host"] = user->GetRealHost();
269 userinfo["ip"] = user->GetIPString();
270 userinfo["real"] = user->GetRealName();
271 userinfo["ident"] = user->ident;
272 userinfo["server"] = user->server->GetName();
273 userinfo["uuid"] = user->uuid;