- ODBC Nullable support and tests (Oracle and SQLServer tested)

- fix for Win7/MSVC80 _WIN32_WINNT macro detection
This commit is contained in:
Aleksandar Fabijanic
2012-09-16 03:00:52 +00:00
parent f2e8cef390
commit 7029c95e07
17 changed files with 152 additions and 22 deletions

View File

@@ -483,9 +483,16 @@ private:
bool extAny(std::size_t pos, T& val) bool extAny(std::size_t pos, T& val)
{ {
NT i; NT i;
extract(pos, i); if (extract(pos, i))
val = i; {
return true; val = i;
return true;
}
else
{
val = Nullable<NT>();
return false;
}
} }
template <typename T> template <typename T>

View File

@@ -441,6 +441,15 @@ void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
} }
void ODBCDB2Test::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCDB2Test::recreatePersonTable() void ODBCDB2Test::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -66,6 +66,7 @@ public:
private: private:
void dropObject(const std::string& type, const std::string& tableName); void dropObject(const std::string& type, const std::string& tableName);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();
void recreatePersonDateTable(); void recreatePersonDateTable();

View File

@@ -261,6 +261,15 @@ void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
} }
void ODBCMySQLTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCMySQLTest::recreatePersonTable() void ODBCMySQLTest::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -71,6 +71,7 @@ public:
private: private:
void dropObject(const std::string& type, const std::string& name); void dropObject(const std::string& type, const std::string& name);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();
void recreatePersonDateTable(); void recreatePersonDateTable();

View File

