mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-28 03:20:11 +01:00
added new memeber SqlState to PostgreSQLException and made use of it. (#4099)
* added new memeber SqlState to PostgreSQLException and made use of it in StatementExecutor * Added test case testSqlState * fixed nameing convention errors. fixed bug in PostgreSQLException::PostgreSQLException regarding null termination of _sqlState data member
This commit is contained in:
@@ -36,6 +36,11 @@ public:
|
|||||||
explicit PostgreSQLException(const std::string& aMessage);
|
explicit PostgreSQLException(const std::string& aMessage);
|
||||||
/// Creates PostgreSQLException.
|
/// Creates PostgreSQLException.
|
||||||
|
|
||||||
|
|
||||||
|
explicit PostgreSQLException(const std::string& aMessage,const char * pAnSqlState);
|
||||||
|
/// Creates PostgreSQLException.
|
||||||
|
|
||||||
|
|
||||||
PostgreSQLException(const PostgreSQLException& exc);
|
PostgreSQLException(const PostgreSQLException& exc);
|
||||||
/// Creates PostgreSQLException.
|
/// Creates PostgreSQLException.
|
||||||
|
|
||||||
@@ -63,6 +68,13 @@ public:
|
|||||||
/// This is useful for temporarily storing a
|
/// This is useful for temporarily storing a
|
||||||
/// copy of an exception (see clone()), then
|
/// copy of an exception (see clone()), then
|
||||||
/// throwing it again.
|
/// throwing it again.
|
||||||
|
|
||||||
|
const char* sqlState() const noexcept;
|
||||||
|
/// Returns the SqlState
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
char _sqlState[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -90,6 +102,10 @@ class StatementException: public PostgreSQLException
|
|||||||
public:
|
public:
|
||||||
StatementException(const std::string& aMessage);
|
StatementException(const std::string& aMessage);
|
||||||
/// Creates StatementException from string.
|
/// Creates StatementException from string.
|
||||||
|
|
||||||
|
StatementException(const std::string& aMessage,const char* pAnSqlState);
|
||||||
|
/// Creates StatementException from string with support for sqlState.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -129,6 +145,13 @@ inline void PostgreSQLException::rethrow() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const char* PostgreSQLException::sqlState() const noexcept
|
||||||
|
{
|
||||||
|
return _sqlState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::PostgreSQL
|
} } } // namespace Poco::Data::PostgreSQL
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/PostgreSQL/PostgreSQLException.h"
|
#include "Poco/Data/PostgreSQL/PostgreSQLException.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Data {
|
namespace Data {
|
||||||
@@ -25,6 +25,19 @@ PostgreSQLException::PostgreSQLException(const std::string& aMessage):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PostgreSQLException::PostgreSQLException(const std::string& aMessage,const char* pAnSqlState):
|
||||||
|
Poco::Data::DataException(std::string("[PostgreSQL]: ") + aMessage)
|
||||||
|
{
|
||||||
|
// handle anSqlState
|
||||||
|
if (pAnSqlState == nullptr) _sqlState[0] = '\0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(_sqlState,pAnSqlState,5);
|
||||||
|
_sqlState[5] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PostgreSQLException::PostgreSQLException(const PostgreSQLException& anException):
|
PostgreSQLException::PostgreSQLException(const PostgreSQLException& anException):
|
||||||
Poco::Data::DataException(anException)
|
Poco::Data::DataException(anException)
|
||||||
@@ -68,5 +81,12 @@ StatementException::StatementException(const std::string& aMessage):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatementException::StatementException(const std::string& aMessage,const char* pAnSqlState):
|
||||||
|
PostgreSQLException(aMessage,pAnSqlState)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::PostgreSQL
|
} } } // namespace Poco::Data::PostgreSQL
|
||||||
|
|||||||
@@ -143,13 +143,18 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// get the sqlState
|
||||||
|
const char* pSQLState = PQresultErrorField(ptrPGResult, PG_DIAG_SQLSTATE);
|
||||||
|
|
||||||
// setup to clear the result from PQprepare
|
// setup to clear the result from PQprepare
|
||||||
PQResultClear resultClearer(ptrPGResult);
|
PQResultClear resultClearer(ptrPGResult);
|
||||||
|
|
||||||
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
//
|
||||||
|
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK )
|
||||||
{
|
{
|
||||||
throw StatementException(std::string("postgresql_stmt_prepare error: ") + PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
throw StatementException(std::string("postgresql_stmt_prepare error: ") + PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement,pSQLState);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine what the structure of a statement result will look like
|
// Determine what the structure of a statement result will look like
|
||||||
@@ -159,11 +164,15 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// get the sqlState
|
||||||
|
const char* pSQLState = PQresultErrorField(ptrPGResult, PG_DIAG_SQLSTATE);
|
||||||
|
|
||||||
PQResultClear resultClearer(ptrPGResult);
|
PQResultClear resultClearer(ptrPGResult);
|
||||||
|
|
||||||
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||||
{
|
{
|
||||||
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
||||||
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement,pSQLState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember the structure of the statement result
|
// remember the structure of the statement result
|
||||||
@@ -270,13 +279,14 @@ void StatementExecutor::execute()
|
|||||||
const char* pHint = PQresultErrorField(ptrPGResult, PG_DIAG_MESSAGE_HINT);
|
const char* pHint = PQresultErrorField(ptrPGResult, PG_DIAG_MESSAGE_HINT);
|
||||||
const char* pConstraint = PQresultErrorField(ptrPGResult, PG_DIAG_CONSTRAINT_NAME);
|
const char* pConstraint = PQresultErrorField(ptrPGResult, PG_DIAG_CONSTRAINT_NAME);
|
||||||
|
|
||||||
|
|
||||||
throw StatementException(std::string("postgresql_stmt_execute error: ")
|
throw StatementException(std::string("postgresql_stmt_execute error: ")
|
||||||
+ PQresultErrorMessage (ptrPGResult)
|
+ PQresultErrorMessage (ptrPGResult)
|
||||||
+ " Severity: " + (pSeverity ? pSeverity : "N/A")
|
+ " Severity: " + (pSeverity ? pSeverity : "N/A")
|
||||||
+ " State: " + (pSQLState ? pSQLState : "N/A")
|
+ " State: " + (pSQLState ? pSQLState : "N/A")
|
||||||
+ " Detail: " + (pDetail ? pDetail : "N/A")
|
+ " Detail: " + (pDetail ? pDetail : "N/A")
|
||||||
+ " Hint: " + (pHint ? pHint : "N/A")
|
+ " Hint: " + (pHint ? pHint : "N/A")
|
||||||
+ " Constraint: " + (pConstraint ? pConstraint : "N/A"));
|
+ " Constraint: " + (pConstraint ? pConstraint : "N/A"),pSQLState);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pResultHandle = ptrPGResult;
|
_pResultHandle = ptrPGResult;
|
||||||
|
|||||||
@@ -765,6 +765,20 @@ void PostgreSQLTest::testReconnect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLTest::testSqlState()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
*_pSession << "syntax error", now;
|
||||||
|
}
|
||||||
|
catch (const Poco::Data::PostgreSQL::PostgreSQLException & exception)
|
||||||
|
{
|
||||||
|
assertTrue(exception.sqlState() == std::string("42601"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PostgreSQLTest::testNullableInt()
|
void PostgreSQLTest::testNullableInt()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1271,6 +1285,7 @@ CppUnit::Test* PostgreSQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testNullableInt);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testNullableInt);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testNullableString);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testNullableString);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testTupleWithNullable);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testTupleWithNullable);
|
||||||
|
CppUnit_addTest(pSuite, PostgreSQLTest, testSqlState);
|
||||||
|
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testBinarySimpleAccess);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testBinarySimpleAccess);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testBinaryComplexType);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testBinaryComplexType);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class PostgreSQLTest: public CppUnit::TestCase
|
|||||||
/// Driver | DB | OS
|
/// Driver | DB | OS
|
||||||
/// ----------------+---------------------------+------------------------------------------
|
/// ----------------+---------------------------+------------------------------------------
|
||||||
/// 03.51.12.00 | PostgreSQL 9.3.1.0(18) | Mac OSX 10.9.1
|
/// 03.51.12.00 | PostgreSQL 9.3.1.0(18) | Mac OSX 10.9.1
|
||||||
///
|
/// | PostgreSQL 15.3 | Ubuntu 16.04
|
||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -113,6 +113,8 @@ public:
|
|||||||
|
|
||||||
void testReconnect();
|
void testReconnect();
|
||||||
|
|
||||||
|
void testSqlState();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user