2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2015 Daniel Vassdal <shutter@canternet.org>
5 * Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
6 * Copyright (C) 2013, 2017-2019 Sadie Powell <sadie@witchery.services>
7 * Copyright (C) 2012 Robby <robby@chatbelgie.be>
8 * Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
10 * This file is part of InspIRCd. InspIRCd is free software: you can
11 * redistribute it and/or modify it under the terms of the GNU General Public
12 * License as published by the Free Software Foundation, version 2.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
35 /** A list of parameter replacement values. */
36 typedef std::vector<std::string> ParamList;
38 /** A map of parameter replacement values. */
39 typedef std::map<std::string, std::string> ParamMap;
41 /** A list of SQL fields from a specific row. */
42 typedef std::vector<Field> Row;
44 /** An enumeration of possible error codes. */
47 /** No error has occurred. */
50 /** The database identifier is invalid. */
53 /** The database connection has failed. */
56 /** Executing the query failed. */
59 /** Reading the response failed. */
63 /** Populates a parameter map with information about a user.
64 * @param user The user to collect information from.
65 * @param userinfo The map to populate.
67 void PopulateUserInfo(User* user, ParamMap& userinfo);
70 /** Represents a single SQL field. */
74 /** Whether this SQL field is NULL. */
77 /** The underlying SQL value. */
81 /** Creates a new NULL SQL field. */
87 /** Creates a new non-NULL SQL field.
88 * @param v The value of the field.
90 Field(const std::string& v)
96 /** Determines whether this SQL entry is NULL. */
97 inline bool IsNull() const { return null; }
99 /** Retrieves the underlying value. */
100 inline operator const std::string&() const { return value; }
103 /** Represents the result of an SQL query. */
104 class SQL::Result : public classbase
108 * Return the number of rows in the result.
110 * Note that if you have performed an INSERT or UPDATE query or other
111 * query which will not return rows, this will return the number of
112 * affected rows. In this case you SHOULD NEVER access any of the result
113 * set rows, as there aren't any!
114 * @returns Number of rows in the result set.
116 virtual int Rows() = 0;
118 /** Retrieves the next available row from the database.
119 * @param result A list to store the fields from this row in.
120 * @return True if a row could be retrieved; otherwise, false.
122 virtual bool GetRow(Row& result) = 0;
124 /** Retrieves a list of SQL columns in the result.
125 * @param result A reference to the vector to store column names in.
127 virtual void GetCols(std::vector<std::string>& result) = 0;
130 * Check if there's a column with the specified name in the result
132 * @param column The column name.
133 * @param index The place to store the column index if it exists.
134 * @returns If the column exists then true; otherwise, false.
136 virtual bool HasColumn(const std::string& column, size_t& index) = 0;
139 /** SQL::Error holds the error state of a request.
140 * The error string varies from database software to database software
141 * and should be used to display informational error messages to users.
146 /** The custom error message if one has been specified. */
147 const std::string message;
150 /** The code which represents this error. */
151 const ErrorCode code;
153 /** Initialize an SQL::Error from an error code.
154 * @param c A code which represents this error.
161 /** Initialize an SQL::Error from an error code and a custom error message.
162 * @param c A code which represents this error.
163 * @param m A custom error message.
165 Error(ErrorCode c, const std::string m)
171 /** Retrieves the error message. */
172 const char* ToString() const
174 if (!message.empty())
175 return message.c_str();
180 return "Invalid database identifier";
182 return "Invalid connection";
184 return "Sending query failed";
186 return "Getting query result failed";
188 return "Unknown error";
194 * Object representing an SQL query. This should be allocated on the heap and
195 * passed to an SQL::Provider, which will free it when the query is complete or
196 * when the querying module is unloaded.
198 * You should store whatever information is needed to have the callbacks work in
199 * this object (UID of user, channel name, etc).
201 class SQL::Query : public classbase
204 /** Creates a new SQL query. */
205 Query(Module* Creator)
211 const ModuleRef creator;
213 /* Destroys this Query instance. */
218 /** Called when an SQL error happens.
219 * @param error The error that occurred.
221 virtual void OnError(Error& error) = 0;
223 /** Called when a SQL result is received.
224 * @param result The result of the SQL query.
226 virtual void OnResult(Result& result) = 0;
230 * Provider object for SQL servers
232 class SQL::Provider : public DataProvider
235 /** The name of the database tag in the config. */
236 const std::string dbid;
239 Provider(Module* Creator, const std::string& Name)
240 : DataProvider(Creator, "SQL/" + Name)
244 /** Retrieves the name of the database tag in the config. */
245 const std::string& GetId() const { return dbid; }
247 /** Submit an asynchronous SQL query.
248 * @param callback The result reporting point
249 * @param query The hardcoded query string. If you have parameters to substitute, see below.
251 virtual void Submit(Query* callback, const std::string& query) = 0;
253 /** Submit an asynchronous SQL query.
254 * @param callback The result reporting point
255 * @param format The simple parameterized query string ('?' parameters)
256 * @param p Parameters to fill in for the '?' entries
258 virtual void Submit(Query* callback, const std::string& format, const SQL::ParamList& p) = 0;
260 /** Submit an asynchronous SQL query.
261 * @param callback The result reporting point
262 * @param format The parameterized query string ('$name' parameters)
263 * @param p Parameters to fill in for the '$name' entries
265 virtual void Submit(Query* callback, const std::string& format, const ParamMap& p) = 0;
268 inline void SQL::PopulateUserInfo(User* user, ParamMap& userinfo)
270 userinfo["nick"] = user->nick;
271 userinfo["host"] = user->GetRealHost();
272 userinfo["ip"] = user->GetIPString();
273 userinfo["real"] = user->GetRealName();
274 userinfo["ident"] = user->ident;
275 userinfo["server"] = user->server->GetName();
276 userinfo["uuid"] = user->uuid;