@@ -68,8 +68,8 @@ using Poco::DateTime;
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER #define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define ORACLE_PORT "1521" #define ORACLE_PORT "1521"
#define ORACLE_SID "XE" #define ORACLE_SID "XE"
#define ORACLE_UID "scott" #define ORACLE_UID "poco"
#define ORACLE_PWD "tiger" #define ORACLE_PWD "poco"
ODBCTest::SessionPtr ODBCOracleTest::_pSession; ODBCTest::SessionPtr ODBCOracleTest::_pSession;
@@ -689,6 +689,15 @@ void ODBCOracleTest::dropObject(const std::string& type, const std::string& name
} }
void ODBCOracleTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR2(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat NUMBER NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCOracleTest::recreatePersonTable() void ODBCOracleTest::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -48,6 +48,7 @@ class ODBCOracleTest: public ODBCTest
/// ------------+-------------------------------+------------------------------------------ /// ------------+-------------------------------+------------------------------------------
/// 10.02.00.01 | Oracle9i Release 9.2.0.4.0 | MS Windows XP Professional x64 v.2003/SP1 /// 10.02.00.01 | Oracle9i Release 9.2.0.4.0 | MS Windows XP Professional x64 v.2003/SP1
/// 10.02.00.01 | Oracle XE Release 10.2.0.1.0 | MS Windows XP Professional x64 v.2003/SP1 /// 10.02.00.01 | Oracle XE Release 10.2.0.1.0 | MS Windows XP Professional x64 v.2003/SP1
/// 11.02.00.02 | Oracle XE Release 11.2.0.2.0 | MS Windows 7 Professional x64 v.2009/SP1
{ {
public: public:
ODBCOracleTest(const std::string& name); ODBCOracleTest(const std::string& name);
@@ -74,6 +75,7 @@ private:
static void testBarebone(); static void testBarebone();
void dropObject(const std::string& type, const std::string& name); void dropObject(const std::string& type, const std::string& name);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonTupleTable(); void recreatePersonTupleTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();

View File

@@ -394,6 +394,15 @@ void ODBCPostgreSQLTest::dropObject(const std::string& type, const std::string&
} }
void ODBCPostgreSQLTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCPostgreSQLTest::recreatePersonTable() void ODBCPostgreSQLTest::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -73,6 +73,7 @@ public:
private: private:
void dropObject(const std::string& type, const std::string& name); void dropObject(const std::string& type, const std::string& name);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();
void recreatePersonDateTimeTable(); void recreatePersonDateTimeTable();

View File

@@ -87,7 +87,7 @@ using Poco::DateTime;
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(FORCE_FREE_TDS) #if defined(POCO_OS_FAMILY_WINDOWS) && !defined(FORCE_FREE_TDS)
#ifdef POCO_ODBC_USE_SQL_NATIVE #ifdef POCO_ODBC_USE_SQL_NATIVE
#define MS_SQL_SERVER_ODBC_DRIVER "SQL Native Client" #define MS_SQL_SERVER_ODBC_DRIVER "SQL Server Native Client 10.0"
#else #else
#define MS_SQL_SERVER_ODBC_DRIVER "SQL Server" #define MS_SQL_SERVER_ODBC_DRIVER "SQL Server"
#endif #endif
@@ -103,9 +103,9 @@ using Poco::DateTime;
#define MS_SQL_SERVER_DSN "PocoDataSQLServerTest" #define MS_SQL_SERVER_DSN "PocoDataSQLServerTest"
#define MS_SQL_SERVER_SERVER POCO_ODBC_TEST_DATABASE_SERVER #define MS_SQL_SERVER_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define MS_SQL_SERVER_PORT "1433" #define MS_SQL_SERVER_PORT "1433"
#define MS_SQL_SERVER_DB "test" #define MS_SQL_SERVER_DB "poco"
#define MS_SQL_SERVER_UID "test" #define MS_SQL_SERVER_UID "poco"
#define MS_SQL_SERVER_PWD "test" #define MS_SQL_SERVER_PWD "poco"
ODBCTest::SessionPtr ODBCSQLServerTest::_pSession; ODBCTest::SessionPtr ODBCSQLServerTest::_pSession;
@@ -115,6 +115,7 @@ std::string ODBCSQLServerTest::_dsn = MS_SQL_SERVER_DSN;
std::string ODBCSQLServerTest::_uid = MS_SQL_SERVER_UID; std::string ODBCSQLServerTest::_uid = MS_SQL_SERVER_UID;
std::string ODBCSQLServerTest::_pwd = MS_SQL_SERVER_PWD; std::string ODBCSQLServerTest::_pwd = MS_SQL_SERVER_PWD;
std::string ODBCSQLServerTest::_db = MS_SQL_SERVER_DB; std::string ODBCSQLServerTest::_db = MS_SQL_SERVER_DB;
std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRIVER ";" std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRIVER ";"
"UID=" MS_SQL_SERVER_UID ";" "UID=" MS_SQL_SERVER_UID ";"
"PWD=" MS_SQL_SERVER_PWD ";" "PWD=" MS_SQL_SERVER_PWD ";"
@@ -126,6 +127,7 @@ std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRI
#endif #endif
; ;
ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name): ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name):
ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString) ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
{ {
@@ -569,6 +571,15 @@ void ODBCSQLServerTest::dropObject(const std::string& type, const std::string& n
} }
void ODBCSQLServerTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime DATETIME NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCSQLServerTest::recreatePersonTable() void ODBCSQLServerTest::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -48,10 +48,11 @@ class ODBCSQLServerTest: public ODBCTest
/// SQLServer ODBC test class /// SQLServer ODBC test class
/// Tested: /// Tested:
/// ///
/// Driver | DB | OS /// Driver | DB | OS
/// ----------------+-------------------------------+------------------------------------------ /// --------------------+-----------------------------------+------------------------------------------
/// 2000.86.1830.00 | SQL Server Express 9.0.2047 | MS Windows XP Professional x64 v.2003/SP1 /// 2000.86.1830.00 | SQL Server Express 9.0.2047 | MS Windows XP Professional x64 v.2003/SP1
/// 2005.90.2047.00 | SQL Server Express 9.0.2047 | MS Windows XP Professional x64 v.2003/SP1 /// 2005.90.2047.00 | SQL Server Express 9.0.2047 | MS Windows XP Professional x64 v.2003/SP1
/// 2009.100.1600.01 | SQL Server Express 10.50.1600.1 | MS Windows XP Professional x64 v.2003/SP1
/// ///
{ {
@@ -76,6 +77,7 @@ public:
private: private:
void dropObject(const std::string& type, const std::string& name); void dropObject(const std::string& type, const std::string& name);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();
void recreatePersonDateTimeTable(); void recreatePersonDateTimeTable();

View File

@@ -187,6 +187,15 @@ void ODBCSQLiteTest::dropObject(const std::string& type, const std::string& name
} }
void ODBCSQLiteTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat REAL NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCSQLiteTest::recreatePersonTable() void ODBCSQLiteTest::recreatePersonTable()
{ {
dropObject("TABLE", "Person"); dropObject("TABLE", "Person");

View File

@@ -60,6 +60,7 @@ public:
private: private:
void dropObject(const std::string& type, const std::string& name); void dropObject(const std::string& type, const std::string& name);
void recreateNullableTable();
void recreatePersonTable(); void recreatePersonTable();
void recreatePersonBLOBTable(); void recreatePersonBLOBTable();
void recreatePersonDateTimeTable(); void recreatePersonDateTimeTable();

View File

@@ -1210,7 +1210,7 @@ void ODBCTest::testNullable()
for (int i = 0; i < 8;) for (int i = 0; i < 8;)
{ {
recreatePersonTable(); recreateNullableTable();
_pSession->setFeature("autoBind", bindValue(i)); _pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1)); _pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->nullable(); _pExecutor->nullable();

View File

@@ -175,6 +175,7 @@ protected:
typedef Poco::Data::ODBC::Utility::DriverMap Drivers; typedef Poco::Data::ODBC::Utility::DriverMap Drivers;
virtual void dropObject(const std::string& type, const std::string& name); virtual void dropObject(const std::string& type, const std::string& name);
virtual void recreateNullableTable();
virtual void recreatePersonTable(); virtual void recreatePersonTable();
virtual void recreatePersonTupleTable(); virtual void recreatePersonTupleTable();
virtual void recreatePersonBLOBTable(); virtual void recreatePersonBLOBTable();
@@ -274,6 +275,12 @@ inline void ODBCTest::dropObject(const std::string& type, const std::string& nam
} }
inline void ODBCTest::recreateNullableTable()
{
throw Poco::NotImplementedException("ODBCTest::recreateNullableTable()");
}
inline void ODBCTest::recreatePersonTable() inline void ODBCTest::recreatePersonTable()
{ {
throw Poco::NotImplementedException("ODBCTest::recreatePersonTable()"); throw Poco::NotImplementedException("ODBCTest::recreatePersonTable()");

View File

@@ -35,8 +35,9 @@
#include "Poco/String.h" #include "Poco/String.h"
#include "Poco/Format.h" #include "Poco/Format.h"
#include "Poco/Tuple.h" #include "Poco/Tuple.h"
#include "Poco/Nullable.h"
#include "Poco/Any.h" #include "Poco/Any.h"
#include "Poco/DynamicAny.h" #include "Poco/Dynamic/Var.h"
#include "Poco/DateTime.h" #include "Poco/DateTime.h"
#include "Poco/Stopwatch.h" #include "Poco/Stopwatch.h"
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
@@ -94,9 +95,10 @@ using Poco::Data::ODBC::DataTruncatedException;
using Poco::Data::ODBC::StatementDiagnostics; using Poco::Data::ODBC::StatementDiagnostics;
using Poco::format; using Poco::format;
using Poco::Tuple; using Poco::Tuple;
using Poco::Nullable;
using Poco::Any; using Poco::Any;
using Poco::AnyCast; using Poco::AnyCast;
using Poco::DynamicAny; using Poco::Dynamic::Var;
using Poco::DateTime; using Poco::DateTime;
using Poco::Stopwatch; using Poco::Stopwatch;
using Poco::NumberFormatter; using Poco::NumberFormatter;
@@ -2731,7 +2733,7 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName
pRF->add(intFldName, RowFilter::VALUE_EQUAL, 1); pRF->add(intFldName, RowFilter::VALUE_EQUAL, 1);
assert (!pRF->isEmpty()); assert (!pRF->isEmpty());
DynamicAny da; Var da;
try try
{ {
da = rset.value(0, 1); da = rset.value(0, 1);
@@ -3271,9 +3273,9 @@ void SQLExecutor::any()
void SQLExecutor::dynamicAny() void SQLExecutor::dynamicAny()
{ {
DynamicAny i = 42; Var i = 42;
DynamicAny f = 42.5; Var f = 42.5;
DynamicAny s = "42"; Var s = "42";
Session tmp = session(); Session tmp = session();
tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now; tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now;
@@ -3789,7 +3791,51 @@ void SQLExecutor::transactor()
void SQLExecutor::nullable() void SQLExecutor::nullable()
{ {
throw NotImplementedException("TODO - see SQLite test for nullable"); try { session() << "INSERT INTO NullableTest VALUES(NULL, NULL, NULL, NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("nullable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("nullable()"); }
Nullable<int> i = 1;
Nullable<double> f = 1.5;
Nullable<std::string> s = std::string("abc");
Nullable<DateTime> d = DateTime();
assert (!i.isNull());
assert (!f.isNull());
assert (!s.isNull());
assert (!d.isNull());
session() << "SELECT EmptyString, EmptyInteger, EmptyFloat, EmptyDateTime FROM NullableTest", into(s), into(i), into(f), into(d), now;
assert (i.isNull());
assert (f.isNull());
assert (s.isNull());
assert (d.isNull());
RecordSet rs(session(), "SELECT * FROM NullableTest");
rs.moveFirst();
assert (rs.isNull("EmptyString"));
assert (rs.isNull("EmptyInteger"));
assert (rs.isNull("EmptyFloat"));
assert (rs.isNull("EmptyDateTime"));
Var di = 1;
Var df = 1.5;
Var ds = "abc";
Var dd = DateTime();
assert (!di.isEmpty());
assert (!df.isEmpty());
assert (!ds.isEmpty());
assert (!dd.isEmpty());
session() << "SELECT EmptyString, EmptyInteger, EmptyFloat, EmptyDateTime FROM NullableTest", into(di), into(df), into(ds), into(dd), now;
assert (di.isEmpty());
assert (df.isEmpty());
assert (ds.isEmpty());
assert (dd.isEmpty());
} }

View File

@@ -57,12 +57,18 @@
#undef _WIN32_WINNT #undef _WIN32_WINNT
#endif #endif
#define _WIN32_WINNT _WIN32_WINNT_WS08 #define _WIN32_WINNT _WIN32_WINNT_WS08
#elif defined (_WIN32_WINNT_VISTA) || defined (_WIN32_WINNT_LONGHORN) #elif defined (_WIN32_WINNT_VISTA)
//Windows Vista _WIN32_WINNT_VISTA (0x0600) //Windows Vista _WIN32_WINNT_VISTA (0x0600)
#ifdef _WIN32_WINNT #ifdef _WIN32_WINNT
#undef _WIN32_WINNT #undef _WIN32_WINNT
#endif #endif
#define _WIN32_WINNT _WIN32_WINNT_VISTA #define _WIN32_WINNT _WIN32_WINNT_VISTA
#elif defined (_WIN32_WINNT_LONGHORN)
//Windows Vista and server 2008 Development _WIN32_WINNT_LONGHORN (0x0600)
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT _WIN32_WINNT_LONGHORN
#elif defined (_WIN32_WINNT_WS03) #elif defined (_WIN32_WINNT_WS03)
//Windows Server 2003 with SP1, //Windows Server 2003 with SP1,
//Windows XP with SP2 _WIN32_WINNT_WS03 (0x0502) //Windows XP with SP2 _WIN32_WINNT_WS03 (0x0502)