1 //
2 // ODBCDB2Test.cpp
3 //
4 // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
5 // and Contributors.
6 //
7 // SPDX-License-Identifier:	BSL-1.0
8 //
9 
10 
11 #include "ODBCDB2Test.h"
12 #include "CppUnit/TestCaller.h"
13 #include "CppUnit/TestSuite.h"
14 #include "Poco/String.h"
15 #include "Poco/Format.h"
16 #include "Poco/Any.h"
17 #include "Poco/DynamicAny.h"
18 #include "Poco/Tuple.h"
19 #include "Poco/Exception.h"
20 #include "Poco/Data/LOB.h"
21 #include "Poco/Data/StatementImpl.h"
22 #include "Poco/Data/ODBC/Connector.h"
23 #include "Poco/Data/ODBC/Utility.h"
24 #include "Poco/Data/ODBC/Diagnostics.h"
25 #include "Poco/Data/ODBC/ODBCException.h"
26 #include "Poco/Data/ODBC/ODBCStatementImpl.h"
27 #include <sqltypes.h>
28 #include <iostream>
29 
30 
31 using namespace Poco::Data::Keywords;
32 using Poco::Data::DataException;
33 using Poco::Data::ODBC::Utility;
34 using Poco::Data::ODBC::ConnectionException;
35 using Poco::Data::ODBC::StatementException;
36 using Poco::Data::ODBC::StatementDiagnostics;
37 using Poco::format;
38 using Poco::Tuple;
39 using Poco::Any;
40 using Poco::AnyCast;
41 using Poco::DynamicAny;
42 using Poco::NotFoundException;
43 
44 
45 #define DB2_ODBC_DRIVER "IBM DB2 ODBC DRIVER - DB2COPY1"
46 #define DB2_DSN "PocoDataDB2Test"
47 #define DB2_SERVER POCO_ODBC_TEST_DATABASE_SERVER
48 #define DB2_PORT "50000"
49 #define DB2_DB "POCOTEST"
50 #define DB2_UID "db2admin"
51 #define DB2_PWD "db2admin"
52 
53 
54 ODBCTest::SessionPtr ODBCDB2Test::_pSession;
55 ODBCTest::ExecPtr    ODBCDB2Test::_pExecutor;
56 std::string          ODBCDB2Test::_driver = DB2_ODBC_DRIVER;
57 std::string          ODBCDB2Test::_dsn = DB2_DSN;
58 std::string          ODBCDB2Test::_uid = DB2_UID;
59 std::string          ODBCDB2Test::_pwd = DB2_PWD;
60 std::string          ODBCDB2Test::_connectString = "Driver=" DB2_ODBC_DRIVER ";"
61 	"Database=" DB2_DB ";"
62 	"Hostname=" DB2_SERVER ";"
63 	"Port=" DB2_PORT ";"
64 	"Protocol=TCPIP;"
65 	"Uid=" DB2_UID ";"
66 	"Pwd=" DB2_PWD ";";
67 
68 
ODBCDB2Test(const std::string & name)69 ODBCDB2Test::ODBCDB2Test(const std::string& name):
70 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
71 {
72 }
73 
74 
~ODBCDB2Test()75 ODBCDB2Test::~ODBCDB2Test()
76 {
77 }
78 
79 
testBareboneODBC()80 void ODBCDB2Test::testBareboneODBC()
81 {
82 	if (!_pSession) fail ("Test not available.");
83 
84 	std::string tableCreateString = "CREATE TABLE Test "
85 		"(First VARCHAR(30),"
86 		"Second VARCHAR(30),"
87 		"Third BLOB,"
88 		"Fourth INTEGER,"
89 		"Fifth FLOAT,"
90 		"Sixth TIMESTAMP)";
91 
92 	_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
93 	_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
94 	_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
95 	_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
96 
97 
98 	tableCreateString = "CREATE TABLE Test "
99 		"(First VARCHAR(30),"
100 		"Second INTEGER,"
101 		"Third FLOAT)";
102 
103 	_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
104 	_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
105 	_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
106 	_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
107 }
108 
109 
testBLOB()110 void ODBCDB2Test::testBLOB()
111 {
112 	if (!_pSession) fail ("Test not available.");
113 
114 	const std::size_t maxFldSize = 1000000;
115 	_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
116 	recreatePersonBLOBTable();
117 
118 	try
119 	{
120 		_pExecutor->blob(maxFldSize);
121 		fail ("must fail");
122 	}
123 	catch (DataException&)
124 	{
125 		_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize));
126 	}
127 
128 	for (int i = 0; i < 8;)
129 	{
130 		recreatePersonBLOBTable();
131 		_pSession->setFeature("autoBind", bindValue(i));
132 		_pSession->setFeature("autoExtract", bindValue(i+1));
133 		_pExecutor->blob(maxFldSize);
134 		i += 2;
135 	}
136 
137 	recreatePersonBLOBTable();
138 	try
139 	{
140 		_pExecutor->blob(maxFldSize+1);
141 		fail ("must fail");
142 	}
143 	catch (DataException&) { }
144 }
145 
146 
testFilter()147 void ODBCDB2Test::testFilter()
148 {
149 	if (!_pSession) fail ("Test not available.");
150 
151 	for (int i = 0; i < 8;)
152 	{
153 		recreateVectorsTable();
154 		_pSession->setFeature("autoBind", bindValue(i));
155 		_pSession->setFeature("autoExtract", bindValue(i+1));
156 		_pExecutor->filter("SELECT * FROM Vectors ORDER BY i0 ASC", "i0");
157 		i += 2;
158 	}
159 }
160 
161 
testStoredProcedure()162 void ODBCDB2Test::testStoredProcedure()
163 {
164 	if (!_pSession) fail ("Test not available.");
165 
166 	for (int k = 0; k < 8;)
167 	{
168 		_pSession->setFeature("autoBind", bindValue(k));
169 		_pSession->setFeature("autoExtract", bindValue(k+1));
170 
171 		dropObject("PROCEDURE", "storedProcedure");
172 		*_pSession << "CREATE PROCEDURE storedProcedure(OUT outParam INTEGER) "
173 			"BEGIN "
174 			" SET outParam = -1; "
175 			"END" , now;
176 
177 		int i = 0;
178 		*_pSession << "{call storedProcedure(?)}", out(i), now;
179 		assertTrue (-1 == i);
180 		dropObject("PROCEDURE", "storedProcedure");
181 
182 		*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
183 			"BEGIN "
184 			" SET outParam = inParam*inParam; "
185 			"END" , now;
186 
187 
188 		i = 2;
189 		int j = 0;
190 		*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
191 		assertTrue (4 == j);
192 		dropObject("PROCEDURE", "storedProcedure");
193 
194 		*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
195 			"BEGIN "
196 			" SET ioParam = ioParam*ioParam; "
197 			"END" , now;
198 
199 		i = 2;
200 		*_pSession << "{call storedProcedure(?)}", io(i), now;
201 		assertTrue (4 == i);
202 		dropObject("PROCEDURE", "storedProcedure");
203 
204 		//TIMESTAMP is not supported as stored procedure parameter in DB2
205 		//(SQL0182N An expression with a datetime value or a labeled duration is not valid.)
206 
207 		*_pSession << "CREATE PROCEDURE storedProcedure(inParam VARCHAR(1000), OUT outParam VARCHAR(1000)) "
208 			"BEGIN "
209 			" SET outParam = inParam; "
210 			"END" , now;
211 
212 		std::string inParam =
213 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
214 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
215 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
216 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
217 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
218 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
219 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
220 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
221 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
222 		std::string outParam;
223 		*_pSession << "{call storedProcedure(?,?)}", in(inParam), out(outParam), now;
224 		assertTrue (inParam == outParam);
225 		dropObject("PROCEDURE", "storedProcedure");
226 
227 		k += 2;
228 	}
229 }
230 
231 
testStoredProcedureAny()232 void ODBCDB2Test::testStoredProcedureAny()
233 {
234 	if (!_pSession) fail ("Test not available.");
235 
236 	for (int k = 0; k < 8;)
237 	{
238 		_pSession->setFeature("autoBind", bindValue(k));
239 		_pSession->setFeature("autoExtract", bindValue(k+1));
240 
241 		Any i = 2;
242 		Any j = 0;
243 
244 		*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
245 			"BEGIN "
246 			" SET outParam = inParam*inParam; "
247 			"END" , now;
248 
249 		*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
250 		assertTrue (4 == AnyCast<int>(j));
251 		*_pSession << "DROP PROCEDURE storedProcedure;", now;
252 
253 		*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
254 			"BEGIN "
255 			" SET ioParam = ioParam*ioParam; "
256 			"END" , now;
257 
258 		i = 2;
259 		*_pSession << "{call storedProcedure(?)}", io(i), now;
260 		assertTrue (4 == AnyCast<int>(i));
261 		dropObject("PROCEDURE", "storedProcedure");
262 
263 		k += 2;
264 	}
265 }
266 
267 
testStoredProcedureDynamicAny()268 void ODBCDB2Test::testStoredProcedureDynamicAny()
269 {
270 	if (!_pSession) fail ("Test not available.");
271 
272 	for (int k = 0; k < 8;)
273 	{
274 		_pSession->setFeature("autoBind", bindValue(k));
275 
276 		DynamicAny i = 2;
277 		DynamicAny j = 0;
278 
279 		*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
280 			"BEGIN "
281 			" SET outParam = inParam*inParam; "
282 			"END" , now;
283 
284 		*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
285 		assertTrue (4 == j);
286 		*_pSession << "DROP PROCEDURE storedProcedure;", now;
287 
288 		*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
289 			"BEGIN "
290 			" SET ioParam = ioParam*ioParam; "
291 			"END" , now;
292 
293 		i = 2;
294 		*_pSession << "{call storedProcedure(?)}", io(i), now;
295 		assertTrue (4 == i);
296 		dropObject("PROCEDURE", "storedProcedure");
297 
298 		k += 2;
299 	}
300 }
301 
302 
testStoredFunction()303 void ODBCDB2Test::testStoredFunction()
304 {
305 	if (!_pSession) fail ("Test not available.");
306 
307 	for (int k = 0; k < 8;)
308 	{
309 		_pSession->setFeature("autoBind", bindValue(k));
310 		_pSession->setFeature("autoExtract", bindValue(k+1));
311 
312 		dropObject("PROCEDURE", "storedFunction");
313 		*_pSession << "CREATE PROCEDURE storedFunction() "
314 			"BEGIN "
315 			"  RETURN -1; "
316 			"END" , now;
317 
318 		int i = 0;
319 		*_pSession << "{? = call storedFunction()}", out(i), now;
320 		assertTrue (-1 == i);
321 		dropObject("PROCEDURE", "storedFunction");
322 
323 		*_pSession << "CREATE PROCEDURE storedFunction(inParam INTEGER) "
324 			"BEGIN "
325 			" RETURN inParam*inParam; "
326 			"END" , now;
327 
328 		i = 2;
329 		int result = 0;
330 		*_pSession << "{? = call storedFunction(?)}", out(result), in(i), now;
331 		assertTrue (4 == result);
332 		dropObject("PROCEDURE", "storedFunction");
333 
334 		*_pSession << "CREATE PROCEDURE storedFunction(inParam INTEGER, OUT outParam INTEGER) "
335 			"BEGIN "
336 			" SET outParam = inParam*inParam; "
337 			" RETURN outParam; "
338 			"END" , now;
339 
340 		i = 2;
341 		int j = 0;
342 		result = 0;
343 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), in(i), out(j), now;
344 		assertTrue (4 == j);
345 		assertTrue (j == result);
346 		dropObject("PROCEDURE", "storedFunction");
347 
348 		*_pSession << "CREATE PROCEDURE storedFunction(INOUT param1 INTEGER, INOUT param2 INTEGER) "
349 			"BEGIN "
350 			" DECLARE temp INTEGER;"
351 			" SET temp = param1; "
352 			" SET param1 = param2; "
353 			" SET param2 = temp; "
354 			" RETURN param1 + param2; "
355 			"END" , now;
356 
357 		i = 1;
358 		j = 2;
359 		result = 0;
360 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now;
361 		assertTrue (1 == j);
362 		assertTrue (2 == i);
363 		assertTrue (3 == result);
364 
365 		Tuple<int, int> params(1, 2);
366 		assertTrue (1 == params.get<0>());
367 		assertTrue (2 == params.get<1>());
368 		result = 0;
369 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(params), now;
370 		assertTrue (1 == params.get<1>());
371 		assertTrue (2 == params.get<0>());
372 		assertTrue (3 == result);
373 
374 		dropObject("PROCEDURE", "storedFunction");
375 
376 		_pSession->setFeature("autoBind", true);
377 
378 		*_pSession << "CREATE PROCEDURE storedFunction(inParam VARCHAR(10), OUT outParam VARCHAR(10)) "
379 			"BEGIN "
380 			" SET outParam = inParam; "
381 			" RETURN LENGTH(outParam);"//DB2 allows only integer as return type
382 			"END" , now;
383 
384 		std::string inParam = "123456789";
385 		std::string outParam;
386 		int ret;
387 		*_pSession << "{? = call storedFunction(?,?)}", out(ret), in(inParam), out(outParam), now;
388 		assertTrue (inParam == outParam);
389 		assertTrue (ret == inParam.size());
390 		dropObject("PROCEDURE", "storedFunction");
391 
392 		k += 2;
393 	}
394 }
395 
396 
dropObject(const std::string & type,const std::string & name)397 void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
398 {
399 	try
400 	{
401 		*_pSession << format("DROP %s %s", type, name), now;
402 	}
403 	catch (StatementException& ex)
404 	{
405 		bool ignoreError = false;
406 		const StatementDiagnostics::FieldVec& flds = ex.diagnostics().fields();
407 		StatementDiagnostics::Iterator it = flds.begin();
408 		for (; it != flds.end(); ++it)
409 		{
410 			if (-204 == it->_nativeError)//(table does not exist)
411 			{
412 				ignoreError = true;
413 				break;
414 			}
415 		}
416 
417 		if (!ignoreError) throw;
418 	}
419 }
420 
421 
recreateNullableTable()422 void ODBCDB2Test::recreateNullableTable()
423 {
424 	dropObject("TABLE", "NullableTest");
425 	try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
426 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
427 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
428 }
429 
430 
recreatePersonTable()431 void ODBCDB2Test::recreatePersonTable()
432 {
433 	dropObject("TABLE", "Person");
434 	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
435 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
436 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
437 }
438 
439 
recreatePersonBLOBTable()440 void ODBCDB2Test::recreatePersonBLOBTable()
441 {
442 	dropObject("TABLE", "Person");
443 	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
444 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
445 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
446 }
447 
448 
recreatePersonDateTable()449 void ODBCDB2Test::recreatePersonDateTable()
450 {
451 	dropObject("TABLE", "Person");
452 	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
453 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
454 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
455 }
456 
457 
recreatePersonTimeTable()458 void ODBCDB2Test::recreatePersonTimeTable()
459 {
460 	dropObject("TABLE", "Person");
461 	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
462 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
463 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
464 }
465 
466 
recreatePersonDateTimeTable()467 void ODBCDB2Test::recreatePersonDateTimeTable()
468 {
469 	dropObject("TABLE", "Person");
470 	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
471 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
472 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
473 }
474 
475 
recreateIntsTable()476 void ODBCDB2Test::recreateIntsTable()
477 {
478 	dropObject("TABLE", "Strings");
479 	try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
480 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
481 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
482 }
483 
484 
recreateStringsTable()485 void ODBCDB2Test::recreateStringsTable()
486 {
487 	dropObject("TABLE", "Strings");
488 	try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; }
489 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
490 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
491 }
492 
493 
recreateFloatsTable()494 void ODBCDB2Test::recreateFloatsTable()
495 {
496 	dropObject("TABLE", "Strings");
497 	try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; }
498 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
499 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
500 }
501 
502 
recreateTuplesTable()503 void ODBCDB2Test::recreateTuplesTable()
504 {
505 	dropObject("TABLE", "Tuples");
506 	try { *_pSession << "CREATE TABLE Tuples "
507 		"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
508 		"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
509 		"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
510 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateTuplesTable()"); }
511 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateTuplesTable()"); }
512 }
513 
514 
recreateVectorsTable()515 void ODBCDB2Test::recreateVectorsTable()
516 {
517 	dropObject("TABLE", "Vectors");
518 	try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
519 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
520 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
521 }
522 
523 
recreateAnysTable()524 void ODBCDB2Test::recreateAnysTable()
525 {
526 	dropObject("TABLE", "Anys");
527 	try { *_pSession << "CREATE TABLE Anys (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
528 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
529 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
530 }
531 
532 
recreateNullsTable(const std::string & notNull)533 void ODBCDB2Test::recreateNullsTable(const std::string& notNull)
534 {
535 	dropObject("TABLE", "NullTest");
536 	try { *_pSession << format("CREATE TABLE NullTest (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",
537 		notNull,
538 		notNull,
539 		notNull), now; }
540 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); }
541 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); }
542 }
543 
544 
recreateMiscTable()545 void ODBCDB2Test::recreateMiscTable()
546 {
547 	dropObject("TABLE", "MiscTest");
548 	try
549 	{
550 		session() << "CREATE TABLE MiscTest "
551 			"(First VARCHAR(30),"
552 			"Second BLOB,"
553 			"Third INTEGER,"
554 			"Fourth FLOAT,"
555 			"Fifth TIMESTAMP)", now;
556 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
557 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
558 }
559 
560 
recreateLogTable()561 void ODBCDB2Test::recreateLogTable()
562 {
563 	dropObject("TABLE", "T_POCO_LOG");
564 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
565 
566 	try
567 	{
568 		std::string sql = "CREATE TABLE %s "
569 			"(Source VARCHAR(100),"
570 			"Name VARCHAR(100),"
571 			"ProcessId INTEGER,"
572 			"Thread VARCHAR(100), "
573 			"ThreadId INTEGER,"
574 			"Priority INTEGER,"
575 			"Text VARCHAR(100),"
576 			"DateTime TIMESTAMP)";
577 
578 		session() << sql, "T_POCO_LOG", now;
579 		session() << sql, "T_POCO_LOG_ARCHIVE", now;
580 
581 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
582 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
583 }
584 
585 
suite()586 CppUnit::Test* ODBCDB2Test::suite()
587 {
588 	if ((_pSession = init(_driver, _dsn, _uid, _pwd, _connectString)))
589 	{
590 		std::cout << "*** Connected to [" << _driver << "] test database." << std::endl;
591 
592 		_pExecutor = new SQLExecutor(_driver + " SQL Executor", _pSession);
593 
594 		CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ODBCDB2Test");
595 
596 		CppUnit_addTest(pSuite, ODBCDB2Test, testBareboneODBC);
597 		CppUnit_addTest(pSuite, ODBCDB2Test, testZeroRows);
598 		CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccess);
599 		CppUnit_addTest(pSuite, ODBCDB2Test, testComplexType);
600 		CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessVector);
601 		CppUnit_addTest(pSuite, ODBCDB2Test, testComplexTypeVector);
602 		CppUnit_addTest(pSuite, ODBCDB2Test, testSharedPtrComplexTypeVector);
603 		CppUnit_addTest(pSuite, ODBCDB2Test, testAutoPtrComplexTypeVector);
604 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertVector);
605 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertEmptyVector);
606 		CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessList);
607 		CppUnit_addTest(pSuite, ODBCDB2Test, testComplexTypeList);
608 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertList);
609 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertEmptyList);
610 		CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessDeque);
611 		CppUnit_addTest(pSuite, ODBCDB2Test, testComplexTypeDeque);
612 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertDeque);
613 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertEmptyDeque);
614 		CppUnit_addTest(pSuite, ODBCDB2Test, testAffectedRows);
615 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertSingleBulk);
616 		CppUnit_addTest(pSuite, ODBCDB2Test, testInsertSingleBulkVec);
617 		CppUnit_addTest(pSuite, ODBCDB2Test, testLimit);
618 		CppUnit_addTest(pSuite, ODBCDB2Test, testLimitOnce);
619 		CppUnit_addTest(pSuite, ODBCDB2Test, testLimitPrepare);
620 		CppUnit_addTest(pSuite, ODBCDB2Test, testLimitZero);
621 		CppUnit_addTest(pSuite, ODBCDB2Test, testPrepare);
622 		CppUnit_addTest(pSuite, ODBCDB2Test, testBulk);
623 		CppUnit_addTest(pSuite, ODBCDB2Test, testBulkPerformance);
624 		CppUnit_addTest(pSuite, ODBCDB2Test, testSetSimple);
625 		CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplex);
626 		CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplexUnique);
627 		CppUnit_addTest(pSuite, ODBCDB2Test, testMultiSetSimple);
628 		CppUnit_addTest(pSuite, ODBCDB2Test, testMultiSetComplex);
629 		CppUnit_addTest(pSuite, ODBCDB2Test, testMapComplex);
630 		CppUnit_addTest(pSuite, ODBCDB2Test, testMapComplexUnique);
631 		CppUnit_addTest(pSuite, ODBCDB2Test, testMultiMapComplex);
632 		CppUnit_addTest(pSuite, ODBCDB2Test, testSelectIntoSingle);
633 		CppUnit_addTest(pSuite, ODBCDB2Test, testSelectIntoSingleStep);
634 		CppUnit_addTest(pSuite, ODBCDB2Test, testSelectIntoSingleFail);
635 		CppUnit_addTest(pSuite, ODBCDB2Test, testLowerLimitOk);
636 		CppUnit_addTest(pSuite, ODBCDB2Test, testLowerLimitFail);
637 		CppUnit_addTest(pSuite, ODBCDB2Test, testCombinedLimits);
638 		CppUnit_addTest(pSuite, ODBCDB2Test, testCombinedIllegalLimits);
639 		CppUnit_addTest(pSuite, ODBCDB2Test, testRange);
640 		CppUnit_addTest(pSuite, ODBCDB2Test, testIllegalRange);
641 		CppUnit_addTest(pSuite, ODBCDB2Test, testSingleSelect);
642 		CppUnit_addTest(pSuite, ODBCDB2Test, testEmptyDB);
643 		CppUnit_addTest(pSuite, ODBCDB2Test, testBLOB);
644 		CppUnit_addTest(pSuite, ODBCDB2Test, testBLOBContainer);
645 		CppUnit_addTest(pSuite, ODBCDB2Test, testBLOBStmt);
646 		CppUnit_addTest(pSuite, ODBCDB2Test, testDate);
647 		CppUnit_addTest(pSuite, ODBCDB2Test, testTime);
648 		CppUnit_addTest(pSuite, ODBCDB2Test, testDateTime);
649 		CppUnit_addTest(pSuite, ODBCDB2Test, testFloat);
650 		CppUnit_addTest(pSuite, ODBCDB2Test, testDouble);
651 		CppUnit_addTest(pSuite, ODBCDB2Test, testTuple);
652 		CppUnit_addTest(pSuite, ODBCDB2Test, testTupleVector);
653 		CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
654 		CppUnit_addTest(pSuite, ODBCDB2Test, testFilter);
655 		CppUnit_addTest(pSuite, ODBCDB2Test, testInternalBulkExtraction);
656 		CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
657 		CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
658 		CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureAny);
659 		CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureDynamicAny);
660 		CppUnit_addTest(pSuite, ODBCDB2Test, testStoredFunction);
661 		CppUnit_addTest(pSuite, ODBCDB2Test, testNull);
662 		CppUnit_addTest(pSuite, ODBCDB2Test, testRowIterator);
663 		CppUnit_addTest(pSuite, ODBCDB2Test, testAsync);
664 		CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
665 		CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
666 		CppUnit_addTest(pSuite, ODBCDB2Test, testMultipleResults);
667 		CppUnit_addTest(pSuite, ODBCDB2Test, testSQLChannel);
668 		CppUnit_addTest(pSuite, ODBCDB2Test, testSQLLogger);
669 		CppUnit_addTest(pSuite, ODBCDB2Test, testSessionTransaction);
670 		CppUnit_addTest(pSuite, ODBCDB2Test, testTransaction);
671 		CppUnit_addTest(pSuite, ODBCDB2Test, testTransactor);
672 		CppUnit_addTest(pSuite, ODBCDB2Test, testNullable);
673 		CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
674 
675 		return pSuite;
676 	}
677 
678 	return 0;
679 }
680