changeset 172:a61cddaf7547

Rename Driver postgres
author David Demelier <markand@malikania.fr>
date Wed, 11 Sep 2013 15:27:00 +0200
parents e47c4e9e3f9d
children 18ad49172e6c
files C++/Driver.cpp C++/Driver.h C++/DriverPG.cpp C++/DriverPG.h C++/DriverPostgres.cpp C++/DriverPostgres.h
diffstat 6 files changed, 396 insertions(+), 374 deletions(-) [+]
line wrap: on
line diff
--- a/C++/Driver.cpp	Tue Sep 10 17:28:32 2013 +0200
+++ b/C++/Driver.cpp	Wed Sep 11 15:27:00 2013 +0200
@@ -38,7 +38,8 @@
 {
 	std::ostringstream oss;
 
-	switch (check) {
+	switch (check)
+	{
 	case QueryCheck::InvalidColumn:
 		oss << "Invalid column '" << column << "'";
 		throw QueryError(oss.str());
--- a/C++/Driver.h	Tue Sep 10 17:28:32 2013 +0200
+++ b/C++/Driver.h	Wed Sep 11 15:27:00 2013 +0200
@@ -106,7 +106,7 @@
 	 * @param row the row number
 	 * @param column the column name
 	 * @param check the result
-	 * @throw Query::ErrorException on erro
+	 * @throw QueryError on erro
 	 */
 	void checkValidRequest(int row, const std::string &column, QueryCheck check);
 
@@ -177,7 +177,7 @@
 	 * @param row the row number
 	 * @param column the column
 	 * @return a boolean
-	 * @throw Query::ErrorException on error
+	 * @throw QueryError on error
 	 */
 	bool getBool(int row, const std::string &column);
 
@@ -187,7 +187,7 @@
 	 * @param row the row number
 	 * @param column the column
 	 * @return a Date
-	 * @throw Query::ErrorException on error
+	 * @throw QueryError on error
 	 */
 	Date getDate(int row, const std::string &column);
 
@@ -197,7 +197,7 @@
 	 * @param row the row number
 	 * @param column the column
 	 * @return a double
-	 * @throw Query::ErrorException on error
+	 * @throw QueryError on error
 	 */
 	double getDouble(int row, const std::string &column);
 
@@ -207,7 +207,7 @@
 	 * @param row the row number
 	 * @param column the column
 	 * @return an integer
-	 * @throw Query::ErrorException on error
+	 * @throw QueryError on error
 	 */
 	int getInt(int row, const std::string &column);
 
@@ -217,7 +217,7 @@
 	 * @param row the row number
 	 * @param column the column
 	 * @return a string
-	 * @throw Query::ErrorException on error
+	 * @throw QueryError on error
 	 */
 	std::string getString(int row, const std::string &column);
 
@@ -258,7 +258,14 @@
 public:
 	typedef std::map<std::string, std::string> Params;
 
+	/**
+	 * Default constructor.
+	 */
 	Driver();
+
+	/**
+	 * Virtual destructor.
+	 */
 	virtual ~Driver();
 
 	/**
--- a/C++/DriverPG.cpp	Tue Sep 10 17:28:32 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-/*
- * DriverPostgres.cpp -- PostgreSQL driver
- *
- * Copyright (c) 2013, David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sstream>
-
-#include "DriverPG.h"
-
-/* --------------------------------------------------------
- * Query PostgreSQL (protected methods)
- * -------------------------------------------------------- */
-
-QueryCheck QueryPG::checkRequest(int row, const std::string &column, ColumnType type)
-{
-	QueryCheck ret = QueryCheck::InvalidType;
-	Oid pqType;
-	int colIndex;
-	bool success = false;
-
-	// Invalid row
-	if (row >= PQntuples(m_result.get()))
-		return QueryCheck::InvalidRow;
-	if ((colIndex = PQfnumber(m_result.get(), column.c_str())) == -1)
-		return QueryCheck::InvalidColumn;
-
-	pqType = PQftype(m_result.get(), colIndex);
-	switch (type) {
-	case ColumnType::Boolean:
-		success = (pqType == 16);
-		break;
-	case ColumnType::Date:
-		success = (pqType == 1082) || (pqType == 1083) || (pqType == 1114);
-		break;
-	case ColumnType::Double:
-		success = (pqType = 1700) || (pqType == 700) || (pqType == 701);
-		break;
-	case ColumnType::Integer:
-		success = (pqType == 20) || (pqType == 21) || (pqType == 23) || (pqType == 1700);
-		break;
-	case ColumnType::String:
-		success = (pqType == 25) || (pqType == 1042) || (pqType == 1043);
-		break;
-	default:
-		ret = QueryCheck::InvalidType;
-	}
-
-	// valid type requested?
-	if (success)
-		ret = QueryCheck::NoError;
-
-	return ret;
-}
-
-/* --------------------------------------------------------
- * Query PostgreSQL (public methods)
- * -------------------------------------------------------- */
-
-QueryPG::QueryPG(PostgresResult result)
-{
-	m_result = std::move(result);
-}
-
-QueryPG::~QueryPG()
-{
-}
-
-int QueryPG::countRows()
-{
-	return PQntuples(m_result.get());
-}
-
-int QueryPG::countColumns()
-{
-	return PQnfields(m_result.get());
-}
-
-bool QueryPG::checkBool(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	std::string code = PQgetvalue(m_result.get(), row, idx);
-
-	return code[0] == 't';
-}
-
-Date QueryPG::checkDate(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	long timestamp = static_cast<long>(time(0));
-
-	try {
-		timestamp = std::stol(PQgetvalue(m_result.get(), row, idx));
-	} catch (std::invalid_argument) {
-	}
-
-	return Date(static_cast<time_t>(timestamp));
-}
-
-double QueryPG::checkDouble(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	double d = 0;
-
-	try {
-		d = std::stod(PQgetvalue(m_result.get(), row, idx));
-	} catch (std::invalid_argument) {
-	}
-
-	return d;
-}
-
-int QueryPG::checkInt(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	int i = 0;
-
-	try {
-		i = std::stoi(PQgetvalue(m_result.get(), row, idx));
-	} catch (std::invalid_argument) {
-	}
-
-	return i;
-}
-
-std::string QueryPG::checkString(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return std::string(PQgetvalue(m_result.get(), row, idx));
-}
-
-bool QueryPG::isNull(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return PQgetisnull(m_result.get(), row, idx) == 1;
-}
-
-void QueryPG::dump(void)
-{
-	std::cout << "Dumping PostgreSQL result, ";
-	std::cout << countRows() << " rows, ";
-	std::cout << countColumns() << " columns" << std::endl;
-
-	for (int r = 0; r < countRows(); ++r) {
-		std::cout << "Dumping row " << r << std::endl;
-		std::cout << "==============================" << std::endl;
-
-		for (int c = 0; c < countColumns(); ++c)
-		{
-			std::cout << "\t" << PQfname(m_result.get(), c);
-			std::cout << " = " << PQgetvalue(m_result.get(), r, c) << std::endl;
-		}
-	}
-}
-
-/* --------------------------------------------------------
- * Driver PostgreSQL
- * -------------------------------------------------------- */
-
-DriverPG::DriverPG()
-{
-}
-
-DriverPG::~DriverPG()
-{
-}
-
-std::string DriverPG::convert(Params &params)
-{
-	std::ostringstream oss;
-
-	oss << "host = " << params["host"] << " ";
-	oss << "port = " << params["port"] << " ";
-	oss << "user = " << params["user"] << " ";
-	oss << "dbname = " << params["database"] << " ";
-	oss << "password = " << params["password"];
-
-	return oss.str();
-}
-
-bool DriverPG::connect(const Params &params)
-{
-	Params copy = params;
-	PGconn *conn = PQconnectdb(convert(copy).c_str());
-
-	if (conn == nullptr) {
-		m_error = strerror(ENOMEM);
-		return false;
-	}
-
-	if (PQstatus(conn) == CONNECTION_BAD) {
-		m_error = PQerrorMessage(conn);
-		PQfinish(conn);
-
-		return false;
-	}
-
-	m_connection = PostgresConn(conn);
-
-	return true;
-}
-
-std::unique_ptr<Query> DriverPG::query(const std::string &cmd)
-{
-	PGresult *info;
-
-	// If NULL, the libpq said no memory
-	info = PQexec(m_connection.get(), cmd.c_str());
-	if (info == nullptr)
-		throw QueryError(strerror(ENOMEM));
-
-	// If an error occured
-	int errorCode = PQresultStatus(info);
-	if (errorCode != PGRES_COMMAND_OK && errorCode != PGRES_TUPLES_OK) {
-		std::string error = PQresultErrorMessage(info);
-		PQclear(info);
-		throw QueryError(error);
-	}
-
-	return std::unique_ptr<Query>(new QueryPG(QueryPG::PostgresResult(info)));
-}
-
-std::string DriverPG::description() const
-{
-	std::ostringstream oss;
-
-	oss << "Connected on PostgreSQL database: " << std::endl;
-	oss << "  host: " << PQhost(m_connection.get()) << std::endl;
-	oss << "  port: " << PQport(m_connection.get()) << std::endl;
-	oss << "  user: " << PQuser(m_connection.get()) << std::endl;
-	oss << "  database: " << PQdb(m_connection.get()) << std::endl;
-
-	return oss.str();
-}
--- a/C++/DriverPG.h	Tue Sep 10 17:28:32 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * DriverPostgres.h -- PostgreSQL driver
- *
- * Copyright (c) 2013, David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
- */
-
-#ifndef _DRIVER_PG_H_
-#define _DRIVER_PG_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <libpq-fe.h>
-
-#include "Driver.h"
-
-/**
- * Query implementation for PostgreSQL.
- */
-class QueryPG : public Query
-{
-public:
-	struct PQQueryDeleter
-	{
-		void operator()(PGresult *result)
-		{
-			PQclear(result);
-		}
-	};
-
-	typedef std::unique_ptr<PGresult, PQQueryDeleter> PostgresResult;
-
-private:
-	PostgresResult m_result;
-
-protected:
-	virtual QueryCheck checkRequest(int row, const std::string &column, ColumnType type);
-
-	virtual Date checkDate(int row, const std::string &column);
-
-	virtual bool checkBool(int row, const std::string &column);
-
-	virtual double checkDouble(int row, const std::string &column);
-
-	virtual int checkInt(int row, const std::string &column);
-
-	virtual std::string checkString(int row, const std::string &column);
-
-	// Avoid copy
-	QueryPG(const QueryPG &src);
-
-	// Avoid copy
-	QueryPG & operator=(const QueryPG &src);
-
-public:
-	QueryPG(PostgresResult);
-	~QueryPG();
-
-	virtual int countRows();
-
-	virtual int countColumns();
-
-	virtual bool isNull(int row, const std::string &column);
-
-	virtual void dump();
-};
-
-class DriverPG : public Driver
-{
-public:
-	struct PGDeleter {
-		void operator()(PGconn *conn) {
-			PQfinish(conn);
-		}
-	};
-
-	typedef std::unique_ptr<PGconn, PGDeleter> PostgresConn;
-
-private:
-	PostgresConn m_connection;
-
-	/**
-	 * Convert the Params from the config
-	 * to the PostgreSQL string.
-	 *
-	 * @param settings the table
-	 * @return a string to be used
-	 */
-	std::string convert(Params &settings);
-
-public:
-	DriverPG();
-	~DriverPG();
-
-	virtual bool connect(const Params &params);
-
-	virtual std::unique_ptr<Query> query(const std::string &command);
-
-	virtual std::string description() const;
-};
-
-#endif // !_DRIVER_PG_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/DriverPostgres.cpp	Wed Sep 11 15:27:00 2013 +0200
@@ -0,0 +1,262 @@
+/*
+ * DriverPostgres.cpp -- PostgreSQL driver
+ *
+ * Copyright (c) 2013, David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sstream>
+
+#include "DriverPostgres.h"
+
+/* --------------------------------------------------------
+ * Query PostgreSQL (protected methods)
+ * -------------------------------------------------------- */
+
+QueryCheck QueryPostgres::checkRequest(int row, const std::string &column, ColumnType type)
+{
+	QueryCheck ret = QueryCheck::InvalidType;
+	Oid pqType;
+	int colIndex;
+	bool success = false;
+
+	// Invalid row
+	if (row >= PQntuples(m_result.get()))
+		return QueryCheck::InvalidRow;
+	if ((colIndex = PQfnumber(m_result.get(), column.c_str())) == -1)
+		return QueryCheck::InvalidColumn;
+
+	pqType = PQftype(m_result.get(), colIndex);
+	switch (type)
+	{
+	case ColumnType::Boolean:
+		success = (pqType == 16);
+		break;
+	case ColumnType::Date:
+		success = (pqType == 1082) || (pqType == 1083) || (pqType == 1114);
+		break;
+	case ColumnType::Double:
+		success = (pqType = 1700) || (pqType == 700) || (pqType == 701);
+		break;
+	case ColumnType::Integer:
+		success = (pqType == 20) || (pqType == 21) || (pqType == 23) || (pqType == 1700);
+		break;
+	case ColumnType::String:
+		success = (pqType == 25) || (pqType == 1042) || (pqType == 1043);
+		break;
+	default:
+		ret = QueryCheck::InvalidType;
+	}
+
+	// valid type requested?
+	if (success)
+		ret = QueryCheck::NoError;
+
+	return ret;
+}
+
+/* --------------------------------------------------------
+ * Query PostgreSQL (public methods)
+ * -------------------------------------------------------- */
+
+QueryPostgres::QueryPostgres(PostgresResult result)
+{
+	m_result = std::move(result);
+}
+
+QueryPostgres::~QueryPostgres()
+{
+}
+
+int QueryPostgres::countRows()
+{
+	return PQntuples(m_result.get());
+}
+
+int QueryPostgres::countColumns()
+{
+	return PQnfields(m_result.get());
+}
+
+bool QueryPostgres::checkBool(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	std::string code = PQgetvalue(m_result.get(), row, idx);
+
+	return code[0] == 't';
+}
+
+Date QueryPostgres::checkDate(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	long timestamp = static_cast<long>(time(0));
+
+	try
+	{
+		timestamp = std::stol(PQgetvalue(m_result.get(), row, idx));
+	}
+	catch (std::invalid_argument)
+	{
+	}
+
+	return Date(static_cast<time_t>(timestamp));
+}
+
+double QueryPostgres::checkDouble(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	double d = 0;
+
+	try
+	{
+		d = std::stod(PQgetvalue(m_result.get(), row, idx));
+	}
+	catch (std::invalid_argument)
+	{
+	}
+
+	return d;
+}
+
+int QueryPostgres::checkInt(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	int i = 0;
+
+	try
+	{
+		i = std::stoi(PQgetvalue(m_result.get(), row, idx));
+	}
+	catch (std::invalid_argument)
+	{
+	}
+
+	return i;
+}
+
+std::string QueryPostgres::checkString(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+
+	return std::string(PQgetvalue(m_result.get(), row, idx));
+}
+
+bool QueryPostgres::isNull(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+
+	return PQgetisnull(m_result.get(), row, idx) == 1;
+}
+
+void QueryPostgres::dump(void)
+{
+	std::cout << "Dumping PostgreSQL result, ";
+	std::cout << countRows() << " rows, ";
+	std::cout << countColumns() << " columns" << std::endl;
+
+	for (int r = 0; r < countRows(); ++r)
+	{
+		std::cout << "Dumping row " << r << std::endl;
+		std::cout << "==============================" << std::endl;
+
+		for (int c = 0; c < countColumns(); ++c)
+		{
+			std::cout << "\t" << PQfname(m_result.get(), c);
+			std::cout << " = " << PQgetvalue(m_result.get(), r, c) << std::endl;
+		}
+	}
+}
+
+/* --------------------------------------------------------
+ * Driver PostgreSQL
+ * -------------------------------------------------------- */
+
+DriverPostgres::DriverPostgres()
+{
+}
+
+DriverPostgres::~DriverPostgres()
+{
+}
+
+std::string DriverPostgres::convert(Params &params)
+{
+	std::ostringstream oss;
+
+	oss << "host = " << params["host"] << " ";
+	oss << "port = " << params["port"] << " ";
+	oss << "user = " << params["user"] << " ";
+	oss << "dbname = " << params["database"] << " ";
+	oss << "password = " << params["password"];
+
+	return oss.str();
+}
+
+bool DriverPostgres::connect(const Params &params)
+{
+	Params copy = params;
+	PGconn *conn = PQconnectdb(convert(copy).c_str());
+
+	if (conn == nullptr)
+	{
+		m_error = strerror(ENOMEM);
+		return false;
+	}
+
+	if (PQstatus(conn) == CONNECTION_BAD)
+	{
+		m_error = PQerrorMessage(conn);
+		PQfinish(conn);
+
+		return false;
+	}
+
+	m_connection = PostgresConn(conn);
+
+	return true;
+}
+
+std::unique_ptr<Query> DriverPostgres::query(const std::string &cmd)
+{
+	PGresult *info;
+
+	// If NULL, the libpq said no memory
+	info = PQexec(m_connection.get(), cmd.c_str());
+	if (info == nullptr)
+		throw QueryError(strerror(ENOMEM));
+
+	// If an error occured
+	int errorCode = PQresultStatus(info);
+	if (errorCode != PGRES_COMMAND_OK && errorCode != PGRES_TUPLES_OK)
+	{
+		std::string error = PQresultErrorMessage(info);
+		PQclear(info);
+		throw QueryError(error);
+	}
+
+	return std::unique_ptr<Query>(new QueryPostgres(QueryPostgres::PostgresResult(info)));
+}
+
+std::string DriverPostgres::description() const
+{
+	std::ostringstream oss;
+
+	oss << "Connected on PostgreSQL database: " << std::endl;
+	oss << "  host: " << PQhost(m_connection.get()) << std::endl;
+	oss << "  port: " << PQport(m_connection.get()) << std::endl;
+	oss << "  user: " << PQuser(m_connection.get()) << std::endl;
+	oss << "  database: " << PQdb(m_connection.get()) << std::endl;
+
+	return oss.str();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/DriverPostgres.h	Wed Sep 11 15:27:00 2013 +0200
@@ -0,0 +1,119 @@
+/*
+ * DriverPostgres.h -- PostgreSQL driver
+ *
+ * Copyright (c) 2013, David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
+ */
+
+#ifndef _DRIVER_PG_H_
+#define _DRIVER_PG_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include <libpq-fe.h>
+
+#include "Driver.h"
+
+/**
+ * Query implementation for PostgreSQL.
+ */
+class QueryPostgres : public Query
+{
+public:
+	struct PQQueryDeleter
+	{
+		void operator()(PGresult *result)
+		{
+			PQclear(result);
+		}
+	};
+
+	typedef std::unique_ptr<PGresult, PQQueryDeleter> PostgresResult;
+
+private:
+	PostgresResult m_result;
+
+protected:
+	virtual QueryCheck checkRequest(int row, const std::string &column, ColumnType type);
+
+	virtual Date checkDate(int row, const std::string &column);
+
+	virtual bool checkBool(int row, const std::string &column);
+
+	virtual double checkDouble(int row, const std::string &column);
+
+	virtual int checkInt(int row, const std::string &column);
+
+	virtual std::string checkString(int row, const std::string &column);
+
+	// Avoid copy
+	QueryPostgres(const QueryPostgres &src);
+
+	// Avoid copy
+	QueryPostgres & operator=(const QueryPostgres &src);
+
+public:
+	QueryPostgres(PostgresResult);
+	~QueryPostgres();
+
+	virtual int countRows();
+
+	virtual int countColumns();
+
+	virtual bool isNull(int row, const std::string &column);
+
+	virtual void dump();
+};
+
+class DriverPostgres : public Driver
+{
+public:
+	struct PGDeleter {
+		void operator()(PGconn *conn) {
+			PQfinish(conn);
+		}
+	};
+
+	typedef std::unique_ptr<PGconn, PGDeleter> PostgresConn;
+
+private:
+	PostgresConn m_connection;
+
+	/**
+	 * Convert the Params from the config
+	 * to the PostgreSQL string.
+	 *
+	 * @param settings the table
+	 * @return a string to be used
+	 */
+	std::string convert(Params &settings);
+
+public:
+	DriverPostgres();
+	~DriverPostgres();
+
+	virtual bool connect(const Params &params);
+
+	virtual std::unique_ptr<Query> query(const std::string &command);
+
+	virtual std::string description() const;
+};
+
+#endif // !_DRIVER_PG_H_