#ifndef PGSQL_RESULT_H #define PGSQL_RESULT_H #include "Pgsql_Row.h" namespace Pgsql { class ErrorDetails { public: static ErrorDetails createErrorDetailsFromPGresult(const PGresult *res); std::string errorMessage; std::string state; ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html std::string severity; std::string messagePrimary; std::string messageDetail; std::string messageHint; int statementPosition; ///< First character is one, measured in characters not bytes! int internalPosition; std::string internalQuery; std::string context; std::string schemaName; std::string tableName; std::string columnName; std::string datatypeName; std::string constraintName; std::string sourceFile; std::string sourceLine; std::string sourceFunction; }; /** \brief Non-copyable but movable wrapper for a postgresql result. * * This class makes sure the result is removed from memory. It also supplies an iterator for the * rows from the result facilitating also the use of the cpp for each. */ class Result { public: class const_iterator { public: const_iterator(const Result &r, int rw) : m_row(r, rw) {} const_iterator operator++() { const_iterator t(*this); m_row.next(); return t; } const_iterator& operator++(int) { m_row.next(); return *this; } bool operator==(const const_iterator &rhs) { return m_row == rhs.m_row; } bool operator!=(const const_iterator &rhs) { return !operator==(rhs); } const Row& operator*() { return m_row; } const Row& operator->() { return m_row; } private: Row m_row; }; Result() = default; Result(PGresult *result); ~Result(); Result(const Result &rhs) = delete; Result& operator=(const Result &rhs) = delete; Result(Result &&rhs); Result& operator=(Result &&rhs); operator bool() const; ExecStatusType resultStatus(); std::string getResStatus(); /** Use this to retrieve an error code when this is an error result * * The possible code are listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html */ std::string diagSqlState(); /** Retrieves all the error fields. */ ErrorDetails diagDetails(); const_iterator begin() const { return const_iterator(*this, 0); } const_iterator end() const { return const_iterator(*this, rows()); } int tuplesAffected() const; int rows() const; int cols() const; const char* getColName(int idx) const; const char* val(int col, int row) const; Value get(int col, int row) const; Oid type(int col) const; bool null(int col, int row) const; /// Return the oid of the table this is a column of /// when the column isn't a table column InvalidOid is returned /// when col is out of range a std::range_error is thrown Oid ftable(int col) const; /// Returns the attnum of col in its table, attnum is negative for system cols like oid /// It is positive for user columns, 0 signals there is no direct table column mapping /// when col is out of range a std::range_error is thrown int ftableCol(int col) const; // iterator begin(); private: PGresult *result = nullptr; void colRangeCheck(int col) const; void rowRangeCheck(int row) const; }; } // end namespace Pgsql #endif // PGSQL_RESULT_H