Any and DynamicAny out and io

This commit is contained in:
Aleksandar Fabijanic
2007-10-31 21:48:22 +00:00
parent d248862406
commit a6aa475b55
14 changed files with 637 additions and 136 deletions

View File

@@ -86,57 +86,57 @@ public:
~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.
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.
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.
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.
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.
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.
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.
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.
#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.
#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.
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.
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.
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.
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.
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.
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.
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.
void setDataBinding(ParameterBinding binding);
@@ -160,7 +160,7 @@ private:
void describeParameter(std::size_t pos);
/// 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.
/// This is a private no-op in this implementation
/// due to security risk.

View File

@@ -35,6 +35,8 @@
#include "CppUnit/TestSuite.h"
#include "Poco/String.h"
#include "Poco/Format.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/Tuple.h"
#include "Poco/Exception.h"
#include "Poco/Data/Common.h"
@@ -56,6 +58,9 @@ using ODBC::StatementException;
using ODBC::StatementDiagnostics;
using Poco::format;
using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
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()
{
if (!_pSession) fail ("Test not available.");
@@ -1375,6 +1451,8 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureAny);
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureDynamicAny);
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredFunction);
CppUnit_addTest(pSuite, ODBCDB2Test, testNull);
CppUnit_addTest(pSuite, ODBCDB2Test, testRowIterator);

View File

@@ -120,6 +120,8 @@ public:
void testInternalStorageType();
void testStoredProcedure();
void testStoredProcedureAny();
void testStoredProcedureDynamicAny();
void testStoredFunction();
void testNull();

View File

@@ -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)
{
*_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)
{
dropObject("TABLE", "NullTest");
@@ -1185,6 +1226,8 @@ CppUnit::Test* ODBCMySQLTest::suite()
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
CppUnit_addTest(pSuite, ODBCMySQLTest, testRowIterator);
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
CppUnit_addTest(pSuite, ODBCMySQLTest, testAny);
CppUnit_addTest(pSuite, ODBCMySQLTest, testDynamicAny);
return pSuite;
}

View File

@@ -129,6 +129,9 @@ public:
void testAsync();
void testAny();
void testDynamicAny();
void setUp();
void tearDown();
@@ -148,6 +151,7 @@ private:
void recreateFloatsTable();
void recreateTuplesTable();
void recreateVectorsTable();
void recreateAnysTable();
void recreateNullsTable(const std::string& notNull = "");
static bool init(const std::string& driver, const std::string& dsn);

View File

@@ -36,6 +36,8 @@
#include "Poco/String.h"
#include "Poco/Tuple.h"
#include "Poco/Format.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
#include "Poco/Data/Common.h"
@@ -58,6 +60,9 @@ using ODBC::StatementException;
using ODBC::StatementDiagnostics;
using Poco::format;
using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::DateTime;
using Poco::NotFoundException;
@@ -918,43 +923,6 @@ void ODBCOracleTest::testStoredProcedure()
assert(-1 == i);
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 "
"PROCEDURE storedProcedure(inParam IN NUMBER, outParam OUT NUMBER) IS "
" 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()
{
if (!_pSession) fail ("Test not available.");
@@ -1036,44 +1126,6 @@ void ODBCOracleTest::testStoredFunction()
assert(-1 == i);
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 "
"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()
{
if (!_pSession) fail ("Test not available.");
@@ -1501,7 +1606,11 @@ CppUnit::Test* ODBCOracleTest::suite()
CppUnit_addTest(pSuite, ODBCOracleTest, testTuple);
CppUnit_addTest(pSuite, ODBCOracleTest, testTupleVector);
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, testStoredCursorFunction);
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);

View File

@@ -120,7 +120,11 @@ public:
void testInternalStorageType();
void testStoredProcedure();
void testStoredCursorProcedure();
void testStoredFunction();
void testStoredCursorFunction();
void testStoredProcedureAny();
void testStoredProcedureDynamicAny();
void testNull();
void testRowIterator();

View File

@@ -35,6 +35,8 @@
#include "CppUnit/TestSuite.h"
#include "Poco/String.h"
#include "Poco/Format.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/Tuple.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
@@ -58,6 +60,9 @@ using ODBC::StatementException;
using ODBC::StatementDiagnostics;
using Poco::format;
using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::DateTime;
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()
{
if (!_pSession) fail ("Test not available.");
@@ -1370,6 +1429,8 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalStorageType);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunction);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionAny);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionDynamicAny);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testNull);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testRowIterator);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStdVectorBool);

View File

@@ -45,7 +45,7 @@
// uncomment to use Mammoth ODBCng driver
#define POCO_ODBC_USE_MAMMOTH_NG
//#define POCO_ODBC_USE_MAMMOTH_NG
class ODBCPostgreSQLTest: public CppUnit::TestCase
@@ -129,6 +129,9 @@ public:
void testInternalStorageType();
void testStoredFunction();
void testStoredFunctionAny();
void testStoredFunctionDynamicAny();
void testNull();
void testRowIterator();
void testStdVectorBool();

View File

@@ -35,12 +35,15 @@
#include "CppUnit/TestSuite.h"
#include "Poco/String.h"
#include "Poco/Format.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/Tuple.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
#include "Poco/Data/Common.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/ODBC/Connector.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/Diagnostics.h"
@@ -57,6 +60,9 @@ using ODBC::StatementException;
using ODBC::StatementDiagnostics;
using Poco::format;
using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::DateTime;
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()
{
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()
{
if (!_pSession) fail ("Test not available.");
@@ -1416,7 +1611,11 @@ CppUnit::Test* ODBCSQLServerTest::suite()
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTuple);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTupleVector);
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, testStoredCursorFunction);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);

View File

@@ -120,7 +120,11 @@ public:
void testTupleVector();
void testStoredProcedure();
void testStoredCursorProcedure();
void testStoredProcedureAny();
void testStoredProcedureDynamicAny();
void testStoredFunction();
void testStoredCursorFunction();
void testInternalExtraction();
void testInternalStorageType();

View File

@@ -64,60 +64,60 @@ public:
~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.
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.
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.
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.
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.
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.
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.
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.
#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
#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.
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.
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.
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.
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.
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.
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.
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.
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.
private:

View File

@@ -96,60 +96,60 @@ public:
virtual ~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.
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.
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.
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.
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.
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.
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.
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.
#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.
#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.
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.
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.
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.
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.
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.
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.
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.
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.
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);

View File

@@ -57,9 +57,6 @@ AbstractBinder::~AbstractBinder()
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))
bind(pos, RefAnyCast<Int32>(val), dir);
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)
{
if (PD_IN != dir)
throw InvalidAccessException("Only IN direction is allowed.");
if(val.type() == typeid(Int32))
bind(pos, val.extract<Int32>(), dir);
else if(val.type() == typeid(std::string))