mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-25 10:09:36 +02:00
Any and DynamicAny out and io
This commit is contained in:
@@ -86,57 +86,57 @@ public:
|
|||||||
~Binder();
|
~Binder();
|
||||||
/// Destroys the Binder.
|
/// Destroys the Binder.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
|
||||||
/// Binds an Int8.
|
/// Binds an Int8.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
|
||||||
/// Binds an UInt8.
|
/// Binds an UInt8.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
|
||||||
/// Binds an Int16.
|
/// Binds an Int16.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
|
||||||
/// Binds an UInt16.
|
/// Binds an UInt16.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
|
||||||
/// Binds an Int32.
|
/// Binds an Int32.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
|
||||||
/// Binds an UInt32.
|
/// Binds an UInt32.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
|
||||||
/// Binds an Int64.
|
/// Binds an Int64.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
|
||||||
/// Binds an UInt64.
|
/// Binds an UInt64.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
void bind(std::size_t pos, const long& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const long& val, Direction dir);
|
||||||
/// Binds a long.
|
/// Binds a long.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void bind(std::size_t pos, const bool& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const bool& val, Direction dir);
|
||||||
/// Binds a boolean.
|
/// Binds a boolean.
|
||||||
|
|
||||||
void bind(std::size_t pos, const float& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const float& val, Direction dir);
|
||||||
/// Binds a float.
|
/// Binds a float.
|
||||||
|
|
||||||
void bind(std::size_t pos, const double& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const double& val, Direction dir);
|
||||||
/// Binds a double.
|
/// Binds a double.
|
||||||
|
|
||||||
void bind(std::size_t pos, const char& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const char& val, Direction dir);
|
||||||
/// Binds a single character.
|
/// Binds a single character.
|
||||||
|
|
||||||
void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const std::string& val, Direction dir);
|
||||||
/// Binds a string.
|
/// Binds a string.
|
||||||
|
|
||||||
void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const BLOB& val, Direction dir);
|
||||||
/// Binds a BLOB. In-bound only.
|
/// Binds a BLOB. In-bound only.
|
||||||
|
|
||||||
void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||||
/// Binds a DateTime.
|
/// Binds a DateTime.
|
||||||
|
|
||||||
void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a null. In-bound only.
|
/// Binds a null. In-bound only.
|
||||||
|
|
||||||
void setDataBinding(ParameterBinding binding);
|
void setDataBinding(ParameterBinding binding);
|
||||||
@@ -160,7 +160,7 @@ private:
|
|||||||
void describeParameter(std::size_t pos);
|
void describeParameter(std::size_t pos);
|
||||||
/// Sets the description field for the parameter, if needed.
|
/// Sets the description field for the parameter, if needed.
|
||||||
|
|
||||||
void bind(std::size_t pos, const char* const &pVal, Direction dir = PD_IN);
|
void bind(std::size_t pos, const char* const &pVal, Direction dir);
|
||||||
/// Binds a const char ptr.
|
/// Binds a const char ptr.
|
||||||
/// This is a private no-op in this implementation
|
/// This is a private no-op in this implementation
|
||||||
/// due to security risk.
|
/// due to security risk.
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/Tuple.h"
|
#include "Poco/Tuple.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Data/Common.h"
|
#include "Poco/Data/Common.h"
|
||||||
@@ -56,6 +58,9 @@ using ODBC::StatementException;
|
|||||||
using ODBC::StatementDiagnostics;
|
using ODBC::StatementDiagnostics;
|
||||||
using Poco::format;
|
using Poco::format;
|
||||||
using Poco::Tuple;
|
using Poco::Tuple;
|
||||||
|
using Poco::Any;
|
||||||
|
using Poco::AnyCast;
|
||||||
|
using Poco::DynamicAny;
|
||||||
using Poco::NotFoundException;
|
using Poco::NotFoundException;
|
||||||
|
|
||||||
|
|
||||||
@@ -958,6 +963,77 @@ void ODBCDB2Test::testStoredProcedure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCDB2Test::testStoredProcedureAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||||
|
|
||||||
|
Any i = 2;
|
||||||
|
Any j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
|
||||||
|
"BEGIN "
|
||||||
|
" SET outParam = inParam*inParam; "
|
||||||
|
"END" , now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == AnyCast<int>(j));
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
|
||||||
|
"BEGIN "
|
||||||
|
" SET ioParam = ioParam*ioParam; "
|
||||||
|
"END" , now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == AnyCast<int>(i));
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCDB2Test::testStoredProcedureDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
|
||||||
|
DynamicAny i = 2;
|
||||||
|
DynamicAny j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
|
||||||
|
"BEGIN "
|
||||||
|
" SET outParam = inParam*inParam; "
|
||||||
|
"END" , now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == j);
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
|
||||||
|
"BEGIN "
|
||||||
|
" SET ioParam = ioParam*ioParam; "
|
||||||
|
"END" , now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == i);
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCDB2Test::testStoredFunction()
|
void ODBCDB2Test::testStoredFunction()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1375,6 +1451,8 @@ CppUnit::Test* ODBCDB2Test::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
|
||||||
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testNull);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testRowIterator);
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ public:
|
|||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
|
void testStoredProcedureAny();
|
||||||
|
void testStoredProcedureDynamicAny();
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
|
|
||||||
void testNull();
|
void testNull();
|
||||||
|
|||||||
@@ -946,6 +946,38 @@ void ODBCMySQLTest::testAsync()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCMySQLTest::testAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreateAnysTable();
|
||||||
|
_pSession->setFeature("autoBind", bindValues[i]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||||
|
_pExecutor->any();
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCMySQLTest::testDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreateAnysTable();
|
||||||
|
_pSession->setFeature("autoBind", bindValues[i]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||||
|
_pExecutor->dynamicAny();
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -1027,6 +1059,15 @@ void ODBCMySQLTest::recreateVectorsTable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCMySQLTest::recreateAnysTable()
|
||||||
|
{
|
||||||
|
dropObject("TABLE", "Anys");
|
||||||
|
try { *_pSession << "CREATE TABLE Anys (i0 INTEGER, flt0 DOUBLE, str0 VARCHAR(30))", now; }
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
|
||||||
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCMySQLTest::recreateNullsTable(const std::string& notNull)
|
void ODBCMySQLTest::recreateNullsTable(const std::string& notNull)
|
||||||
{
|
{
|
||||||
dropObject("TABLE", "NullTest");
|
dropObject("TABLE", "NullTest");
|
||||||
@@ -1185,6 +1226,8 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testRowIterator);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
|
||||||
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testDynamicAny);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,9 @@ public:
|
|||||||
|
|
||||||
void testAsync();
|
void testAsync();
|
||||||
|
|
||||||
|
void testAny();
|
||||||
|
void testDynamicAny();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
@@ -148,6 +151,7 @@ private:
|
|||||||
void recreateFloatsTable();
|
void recreateFloatsTable();
|
||||||
void recreateTuplesTable();
|
void recreateTuplesTable();
|
||||||
void recreateVectorsTable();
|
void recreateVectorsTable();
|
||||||
|
void recreateAnysTable();
|
||||||
void recreateNullsTable(const std::string& notNull = "");
|
void recreateNullsTable(const std::string& notNull = "");
|
||||||
|
|
||||||
static bool init(const std::string& driver, const std::string& dsn);
|
static bool init(const std::string& driver, const std::string& dsn);
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Tuple.h"
|
#include "Poco/Tuple.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Data/Common.h"
|
#include "Poco/Data/Common.h"
|
||||||
@@ -58,6 +60,9 @@ using ODBC::StatementException;
|
|||||||
using ODBC::StatementDiagnostics;
|
using ODBC::StatementDiagnostics;
|
||||||
using Poco::format;
|
using Poco::format;
|
||||||
using Poco::Tuple;
|
using Poco::Tuple;
|
||||||
|
using Poco::Any;
|
||||||
|
using Poco::AnyCast;
|
||||||
|
using Poco::DynamicAny;
|
||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
using Poco::NotFoundException;
|
using Poco::NotFoundException;
|
||||||
|
|
||||||
@@ -918,43 +923,6 @@ void ODBCOracleTest::testStoredProcedure()
|
|||||||
assert(-1 == i);
|
assert(-1 == i);
|
||||||
dropObject("PROCEDURE", "storedProcedure");
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
*_pSession << "CREATE OR REPLACE "
|
|
||||||
"PROCEDURE storedCursorProcedure(ret OUT SYS_REFCURSOR, ageLimit IN NUMBER) IS "
|
|
||||||
" BEGIN "
|
|
||||||
" OPEN ret FOR "
|
|
||||||
" SELECT * "
|
|
||||||
" FROM Person "
|
|
||||||
" WHERE Age < ageLimit "
|
|
||||||
" ORDER BY Age DESC; "
|
|
||||||
" END storedCursorProcedure;" , now;
|
|
||||||
|
|
||||||
people.clear();
|
|
||||||
int age = 13;
|
|
||||||
|
|
||||||
*_pSession << "{call storedCursorProcedure(?)}", in(age), into(people), now;
|
|
||||||
|
|
||||||
assert (2 == people.size());
|
|
||||||
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
|
||||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
|
||||||
|
|
||||||
Statement stmt = ((*_pSession << "{call storedCursorProcedure(?)}", 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");
|
|
||||||
dropObject("PROCEDURE", "storedCursorProcedure");
|
|
||||||
|
|
||||||
*_pSession << "CREATE OR REPLACE "
|
*_pSession << "CREATE OR REPLACE "
|
||||||
"PROCEDURE storedProcedure(inParam IN NUMBER, outParam OUT NUMBER) IS "
|
"PROCEDURE storedProcedure(inParam IN NUMBER, outParam OUT NUMBER) IS "
|
||||||
" BEGIN outParam := inParam*inParam; "
|
" BEGIN outParam := inParam*inParam; "
|
||||||
@@ -1015,6 +983,128 @@ void ODBCOracleTest::testStoredProcedure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testStoredProcedureAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||||
|
|
||||||
|
Any i = 2;
|
||||||
|
Any j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE storedProcedure(inParam IN NUMBER, outParam OUT NUMBER) IS "
|
||||||
|
" BEGIN outParam := inParam*inParam; "
|
||||||
|
"END storedProcedure;" , now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == AnyCast<int>(j));
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE storedProcedure(ioParam IN OUT NUMBER) IS "
|
||||||
|
" BEGIN ioParam := ioParam*ioParam; "
|
||||||
|
" END storedProcedure;" , now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == AnyCast<int>(i));
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testStoredProcedureDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
|
||||||
|
DynamicAny i = 2;
|
||||||
|
DynamicAny j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE storedProcedure(inParam IN NUMBER, outParam OUT NUMBER) IS "
|
||||||
|
" BEGIN outParam := inParam*inParam; "
|
||||||
|
"END storedProcedure;" , now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == j);
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE storedProcedure(ioParam IN OUT NUMBER) IS "
|
||||||
|
" BEGIN ioParam := ioParam*ioParam; "
|
||||||
|
" END storedProcedure;" , now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == i);
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testStoredCursorProcedure()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"PROCEDURE storedCursorProcedure(ret OUT SYS_REFCURSOR, ageLimit IN NUMBER) IS "
|
||||||
|
" BEGIN "
|
||||||
|
" OPEN ret FOR "
|
||||||
|
" SELECT * "
|
||||||
|
" FROM Person "
|
||||||
|
" WHERE Age < ageLimit "
|
||||||
|
" ORDER BY Age DESC; "
|
||||||
|
" END storedCursorProcedure;" , now;
|
||||||
|
|
||||||
|
people.clear();
|
||||||
|
int age = 13;
|
||||||
|
|
||||||
|
*_pSession << "{call storedCursorProcedure(?)}", in(age), into(people), now;
|
||||||
|
|
||||||
|
assert (2 == people.size());
|
||||||
|
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
||||||
|
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
||||||
|
|
||||||
|
Statement stmt = ((*_pSession << "{call storedCursorProcedure(?)}", 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");
|
||||||
|
dropObject("PROCEDURE", "storedCursorProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::testStoredFunction()
|
void ODBCOracleTest::testStoredFunction()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1036,44 +1126,6 @@ void ODBCOracleTest::testStoredFunction()
|
|||||||
assert(-1 == i);
|
assert(-1 == i);
|
||||||
dropObject("FUNCTION", "storedFunction");
|
dropObject("FUNCTION", "storedFunction");
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
*_pSession << "CREATE OR REPLACE "
|
|
||||||
"FUNCTION storedCursorFunction(ageLimit IN NUMBER) RETURN SYS_REFCURSOR IS "
|
|
||||||
" ret SYS_REFCURSOR; "
|
|
||||||
" BEGIN "
|
|
||||||
" OPEN ret FOR "
|
|
||||||
" SELECT * "
|
|
||||||
" FROM Person "
|
|
||||||
" WHERE Age < ageLimit "
|
|
||||||
" ORDER BY Age DESC; "
|
|
||||||
" RETURN ret; "
|
|
||||||
" END storedCursorFunction;" , now;
|
|
||||||
|
|
||||||
people.clear();
|
|
||||||
int age = 13;
|
|
||||||
|
|
||||||
*_pSession << "{call storedCursorFunction(?)}", in(age), into(people), now;
|
|
||||||
|
|
||||||
assert (2 == people.size());
|
|
||||||
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
|
||||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
|
||||||
|
|
||||||
Statement stmt = ((*_pSession << "{call storedCursorFunction(?)}", 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");
|
|
||||||
dropObject("FUNCTION", "storedCursorFunction");
|
|
||||||
|
|
||||||
*_pSession << "CREATE OR REPLACE "
|
*_pSession << "CREATE OR REPLACE "
|
||||||
"FUNCTION storedFunction(inParam IN NUMBER) RETURN NUMBER IS "
|
"FUNCTION storedFunction(inParam IN NUMBER) RETURN NUMBER IS "
|
||||||
@@ -1144,6 +1196,59 @@ void ODBCOracleTest::testStoredFunction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testStoredCursorFunction()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
*_pSession << "CREATE OR REPLACE "
|
||||||
|
"FUNCTION storedCursorFunction(ageLimit IN NUMBER) RETURN SYS_REFCURSOR IS "
|
||||||
|
" ret SYS_REFCURSOR; "
|
||||||
|
" BEGIN "
|
||||||
|
" OPEN ret FOR "
|
||||||
|
" SELECT * "
|
||||||
|
" FROM Person "
|
||||||
|
" WHERE Age < ageLimit "
|
||||||
|
" ORDER BY Age DESC; "
|
||||||
|
" RETURN ret; "
|
||||||
|
" END storedCursorFunction;" , now;
|
||||||
|
|
||||||
|
people.clear();
|
||||||
|
int age = 13;
|
||||||
|
|
||||||
|
*_pSession << "{call storedCursorFunction(?)}", in(age), into(people), now;
|
||||||
|
|
||||||
|
assert (2 == people.size());
|
||||||
|
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
||||||
|
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
||||||
|
|
||||||
|
Statement stmt = ((*_pSession << "{call storedCursorFunction(?)}", 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");
|
||||||
|
dropObject("FUNCTION", "storedCursorFunction");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::testRowIterator()
|
void ODBCOracleTest::testRowIterator()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1501,7 +1606,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, testStoredProcedureAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
||||||
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredCursorFunction);
|
||||||
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);
|
||||||
|
|||||||
@@ -120,7 +120,11 @@ public:
|
|||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
|
void testStoredCursorProcedure();
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
|
void testStoredCursorFunction();
|
||||||
|
void testStoredProcedureAny();
|
||||||
|
void testStoredProcedureDynamicAny();
|
||||||
|
|
||||||
void testNull();
|
void testNull();
|
||||||
void testRowIterator();
|
void testRowIterator();
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/Tuple.h"
|
#include "Poco/Tuple.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
@@ -58,6 +60,9 @@ using ODBC::StatementException;
|
|||||||
using ODBC::StatementDiagnostics;
|
using ODBC::StatementDiagnostics;
|
||||||
using Poco::format;
|
using Poco::format;
|
||||||
using Poco::Tuple;
|
using Poco::Tuple;
|
||||||
|
using Poco::Any;
|
||||||
|
using Poco::AnyCast;
|
||||||
|
using Poco::DynamicAny;
|
||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
using Poco::NotFoundException;
|
using Poco::NotFoundException;
|
||||||
|
|
||||||
@@ -957,6 +962,60 @@ void ODBCPostgreSQLTest::testStoredFunction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCPostgreSQLTest::testStoredFunctionAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
*_pSession << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
|
||||||
|
"BEGIN "
|
||||||
|
" RETURN $1 * $1; "
|
||||||
|
"END;'"
|
||||||
|
"LANGUAGE 'plpgsql'" , now;
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||||
|
|
||||||
|
Any i = 2;
|
||||||
|
Any result = 0;
|
||||||
|
*_pSession << "{? = call storedFunction(?)}", out(result), in(i), now;
|
||||||
|
assert(4 == AnyCast<int>(result));
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
dropObject("FUNCTION", "storedFunction(INTEGER)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCPostgreSQLTest::testStoredFunctionDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
*_pSession << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
|
||||||
|
"BEGIN "
|
||||||
|
" RETURN $1 * $1; "
|
||||||
|
"END;'"
|
||||||
|
"LANGUAGE 'plpgsql'" , now;
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||||
|
|
||||||
|
DynamicAny i = 2;
|
||||||
|
DynamicAny result = 0;
|
||||||
|
*_pSession << "{? = call storedFunction(?)}", out(result), in(i), now;
|
||||||
|
assert(4 == result);
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
dropObject("FUNCTION", "storedFunction(INTEGER)");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCPostgreSQLTest::testRowIterator()
|
void ODBCPostgreSQLTest::testRowIterator()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@@ -1370,6 +1429,8 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunction);
|
||||||
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionAny);
|
||||||
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testNull);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testRowIterator);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStdVectorBool);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStdVectorBool);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -129,6 +129,9 @@ public:
|
|||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
|
void testStoredFunctionAny();
|
||||||
|
void testStoredFunctionDynamicAny();
|
||||||
|
|
||||||
void testNull();
|
void testNull();
|
||||||
void testRowIterator();
|
void testRowIterator();
|
||||||
void testStdVectorBool();
|
void testStdVectorBool();
|
||||||
|
|||||||
@@ -35,12 +35,15 @@
|
|||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/Tuple.h"
|
#include "Poco/Tuple.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Data/Common.h"
|
#include "Poco/Data/Common.h"
|
||||||
#include "Poco/Data/BLOB.h"
|
#include "Poco/Data/BLOB.h"
|
||||||
#include "Poco/Data/StatementImpl.h"
|
#include "Poco/Data/StatementImpl.h"
|
||||||
|
#include "Poco/Data/RecordSet.h"
|
||||||
#include "Poco/Data/ODBC/Connector.h"
|
#include "Poco/Data/ODBC/Connector.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Data/ODBC/Diagnostics.h"
|
#include "Poco/Data/ODBC/Diagnostics.h"
|
||||||
@@ -57,6 +60,9 @@ using ODBC::StatementException;
|
|||||||
using ODBC::StatementDiagnostics;
|
using ODBC::StatementDiagnostics;
|
||||||
using Poco::format;
|
using Poco::format;
|
||||||
using Poco::Tuple;
|
using Poco::Tuple;
|
||||||
|
using Poco::Any;
|
||||||
|
using Poco::AnyCast;
|
||||||
|
using Poco::DynamicAny;
|
||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
using Poco::NotFoundException;
|
using Poco::NotFoundException;
|
||||||
|
|
||||||
@@ -970,6 +976,138 @@ Deprecated types are not supported as output parameters. Use current large obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::testStoredCursorProcedure()
|
||||||
|
{
|
||||||
|
/*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.");
|
||||||
|
|
||||||
|
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", "storedCursorProcedure");
|
||||||
|
*_pSession << "CREATE PROCEDURE storedCursorProcedure(@ageLimit int) AS "
|
||||||
|
"BEGIN "
|
||||||
|
" SELECT * "
|
||||||
|
" FROM Person "
|
||||||
|
" WHERE Age < @ageLimit "
|
||||||
|
" ORDER BY Age DESC; "
|
||||||
|
"END;"
|
||||||
|
, now;
|
||||||
|
|
||||||
|
people.clear();
|
||||||
|
int age = 13;
|
||||||
|
|
||||||
|
*_pSession << "{call storedCursorProcedure(?)}", in(age), into(people), now;
|
||||||
|
|
||||||
|
assert (2 == people.size());
|
||||||
|
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
||||||
|
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
||||||
|
|
||||||
|
Statement stmt = ((*_pSession << "{call storedCursorProcedure(?)}", 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");
|
||||||
|
dropObject("PROCEDURE", "storedCursorProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::testStoredProcedureAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||||
|
|
||||||
|
Any i = 2;
|
||||||
|
Any j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(@inParam int, @outParam int OUTPUT) AS "
|
||||||
|
"BEGIN "
|
||||||
|
"SET @outParam = @inParam*@inParam; "
|
||||||
|
"END;"
|
||||||
|
, now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == AnyCast<int>(j));
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(@ioParam int OUTPUT) AS "
|
||||||
|
"BEGIN "
|
||||||
|
"SET @ioParam = @ioParam*@ioParam; "
|
||||||
|
"END;"
|
||||||
|
, now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == AnyCast<int>(i));
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::testStoredProcedureDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int k = 0; k < 8;)
|
||||||
|
{
|
||||||
|
_pSession->setFeature("autoBind", bindValues[k]);
|
||||||
|
|
||||||
|
DynamicAny i = 2;
|
||||||
|
DynamicAny j = 0;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(@inParam int, @outParam int OUTPUT) AS "
|
||||||
|
"BEGIN "
|
||||||
|
"SET @outParam = @inParam*@inParam; "
|
||||||
|
"END;"
|
||||||
|
, now;
|
||||||
|
|
||||||
|
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
|
||||||
|
assert(4 == j);
|
||||||
|
*_pSession << "DROP PROCEDURE storedProcedure;", now;
|
||||||
|
|
||||||
|
*_pSession << "CREATE PROCEDURE storedProcedure(@ioParam int OUTPUT) AS "
|
||||||
|
"BEGIN "
|
||||||
|
"SET @ioParam = @ioParam*@ioParam; "
|
||||||
|
"END;"
|
||||||
|
, now;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
*_pSession << "{call storedProcedure(?)}", io(i), now;
|
||||||
|
assert(4 == i);
|
||||||
|
dropObject("PROCEDURE", "storedProcedure");
|
||||||
|
|
||||||
|
k += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::testStoredFunction()
|
void ODBCSQLServerTest::testStoredFunction()
|
||||||
{
|
{
|
||||||
for (int k = 0; k < 8;)
|
for (int k = 0; k < 8;)
|
||||||
@@ -1055,6 +1193,63 @@ 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.");
|
||||||
@@ -1416,7 +1611,11 @@ 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, testStoredProcedureAny);
|
||||||
|
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,7 +120,11 @@ public:
|
|||||||
void testTupleVector();
|
void testTupleVector();
|
||||||
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
|
void testStoredCursorProcedure();
|
||||||
|
void testStoredProcedureAny();
|
||||||
|
void testStoredProcedureDynamicAny();
|
||||||
void testStoredFunction();
|
void testStoredFunction();
|
||||||
|
void testStoredCursorFunction();
|
||||||
|
|
||||||
void testInternalExtraction();
|
void testInternalExtraction();
|
||||||
void testInternalStorageType();
|
void testInternalStorageType();
|
||||||
|
|||||||
@@ -64,60 +64,60 @@ public:
|
|||||||
~Binder();
|
~Binder();
|
||||||
/// Destroys the Binder.
|
/// Destroys the Binder.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir);
|
||||||
/// Binds an Int8.
|
/// Binds an Int8.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir);
|
||||||
/// Binds an UInt8.
|
/// Binds an UInt8.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir);
|
||||||
/// Binds an Int16.
|
/// Binds an Int16.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir);
|
||||||
/// Binds an UInt16.
|
/// Binds an UInt16.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir);
|
||||||
/// Binds an Int32.
|
/// Binds an Int32.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir);
|
||||||
/// Binds an UInt32.
|
/// Binds an UInt32.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir);
|
||||||
/// Binds an Int64.
|
/// Binds an Int64.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir);
|
||||||
/// Binds an UInt64.
|
/// Binds an UInt64.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
void bind(std::size_t pos, const long &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const long &val, Direction dir);
|
||||||
/// Binds a long
|
/// Binds a long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void bind(std::size_t pos, const bool &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const bool &val, Direction dir);
|
||||||
/// Binds a boolean.
|
/// Binds a boolean.
|
||||||
|
|
||||||
void bind(std::size_t pos, const float &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const float &val, Direction dir);
|
||||||
/// Binds a float.
|
/// Binds a float.
|
||||||
|
|
||||||
void bind(std::size_t pos, const double &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const double &val, Direction dir);
|
||||||
/// Binds a double.
|
/// Binds a double.
|
||||||
|
|
||||||
void bind(std::size_t pos, const char &val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const char &val, Direction dir);
|
||||||
/// Binds a single character.
|
/// Binds a single character.
|
||||||
|
|
||||||
void bind(std::size_t pos, const char* const &pVal, Direction dir = PD_IN);
|
void bind(std::size_t pos, const char* const &pVal, Direction dir);
|
||||||
/// Binds a const char ptr.
|
/// Binds a const char ptr.
|
||||||
|
|
||||||
void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const std::string& val, Direction dir);
|
||||||
/// Binds a string.
|
/// Binds a string.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
|
||||||
/// Binds a BLOB.
|
/// Binds a BLOB.
|
||||||
|
|
||||||
void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||||
/// Binds a DateTime.
|
/// Binds a DateTime.
|
||||||
|
|
||||||
void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -96,60 +96,60 @@ public:
|
|||||||
virtual ~AbstractBinder();
|
virtual ~AbstractBinder();
|
||||||
/// Destroys the AbstractBinder.
|
/// Destroys the AbstractBinder.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int8.
|
/// Binds an Int8.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt8.
|
/// Binds an UInt8.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int16.
|
/// Binds an Int16.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt16.
|
/// Binds an UInt16.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int32.
|
/// Binds an Int32.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt32.
|
/// Binds an UInt32.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int64.
|
/// Binds an Int64.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt64.
|
/// Binds an UInt64.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
virtual void bind(std::size_t pos, const long& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a long.
|
/// Binds a long.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const bool& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const bool& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a boolean.
|
/// Binds a boolean.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const float& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const float& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a float.
|
/// Binds a float.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const double& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const double& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a double.
|
/// Binds a double.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const char& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const char& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a single character.
|
/// Binds a single character.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const char* const &pVal, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const char* const &pVal, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a const char ptr.
|
/// Binds a const char ptr.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::string& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a string.
|
/// Binds a string.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const BLOB& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a BLOB.
|
/// Binds a BLOB.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const DateTime& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a DateTime.
|
/// Binds a DateTime.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir) = 0;
|
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
|
||||||
|
|||||||
@@ -57,9 +57,6 @@ AbstractBinder::~AbstractBinder()
|
|||||||
|
|
||||||
void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
|
void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
|
||||||
{
|
{
|
||||||
if (PD_IN != dir)
|
|
||||||
throw InvalidAccessException("Only IN direction is allowed.");
|
|
||||||
|
|
||||||
if(val.type() == typeid(Int32))
|
if(val.type() == typeid(Int32))
|
||||||
bind(pos, RefAnyCast<Int32>(val), dir);
|
bind(pos, RefAnyCast<Int32>(val), dir);
|
||||||
else if(val.type() == typeid(std::string))
|
else if(val.type() == typeid(std::string))
|
||||||
@@ -101,9 +98,6 @@ void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
|
|||||||
|
|
||||||
void AbstractBinder::bind(std::size_t pos, const DynamicAny& val, Direction dir)
|
void AbstractBinder::bind(std::size_t pos, const DynamicAny& val, Direction dir)
|
||||||
{
|
{
|
||||||
if (PD_IN != dir)
|
|
||||||
throw InvalidAccessException("Only IN direction is allowed.");
|
|
||||||
|
|
||||||
if(val.type() == typeid(Int32))
|
if(val.type() == typeid(Int32))
|
||||||
bind(pos, val.extract<Int32>(), dir);
|
bind(pos, val.extract<Int32>(), dir);
|
||||||
else if(val.type() == typeid(std::string))
|
else if(val.type() == typeid(std::string))
|
||||||
|
|||||||
Reference in New Issue
Block a user