From b6f57c0f06f4905b04de6ec2069522d2263626c4 Mon Sep 17 00:00:00 2001
From: Peter Powell <petpow@saberuk.com>
Date: Fri, 22 Dec 2017 02:47:54 +0000
Subject: 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.
---
 include/modules/sql.h           | 235 ++++++++++++++++++++++++++--------------
 src/modules/extra/m_mysql.cpp   |  52 ++++-----
 src/modules/extra/m_pgsql.cpp   |  46 ++++----
 src/modules/extra/m_sqlite3.cpp |  30 ++---
 src/modules/m_sqlauth.cpp       |  21 ++--
 src/modules/m_sqloper.cpp       |  25 +++--
 6 files changed, 245 insertions(+), 164 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;
+}
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp
index aa396d55f..a16a293d7 100644
--- a/src/modules/extra/m_mysql.cpp
+++ b/src/modules/extra/m_mysql.cpp
@@ -84,17 +84,17 @@ class DispatcherThread;
 
 struct QQueueItem
 {
-	SQLQuery* q;
+	SQL::Query* q;
 	std::string query;
 	SQLConnection* c;
-	QQueueItem(SQLQuery* Q, const std::string& S, SQLConnection* C) : q(Q), query(S), c(C) {}
+	QQueueItem(SQL::Query* Q, const std::string& S, SQLConnection* C) : q(Q), query(S), c(C) {}
 };
 
 struct RQueueItem
 {
-	SQLQuery* q;
+	SQL::Query* q;
 	MySQLresult* r;
-	RQueueItem(SQLQuery* Q, MySQLresult* R) : q(Q), r(R) {}
+	RQueueItem(SQL::Query* Q, MySQLresult* R) : q(Q), r(R) {}
 };
 
 typedef insp::flat_map<std::string, SQLConnection*> ConnMap;
@@ -136,16 +136,16 @@ class DispatcherThread : public SocketThread
 
 /** Represents a mysql result set
  */
-class MySQLresult : public SQLResult
+class MySQLresult : public SQL::Result
 {
  public:
-	SQLerror err;
+	SQL::Error err;
 	int currentrow;
 	int rows;
 	std::vector<std::string> colnames;
-	std::vector<SQLEntries> fieldlists;
+	std::vector<SQL::Row> fieldlists;
 
-	MySQLresult(MYSQL_RES* res, int affected_rows) : err(SQL_NO_ERROR), currentrow(0), rows(0)
+	MySQLresult(MYSQL_RES* res, int affected_rows) : err(SQL::NO_ERROR), currentrow(0), rows(0)
 	{
 		if (affected_rows >= 1)
 		{
@@ -174,9 +174,9 @@ class MySQLresult : public SQLResult
 					{
 						std::string a = (fields[field_count].name ? fields[field_count].name : "");
 						if (row[field_count])
-							fieldlists[n].push_back(SQLEntry(row[field_count]));
+							fieldlists[n].push_back(SQL::Field(row[field_count]));
 						else
-							fieldlists[n].push_back(SQLEntry());
+							fieldlists[n].push_back(SQL::Field());
 						colnames.push_back(a);
 						field_count++;
 					}
@@ -188,7 +188,7 @@ class MySQLresult : public SQLResult
 		}
 	}
 
-	MySQLresult(SQLerror& e) : err(e)
+	MySQLresult(SQL::Error& e) : err(e)
 	{
 
 	}
@@ -203,16 +203,16 @@ class MySQLresult : public SQLResult
 		result.assign(colnames.begin(), colnames.end());
 	}
 
-	SQLEntry GetValue(int row, int column)
+	SQL::Field GetValue(int row, int column)
 	{
 		if ((row >= 0) && (row < rows) && (column >= 0) && (column < (int)fieldlists[row].size()))
 		{
 			return fieldlists[row][column];
 		}
-		return SQLEntry();
+		return SQL::Field();
 	}
 
