From d5451970dca996018e16e4c57f75adcdc34fd2f9 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Thu, 15 May 2025 13:22:25 +0500 Subject: [PATCH] Added comments --- include/PgSQL_Connection.h | 47 ++++++++++++++++++++++++++++++++++++++ lib/PgSQL_Connection.cpp | 6 +---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/PgSQL_Connection.h b/include/PgSQL_Connection.h index 21c14c6b3..2d47c4075 100644 --- a/include/PgSQL_Connection.h +++ b/include/PgSQL_Connection.h @@ -279,6 +279,24 @@ public: bool requires_RESETTING_CONNECTION(const PgSQL_Connection* client_conn); bool has_same_connection_options(const PgSQL_Connection* c); + + /** + * @brief Sets the error information for this connection from the current libpq error message. + * + * This method retrieves the latest error message from the underlying PostgreSQL connection (via PQerrorMessage), + * parses it into its component fields (such as severity, SQLSTATE, and message), and fills the internal error_info + * structure accordingly. If the error message is not available, it sets a generic "Unknown error" with fatal severity. + * + * The function distinguishes between server errors (with fields like "S", "C", "M") and library-generated errors + * (stored under the "LE" key). If a server error is present, it is preferred; otherwise, the library error message + * is used. The error fields are extracted using parse_pq_error_message(). + * + * Example error string: "S:5:ERRORC:5:12345M:12:Some message" + * - S: Severity + * - C: SQLSTATE code + * - M: Primary message + * - LE: Library error (if present) + */ void set_error_from_PQerrorMessage(); int get_server_version() { @@ -503,7 +521,36 @@ private: bool handle_copy_out(const PGresult* result, uint64_t* processed_bytes); static void notice_handler_cb(void* arg, const PGresult* result); static void unhandled_notice_cb(void* arg, const PGresult* result); + + /** + * @brief Checks if a substring at a given position in a string matches the format of a formatted PostgreSQL error header. + * + * The expected format is: :: + * - : One or more uppercase letters (A-Z). + * - : One or more digits representing the length of the following value. + * - The header must be followed by a colon ':'. + * + * Example of a valid header: "S:5:Error" + * + * @param s The string to check. + * @param pos The position in the string to start checking. + * @return true if a valid formatted error header is found at the given position, false otherwise. + */ static bool is_valid_formatted_pq_error_header(const std::string& s, size_t pos); + + /** + * @brief Parses a PostgreSQL error message string into its component fields. + * + * This function scans the input error string, extracts all such formatted fields, and stores them + * in a map from prefix to a vector of values (to support repeated fields). Any unformatted text + * is stored under the "LE" (Library Error) key. + * + * Example input: "S:5:ERRORC:5:12345M:12:Some message" + * Output: { "S": ["ERROR"], "C": ["12345"], "M": ["Some message"] } + * + * @param error_str The error message string to parse. + * @return std::map> Map of error field prefixes to their values. + */ static std::map> parse_pq_error_message(const std::string& error_str); }; diff --git a/lib/PgSQL_Connection.cpp b/lib/PgSQL_Connection.cpp index b5cb590be..b5e668948 100644 --- a/lib/PgSQL_Connection.cpp +++ b/lib/PgSQL_Connection.cpp @@ -810,7 +810,7 @@ void PgSQL_Connection::connect_start() { const std::string& conninfo_str = conninfo.str(); pgsql_conn = PQconnectStart(conninfo_str.c_str()); - // introduce a new, formatted error verbosity type. + // introduced a new, formatted error verbosity type. PQsetErrorVerbosity(pgsql_conn, PSERRORS_FORMATTED_DEFAULT); //PQsetErrorContextVisibility(pgsql_conn, PQSHOW_CONTEXT_ERRORS); @@ -2136,15 +2136,11 @@ std::map> PgSQL_Connection::parse_pq_error size = size * 10 + digit; } } - - if (!valid_size || size < 0) { pos = size_start; continue; } - pos++; - // Extract value size_t value_start = pos; size_t value_end;