mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-08 23:10:36 +01:00
Oracle ODBC fixes
This commit is contained in:
parent
bbf30dc674
commit
494579542f
@ -158,7 +158,6 @@ private:
|
|||||||
bool _prepared;
|
bool _prepared;
|
||||||
mutable std::size_t _affectedRowCount;
|
mutable std::size_t _affectedRowCount;
|
||||||
bool _canCompile;
|
bool _canCompile;
|
||||||
bool _isPostgres;
|
|
||||||
bool _insertHint;
|
bool _insertHint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,9 +99,7 @@ public:
|
|||||||
Preparator(const StatementHandle& rStmt,
|
Preparator(const StatementHandle& rStmt,
|
||||||
const std::string& statement,
|
const std::string& statement,
|
||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
DataExtraction dataExtraction,
|
DataExtraction dataExtraction);
|
||||||
bool isPostgres
|
|
||||||
);
|
|
||||||
/// Creates the Preparator.
|
/// Creates the Preparator.
|
||||||
|
|
||||||
Preparator(const Preparator& other);
|
Preparator(const Preparator& other);
|
||||||
|
@ -135,18 +135,11 @@ void ODBCMetaColumn::init()
|
|||||||
|
|
||||||
case SQL_NUMERIC:
|
case SQL_NUMERIC:
|
||||||
case SQL_DECIMAL:
|
case SQL_DECIMAL:
|
||||||
if (0 == _columnDesc.decimalDigits)
|
// Oracle has no INTEGER type - it's essentially NUMBER with 38 whole and
|
||||||
{
|
// 0 fractional digits. It also does not recognize SQL_BIGINT type,
|
||||||
#ifdef POCO_64_BIT
|
// so the workaround here is to hardcode it to 32 bit integer
|
||||||
setType(MetaColumn::FDT_INT64);
|
if (0 == _columnDesc.decimalDigits) setType(MetaColumn::FDT_INT32);
|
||||||
#else
|
else setType(MetaColumn::FDT_DOUBLE);
|
||||||
setType(MetaColumn::FDT_INT32);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setType(MetaColumn::FDT_DOUBLE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_REAL:
|
case SQL_REAL:
|
||||||
|
@ -45,7 +45,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
|||||||
_prepared(false),
|
_prepared(false),
|
||||||
_affectedRowCount(0),
|
_affectedRowCount(0),
|
||||||
_canCompile(true),
|
_canCompile(true),
|
||||||
_isPostgres(false),
|
|
||||||
_insertHint(false)
|
_insertHint(false)
|
||||||
{
|
{
|
||||||
int queryTimeout = rSession.queryTimeout();
|
int queryTimeout = rSession.queryTimeout();
|
||||||
@ -64,7 +63,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
|||||||
std::string serverString;
|
std::string serverString;
|
||||||
serverString.resize(static_cast<std::size_t>(t) + 2);
|
serverString.resize(static_cast<std::size_t>(t) + 2);
|
||||||
r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t);
|
r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t);
|
||||||
_isPostgres = (!Utility::isError(r) && Poco::toUpperInPlace(serverString).find("PSQLODBC") == 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +150,7 @@ bool ODBCStatementImpl::addPreparator(bool addAlways)
|
|||||||
|
|
||||||
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
||||||
|
|
||||||
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _isPostgres);
|
prep = new Preparator(_stmt, statement, maxFieldSize, ext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prep = new Preparator(*_preparations[0]);
|
prep = new Preparator(*_preparations[0]);
|
||||||
@ -307,14 +305,13 @@ bool ODBCStatementImpl::nextResultSet()
|
|||||||
if (SQL_NO_DATA == ret)
|
if (SQL_NO_DATA == ret)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Utility::isError(ret)) {
|
if (Utility::isError(ret))
|
||||||
throw StatementException(_stmt, "SQLMoreResults()");
|
throw StatementException(_stmt, "SQLMoreResults()");
|
||||||
}
|
|
||||||
|
|
||||||
// need to remove old bindings, as Sybase doesn't like old ones
|
// need to remove old bindings, as Sybase doesn't like old ones
|
||||||
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND))) {
|
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND)))
|
||||||
throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)");
|
throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)");
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,7 @@ namespace ODBC {
|
|||||||
Preparator::Preparator(const StatementHandle& rStmt,
|
Preparator::Preparator(const StatementHandle& rStmt,
|
||||||
const std::string& statement,
|
const std::string& statement,
|
||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
DataExtraction dataExtraction,
|
DataExtraction dataExtraction) :
|
||||||
bool isPostgres) :
|
|
||||||
_rStmt(rStmt),
|
_rStmt(rStmt),
|
||||||
_maxFieldSize(maxFieldSize),
|
_maxFieldSize(maxFieldSize),
|
||||||
_dataExtraction(dataExtraction)
|
_dataExtraction(dataExtraction)
|
||||||
@ -38,9 +37,8 @@ Preparator::Preparator(const StatementHandle& rStmt,
|
|||||||
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
|
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
|
||||||
throw StatementException(_rStmt);
|
throw StatementException(_rStmt);
|
||||||
// PostgreSQL error swallowing workaround:
|
// PostgreSQL error swallowing workaround:
|
||||||
// Postgres may execute a statement with sintax error fine,
|
// Postgres may execute a statement with syntax error fine,
|
||||||
// but would return error once num of columns requested!
|
// but will return error later
|
||||||
if (isPostgres)
|
|
||||||
{
|
{
|
||||||
SQLSMALLINT t = 0;
|
SQLSMALLINT t = 0;
|
||||||
SQLRETURN r = SQLNumResultCols(rStmt, &t);
|
SQLRETURN r = SQLNumResultCols(rStmt, &t);
|
||||||
|
@ -41,7 +41,7 @@ using Poco::DynamicAny;
|
|||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
|
|
||||||
|
|
||||||
#define ORACLE_ODBC_DRIVER "Oracle in OraClient12Home1_32bit"//XE"
|
#define ORACLE_ODBC_DRIVER "Oracle in OraDB12Home1"//XE"
|
||||||
#define ORACLE_DSN "PocoDataOracleTest"
|
#define ORACLE_DSN "PocoDataOracleTest"
|
||||||
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
||||||
#define ORACLE_PORT "1521"
|
#define ORACLE_PORT "1521"
|
||||||
@ -775,13 +775,22 @@ void ODBCOracleTest::recreateStringsTable()
|
|||||||
|
|
||||||
void ODBCOracleTest::recreateFloatsTable()
|
void ODBCOracleTest::recreateFloatsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::floats());
|
||||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str NUMBER)", now; }
|
try { *_pSession << "CREATE TABLE " << ExecUtil::floats() <<" (str NUMBER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::recreateDoublesTable()
|
||||||
|
{
|
||||||
|
dropObject("TABLE", ExecUtil::doubles());
|
||||||
|
try { *_pSession << "CREATE TABLE " << ExecUtil::doubles() << " (str NUMBER)", now; }
|
||||||
|
catch (ConnectionException& ce) { std::cout << ce.toString() << std::endl; fail("recreateFloatsTable()"); }
|
||||||
|
catch (StatementException& se) { std::cout << se.toString() << std::endl; fail("recreateFloatsTable()"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::recreateTuplesTable()
|
void ODBCOracleTest::recreateTuplesTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::tuples());
|
dropObject("TABLE", ExecUtil::tuples());
|
||||||
@ -815,10 +824,13 @@ void ODBCOracleTest::recreateAnysTable()
|
|||||||
void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
|
void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::nulltest());
|
dropObject("TABLE", ExecUtil::nulltest());
|
||||||
try { *_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)",ExecUtil::nulltest(),
|
try
|
||||||
|
{
|
||||||
|
*_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
|
||||||
notNull,
|
notNull,
|
||||||
notNull,
|
notNull,
|
||||||
notNull), now; }
|
notNull), now;
|
||||||
|
}
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ private:
|
|||||||
void recreateStringsTable();
|
void recreateStringsTable();
|
||||||
void recreateIntsTable();
|
void recreateIntsTable();
|
||||||
void recreateFloatsTable();
|
void recreateFloatsTable();
|
||||||
|
void recreateDoublesTable();
|
||||||
void recreateTuplesTable();
|
void recreateTuplesTable();
|
||||||
void recreateVectorsTable();
|
void recreateVectorsTable();
|
||||||
void recreateAnysTable();
|
void recreateAnysTable();
|
||||||
|
@ -3015,7 +3015,8 @@ void SQLExecutor::notNulls(const std::string& sqlState)
|
|||||||
{
|
{
|
||||||
session() << "INSERT INTO "<< ExecUtil::nulltest() << " (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
|
session() << "INSERT INTO "<< ExecUtil::nulltest() << " (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
|
||||||
fail ("must fail");
|
fail ("must fail");
|
||||||
}catch (StatementException& se)
|
}
|
||||||
|
catch (StatementException& se)
|
||||||
{
|
{
|
||||||
//double check if we're failing for the right reason
|
//double check if we're failing for the right reason
|
||||||
//default sqlState value is "23502"; some drivers report "HY???" codes
|
//default sqlState value is "23502"; some drivers report "HY???" codes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user