-	bool GetRow(SQLEntries& result) CXX11_OVERRIDE
+	bool GetRow(SQL::Row& result) CXX11_OVERRIDE
 	{
 		if (currentrow < rows)
 		{
@@ -230,7 +230,7 @@ class MySQLresult : public SQLResult
 
 /** Represents a connection to a mysql database
  */
-class SQLConnection : public SQLProvider
+class SQLConnection : public SQL::Provider
 {
  public:
 	reference<ConfigTag> config;
@@ -238,7 +238,7 @@ class SQLConnection : public SQLProvider
 	Mutex lock;
 
 	// This constructor creates an SQLConnection object with the given credentials, but does not connect yet.
-	SQLConnection(Module* p, ConfigTag* tag) : SQLProvider(p, "SQL/" + tag->getString("id")),
+	SQLConnection(Module* p, ConfigTag* tag) : SQL::Provider(p, "SQL/" + tag->getString("id")),
 		config(tag), connection(NULL)
 	{
 	}
@@ -297,7 +297,7 @@ class SQLConnection : public SQLProvider
 		{
 			/* XXX: See /usr/include/mysql/mysqld_error.h for a list of
 			 * possible error numbers and error messages */
-			SQLerror e(SQL_QREPLY_FAIL, ConvToStr(mysql_errno(connection)) + ": " + mysql_error(connection));
+			SQL::Error e(SQL::QREPLY_FAIL, InspIRCd::Format("%u: %s", mysql_errno(connection), mysql_error(connection)));
 			return new MySQLresult(e);
 		}
 	}
@@ -319,14 +319,14 @@ class SQLConnection : public SQLProvider
 		mysql_close(connection);
 	}
 
-	void submit(SQLQuery* q, const std::string& qs) CXX11_OVERRIDE
+	void Submit(SQL::Query* q, const std::string& qs) CXX11_OVERRIDE
 	{
 		Parent()->Dispatcher->LockQueue();
 		Parent()->qq.push_back(QQueueItem(q, qs, this));
 		Parent()->Dispatcher->UnlockQueueWakeup();
 	}
 
-	void submit(SQLQuery* call, const std::string& q, const ParamL& p) CXX11_OVERRIDE
+	void Submit(SQL::Query* call, const std::string& q, const SQL::ParamList& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		unsigned int param = 0;
@@ -351,10 +351,10 @@ class SQLConnection : public SQLProvider
 				}
 			}
 		}
-		submit(call, res);
+		Submit(call, res);
 	}
 
-	void submit(SQLQuery* call, const std::string& q, const ParamM& p) CXX11_OVERRIDE
+	void Submit(SQL::Query* call, const std::string& q, const SQL::ParamMap& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		for(std::string::size_type i = 0; i < q.length(); i++)
@@ -369,7 +369,7 @@ class SQLConnection : public SQLProvider
 					field.push_back(q[i++]);
 				i--;
 
-				ParamM::const_iterator it = p.find(field);
+				SQL::ParamMap::const_iterator it = p.find(field);
 				if (it != p.end())
 				{
 					std::string parm = it->second;
@@ -380,7 +380,7 @@ class SQLConnection : public SQLProvider
 				}
 			}
 		}
-		submit(call, res);
+		Submit(call, res);
 	}
 };
 
@@ -434,7 +434,7 @@ void ModuleSQL::ReadConfig(ConfigStatus& status)
 
 	// now clean up the deleted databases
 	Dispatcher->LockQueue();
