#include "Pgsql_Result.h" using namespace Pgsql; namespace { void set_stdstring_with_charptr(std::string &s, const char *p) { if (p) { s = p; } else { s.clear(); } } } // einde unnamed namespace ErrorDetails ErrorDetails::createErrorDetailsFromPGresult(const PGresult *result) { ErrorDetails r; set_stdstring_with_charptr(r.errorMessage, PQresultErrorMessage(result)); set_stdstring_with_charptr(r.state, PQresultErrorField(result, PG_DIAG_SQLSTATE)); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html set_stdstring_with_charptr(r.severity, PQresultErrorField(result, PG_DIAG_SEVERITY)); set_stdstring_with_charptr(r.messagePrimary, PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY)); set_stdstring_with_charptr(r.messageDetail, PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL)); set_stdstring_with_charptr(r.messageHint, PQresultErrorField(result, PG_DIAG_MESSAGE_HINT)); const char * p = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION); r.statementPosition = p != nullptr ? atoi(p) : -1; ///< First character is one, measured in characters not bytes! p = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION); r.internalPosition = p != nullptr ? atoi(p) : -1; set_stdstring_with_charptr(r.internalQuery, PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY)); set_stdstring_with_charptr(r.context, PQresultErrorField(result, PG_DIAG_CONTEXT)); set_stdstring_with_charptr(r.schemaName, PQresultErrorField(result, PG_DIAG_SCHEMA_NAME)); set_stdstring_with_charptr(r.tableName, PQresultErrorField(result, PG_DIAG_TABLE_NAME)); set_stdstring_with_charptr(r.columnName, PQresultErrorField(result, PG_DIAG_COLUMN_NAME)); set_stdstring_with_charptr(r.datatypeName, PQresultErrorField(result, PG_DIAG_DATATYPE_NAME)); set_stdstring_with_charptr(r.constraintName, PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME)); set_stdstring_with_charptr(r.sourceFile, PQresultErrorField(result, PG_DIAG_SOURCE_FILE)); set_stdstring_with_charptr(r.sourceLine, PQresultErrorField(result, PG_DIAG_SOURCE_LINE)); set_stdstring_with_charptr(r.sourceFunction, PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION)); return r; } Result::Result(PGresult *res) : result(res) { if (res == nullptr) { throw std::runtime_error("Passing nullptr to Result::Result is not allowed"); } } Result::~Result() { PQclear(result); } Result::Result(Result &&rhs) : result(rhs.result) { rhs.result = nullptr; } Result& Result::operator=(Result &&rhs) { if (result) { PQclear(result); } result = rhs.result; rhs.result = nullptr; return *this; } Result::operator bool() const { return result != nullptr; } ExecStatusType Result::resultStatus() { return PQresultStatus(result); } std::string Result::getResStatus() { // return PQresStatus(result); return ""; } std::string Result::diagSqlState() { std::string s(PQresultErrorField(result, PG_DIAG_SQLSTATE)); return s; } ErrorDetails Result::diagDetails() { // ErrorDetails r; // r.state = PQresultErrorField(result, PG_DIAG_SQLSTATE); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html // r.severity = PQresultErrorField(result, PG_DIAG_SEVERITY); // r.messagePrimary = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY); // r.messageDetail = PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL); // r.messageHint = PQresultErrorField(result, PG_DIAG_MESSAGE_HINT); // r.statementPosition = atoi(PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION)); ///< First character is one, measured in characters not bytes! // r.internalPosition = atoi(PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION)); // r.internalQuery = PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY); // r.context = PQresultErrorField(result, PG_DIAG_CONTEXT); // r.schemaName = PQresultErrorField(result, PG_DIAG_SCHEMA_NAME); // r.tableName = PQresultErrorField(result, PG_DIAG_TABLE_NAME); // r.columnName = PQresultErrorField(result, PG_DIAG_COLUMN_NAME); // r.datatypeName = PQresultErrorField(result, PG_DIAG_DATATYPE_NAME); // r.constraintName = PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME); // r.sourceFile = PQresultErrorField(result, PG_DIAG_SOURCE_FILE); // r.sourceLine = PQresultErrorField(result, PG_DIAG_SOURCE_LINE); // r.sourceFunction = PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION); // return r; return ErrorDetails::createErrorDetailsFromPGresult(result); } int Result::tuplesAffected() const { int i; char * res = PQcmdTuples(result); if (res && res[0] != '\0') { try { i = std::stoi(res); } catch (std::invalid_argument& ) { i = -1; } catch (std::out_of_range& ) { i = -1; } } else { i = -1; } return i; } int Result::rows() const { return PQntuples(result); } int Result::cols() const { return PQnfields(result); } const char * Result::getColName(int idx) const { return PQfname(result, idx); } const char * Result::val(int col, int row) const { return PQgetvalue(result, row, col); } Value Result::get(int col, int row) const { return Value( PQgetvalue(result, row, col), PQftype(result, col) ); } Oid Result::type(int col) const { return PQftype(result, col); } bool Result::null(int col, int row) const { return PQgetisnull(result, row, col); }