mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-30 13:47:10 +01:00
batch statements (multiple results) support
This commit is contained in:
@@ -126,6 +126,9 @@ private:
|
|||||||
void makeInternalExtractors();
|
void makeInternalExtractors();
|
||||||
/// Creates internal extractors if none were supplied from the user.
|
/// Creates internal extractors if none were supplied from the user.
|
||||||
|
|
||||||
|
bool isStoredProcedure() const;
|
||||||
|
/// Returns true if SQL is a stored procedure call.
|
||||||
|
|
||||||
void doPrepare();
|
void doPrepare();
|
||||||
/// Prepares placeholders for data returned by statement.
|
/// Prepares placeholders for data returned by statement.
|
||||||
/// It is called during statement compilation for SQL statements
|
/// It is called during statement compilation for SQL statements
|
||||||
|
|||||||
@@ -199,6 +199,9 @@ private:
|
|||||||
void prepareImpl(std::size_t pos);
|
void prepareImpl(std::size_t pos);
|
||||||
/// Utility function to prepare Any and DynamicAny
|
/// Utility function to prepare Any and DynamicAny
|
||||||
|
|
||||||
|
void resize() const;
|
||||||
|
/// Resize the values and lengths vectors.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void preparePOD(std::size_t pos, SQLSMALLINT valueType)
|
void preparePOD(std::size_t pos, SQLSMALLINT valueType)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -284,25 +284,17 @@ bool ODBCStatementImpl::hasNext()
|
|||||||
|
|
||||||
if (!nextRowReady())
|
if (!nextRowReady())
|
||||||
{
|
{
|
||||||
try
|
try { activateNextDataSet(); }
|
||||||
{
|
catch (InvalidAccessException&)
|
||||||
activateNextDataSet();
|
{ return false; }
|
||||||
} catch (InvalidAccessException&)
|
|
||||||
{
|
try { checkError(SQLMoreResults(_stmt)); }
|
||||||
return false;
|
catch (NoDataException&)
|
||||||
}
|
{ return false; }
|
||||||
|
|
||||||
addPreparation();
|
addPreparation();
|
||||||
doPrepare();
|
doPrepare();
|
||||||
fixupExtraction();
|
fixupExtraction();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
checkError(SQLMoreResults(_stmt));
|
|
||||||
} catch (NoDataException&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
makeStep();
|
makeStep();
|
||||||
}
|
}
|
||||||
else if (Utility::isError(_nextResponse))
|
else if (Utility::isError(_nextResponse))
|
||||||
@@ -408,4 +400,13 @@ void ODBCStatementImpl::fillColumns()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ODBCStatementImpl::isStoredProcedure() const
|
||||||
|
{
|
||||||
|
std::string str = toString();
|
||||||
|
if (trimInPlace(str).size() < 2) return false;
|
||||||
|
|
||||||
|
return ('{' == str[0] && '}' == str[str.size()-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
} } } // namespace Poco::Data::ODBC
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ Preparation::Preparation(const Preparation& other):
|
|||||||
_maxFieldSize(other._maxFieldSize),
|
_maxFieldSize(other._maxFieldSize),
|
||||||
_dataExtraction(other._dataExtraction)
|
_dataExtraction(other._dataExtraction)
|
||||||
{
|
{
|
||||||
|
resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -79,21 +80,23 @@ Preparation::~Preparation()
|
|||||||
|
|
||||||
std::size_t Preparation::columns() const
|
std::size_t Preparation::columns() const
|
||||||
{
|
{
|
||||||
if (_pValues.empty())
|
if (_pValues.empty()) resize();
|
||||||
{
|
|
||||||
SQLSMALLINT nCol = 0;
|
|
||||||
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) &&
|
|
||||||
0 != nCol)
|
|
||||||
{
|
|
||||||
_pValues.resize(nCol, 0);
|
|
||||||
_pLengths.resize(nCol, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _pValues.size();
|
return _pValues.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Preparation::resize() const
|
||||||
|
{
|
||||||
|
SQLSMALLINT nCol = 0;
|
||||||
|
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) &&
|
||||||
|
0 != nCol)
|
||||||
|
{
|
||||||
|
_pValues.resize(nCol, 0);
|
||||||
|
_pLengths.resize(nCol, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Poco::Any& Preparation::operator [] (std::size_t pos)
|
Poco::Any& Preparation::operator [] (std::size_t pos)
|
||||||
{
|
{
|
||||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||||
|
|||||||
@@ -1201,6 +1201,22 @@ void ODBCDB2Test::testDynamicAny()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCDB2Test::testMultipleResults()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreatePersonTable();
|
||||||
|
_pSession->setFeature("autoBind", bindValues[i]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||||
|
_pExecutor->multipleResults();
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
|
void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1350,7 +1366,11 @@ bool ODBCDB2Test::canConnect(const std::string& driver, const std::string& dsn)
|
|||||||
{
|
{
|
||||||
std::cout << "DSN found: " << itDSN->first
|
std::cout << "DSN found: " << itDSN->first
|
||||||
<< " (" << itDSN->second << ')' << std::endl;
|
<< " (" << itDSN->second << ')' << std::endl;
|
||||||
format(_dbConnString, "DSN=%s", dsn);
|
format(_dbConnString,
|
||||||
|
"DSN=%s;"
|
||||||
|
"Uid=db2admin;"
|
||||||
|
"Pwd=db2admin;",
|
||||||
|
dsn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1470,6 +1490,7 @@ CppUnit::Test* ODBCDB2Test::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testAsync);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testAsync);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCDB2Test, testMultipleResults);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ public:
|
|||||||
void testAny();
|
void testAny();
|
||||||
void testDynamicAny();
|
void testDynamicAny();
|
||||||
|
|
||||||
|
void testMultipleResults();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ void ODBCMySQLTest::testBareboneODBC()
|
|||||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
||||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
MySQL supports batch statements as of 3.51.18
|
||||||
|
http://bugs.mysql.com/bug.php?id=7445
|
||||||
|
|
||||||
tableCreateString = "CREATE TABLE Test "
|
tableCreateString = "CREATE TABLE Test "
|
||||||
"(First VARCHAR(30),"
|
"(First VARCHAR(30),"
|
||||||
@@ -118,6 +121,7 @@ void ODBCMySQLTest::testBareboneODBC()
|
|||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -989,6 +993,27 @@ void ODBCMySQLTest::testDynamicAny()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCMySQLTest::testMultipleResults()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
MySQL supports batch statements as of 3.51.18
|
||||||
|
http://bugs.mysql.com/bug.php?id=7445
|
||||||
|
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreatePersonTable();
|
||||||
|
_pSession->setFeature("autoBind", bindValues[i]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||||
|
_pExecutor->multipleResults();
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
|
void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
|
||||||
{
|
{
|
||||||
*_pSession << format("DROP %s IF EXISTS %s", type, name), now;
|
*_pSession << format("DROP %s IF EXISTS %s", type, name), now;
|
||||||
@@ -1239,6 +1264,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAny);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testAny);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testDynamicAny);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testDynamicAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testMultipleResults);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ public:
|
|||||||
void testAny();
|
void testAny();
|
||||||
void testDynamicAny();
|
void testDynamicAny();
|
||||||
|
|
||||||
|
void testMultipleResults();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
|||||||
@@ -131,17 +131,17 @@ void ODBCOracleTest::testBarebone()
|
|||||||
"Third NUMBER)";
|
"Third NUMBER)";
|
||||||
|
|
||||||
*_pSession << "CREATE OR REPLACE "
|
*_pSession << "CREATE OR REPLACE "
|
||||||
"PROCEDURE multiResultsProcedure(tmp1 OUT SYS_REFCURSOR, "
|
"PROCEDURE multiResultsProcedure(ret1 OUT SYS_REFCURSOR, "
|
||||||
"tmp2 OUT SYS_REFCURSOR,"
|
"ret2 OUT SYS_REFCURSOR,"
|
||||||
"tmp3 OUT SYS_REFCURSOR,"
|
"ret3 OUT SYS_REFCURSOR,"
|
||||||
"tmp4 OUT SYS_REFCURSOR,"
|
"ret4 OUT SYS_REFCURSOR,"
|
||||||
"tmp5 OUT SYS_REFCURSOR) IS "
|
"ret5 OUT SYS_REFCURSOR) IS "
|
||||||
"BEGIN "
|
"BEGIN "
|
||||||
"OPEN tmp1 FOR SELECT * FROM Test WHERE First = '1';"
|
"OPEN ret1 FOR SELECT * FROM Test WHERE First = '1';"
|
||||||
"OPEN tmp2 FOR SELECT * FROM Test WHERE First = '2';"
|
"OPEN ret2 FOR SELECT * FROM Test WHERE First = '2';"
|
||||||
"OPEN tmp3 FOR SELECT * FROM Test WHERE First = '3';"
|
"OPEN ret3 FOR SELECT * FROM Test WHERE First = '3';"
|
||||||
"OPEN tmp4 FOR SELECT * FROM Test WHERE First = '4';"
|
"OPEN ret4 FOR SELECT * FROM Test WHERE First = '4';"
|
||||||
"OPEN tmp5 FOR SELECT * FROM Test WHERE First = '5';"
|
"OPEN ret5 FOR SELECT * FROM Test WHERE First = '5';"
|
||||||
"END multiResultsProcedure;" , now;
|
"END multiResultsProcedure;" , now;
|
||||||
|
|
||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString,
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString,
|
||||||
@@ -1109,7 +1109,7 @@ void ODBCOracleTest::testStoredProcedureDynamicAny()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::testStoredCursorProcedure()
|
void ODBCOracleTest::testCursorStoredProcedure()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
@@ -1251,7 +1251,7 @@ void ODBCOracleTest::testStoredFunction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::testStoredCursorFunction()
|
void ODBCOracleTest::testCursorStoredFunction()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
@@ -1367,6 +1367,39 @@ void ODBCOracleTest::testDynamicAny()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testMultipleResults()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
|
||||||
|
std::string sql = "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE multiResultsProcedure(paramAge1 IN NUMBER,"
|
||||||
|
" paramAge2 IN NUMBER,"
|
||||||
|
" ret1 OUT SYS_REFCURSOR, "
|
||||||
|
" ret2 OUT SYS_REFCURSOR,"
|
||||||
|
" ret3 OUT SYS_REFCURSOR) IS "
|
||||||
|
"BEGIN "
|
||||||
|
" OPEN ret1 FOR SELECT * FROM Person WHERE Age = paramAge1;"
|
||||||
|
" OPEN ret2 FOR SELECT Age FROM Person WHERE FirstName = 'Bart';"
|
||||||
|
" OPEN ret3 FOR SELECT * FROM Person WHERE Age = paramAge2;"
|
||||||
|
"END multiResultsProcedure;";
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreatePersonTable();
|
||||||
|
*_pSession << sql, now;
|
||||||
|
_pSession->setFeature("autoBind", bindValues[i]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||||
|
_pExecutor->multipleResults("{call multiResultsProcedure(?, ?)}");
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::dropObject(const std::string& type, const std::string& name)
|
void ODBCOracleTest::dropObject(const std::string& type, const std::string& name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1593,14 +1626,16 @@ bool ODBCOracleTest::init(const std::string& driver, const std::string& dsn)
|
|||||||
|
|
||||||
_pExecutor = new SQLExecutor(driver + " SQL Executor", _pSession);
|
_pExecutor = new SQLExecutor(driver + " SQL Executor", _pSession);
|
||||||
|
|
||||||
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
// Workaround:
|
// Workaround:
|
||||||
//
|
//
|
||||||
// Barebone ODBC test is called initially for Oracle only.
|
// Barebone ODBC test is called automatically on startup for Oracle.
|
||||||
// The test framework does not exit cleanly if
|
// The test framework does not exit cleanly if
|
||||||
// Oracle tests are enabled (i.e. Oracle driver is found)
|
// Oracle tests are enabled (i.e. Oracle driver is found)
|
||||||
// but no tests are executed.
|
// but no tests are executed.
|
||||||
// The exact reason for this behavior is unknown at this time.
|
// The exact reason for this behavior is unknown at this time.
|
||||||
testBarebone();
|
testBarebone();
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1661,11 +1696,11 @@ CppUnit::Test* ODBCOracleTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testTuple);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testTupleVector);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedure);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredCursorProcedure);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureAny);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureAny);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureDynamicAny);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredCursorFunction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
||||||
@@ -1673,6 +1708,7 @@ CppUnit::Test* ODBCOracleTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testAsync);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testAsync);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testAny);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testAny);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testDynamicAny);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testDynamicAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCOracleTest, testMultipleResults);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ public:
|
|||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
void testStoredCursorProcedure();
|
void testCursorStoredProcedure();
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
void testStoredCursorFunction();
|
void testCursorStoredFunction();
|
||||||
void testStoredProcedureAny();
|
void testStoredProcedureAny();
|
||||||
void testStoredProcedureDynamicAny();
|
void testStoredProcedureDynamicAny();
|
||||||
|
|
||||||
@@ -134,6 +134,8 @@ public:
|
|||||||
void testAny();
|
void testAny();
|
||||||
void testDynamicAny();
|
void testDynamicAny();
|
||||||
|
|
||||||
|
void testMultipleResults();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ void ODBCPostgreSQLTest::testBareboneODBC()
|
|||||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
||||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
||||||
|
|
||||||
|
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
|
||||||
|
/*
|
||||||
tableCreateString = "CREATE TABLE Test "
|
tableCreateString = "CREATE TABLE Test "
|
||||||
"(First VARCHAR(30),"
|
"(First VARCHAR(30),"
|
||||||
"Second INTEGER,"
|
"Second INTEGER,"
|
||||||
@@ -133,6 +134,7 @@ void ODBCPostgreSQLTest::testBareboneODBC()
|
|||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1113,6 +1115,8 @@ void ODBCPostgreSQLTest::testDynamicAny()
|
|||||||
|
|
||||||
void ODBCPostgreSQLTest::testMultipleResults()
|
void ODBCPostgreSQLTest::testMultipleResults()
|
||||||
{
|
{
|
||||||
|
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
|
||||||
|
/*
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
for (int i = 0; i < 8;)
|
for (int i = 0; i < 8;)
|
||||||
@@ -1124,6 +1128,7 @@ void ODBCPostgreSQLTest::testMultipleResults()
|
|||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// uncomment to use Mammoth ODBCng driver
|
// uncomment to use Mammoth ODBCng driver
|
||||||
//#define POCO_ODBC_USE_MAMMOTH_NG
|
#define POCO_ODBC_USE_MAMMOTH_NG
|
||||||
|
|
||||||
|
|
||||||
class ODBCPostgreSQLTest: public CppUnit::TestCase
|
class ODBCPostgreSQLTest: public CppUnit::TestCase
|
||||||
|
|||||||
@@ -987,14 +987,8 @@ Deprecated types are not supported as output parameters. Use current large obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::testStoredCursorProcedure()
|
void ODBCSQLServerTest::testCursorStoredProcedure()
|
||||||
{
|
{
|
||||||
/*TODO: Support for returning recordsets from MS SQL Server is currently limited.
|
|
||||||
In order for it to work, nothing else but the recordset (not even output parameters)
|
|
||||||
can be returned.
|
|
||||||
To achieve full functionality, SQLMoreResults functionality probably must be incorporated
|
|
||||||
into the framework.
|
|
||||||
*/
|
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
for (int k = 0; k < 8;)
|
for (int k = 0; k < 8;)
|
||||||
@@ -1204,63 +1198,6 @@ void ODBCSQLServerTest::testStoredFunction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::testStoredCursorFunction()
|
|
||||||
{
|
|
||||||
/* TODO (see comments about errors below - probably needs SQLMoreResults to function properly)
|
|
||||||
if (!_pSession) fail ("Test not available.");
|
|
||||||
|
|
||||||
for (int k = 0; k < 8;)
|
|
||||||
{
|
|
||||||
_pSession->setFeature("autoBind", bindValues[k]);
|
|
||||||
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
|
||||||
|
|
||||||
recreatePersonTable();
|
|
||||||
typedef Tuple<std::string, std::string, std::string, int> Person;
|
|
||||||
std::vector<Person> people;
|
|
||||||
people.push_back(Person("Simpson", "Homer", "Springfield", 42));
|
|
||||||
people.push_back(Person("Simpson", "Bart", "Springfield", 12));
|
|
||||||
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
|
|
||||||
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
|
|
||||||
|
|
||||||
dropObject("PROCEDURE", "storedCursorFunction");
|
|
||||||
*_pSession << "CREATE PROCEDURE storedCursorFunction(@ageLimit int) AS "
|
|
||||||
"BEGIN "
|
|
||||||
" SELECT * "
|
|
||||||
" FROM Person "
|
|
||||||
" WHERE Age < @ageLimit "
|
|
||||||
" ORDER BY Age DESC; "
|
|
||||||
" RETURN @ageLimit; "
|
|
||||||
"END;"
|
|
||||||
, now;
|
|
||||||
|
|
||||||
people.clear();
|
|
||||||
int age = 13;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
*_pSession << "{? = call storedCursorFunction(?)}", out(result), in(age), into(people), now;
|
|
||||||
|
|
||||||
//assert (result == age); //fails (result == 0)
|
|
||||||
assert (2 == people.size());
|
|
||||||
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
|
||||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
|
||||||
|
|
||||||
result = 0;
|
|
||||||
Statement stmt = ((*_pSession << "{? = call storedCursorFunction(?)}", out(result), in(age), now));
|
|
||||||
RecordSet rs(stmt);
|
|
||||||
assert (rs["LastName"] == "Simpson");
|
|
||||||
assert (rs["FirstName"] == "Bart");
|
|
||||||
assert (rs["Address"] == "Springfield");
|
|
||||||
assert (rs["Age"] == 12);
|
|
||||||
|
|
||||||
dropObject("TABLE", "Person");//fails ([Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt")
|
|
||||||
dropObject("PROCEDURE", "storedCursorFunction");
|
|
||||||
|
|
||||||
k += 2;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::testRowIterator()
|
void ODBCSQLServerTest::testRowIterator()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1638,11 +1575,10 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTuple);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTupleVector);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedure);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredCursorProcedure);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testCursorStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureAny);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureAny);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredCursorFunction);
|
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
||||||
|
|||||||
@@ -120,11 +120,10 @@ public:
|
|||||||
void testTupleVector();
|
void testTupleVector();
|
||||||
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
void testStoredCursorProcedure();
|
void testCursorStoredProcedure();
|
||||||
void testStoredProcedureAny();
|
void testStoredProcedureAny();
|
||||||
void testStoredProcedureDynamicAny();
|
void testStoredProcedureDynamicAny();
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
void testStoredCursorFunction();
|
|
||||||
|
|
||||||
void testInternalExtraction();
|
void testInternalExtraction();
|
||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|||||||
@@ -56,12 +56,13 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
|
||||||
#define print_odbc_error(r, h) \
|
#define poco_odbc_check(r, h) \
|
||||||
if (!SQL_SUCCEEDED(r)) \
|
if (!SQL_SUCCEEDED(r)) \
|
||||||
{ \
|
{ \
|
||||||
StatementException se(h); \
|
StatementException se(h); \
|
||||||
std::cout << se.toString() << std::endl; \
|
std::cout << se.toString() << std::endl; \
|
||||||
}
|
} \
|
||||||
|
assert (SQL_SUCCEEDED(r));
|
||||||
|
|
||||||
|
|
||||||
using namespace Poco::Data;
|
using namespace Poco::Data;
|
||||||
@@ -218,13 +219,13 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
|
|
||||||
// Environment begin
|
// Environment begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Connection begin
|
// Connection begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
POCO_SQLCHAR connectOutput[512] = {0};
|
POCO_SQLCHAR connectOutput[512] = {0};
|
||||||
SQLSMALLINT result;
|
SQLSMALLINT result;
|
||||||
@@ -236,14 +237,14 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
, sizeof(connectOutput)
|
, sizeof(connectOutput)
|
||||||
, &result
|
, &result
|
||||||
, SQL_DRIVER_NOPROMPT);
|
, SQL_DRIVER_NOPROMPT);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// retrieve datetime type information for this DBMS
|
// retrieve datetime type information for this DBMS
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetTypeInfo(hstmt, SQL_TIMESTAMP);
|
rc = SQLGetTypeInfo(hstmt, SQL_TIMESTAMP);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
SQLINTEGER dateTimeColSize = 0;
|
SQLINTEGER dateTimeColSize = 0;
|
||||||
SQLSMALLINT dateTimeDecDigits = 0;
|
SQLSMALLINT dateTimeDecDigits = 0;
|
||||||
|
|
||||||
@@ -252,19 +253,19 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
if (SQL_SUCCEEDED(rc))
|
if (SQL_SUCCEEDED(rc))
|
||||||
{
|
{
|
||||||
rc = SQLGetData(hstmt, 3, SQL_C_SLONG, &dateTimeColSize, sizeof(SQLINTEGER), 0);
|
rc = SQLGetData(hstmt, 3, SQL_C_SLONG, &dateTimeColSize, sizeof(SQLINTEGER), 0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLGetData(hstmt, 14, SQL_C_SSHORT, &dateTimeDecDigits, sizeof(SQLSMALLINT), 0);
|
rc = SQLGetData(hstmt, 14, SQL_C_SSHORT, &dateTimeDecDigits, sizeof(SQLSMALLINT), 0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
else if (SQL_NO_DATA == rc)
|
else if (SQL_NO_DATA == rc)
|
||||||
std::cerr << "Warning: no data type info returned by driver." << std::endl;
|
std::cerr << "Warning: no data type info returned by driver." << std::endl;
|
||||||
|
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Statement begin
|
// Statement begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
std::string sql = "DROP TABLE Test";
|
std::string sql = "DROP TABLE Test";
|
||||||
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
@@ -275,15 +276,15 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
sql = tableCreateString;
|
sql = tableCreateString;
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLExecute(hstmt);
|
rc = SQLExecute(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
sql = "INSERT INTO Test VALUES (?,?,?,?,?,?)";
|
sql = "INSERT INTO Test VALUES (?,?,?,?,?,?)";
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
std::string str[3] = { "111", "222", "333" };
|
std::string str[3] = { "111", "222", "333" };
|
||||||
int fourth = 4;
|
int fourth = 4;
|
||||||
@@ -314,7 +315,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) str[0].c_str(),
|
(SQLPOINTER) str[0].c_str(),
|
||||||
size,
|
size,
|
||||||
&li);
|
&li);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
size = (SQLINTEGER) str[1].size();
|
size = (SQLINTEGER) str[1].size();
|
||||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||||
@@ -330,7 +331,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) str[1].c_str(),
|
(SQLPOINTER) str[1].c_str(),
|
||||||
size,
|
size,
|
||||||
&li);
|
&li);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
size = (SQLINTEGER) str[2].size();
|
size = (SQLINTEGER) str[2].size();
|
||||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||||
@@ -347,7 +348,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) str[2].data(),
|
(SQLPOINTER) str[2].data(),
|
||||||
size,
|
size,
|
||||||
&li);
|
&li);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindParameter(hstmt,
|
rc = SQLBindParameter(hstmt,
|
||||||
(SQLUSMALLINT) 4,
|
(SQLUSMALLINT) 4,
|
||||||
@@ -359,7 +360,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &fourth,
|
(SQLPOINTER) &fourth,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindParameter(hstmt,
|
rc = SQLBindParameter(hstmt,
|
||||||
(SQLUSMALLINT) 5,
|
(SQLUSMALLINT) 5,
|
||||||
@@ -371,7 +372,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &fifth,
|
(SQLPOINTER) &fifth,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindParameter(hstmt,
|
rc = SQLBindParameter(hstmt,
|
||||||
(SQLUSMALLINT) 6,
|
(SQLUSMALLINT) 6,
|
||||||
@@ -383,7 +384,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &sixth,
|
(SQLPOINTER) &sixth,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||||
@@ -414,12 +415,12 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
++i;
|
++i;
|
||||||
}while (SQL_NEED_DATA == (rc = SQLParamData(hstmt, &pParam)));
|
}while (SQL_NEED_DATA == (rc = SQLParamData(hstmt, &pParam)));
|
||||||
}
|
}
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
sql = "SELECT * FROM Test";
|
sql = "SELECT * FROM Test";
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
char chr[3][5] = {{ 0 }};
|
char chr[3][5] = {{ 0 }};
|
||||||
SQLLEN lengths[6] = { 0 };
|
SQLLEN lengths[6] = { 0 };
|
||||||
@@ -435,7 +436,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) chr[0],
|
(SQLPOINTER) chr[0],
|
||||||
(SQLINTEGER) 4,
|
(SQLINTEGER) 4,
|
||||||
&lengths[0]);
|
&lengths[0]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 2,
|
(SQLUSMALLINT) 2,
|
||||||
@@ -443,7 +444,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) chr[1],
|
(SQLPOINTER) chr[1],
|
||||||
(SQLINTEGER) 4,
|
(SQLINTEGER) 4,
|
||||||
&lengths[1]);
|
&lengths[1]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 3,
|
(SQLUSMALLINT) 3,
|
||||||
@@ -451,7 +452,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) chr[2],
|
(SQLPOINTER) chr[2],
|
||||||
(SQLINTEGER) 4,
|
(SQLINTEGER) 4,
|
||||||
&lengths[2]);
|
&lengths[2]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 4,
|
(SQLUSMALLINT) 4,
|
||||||
@@ -459,7 +460,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &fourth,
|
(SQLPOINTER) &fourth,
|
||||||
(SQLINTEGER) 0,
|
(SQLINTEGER) 0,
|
||||||
&lengths[3]);
|
&lengths[3]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 5,
|
(SQLUSMALLINT) 5,
|
||||||
@@ -467,7 +468,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &fifth,
|
(SQLPOINTER) &fifth,
|
||||||
(SQLINTEGER) 0,
|
(SQLINTEGER) 0,
|
||||||
&lengths[4]);
|
&lengths[4]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 6,
|
(SQLUSMALLINT) 6,
|
||||||
@@ -475,13 +476,13 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &sixth,
|
(SQLPOINTER) &sixth,
|
||||||
(SQLINTEGER) 0,
|
(SQLINTEGER) 0,
|
||||||
&lengths[5]);
|
&lengths[5]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLExecute(hstmt);
|
rc = SQLExecute(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLFetch(hstmt);
|
rc = SQLFetch(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
if (SQLExecutor::DE_MANUAL == extractMode)
|
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||||
{
|
{
|
||||||
@@ -491,7 +492,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
chr[0],
|
chr[0],
|
||||||
4,
|
4,
|
||||||
&lengths[0]);
|
&lengths[0]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 2,
|
(SQLUSMALLINT) 2,
|
||||||
@@ -499,7 +500,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
chr[1],
|
chr[1],
|
||||||
4,
|
4,
|
||||||
&lengths[1]);
|
&lengths[1]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 3,
|
(SQLUSMALLINT) 3,
|
||||||
@@ -507,7 +508,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
chr[2],
|
chr[2],
|
||||||
3,
|
3,
|
||||||
&lengths[2]);
|
&lengths[2]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 4,
|
(SQLUSMALLINT) 4,
|
||||||
@@ -515,7 +516,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
&fourth,
|
&fourth,
|
||||||
0,
|
0,
|
||||||
&lengths[3]);
|
&lengths[3]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 5,
|
(SQLUSMALLINT) 5,
|
||||||
@@ -523,7 +524,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
&fifth,
|
&fifth,
|
||||||
0,
|
0,
|
||||||
&lengths[4]);
|
&lengths[4]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 6,
|
(SQLUSMALLINT) 6,
|
||||||
@@ -531,7 +532,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
&sixth,
|
&sixth,
|
||||||
0,
|
0,
|
||||||
&lengths[5]);
|
&lengths[5]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (0 == strncmp("111", chr[0], 3));
|
assert (0 == strncmp("111", chr[0], 3));
|
||||||
@@ -550,25 +551,25 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLCloseCursor(hstmt);
|
rc = SQLCloseCursor(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
sql = "DROP TABLE Test";
|
sql = "DROP TABLE Test";
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Connection end
|
// Connection end
|
||||||
rc = SQLDisconnect(hdbc);
|
rc = SQLDisconnect(hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Environment end
|
// Environment end
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -586,13 +587,13 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
|
|
||||||
// Environment begin
|
// Environment begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Connection begin
|
// Connection begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
POCO_SQLCHAR connectOutput[512] = {0};
|
POCO_SQLCHAR connectOutput[512] = {0};
|
||||||
SQLSMALLINT result;
|
SQLSMALLINT result;
|
||||||
@@ -604,11 +605,11 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
, sizeof(connectOutput)
|
, sizeof(connectOutput)
|
||||||
, &result
|
, &result
|
||||||
, SQL_DRIVER_NOPROMPT);
|
, SQL_DRIVER_NOPROMPT);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Statement begin
|
// Statement begin
|
||||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
std::string sql = "DROP TABLE Test";
|
std::string sql = "DROP TABLE Test";
|
||||||
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
@@ -619,17 +620,17 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
sql = tableCreateString;
|
sql = tableCreateString;
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLExecute(hstmt);
|
rc = SQLExecute(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// insert multiple rows
|
// insert multiple rows
|
||||||
pStr = (POCO_SQLCHAR*) insert.c_str();
|
pStr = (POCO_SQLCHAR*) insert.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) insert.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) insert.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLExecute(hstmt);
|
rc = SQLExecute(hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SQLINTEGER rowCount = 0;
|
SQLINTEGER rowCount = 0;
|
||||||
@@ -638,10 +639,49 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
|
|
||||||
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
||||||
|
|
||||||
|
// make sure all five rows made it in
|
||||||
|
sql = "select count(*) from Test";
|
||||||
|
int count = 0;
|
||||||
|
SQLLEN length = 0;
|
||||||
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
if (SQLExecutor::DE_BOUND == extractMode)
|
||||||
|
{
|
||||||
|
rc = SQLBindCol(hstmt,
|
||||||
|
(SQLUSMALLINT) 1,
|
||||||
|
SQL_C_SLONG,
|
||||||
|
(SQLPOINTER) &count,
|
||||||
|
(SQLINTEGER) 0,
|
||||||
|
&length);
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = SQLExecute(hstmt);
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
|
rc = SQLFetch(hstmt);
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
|
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||||
|
{
|
||||||
|
rc = SQLGetData(hstmt,
|
||||||
|
(SQLUSMALLINT) 1,
|
||||||
|
SQL_C_SLONG,
|
||||||
|
&count,
|
||||||
|
0,
|
||||||
|
&length);
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
}
|
||||||
|
assert (5 == count);
|
||||||
|
|
||||||
|
rc = SQLCloseCursor(hstmt);
|
||||||
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// select multiple rows
|
// select multiple rows
|
||||||
pStr = (POCO_SQLCHAR*) select.c_str();
|
pStr = (POCO_SQLCHAR*) select.c_str();
|
||||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) select.length());
|
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) select.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
char chr[5] = { 0 };
|
char chr[5] = { 0 };
|
||||||
SQLLEN lengths[3] = { 0 };
|
SQLLEN lengths[3] = { 0 };
|
||||||
@@ -656,7 +696,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) chr,
|
(SQLPOINTER) chr,
|
||||||
(SQLINTEGER) 4,
|
(SQLINTEGER) 4,
|
||||||
&lengths[0]);
|
&lengths[0]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 2,
|
(SQLUSMALLINT) 2,
|
||||||
@@ -664,7 +704,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &second,
|
(SQLPOINTER) &second,
|
||||||
(SQLINTEGER) 0,
|
(SQLINTEGER) 0,
|
||||||
&lengths[1]);
|
&lengths[1]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLBindCol(hstmt,
|
rc = SQLBindCol(hstmt,
|
||||||
(SQLUSMALLINT) 3,
|
(SQLUSMALLINT) 3,
|
||||||
@@ -672,22 +712,21 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
(SQLPOINTER) &third,
|
(SQLPOINTER) &third,
|
||||||
(SQLINTEGER) 0,
|
(SQLINTEGER) 0,
|
||||||
&lengths[2]);
|
&lengths[2]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLExecute(hstmt);
|
rc = SQLExecute(hstmt);
|
||||||
print_odbc_error (rc, hstmt);
|
poco_odbc_check (rc, hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
|
||||||
|
|
||||||
char one = 0x31;
|
char one = 0x31;
|
||||||
int two = 2;
|
int two = 2;
|
||||||
float three = 3.5;
|
float three = 3.5;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rc = SQLFetch(hstmt);
|
rc = SQLFetch(hstmt);
|
||||||
print_odbc_error (rc, hstmt);
|
poco_odbc_check (rc, hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
|
||||||
|
|
||||||
if (SQLExecutor::DE_MANUAL == extractMode)
|
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||||
{
|
{
|
||||||
@@ -697,7 +736,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
chr,
|
chr,
|
||||||
4,
|
4,
|
||||||
&lengths[0]);
|
&lengths[0]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 2,
|
(SQLUSMALLINT) 2,
|
||||||
@@ -705,7 +744,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
&second,
|
&second,
|
||||||
0,
|
0,
|
||||||
&lengths[1]);
|
&lengths[1]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLGetData(hstmt,
|
rc = SQLGetData(hstmt,
|
||||||
(SQLUSMALLINT) 3,
|
(SQLUSMALLINT) 3,
|
||||||
@@ -713,7 +752,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
&third,
|
&third,
|
||||||
0,
|
0,
|
||||||
&lengths[2]);
|
&lengths[2]);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (one++ == chr[0]);
|
assert (one++ == chr[0]);
|
||||||
@@ -721,25 +760,28 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
|||||||
assert (three == third);
|
assert (three == third);
|
||||||
three += 1.0;
|
three += 1.0;
|
||||||
|
|
||||||
|
++count;
|
||||||
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
||||||
|
|
||||||
|
assert (5 == count);
|
||||||
|
|
||||||
sql = "DROP TABLE Test";
|
sql = "DROP TABLE Test";
|
||||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||||
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Connection end
|
// Connection end
|
||||||
rc = SQLDisconnect(hdbc);
|
rc = SQLDisconnect(hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
|
|
||||||
// Environment end
|
// Environment end
|
||||||
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
assert (SQL_SUCCEEDED(rc));
|
poco_odbc_check (rc, hstmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2569,7 +2611,7 @@ void SQLExecutor::dynamicAny()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLExecutor::multipleResults()
|
void SQLExecutor::multipleResults(const std::string& sql)
|
||||||
{
|
{
|
||||||
typedef Tuple<std::string, std::string, std::string, int> Person;
|
typedef Tuple<std::string, std::string, std::string, int> Person;
|
||||||
std::vector<Person> people;
|
std::vector<Person> people;
|
||||||
@@ -2578,16 +2620,22 @@ void SQLExecutor::multipleResults()
|
|||||||
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
|
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
|
||||||
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
|
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
|
||||||
|
|
||||||
Person Homer, Lisa, Bart;
|
Person pHomer, pLisa;
|
||||||
|
int aHomer(42), aLisa(10), aBart(0);
|
||||||
|
|
||||||
*_pSession << "SELECT * FROM Person WHERE FirstName = 'Homer'; "
|
try {
|
||||||
"SELECT * FROM Person WHERE FirstName = 'Bart'; "
|
*_pSession << sql
|
||||||
"SELECT * FROM Person WHERE FirstName = 'Lisa'; "
|
, into(pHomer), use(aHomer)
|
||||||
, into(Homer, 0), into(Bart, 1), into(Lisa, 2)
|
, into(aBart, 1)
|
||||||
|
, into(pLisa, 2), use(aLisa)
|
||||||
, now;
|
, now;
|
||||||
|
} catch (StatementException& ex)
|
||||||
|
{
|
||||||
|
std::cout << ex.toString() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
assert (Person("Simpson", "Homer", "Springfield", 42) == Homer);
|
assert (Person("Simpson", "Homer", "Springfield", 42) == pHomer);
|
||||||
assert (Person("Simpson", "Bart", "Springfield", 12) == Bart);
|
assert (12 == aBart);
|
||||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == Lisa);
|
assert (Person("Simpson", "Lisa", "Springfield", 10) == pLisa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,10 @@ public:
|
|||||||
void any();
|
void any();
|
||||||
void dynamicAny();
|
void dynamicAny();
|
||||||
|
|
||||||
void multipleResults();
|
void multipleResults(const std::string& sql =
|
||||||
|
"SELECT * FROM Person WHERE Age = ?; "
|
||||||
|
"SELECT Age FROM Person WHERE FirstName = 'Bart'; "
|
||||||
|
"SELECT * FROM Person WHERE Age = ?; ");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const std::string MULTI_INSERT;
|
static const std::string MULTI_INSERT;
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ Binding<T>* in(const T& t, const std::string& name = "")
|
|||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Binding<T>* out(const T& t, const std::string& name = "")
|
Binding<T>* out(T& t, const std::string& name = "")
|
||||||
/// Convenience function for a more compact Binding creation.
|
/// Convenience function for a more compact Binding creation.
|
||||||
{
|
{
|
||||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_OUT);
|
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_OUT);
|
||||||
@@ -610,7 +610,7 @@ Binding<T>* out(const T& t, const std::string& name = "")
|
|||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Binding<T>* io(const T& t, const std::string& name = "")
|
Binding<T>* io(T& t, const std::string& name = "")
|
||||||
/// Convenience function for a more compact Binding creation.
|
/// Convenience function for a more compact Binding creation.
|
||||||
{
|
{
|
||||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN_OUT);
|
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN_OUT);
|
||||||
|
|||||||
@@ -346,7 +346,6 @@ Poco::UInt32 StatementImpl::activateNextDataSet()
|
|||||||
void StatementImpl::addExtract(AbstractExtraction* pExtraction)
|
void StatementImpl::addExtract(AbstractExtraction* pExtraction)
|
||||||
{
|
{
|
||||||
poco_check_ptr (pExtraction);
|
poco_check_ptr (pExtraction);
|
||||||
|
|
||||||
Poco::UInt32 pos = pExtraction->position();
|
Poco::UInt32 pos = pExtraction->position();
|
||||||
if (pos >= _extractors.size())
|
if (pos >= _extractors.size())
|
||||||
_extractors.resize(pos + 1);
|
_extractors.resize(pos + 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user