diff C++/DriverPostgres.cpp @ 177:f0cca031bcce

Improve Drivers
author David Demelier <markand@malikania.fr>
date Sat, 21 Sep 2013 09:25:28 +0200
parents a61cddaf7547
children 4c746050969a
line wrap: on
line diff
--- a/C++/DriverPostgres.cpp	Fri Sep 13 13:35:32 2013 +0200
+++ b/C++/DriverPostgres.cpp	Sat Sep 21 09:25:28 2013 +0200
@@ -24,54 +24,72 @@
  * Query PostgreSQL (protected methods)
  * -------------------------------------------------------- */
 
-QueryCheck QueryPostgres::checkRequest(int row, const std::string &column, ColumnType type)
+bool QueryPostgres::getBoolean(int row, const std::string &column)
 {
-	QueryCheck ret = QueryCheck::InvalidType;
-	Oid pqType;
-	int colIndex;
-	bool success = false;
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	std::string code = PQgetvalue(m_result.get(), row, idx);
 
-	// Invalid row
-	if (row >= PQntuples(m_result.get()))
-		return QueryCheck::InvalidRow;
-	if ((colIndex = PQfnumber(m_result.get(), column.c_str())) == -1)
-		return QueryCheck::InvalidColumn;
+	return code[0] == 't';
+}
 
-	pqType = PQftype(m_result.get(), colIndex);
-	switch (type)
+Date QueryPostgres::getDate(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+	long timestamp = static_cast<long>(time(0));
+
+	try
 	{
-	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;
+		std::ostringstream oss;
+		std::string value, req;
+
+		value = PQgetvalue(m_result.get(), row, idx);
+
+		/*
+		 * Convert the date using the SQL function so that user does
+		 * not require any explicit conversion itself.
+		 */
+		oss << "Select EXTRACT(EPOCH FROM TIMESTAMP '";
+		oss << value;
+		oss << "') AS RESULT";
+		req = oss.str();
+
+		Query::Ptr result = m_driver->query(req);
+		timestamp = result->get<double>(0, "RESULT");
 	}
+	catch (...) { }
 
-	// valid type requested?
-	if (success)
-		ret = QueryCheck::NoError;
+	return Date(static_cast<time_t>(timestamp));
+}
+
+double QueryPostgres::getDouble(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+
+	return std::stod(PQgetvalue(m_result.get(), row, idx));
+}
 
-	return ret;
+int QueryPostgres::getInt(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+
+	return std::stoi(PQgetvalue(m_result.get(), row, idx));
+
+}
+
+std::string QueryPostgres::getString(int row, const std::string &column)
+{
+	int idx = PQfnumber(m_result.get(), column.c_str());
+
+	return std::string(PQgetvalue(m_result.get(), row, idx));
 }
 
 /* --------------------------------------------------------
  * Query PostgreSQL (public methods)
  * -------------------------------------------------------- */
 
-QueryPostgres::QueryPostgres(PostgresResult result)
+QueryPostgres::QueryPostgres(Driver::Ptr driver, PostgresResult result)
 {
+	m_driver = driver;
 	m_result = std::move(result);
 }
 
@@ -79,6 +97,45 @@
 {
 }
 
+ColumnType QueryPostgres::type(const std::string &column) const
+{
+	ColumnType type;
+	int pqType, index;
+	
+	index = PQfnumber(m_result.get(), column.c_str());
+	pqType = PQftype(m_result.get(), index);
+	switch (pqType)
+	{
+	case 16:
+		type = ColumnType::Boolean;
+		break;
+	case 1082:
+	case 1083:
+	case 1114:
+		type = ColumnType::Date;
+		break;
+	case 1700:
+	case 700:
+	case 701:
+		type = ColumnType::Double;
+		break;
+	case 20:
+	case 21:
+	case 23:
+		type = ColumnType::Integer;
+		break;
+	case 25:
+	case 1042:
+	case 1043:
+		type = ColumnType::String;
+		break;
+	default:
+		type = ColumnType::Invalid;
+	}
+
+	return type;
+}
+
 int QueryPostgres::countRows()
 {
 	return PQntuples(m_result.get());
@@ -89,69 +146,6 @@
 	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());
@@ -227,14 +221,14 @@
 	return true;
 }
 
-std::unique_ptr<Query> DriverPostgres::query(const std::string &cmd)
+Query::Ptr 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));
+		throw Query::Error(strerror(ENOMEM));
 
 	// If an error occured
 	int errorCode = PQresultStatus(info);
@@ -242,10 +236,11 @@
 	{
 		std::string error = PQresultErrorMessage(info);
 		PQclear(info);
-		throw QueryError(error);
+		throw Query::Error(error);
 	}
 
-	return std::unique_ptr<Query>(new QueryPostgres(QueryPostgres::PostgresResult(info)));
+	return std::unique_ptr<Query>(new QueryPostgres(shared_from_this(),
+				      QueryPostgres::PostgresResult(info)));
 }
 
 std::string DriverPostgres::description() const
@@ -260,3 +255,14 @@
 
 	return oss.str();
 }
+
+std::string DriverPostgres::version() const
+{
+	std::ostringstream oss;
+
+	// TODO: ADD VERSION
+
+	oss << "PostgreSQL driver";
+
+	return oss.str();
+}