summaryrefslogtreecommitdiff
path: root/include/modules
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2017-12-22 02:47:54 +0000
committerPeter Powell <petpow@saberuk.com>2017-12-22 16:49:01 +0000
commitb6f57c0f06f4905b04de6ec2069522d2263626c4 (patch)
treed682ab49c248abeaf68f90d49f3322feb738f492 /include/modules
parentc8f515121fbdf3e4de693712ef2311cece45477d (diff)
Improve and modernize the SQL system API.
- Move everything into the SQL namespace and drop the SQL prefix. - Move SQLProvider::PopulateUserInfo to SQL::PopulateUserInfo. - Rename SQLEntry to SQL::Field and clean up. - Rename SQLEntries to SQL::Row. - Rename SQLerror to SQL::Error and clean up. - Rename SQLerrorNum to SQL::ErrorCode and drop the SQL_ prefix. - Rename ParamL to SQL::ParamList. - Rename ParamM to SQL::ParamMap; - Make implementing SQLQuery::OnError mandatory. - Redo most of the documentation in the sql header.
Diffstat (limited to 'include/modules')
-rw-r--r--include/modules/sql.h235
1 files changed, 155 insertions, 80 deletions
diff --git a/include/modules/sql.h b/include/modules/sql.h
index f81a85a33..dd33fc676 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -1,6 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
+ * Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
* Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
@@ -19,32 +20,85 @@
#pragma once
-/** Defines the error types which SQLerror may be set to
- */
-enum SQLerrorNum { SQL_NO_ERROR, SQL_BAD_DBID, SQL_BAD_CONN, SQL_QSEND_FAIL, SQL_QREPLY_FAIL };
-/** A list of format parameters for an SQLquery object.
- */
-typedef std::vector<std::string> ParamL;
+namespace SQL
+{
+ class Error;
+ class Field;
+ class Provider;
+ class Query;
+ class Result;
+
+ /** A list of parameter replacement values. */
+ typedef std::vector<std::string> ParamList;
-typedef std::map<std::string, std::string> ParamM;
+ /** A map of parameter replacement values. */
+ typedef std::map<std::string, std::string> ParamMap;
+
+ /** A list of SQL fields from a specific row. */
+ typedef std::vector<Field> Row;
+
+ /** An enumeration of possible error codes. */
+ enum ErrorCode
+ {
+ /** No error has occurred. */
+ NO_ERROR,
+
+ /** The database identifier is invalid. */
+ BAD_DBID,
+
+ /** The database connection has failed. */
+ BAD_CONN,
+
+ /** Executing the query failed. */
+ QSEND_FAIL,
+
+ /** Reading the response failed. */
+ QREPLY_FAIL
+ };
+
+ /** Populates a parameter map with information about a user.
+ * @param user The user to collect information from.
+ * @param userinfo The map to populate.
+ */
+ void PopulateUserInfo(User* user, ParamMap& userinfo);
+}
-class SQLEntry
+/** Represents a single SQL field. */
+class SQL::Field
{
- public:
+ private:
+ /** Whether this SQL field is NULL. */
+ bool null;
+
+ /** The underlying SQL value. */
std::string value;
- bool nul;
- SQLEntry() : nul(true) {}
- SQLEntry(const std::string& v) : value(v), nul(false) {}
- inline operator std::string&() { return value; }
-};
-typedef std::vector<SQLEntry> SQLEntries;
+ public:
+ /** Creates a new NULL SQL field. */
+ Field()
+ : null(true)
+ {
+ }
-/**
- * Result of an SQL query. Only valid inside OnResult
- */
-class SQLResult : public classbase
+ /** Creates a new non-NULL SQL field.
+ * @param v The value of the field.
+ */
+ Field(const std::string& v)
+ : null(false)
+ , value(v)
+ {
+ }
+
+ /** Determines whether this SQL entry is NULL. */
+ inline bool IsNull() const { return null; }
+
+ /** Retrieves the underlying value. */
+ inline operator const std::string&() const { return value; }
+};
+
+/** Represents the result of an SQL query. */
+class SQL::Result : public classbase
{
public:
/**
@@ -58,61 +112,66 @@ class SQLResult : public classbase
*/
virtual int Rows() = 0;
- /**
- * Return a single row (result of the query). The internal row counter
- * is incremented by one.
- *
- * @param result Storage for the result data.
- * @returns true if there was a row, false if no row exists (end of
- * iteration)
+ /** Retrieves the next available row from the database.
+ * @param result A list to store the fields from this row in.
+ * @return True if a row could be retrieved; otherwise, false.
*/
- virtual bool GetRow(SQLEntries& result) = 0;
+ virtual bool GetRow(Row& result) = 0;
- /** Returns column names for the items in this row
+ /** Retrieves a list of SQL columns in the result.
+ * @param result A reference to the vector to store column names in.
*/
virtual void GetCols(std::vector<std::string>& result) = 0;
};
-/** SQLerror holds the error state of a request.
+/** SQL::Error holds the error state of a request.
* The error string varies from database software to database software
* and should be used to display informational error messages to users.
*/
-class SQLerror
+class SQL::Error
{
+ private:
+ /** The custom error message if one has been specified. */
+ const char* message;
+
public:
- /** The error id
- */
- SQLerrorNum id;
+ /** The code which represents this error. */
+ const ErrorCode code;
- /** The error string
+ /** Initialize an SQL::Error from an error code.
+ * @param c A code which represents this error.
*/
- std::string str;
+ Error(ErrorCode c)
+ : message(NULL)
+ , code(c)
+ {
+ }
- /** Initialize an SQLerror
- * @param i The error ID to set
- * @param s The (optional) error string to set
+ /** Initialize an SQL::Error from an error code and a custom error message.
+ * @param c A code which represents this error.
+ * @param m A custom error message.
*/
- SQLerror(SQLerrorNum i, const std::string &s = "")
- : id(i), str(s)
+ Error(ErrorCode c, const char* m)
+ : message(m)
+ , code(c)
{
}
- /** Return the error string for an error
- */
- const char* Str()
+ /** Retrieves the error message. */
+ const char* ToString() const
{
- if(str.length())
- return str.c_str();
+ if (message)
+ return message;
- switch(id)
+ switch (code)
{
- case SQL_BAD_DBID:
- return "Invalid database ID";
- case SQL_BAD_CONN:
+ case BAD_DBID:
+ return "Invalid database identifier";
+ case BAD_CONN:
return "Invalid connection";
- case SQL_QSEND_FAIL:
+ case QSEND_FAIL:
return "Sending query failed";
- case SQL_QREPLY_FAIL:
+ case QREPLY_FAIL:
return "Getting query result failed";
default:
return "Unknown error";
@@ -122,63 +181,79 @@ class SQLerror
/**
* Object representing an SQL query. This should be allocated on the heap and
- * passed to an SQLProvider, which will free it when the query is complete or
+ * passed to an SQL::Provider, which will free it when the query is complete or
* when the querying module is unloaded.
*
* You should store whatever information is needed to have the callbacks work in
* this object (UID of user, channel name, etc).
*/
-class SQLQuery : public classbase
+class SQL::Query : public classbase
{
+ protected:
+ /** Creates a new SQL query. */
+ Query(Module* Creator)
+ : creator(Creator)
+ {
+ }
+
public:
- ModuleRef creator;
+ const ModuleRef creator;
- SQLQuery(Module* Creator) : creator(Creator) {}
- virtual ~SQLQuery() {}
+ /* Destroys this Query instance. */
+ virtual ~Query()
+ {
+ }
- virtual void OnResult(SQLResult& result) = 0;
- /**
- * Called when the query fails
+ /** Called when an SQL error happens.
+ * @param error The error that occurred.
+ */
+ virtual void OnError(Error& error) = 0;
+
+ /** Called when a SQL result is received.
+ * @param result The result of the SQL query.
*/
- virtual void OnError(SQLerror& error) { }
+ virtual void OnResult(Result& result) = 0;
};
/**
* Provider object for SQL servers
*/
-class SQLProvider : public DataProvider
+class SQL::Provider : public DataProvider
{
public:
- SQLProvider(Module* Creator, const std::string& Name) : DataProvider(Creator, Name) {}
- /** Submit an asynchronous SQL request
+ Provider(Module* Creator, const std::string& Name)
+ : DataProvider(Creator, Name)
+ {
+ }
+
+ /** Submit an asynchronous SQL query.
* @param callback The result reporting point
* @param query The hardcoded query string. If you have parameters to substitute, see below.
*/
- virtual void submit(SQLQuery* callback, const std::string& query) = 0;
+ virtual void Submit(Query* callback, const std::string& query) = 0;
- /** Submit an asynchronous SQL request
+ /** Submit an asynchronous SQL query.
* @param callback The result reporting point
* @param format The simple parameterized query string ('?' parameters)
* @param p Parameters to fill in for the '?' entries
*/
- virtual void submit(SQLQuery* callback, const std::string& format, const ParamL& p) = 0;
+ virtual void Submit(Query* callback, const std::string& format, const SQL::ParamList& p) = 0;
- /** Submit an asynchronous SQL request.
+ /** Submit an asynchronous SQL query.
* @param callback The result reporting point
* @param format The parameterized query string ('$name' parameters)
* @param p Parameters to fill in for the '$name' entries
*/
- virtual void submit(SQLQuery* callback, const std::string& format, const ParamM& p) = 0;
-
- /** Convenience function to prepare a map from a User* */
- void PopulateUserInfo(User* user, ParamM& userinfo)
- {
- userinfo["nick"] = user->nick;
- userinfo["host"] = user->GetRealHost();
- userinfo["ip"] = user->GetIPString();
- userinfo["gecos"] = user->fullname;
- userinfo["ident"] = user->ident;
- userinfo["server"] = user->server->GetName();
- userinfo["uuid"] = user->uuid;
- }
+ virtual void Submit(Query* callback, const std::string& format, const ParamMap& p) = 0;
};
+
+inline void SQL::PopulateUserInfo(User* user, ParamMap& userinfo)
+{
+ userinfo["nick"] = user->nick;
+ userinfo["host"] = user->GetRealHost();
+ userinfo["ip"] = user->GetIPString();
+ userinfo["gecos"] = user->fullname;
+ userinfo["ident"] = user->ident;
+ userinfo["server"] = user->server->GetName();
+ userinfo["uuid"] = user->uuid;
+}