-	SQLerror err(SQL_BAD_DBID);
+	SQL::Error err(SQL::BAD_DBID);
 	for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++)
 	{
 		ServerInstance->Modules->DelService(*i->second);
@@ -461,7 +461,7 @@ void ModuleSQL::ReadConfig(ConfigStatus& status)
 
 void ModuleSQL::OnUnloadModule(Module* mod)
 {
-	SQLerror err(SQL_BAD_DBID);
+	SQL::Error err(SQL::BAD_DBID);
 	Dispatcher->LockQueue();
 	unsigned int i = qq.size();
 	while (i > 0)
@@ -541,7 +541,7 @@ void DispatcherThread::OnNotify()
 	for(ResultQueue::iterator i = Parent->rq.begin(); i != Parent->rq.end(); i++)
 	{
 		MySQLresult* res = i->r;
-		if (res->err.id == SQL_NO_ERROR)
+		if (res->err.code == SQL::NO_ERROR)
 			i->q->OnResult(*res);
 		else
 			i->q->OnError(res->err);
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index 7aaf96a67..25ce6c7f1 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -70,9 +70,9 @@ class ReconnectTimer : public Timer
 
 struct QueueItem
 {
-	SQLQuery* c;
+	SQL::Query* c;
 	std::string q;
-	QueueItem(SQLQuery* C, const std::string& Q) : c(C), q(Q) {}
+	QueueItem(SQL::Query* C, const std::string& Q) : c(C), q(Q) {}
 };
 
 /** PgSQLresult is a subclass of the mostly-pure-virtual class SQLresult.
@@ -82,7 +82,7 @@ struct QueueItem
  * data is passes to the module nearly as directly as if it was using the API directly itself.
  */
 
-class PgSQLresult : public SQLResult
+class PgSQLresult : public SQL::Result
 {
 	PGresult* res;
 	int currentrow;
@@ -114,16 +114,16 @@ class PgSQLresult : public SQLResult
 		}
 	}
 
-	SQLEntry GetValue(int row, int column)
+	SQL::Field GetValue(int row, int column)
 	{
 		char* v = PQgetvalue(res, row, column);
 		if (!v || PQgetisnull(res, row, column))
-			return SQLEntry();
+			return SQL::Field();
 
-		return SQLEntry(std::string(v, PQgetlength(res, row, column)));
+		return SQL::Field(std::string(v, PQgetlength(res, row, column)));
 	}
 
-	bool GetRow(SQLEntries& result) CXX11_OVERRIDE
+	bool GetRow(SQL::Row& result) CXX11_OVERRIDE
 	{
 		if (currentrow >= PQntuples(res))
 			return false;
@@ -141,7 +141,7 @@ class PgSQLresult : public SQLResult
 
 /** SQLConn represents one SQL session.
  */
-class SQLConn : public SQLProvider, public EventHandler
+class SQLConn : public SQL::Provider, public EventHandler
 {
  public:
 	reference<ConfigTag> conf;	/* The <database> entry */
@@ -151,7 +151,7 @@ class SQLConn : public SQLProvider, public EventHandler
 	QueueItem		qinprog;	/* If there is currently a query in progress */
 
 	SQLConn(Module* Creator, ConfigTag* tag)
-	: SQLProvider(Creator, "SQL/" + tag->getString("id")), conf(tag), sql(NULL), status(CWRITE), qinprog(NULL, "")
+	: SQL::Provider(Creator, "SQL/" + tag->getString("id")), conf(tag), sql(NULL), status(CWRITE), qinprog(NULL, "")
 	{
 		if (!DoConnect())
 		{
@@ -162,14 +162,14 @@ class SQLConn : public SQLProvider, public EventHandler
 
 	CullResult cull() CXX11_OVERRIDE
 	{
-		this->SQLProvider::cull();
+		this->SQL::Provider::cull();
 		ServerInstance->Modules->DelService(*this);
 		return this->EventHandler::cull();
 	}
 
 	~SQLConn()
 	{
-		SQLerror err(SQL_BAD_DBID);
+		SQL::Error err(SQL::BAD_DBID);
 		if (qinprog.c)
 		{
 			qinprog.c->OnError(err);
@@ -177,7 +177,7 @@ class SQLConn : public SQLProvider, public EventHandler
 		}
 		for(std::deque<QueueItem>::iterator i = queue.begin(); i != queue.end(); i++)
 		{
-			SQLQuery* q = i->c;
+			SQL::Query* q = i->c;
 			q->OnError(err);
 			delete q;
 		}
@@ -320,7 +320,7 @@ restart:
 					case PGRES_BAD_RESPONSE:
 					case PGRES_FATAL_ERROR:
 					{
-						SQLerror err(SQL_QREPLY_FAIL, PQresultErrorMessage(result));
+						SQL::Error err(SQL::QREPLY_FAIL, PQresultErrorMessage(result));
 						qinprog.c->OnError(err);
 						break;
 					}
@@ -390,7 +390,7 @@ restart:
 		}
 	}
 
-	void submit(SQLQuery *req, const std::string& q) CXX11_OVERRIDE
+	void Submit(SQL::Query *req, const std::string& q) CXX11_OVERRIDE
 	{
 		if (qinprog.q.empty())
 		{
@@ -403,7 +403,7 @@ restart:
 		}
 	}
 
-	void submit(SQLQuery *req, const std::string& q, const ParamL& p) CXX11_OVERRIDE
+	void Submit(SQL::Query *req, const std::string& q, const SQL::ParamList& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		unsigned int param = 0;
@@ -425,10 +425,10 @@ restart:
 				}
 			}
 		}
-		submit(req, res);
+		Submit(req, res);
 	}
 
-	void submit(SQLQuery *req, const std::string& q, const ParamM& p) CXX11_OVERRIDE
+	void Submit(SQL::Query *req, const std::string& q, const SQL::ParamMap& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		for(std::string::size_type i = 0; i < q.length(); i++)
@@ -443,7 +443,7 @@ restart:
 					field.push_back(q[i++]);
 				i--;
 
-				ParamM::const_iterator it = p.find(field);
+				SQL::ParamMap::const_iterator it = p.find(field);
 				if (it != p.end())
 				{
 					std::string parm = it->second;
@@ -456,7 +456,7 @@ restart:
 				}
 			}
 		}
-		submit(req, res);
+		Submit(req, res);
 	}
 
 	void DoQuery(const QueueItem& req)
