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 /** 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.
134 /** The custom error message if one has been specified. */
135 const std::string message;
138 /** The code which represents this error. */
139 const ErrorCode code;
141 /** Initialize an SQL::Error from an error code.
142 * @param c A code which represents this error.
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.
153 Error(ErrorCode c, const std::string m)
159 /** Retrieves the error message. */
160 const char* ToString() const
162 if (!message.empty())
163 return message.c_str();
168 return "Invalid database identifier";
170 return "Invalid connection";
172 return "Sending query failed";
174 return "Getting query result failed";
176 return "Unknown error";
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.
186 * You should store whatever information is needed to have the callbacks work in
187 * this object (UID of user, channel name, etc).
189 class SQL::Query : public classbase
192 /** Creates a new SQL query. */
193 Query(Module* Creator)
199 const ModuleRef creator;
201 /* Destroys this Query instance. */
206 /** Called when an SQL error happens.
207 * @param error The error that occurred.
209 virtual void OnError(Error& error) = 0;
211 /** Called when a SQL result is received.
212 * @param result The result of the SQL query.
214 virtual void OnResult(Result& result) = 0;
218 * Provider object for SQL servers
220 class SQL::Provider : public DataProvider
223 Provider(Module* Creator, const std::string& Name)
224 : DataProvider(Creator, Name)
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.
232 virtual void Submit(Query* callback, const std::string& query) = 0;
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
239 virtual void Submit(Query* callback, const std::string& format, const SQL::ParamList& p) = 0;
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
246 virtual void Submit(Query* callback, const std::string& format, const ParamMap& p) = 0;
249 inline void SQL::PopulateUserInfo(User* user, ParamMap& userinfo)
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;