diff --git a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h index 2e9cb5a4e..2e2d833cc 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h @@ -483,9 +483,16 @@ private: bool extAny(std::size_t pos, T& val) { NT i; - extract(pos, i); - val = i; - return true; + if (extract(pos, i)) + { + val = i; + return true; + } + else + { + val = Nullable(); + return false; + } } template diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp index 8d54f319f..36d04a1a8 100644 --- a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp +++ b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp @@ -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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.h b/Data/ODBC/testsuite/src/ODBCDB2Test.h index e96a811f0..d3775de05 100644 --- a/Data/ODBC/testsuite/src/ODBCDB2Test.h +++ b/Data/ODBC/testsuite/src/ODBCDB2Test.h @@ -66,6 +66,7 @@ public: private: void dropObject(const std::string& type, const std::string& tableName); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonBLOBTable(); void recreatePersonDateTable(); diff --git a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp index 10865258b..37d8004f9 100644 --- a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp @@ -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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCMySQLTest.h b/Data/ODBC/testsuite/src/ODBCMySQLTest.h index 34ee7c495..2381044ac 100644 --- a/Data/ODBC/testsuite/src/ODBCMySQLTest.h +++ b/Data/ODBC/testsuite/src/ODBCMySQLTest.h @@ -71,6 +71,7 @@ public: private: void dropObject(const std::string& type, const std::string& name); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonBLOBTable(); void recreatePersonDateTable(); diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp index 7c65a2334..80609a98e 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp @@ -68,8 +68,8 @@ using Poco::DateTime; #define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER #define ORACLE_PORT "1521" #define ORACLE_SID "XE" -#define ORACLE_UID "scott" -#define ORACLE_PWD "tiger" +#define ORACLE_UID "poco" +#define ORACLE_PWD "poco" 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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.h b/Data/ODBC/testsuite/src/ODBCOracleTest.h index 30bd35215..3e72c9f05 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.h +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.h @@ -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 | 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: ODBCOracleTest(const std::string& name); @@ -74,6 +75,7 @@ private: static void testBarebone(); void dropObject(const std::string& type, const std::string& name); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonTupleTable(); void recreatePersonBLOBTable(); diff --git a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp index c1519fbac..e270e5777 100644 --- a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp @@ -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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h index b3312437c..01d09f65c 100644 --- a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h +++ b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h @@ -73,6 +73,7 @@ public: private: void dropObject(const std::string& type, const std::string& name); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonBLOBTable(); void recreatePersonDateTimeTable(); diff --git a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp index 774dab2ef..4a01bda7b 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp @@ -87,7 +87,7 @@ using Poco::DateTime; #if defined(POCO_OS_FAMILY_WINDOWS) && !defined(FORCE_FREE_TDS) #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 #define MS_SQL_SERVER_ODBC_DRIVER "SQL Server" #endif @@ -103,9 +103,9 @@ using Poco::DateTime; #define MS_SQL_SERVER_DSN "PocoDataSQLServerTest" #define MS_SQL_SERVER_SERVER POCO_ODBC_TEST_DATABASE_SERVER #define MS_SQL_SERVER_PORT "1433" -#define MS_SQL_SERVER_DB "test" -#define MS_SQL_SERVER_UID "test" -#define MS_SQL_SERVER_PWD "test" +#define MS_SQL_SERVER_DB "poco" +#define MS_SQL_SERVER_UID "poco" +#define MS_SQL_SERVER_PWD "poco" 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::_pwd = MS_SQL_SERVER_PWD; std::string ODBCSQLServerTest::_db = MS_SQL_SERVER_DB; + std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRIVER ";" "UID=" MS_SQL_SERVER_UID ";" "PWD=" MS_SQL_SERVER_PWD ";" @@ -126,6 +127,7 @@ std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRI #endif ; + ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name): 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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCSQLServerTest.h b/Data/ODBC/testsuite/src/ODBCSQLServerTest.h index ceb2411fb..188624cf7 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLServerTest.h +++ b/Data/ODBC/testsuite/src/ODBCSQLServerTest.h @@ -48,10 +48,11 @@ class ODBCSQLServerTest: public ODBCTest /// SQLServer ODBC test class /// Tested: /// - /// Driver | DB | OS - /// ----------------+-------------------------------+------------------------------------------ - /// 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 + /// Driver | DB | OS + /// --------------------+-----------------------------------+------------------------------------------ + /// 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 + /// 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: void dropObject(const std::string& type, const std::string& name); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonBLOBTable(); void recreatePersonDateTimeTable(); diff --git a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp index c7d79181e..2200b3b27 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp @@ -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() { dropObject("TABLE", "Person"); diff --git a/Data/ODBC/testsuite/src/ODBCSQLiteTest.h b/Data/ODBC/testsuite/src/ODBCSQLiteTest.h index 1e506a73e..471bce92e 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLiteTest.h +++ b/Data/ODBC/testsuite/src/ODBCSQLiteTest.h @@ -60,6 +60,7 @@ public: private: void dropObject(const std::string& type, const std::string& name); + void recreateNullableTable(); void recreatePersonTable(); void recreatePersonBLOBTable(); void recreatePersonDateTimeTable(); diff --git a/Data/ODBC/testsuite/src/ODBCTest.cpp b/Data/ODBC/testsuite/src/ODBCTest.cpp index 58b13aeea..6fe5e1c71 100644 --- a/Data/ODBC/testsuite/src/ODBCTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCTest.cpp @@ -1210,7 +1210,7 @@ void ODBCTest::testNullable() for (int i = 0; i < 8;) { - recreatePersonTable(); + recreateNullableTable(); _pSession->setFeature("autoBind", bindValue(i)); _pSession->setFeature("autoExtract", bindValue(i+1)); _pExecutor->nullable(); diff --git a/Data/ODBC/testsuite/src/ODBCTest.h b/Data/ODBC/testsuite/src/ODBCTest.h index e8b203c8c..254c310f7 100644 --- a/Data/ODBC/testsuite/src/ODBCTest.h +++ b/Data/ODBC/testsuite/src/ODBCTest.h @@ -175,6 +175,7 @@ protected: typedef Poco::Data::ODBC::Utility::DriverMap Drivers; virtual void dropObject(const std::string& type, const std::string& name); + virtual void recreateNullableTable(); virtual void recreatePersonTable(); virtual void recreatePersonTupleTable(); 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() { throw Poco::NotImplementedException("ODBCTest::recreatePersonTable()"); diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp index b421b26c2..32103ed7d 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.cpp +++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp @@ -35,8 +35,9 @@ #include "Poco/String.h" #include "Poco/Format.h" #include "Poco/Tuple.h" +#include "Poco/Nullable.h" #include "Poco/Any.h" -#include "Poco/DynamicAny.h" +#include "Poco/Dynamic/Var.h" #include "Poco/DateTime.h" #include "Poco/Stopwatch.h" #include "Poco/NumberFormatter.h" @@ -94,9 +95,10 @@ using Poco::Data::ODBC::DataTruncatedException; using Poco::Data::ODBC::StatementDiagnostics; using Poco::format; using Poco::Tuple; +using Poco::Nullable; using Poco::Any; using Poco::AnyCast; -using Poco::DynamicAny; +using Poco::Dynamic::Var; using Poco::DateTime; using Poco::Stopwatch; 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); assert (!pRF->isEmpty()); - DynamicAny da; + Var da; try { da = rset.value(0, 1); @@ -3271,9 +3273,9 @@ void SQLExecutor::any() void SQLExecutor::dynamicAny() { - DynamicAny i = 42; - DynamicAny f = 42.5; - DynamicAny s = "42"; + Var i = 42; + Var f = 42.5; + Var s = "42"; Session tmp = session(); tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now; @@ -3789,7 +3791,51 @@ void SQLExecutor::transactor() 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 i = 1; + Nullable f = 1.5; + Nullable s = std::string("abc"); + Nullable 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()); } diff --git a/Foundation/include/Poco/Platform_WIN32.h b/Foundation/include/Poco/Platform_WIN32.h index 3ab11041d..9ddc1f0ef 100644 --- a/Foundation/include/Poco/Platform_WIN32.h +++ b/Foundation/include/Poco/Platform_WIN32.h @@ -57,12 +57,18 @@ #undef _WIN32_WINNT #endif #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) #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif #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) //Windows Server 2003 with SP1, //Windows XP with SP2 _WIN32_WINNT_WS03 (0x0502)