@@ -464,7 +464,7 @@ restart:
 		if (status != WREAD && status != WWRITE)
 		{
 			// whoops, not connected...
-			SQLerror err(SQL_BAD_CONN);
+			SQL::Error err(SQL::BAD_CONN);
 			req.c->OnError(err);
 			delete req.c;
 			return;
@@ -476,7 +476,7 @@ restart:
 		}
 		else
 		{
-			SQLerror err(SQL_QSEND_FAIL, PQerrorMessage(sql));
+			SQL::Error err(SQL::QSEND_FAIL, PQerrorMessage(sql));
 			req.c->OnError(err);
 			delete req.c;
 		}
@@ -554,7 +554,7 @@ class ModulePgSQL : public Module
 
 	void OnUnloadModule(Module* mod) CXX11_OVERRIDE
 	{
-		SQLerror err(SQL_BAD_DBID);
+		SQL::Error err(SQL::BAD_DBID);
 		for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++)
 		{
 			SQLConn* conn = i->second;
@@ -567,7 +567,7 @@ class ModulePgSQL : public Module
 			std::deque<QueueItem>::iterator j = conn->queue.begin();
 			while (j != conn->queue.end())
 			{
-				SQLQuery* q = j->c;
+				SQL::Query* q = j->c;
 				if (q->creator == mod)
 				{
 					q->OnError(err);
diff --git a/src/modules/extra/m_sqlite3.cpp b/src/modules/extra/m_sqlite3.cpp
index 5f6cd1ce3..0f596a0f7 100644
--- a/src/modules/extra/m_sqlite3.cpp
+++ b/src/modules/extra/m_sqlite3.cpp
@@ -46,13 +46,13 @@
 class SQLConn;
 typedef insp::flat_map<std::string, SQLConn*> ConnMap;
 
-class SQLite3Result : public SQLResult
+class SQLite3Result : public SQL::Result
 {
  public:
 	int currentrow;
 	int rows;
 	std::vector<std::string> columns;
-	std::vector<SQLEntries> fieldlists;
+	std::vector<SQL::Row> fieldlists;
 
 	SQLite3Result() : currentrow(0), rows(0)
 	{
@@ -63,7 +63,7 @@ class SQLite3Result : public SQLResult
 		return rows;
 	}
 
-	bool GetRow(SQLEntries& result) CXX11_OVERRIDE
+	bool GetRow(SQL::Row& result) CXX11_OVERRIDE
 	{
 		if (currentrow < rows)
 		{
@@ -84,13 +84,13 @@ class SQLite3Result : public SQLResult
 	}
 };
 
-class SQLConn : public SQLProvider
+class SQLConn : public SQL::Provider
 {
 	sqlite3* conn;
 	reference<ConfigTag> config;
 
  public:
-	SQLConn(Module* Parent, ConfigTag* tag) : SQLProvider(Parent, "SQL/" + tag->getString("id")), config(tag)
+	SQLConn(Module* Parent, ConfigTag* tag) : SQL::Provider(Parent, "SQL/" + tag->getString("id")), config(tag)
 	{
 		std::string host = tag->getString("hostname");
 		if (sqlite3_open_v2(host.c_str(), &conn, SQLITE_OPEN_READWRITE, 0) != SQLITE_OK)
@@ -111,14 +111,14 @@ class SQLConn : public SQLProvider
 		}
 	}
 
-	void Query(SQLQuery* query, const std::string& q)
+	void Query(SQL::Query* query, const std::string& q)
 	{
 		SQLite3Result res;
 		sqlite3_stmt *stmt;
 		int err = sqlite3_prepare_v2(conn, q.c_str(), q.length(), &stmt, NULL);
 		if (err != SQLITE_OK)
 		{
-			SQLerror error(SQL_QSEND_FAIL, sqlite3_errmsg(conn));
+			SQL::Error error(SQL::QSEND_FAIL, sqlite3_errmsg(conn));
 			query->OnError(error);
 			return;
 		}
@@ -140,7 +140,7 @@ class SQLConn : public SQLProvider
 				{
 					const char* txt = (const char*)sqlite3_column_text(stmt, i);
 					if (txt)
-						res.fieldlists[res.rows][i] = SQLEntry(txt);
+						res.fieldlists[res.rows][i] = SQL::Field(txt);
 				}
 				res.rows++;
 			}
@@ -151,7 +151,7 @@ class SQLConn : public SQLProvider
 			}
 			else
 			{
-				SQLerror error(SQL_QREPLY_FAIL, sqlite3_errmsg(conn));
+				SQL::Error error(SQL::QREPLY_FAIL, sqlite3_errmsg(conn));
 				query->OnError(error);
 				break;
 			}
@@ -159,13 +159,13 @@ class SQLConn : public SQLProvider
 		sqlite3_finalize(stmt);
 	}
 
-	void submit(SQLQuery* query, const std::string& q) CXX11_OVERRIDE
+	void Submit(SQL::Query* query, const std::string& q) CXX11_OVERRIDE
 	{
 		Query(query, q);
 		delete query;
 	}
 
-	void submit(SQLQuery* query, const std::string& q, const ParamL& p) CXX11_OVERRIDE
+	void Submit(SQL::Query* query, const std::string& q, const SQL::ParamList& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		unsigned int param = 0;
@@ -183,10 +183,10 @@ class SQLConn : public SQLProvider
 				}
 			}
 		}
-		submit(query, res);
+		Submit(query, res);
 	}
 
-	void submit(SQLQuery* query, const std::string& q, const ParamM& p) CXX11_OVERRIDE
+	void Submit(SQL::Query* query, const std::string& q, const SQL::ParamMap& p) CXX11_OVERRIDE
 	{
 		std::string res;
 		for(std::string::size_type i = 0; i < q.length(); i++)
@@ -201,7 +201,7 @@ class SQLConn : public SQLProvider
 					field.push_back(q[i++]);
 				i--;
 
-				ParamM::const_iterator it = p.find(field);
+				SQL::ParamMap::const_iterator it = p.find(field);
 				if (it != p.end())
 				{
 					char* escaped = sqlite3_mprintf("%q", it->second.c_str());
@@ -210,7 +210,7 @@ class SQLConn : public SQLProvider
 				}
 			}
 		}
-		submit(query, res);
+		Submit(query, res);
 	}
 };
 
diff --git a/src/modules/m_sqlauth.cpp b/src/modules/m_sqlauth.cpp
index 1a5b68dd9..4c6a221b7 100644
--- a/src/modules/m_sqlauth.cpp
+++ b/src/modules/m_sqlauth.cpp
@@ -28,18 +28,21 @@ enum AuthState {
 	AUTH_STATE_FAIL = 2
 };
 
-class AuthQuery : public SQLQuery
+class AuthQuery : public SQL::Query
 {
  public:
 	const std::string uid;
 	LocalIntExt& pendingExt;
 	bool verbose;
 	AuthQuery(Module* me, const std::string& u, LocalIntExt& e, bool v)
-		: SQLQuery(me), uid(u), pendingExt(e), verbose(v)
+		: SQL::Query(me)
+		, uid(u)
+		, pendingExt(e)
+		, verbose(v)
 	{
 	}
 
-	void OnResult(SQLResult& res) CXX11_OVERRIDE
+	void OnResult(SQL::Result& res) CXX11_OVERRIDE
 	{
 		User* user = ServerInstance->FindNick(uid);
 		if (!user)
@@ -56,21 +59,21 @@ class AuthQuery : public SQLQuery
 		}
 	}
 
-	void OnError(SQLerror& error) CXX11_OVERRIDE
+	void OnError(SQL::Error& error) CXX11_OVERRIDE
 	{
 		User* user = ServerInstance->FindNick(uid);
 		if (!user)
 			return;
 		pendingExt.set(user, AUTH_STATE_FAIL);
 		if (verbose)
-			ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (SQL query failed: %s)", user->GetFullRealHost().c_str(), error.Str());
+			ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (SQL query failed: %s)", user->GetFullRealHost().c_str(), error.ToString());
 	}
 };
 
 class ModuleSQLAuth : public Module
 {
 	LocalIntExt pendingExt;
-	dynamic_reference<SQLProvider> SQL;
+	dynamic_reference<SQL::Provider> SQL;
 
 	std::string freeformquery;
 	std::string killreason;
@@ -120,8 +123,8 @@ class ModuleSQLAuth : public Module
 
 		pendingExt.set(user, AUTH_STATE_BUSY);
 
-		ParamM userinfo;
-		SQL->PopulateUserInfo(user, userinfo);
+		SQL::ParamMap userinfo;
+		SQL::PopulateUserInfo(user, userinfo);
 		userinfo["pass"] = user->password;
 
 		HashProvider* md5 = ServerInstance->Modules->FindDataService<HashProvider>("hash/md5");
@@ -135,7 +138,7 @@ class ModuleSQLAuth : public Module
 		const std::string certfp = SSLClientCert::GetFingerprint(&user->eh);
 		userinfo["certfp"] = certfp;
 
-		SQL->submit(new AuthQuery(this, user->uuid, pendingExt, verbose), freeformquery, userinfo);
+		SQL->Submit(new AuthQuery(this, user->uuid, pendingExt, verbose), freeformquery, userinfo);
 
 		return MOD_RES_PASSTHRU;
 	}
diff --git a/src/modules/m_sqloper.cpp b/src/modules/m_sqloper.cpp
index b6aa90f49..d4baae7d2 100644
--- a/src/modules/m_sqloper.cpp
+++ b/src/modules/m_sqloper.cpp
@@ -21,16 +21,19 @@
 #include "modules/sql.h"
 #include "modules/hash.h"
 
-class OpMeQuery : public SQLQuery
+class OperQuery : public SQL::Query
 {
  public:
 	const std::string uid, username, password;
-	OpMeQuery(Module* me, const std::string& u, const std::string& un, const std::string& pw)
-		: SQLQuery(me), uid(u), username(un), password(pw)
+	OperQuery(Module* me, const std::string& u, const std::string& un, const std::string& pw)
+		: SQL::Query(me)
+		, uid(u)
+		, username(un)
+		, password(pw)
 	{
 	}
 
-	void OnResult(SQLResult& res) CXX11_OVERRIDE
+	void OnResult(SQL::Result& res) CXX11_OVERRIDE
 	{
 		ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "result for %s", uid.c_str());
 		User* user = ServerInstance->FindNick(uid);
@@ -38,7 +41,7 @@ class OpMeQuery : public SQLQuery
 			return;
 
 		// multiple rows may exist
-		SQLEntries row;
+		SQL::Row row;
 		while (res.GetRow(row))
 		{
 			if (OperUser(user, row[0], row[1]))
@@ -49,9 +52,9 @@ class OpMeQuery : public SQLQuery
 		fallback();
 	}
 
-	void OnError(SQLerror& error) CXX11_OVERRIDE
+	void OnError(SQL::Error& error) CXX11_OVERRIDE
 	{
-		ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "query failed (%s)", error.Str());
+		ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "query failed (%s)", error.ToString());
 		fallback();
 	}
 
@@ -106,7 +109,7 @@ class ModuleSQLOper : public Module
 {
 	std::string query;
 	std::string hashtype;
-	dynamic_reference<SQLProvider> SQL;
+	dynamic_reference<SQL::Provider> SQL;
 
 public:
 	ModuleSQLOper() : SQL(this, "SQL") {}
@@ -144,12 +147,12 @@ public:
 	{
 		HashProvider* hash = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
 
-		ParamM userinfo;
-		SQL->PopulateUserInfo(user, userinfo);
+		SQL::ParamMap userinfo;
+		SQL::PopulateUserInfo(user, userinfo);
 		userinfo["username"] = username;
 		userinfo["password"] = hash ? hash->Generate(password) : password;
 
-		SQL->submit(new OpMeQuery(this, user->uuid, username, password), query, userinfo);
+		SQL->Submit(new OperQuery(this, user->uuid, username, password), query, userinfo);
 	}
 
 	Version GetVersion() CXX11_OVERRIDE
-- 
cgit v1.2.3