1 //
2 // SQLiteTest.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 "SQLiteTest.h"
12 #include "CppUnit/TestCaller.h"
13 #include "CppUnit/TestSuite.h"
14 #include "Poco/Data/Date.h"
15 #include "Poco/Data/Time.h"
16 #include "Poco/Data/LOB.h"
17 #include "Poco/Data/Statement.h"
18 #include "Poco/Data/RecordSet.h"
19 #include "Poco/Data/SQLChannel.h"
20 #include "Poco/Data/SessionFactory.h"
21 #include "Poco/Data/SQLite/Connector.h"
22 #include "Poco/Data/SQLite/Utility.h"
23 #include "Poco/Data/SQLite/Notifier.h"
24 #include "Poco/Data/SQLite/Connector.h"
25 #include "Poco/Dynamic/Var.h"
26 #include "Poco/Data/TypeHandler.h"
27 #include "Poco/Nullable.h"
28 #include "Poco/Data/Transaction.h"
29 #include "Poco/Data/DataException.h"
30 #include "Poco/Data/SQLite/SQLiteException.h"
31 #include "Poco/Tuple.h"
32 #include "Poco/Any.h"
33 #include "Poco/SharedPtr.h"
34 #include "Poco/DynamicAny.h"
35 #include "Poco/DateTime.h"
36 #include "Poco/Logger.h"
37 #include "Poco/Message.h"
38 #include "Poco/Thread.h"
39 #include "Poco/AutoPtr.h"
40 #include "Poco/Exception.h"
41 #include "Poco/RefCountedObject.h"
42 #include "Poco/Stopwatch.h"
43 #include "Poco/Delegate.h"
44 #include <iostream>
45
46
47 using namespace Poco::Data::Keywords;
48 using Poco::Data::Session;
49 using Poco::Data::Statement;
50 using Poco::Data::RecordSet;
51 using Poco::Data::Column;
52 using Poco::Data::Row;
53 using Poco::Data::SQLChannel;
54 using Poco::Data::LimitException;
55 using Poco::Data::ConnectionFailedException;
56 using Poco::Data::CLOB;
57 using Poco::Data::Date;
58 using Poco::Data::Time;
59 using Poco::Data::Transaction;
60 using Poco::Data::AbstractExtractionVec;
61 using Poco::Data::AbstractExtractionVecVec;
62 using Poco::Data::AbstractBindingVec;
63 using Poco::Data::NotConnectedException;
64 using Poco::Data::SQLite::Notifier;
65 using Poco::Nullable;
66 using Poco::Tuple;
67 using Poco::Any;
68 using Poco::AnyCast;
69 using Poco::DynamicAny;
70 using Poco::DateTime;
71 using Poco::Logger;
72 using Poco::Message;
73 using Poco::AutoPtr;
74 using Poco::Thread;
75 using Poco::format;
76 using Poco::InvalidAccessException;
77 using Poco::RangeException;
78 using Poco::BadCastException;
79 using Poco::NotFoundException;
80 using Poco::NullPointerException;
81 using Poco::TimeoutException;
82 using Poco::NotImplementedException;
83 using Poco::Data::SQLite::ConstraintViolationException;
84 using Poco::Data::SQLite::ParameterCountMismatchException;
85 using Poco::Int32;
86 using Poco::Int64;
87 using Poco::Dynamic::Var;
88 using Poco::Data::SQLite::Utility;
89 using Poco::delegate;
90
91
92 class Person
93 {
94 public:
Person()95 Person(){_age = 0;}
Person(const std::string & ln,const std::string & fn,const std::string & adr,int a)96 Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):_lastName(ln), _firstName(fn), _address(adr), _age(a)
97 {
98 }
operator ==(const Person & other) const99 bool operator==(const Person& other) const
100 {
101 return _lastName == other._lastName && _firstName == other._firstName && _address == other._address && _age == other._age;
102 }
103
operator <(const Person & p) const104 bool operator < (const Person& p) const
105 {
106 if (_age < p._age)
107 return true;
108 if (_lastName < p._lastName)
109 return true;
110 if (_firstName < p._firstName)
111 return true;
112 return (_address < p._address);
113 }
114
operator ()() const115 const std::string& operator () () const
116 /// This method is required so we can extract data to a map!
117 {
118 // we choose the lastName as examplary key
119 return _lastName;
120 }
121
getLastName() const122 const std::string& getLastName() const
123 {
124 return _lastName;
125 }
126
setLastName(const std::string & lastName)127 void setLastName(const std::string& lastName)
128 {
129 _lastName = lastName;
130 }
131
getFirstName() const132 const std::string& getFirstName() const
133 {
134 return _firstName;
135 }
136
setFirstName(const std::string & firstName)137 void setFirstName(const std::string& firstName)
138 {
139 _firstName = firstName;
140 }
141
getAddress() const142 const std::string& getAddress() const
143 {
144 return _address;
145 }
146
setAddress(const std::string & address)147 void setAddress(const std::string& address)
148 {
149 _address = address;
150 }
151
getAge() const152 const int& getAge() const
153 {
154 return _age;
155 }
156
setAge(const int & age)157 void setAge(const int& age)
158 {
159 _age = age;
160 }
161
162 private:
163 std::string _lastName;
164 std::string _firstName;
165 std::string _address;
166 int _age;
167 };
168
169
170 namespace Poco {
171 namespace Data {
172
173
174 template <>
175 class TypeHandler<Person>
176 {
177 public:
bind(std::size_t pos,const Person & obj,AbstractBinder::Ptr pBinder,AbstractBinder::Direction dir)178 static void bind(std::size_t pos, const Person& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
179 {
180 // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
181 poco_assert_dbg (!pBinder.isNull());
182 pBinder->bind(pos++, obj.getLastName(), dir);
183 pBinder->bind(pos++, obj.getFirstName(), dir);
184 pBinder->bind(pos++, obj.getAddress(), dir);
185 pBinder->bind(pos++, obj.getAge(), dir);
186 }
187
prepare(std::size_t pos,const Person & obj,AbstractPreparator::Ptr pPrepare)188 static void prepare(std::size_t pos, const Person& obj, AbstractPreparator::Ptr pPrepare)
189 {
190 // no-op (SQLite is prepare-less connector)
191 }
192
size()193 static std::size_t size()
194 {
195 return 4;
196 }
197
extract(std::size_t pos,Person & obj,const Person & defVal,AbstractExtractor::Ptr pExt)198 static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor::Ptr pExt)
199 {
200 poco_assert_dbg (!pExt.isNull());
201 std::string lastName;
202 std::string firstName;
203 std::string address;
204 int age;
205
206 if (pExt->extract(pos++, lastName))
207 obj.setLastName(lastName);
208 else
209 obj.setLastName(defVal.getLastName());
210
211 if (pExt->extract(pos++, firstName))
212 obj.setFirstName(firstName);
213 else
214 obj.setFirstName(defVal.getFirstName());
215
216 if (pExt->extract(pos++, address))
217 obj.setAddress(address);
218 else
219 obj.setAddress(defVal.getAddress());
220
221 if (pExt->extract(pos++, age))
222 obj.setAge(age);
223 else
224 obj.setAge(defVal.getAge());
225 }
226
227 private:
228 TypeHandler();
229 ~TypeHandler();
230 TypeHandler(const TypeHandler&);
231 TypeHandler& operator=(const TypeHandler&);
232 };
233
234
235 } } // namespace Poco::Data
236
237
238 int SQLiteTest::_insertCounter;
239 int SQLiteTest::_updateCounter;
240 int SQLiteTest::_deleteCounter;
241
242
SQLiteTest(const std::string & name)243 SQLiteTest::SQLiteTest(const std::string& name): CppUnit::TestCase(name)
244 {
245 Poco::Data::SQLite::Connector::registerConnector();
246 }
247
248
~SQLiteTest()249 SQLiteTest::~SQLiteTest()
250 {
251 Poco::Data::SQLite::Connector::unregisterConnector();
252 }
253
254
testBinding()255 void SQLiteTest::testBinding()
256 {
257 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
258 assertTrue (tmp.getConnectionTimeout() == Session::LOGIN_TIMEOUT_DEFAULT);
259 tmp.setConnectionTimeout(5);
260 assertTrue (tmp.getConnectionTimeout() == 5);
261 assertTrue (tmp.isConnected());
262 std::string tableName("Simpsons");
263 std::string lastName("Simpson");
264 std::string firstName("Bart");
265 std::string address("Springfield");
266 int age = 12;
267
268 std::string& rLastName(lastName);
269 std::string& rFirstName(firstName);
270 std::string& rAddress(address);
271 int& rAge = age;
272
273 const std::string& crLastName(lastName);
274 const std::string& crFirstName(firstName);
275 const std::string& crAddress(address);
276 const int& crAge = age;
277
278 int count = 0;
279 std::string result;
280
281 tmp << "DROP TABLE IF EXISTS Simpsons", now;
282 tmp << "CREATE TABLE IF NOT EXISTS Simpsons (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
283 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
284 assertTrue (result == tableName);
285
286 // following should not compile:
287 //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use("Simpson"), use("Bart"), use("Springfield"), use(age), now;
288 //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(lastName), use(firstName), use(address), use(12), now;
289 //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef(lastName), useRef(firstName), useRef(address), useRef(12), now;
290
291 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef("Simpson"), useRef("Bart"), useRef("Springfield"), useRef(age), now;
292
293 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(rLastName), use(rFirstName), use(rAddress), use(rAge), now;
294 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef(crLastName), useRef(crFirstName), useRef(crAddress), useRef(crAge), now;
295 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind("Simpson"), bind("Bart"), bind("Springfield"), bind(12), now;
296 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind(rLastName), bind(rFirstName), bind(rAddress), bind(rAge), now;
297 tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind(crLastName), bind(crFirstName), bind(crAddress), bind(crAge), now;
298
299 tmp << "SELECT COUNT(*) FROM Simpsons", into(count), now;
300 assertTrue (6 == count);
301 }
302
303
testZeroRows()304 void SQLiteTest::testZeroRows()
305 {
306 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
307 tmp << "DROP TABLE IF EXISTS ZeroTest", now;
308 tmp << "CREATE TABLE IF NOT EXISTS ZeroTest (zt INTEGER(3))", now;
309 Statement stmt = (tmp << "SELECT * FROM ZeroTest");
310 assertTrue (0 == stmt.execute());
311 }
312
313
testSimpleAccess()314 void SQLiteTest::testSimpleAccess()
315 {
316 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
317 assertTrue (tmp.isConnected());
318 std::string tableName("Person");
319 std::string lastName("lastname");
320 std::string firstName("firstname");
321 std::string address("Address");
322 int age = 133132;
323 int count = 0;
324 std::string result;
325 tmp << "DROP TABLE IF EXISTS Person", now;
326 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
327 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
328 assertTrue (result == tableName);
329
330 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
331 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
332 assertTrue (count == 1);
333 tmp << "SELECT LastName FROM PERSON", into(result), now;
334 assertTrue (lastName == result);
335 tmp << "SELECT Age FROM PERSON", into(count), now;
336 assertTrue (count == age);
337 tmp << "UPDATE PERSON SET Age = -1", now;
338 tmp << "SELECT Age FROM PERSON", into(age), now;
339 assertTrue (-1 == age);
340 tmp.close();
341 assertTrue (!tmp.isConnected());
342 }
343
344
testInMemory()345 void SQLiteTest::testInMemory()
346 {
347 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
348 assertTrue (tmp.isConnected());
349 std::string tableName("Person");
350 std::string lastName("lastname");
351 std::string firstName("firstname");
352 std::string address("Address");
353 int age = 133132;
354 int count = 0;
355 std::string result;
356 tmp << "DROP TABLE IF EXISTS Person", now;
357 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
358 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
359 assertTrue (result == tableName);
360
361 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
362
363 // load db from file to memory
364 Session mem (Poco::Data::SQLite::Connector::KEY, ":memory:");
365 assertTrue (Poco::Data::SQLite::Utility::fileToMemory(mem, "dummy.db"));
366
367 mem << "SELECT COUNT(*) FROM PERSON", into(count), now;
368 assertTrue (count == 1);
369 mem << "SELECT LastName FROM PERSON", into(result), now;
370 assertTrue (lastName == result);
371 mem << "SELECT Age FROM PERSON", into(count), now;
372 assertTrue (count == age);
373 mem << "UPDATE PERSON SET Age = -1", now;
374 mem << "SELECT Age FROM PERSON", into(age), now;
375 assertTrue (-1 == age);
376
377 // save db from memory to file on the disk
378 Session dsk (Poco::Data::SQLite::Connector::KEY, "dsk.db");
379 assertTrue (Poco::Data::SQLite::Utility::memoryToFile("dsk.db", mem));
380
381 dsk << "SELECT COUNT(*) FROM PERSON", into(count), now;
382 assertTrue (count == 1);
383 dsk << "SELECT LastName FROM PERSON", into(result), now;
384 assertTrue (lastName == result);
385 dsk << "SELECT Age FROM PERSON", into(count), now;
386 assertTrue (count == age);
387 dsk << "UPDATE PERSON SET Age = -1", now;
388 dsk << "SELECT Age FROM PERSON", into(age), now;
389 assertTrue (-1 == age);
390
391 tmp.close();
392 mem.close();
393 dsk.close();
394
395 assertTrue (!tmp.isConnected());
396 assertTrue (!mem.isConnected());
397 assertTrue (!dsk.isConnected());
398 }
399
400
testNullCharPointer()401 void SQLiteTest::testNullCharPointer()
402 {
403 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
404 std::string lastName("lastname");
405 int age = 100;
406 int count = 100;
407 std::string result;
408 tmp << "DROP TABLE IF EXISTS Person", now;
409 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
410
411 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)",
412 bind(lastName),
413 bind("firstname"),
414 bind("Address"),
415 bind(0), now;
416
417 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
418 assertTrue (count == 1);
419 tmp << "SELECT LastName FROM PERSON", into(result), now;
420 assertTrue (lastName == result);
421 tmp << "SELECT Age FROM PERSON", into(age), now;
422 assertTrue (0 == age);
423
424 try
425 {
426 const char* pc = 0;
427 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)",
428 bind("lastname"),
429 bind("firstname"),
430 bind("Address"), bind(pc), now;
431 fail ("must fail");
432 } catch (NullPointerException&) { }
433
434 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
435 assertTrue (count == 1);
436 tmp << "SELECT LastName FROM PERSON", into(result), now;
437 assertTrue (lastName == result);
438 tmp << "SELECT Age FROM PERSON", into(age), now;
439 assertTrue (0 == age);
440 }
441
442
testInsertCharPointer()443 void SQLiteTest::testInsertCharPointer()
444 {
445 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
446 std::string tableName("Person");
447 std::string lastName("lastname");
448 std::string firstName("firstname");
449 std::string address("Address");
450 int age = 133132;
451 int count = 0;
452 std::string result;
453 tmp << "DROP TABLE IF EXISTS Person", now;
454 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
455
456 const char* pc = 0;
457 try
458 {
459 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind(pc), now;
460 fail ("must fail");
461 } catch (NullPointerException&) { }
462
463 pc = (const char*) std::calloc(9, sizeof(char));
464 poco_check_ptr (pc);
465 std::strncpy((char*) pc, "lastname", 8);
466 Statement stmt = (tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)",
467 bind(pc),
468 bind("firstname"),
469 bind("Address"),
470 bind(133132));
471
472 std::free((void*) pc); pc = 0;
473 assertTrue (1 == stmt.execute());
474
475 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
476 assertTrue (count == 1);
477 tmp << "SELECT LastName FROM PERSON", into(result), now;
478 assertTrue (lastName == result);
479 tmp << "SELECT Age FROM PERSON", into(count), now;
480 assertTrue (count == age);
481 }
482
483
testInsertCharPointer2()484 void SQLiteTest::testInsertCharPointer2()
485 {
486 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
487 std::string tableName("Person");
488 std::string lastName("lastname");
489 std::string firstName("firstname");
490 std::string address("Address");
491 int age = 133132;
492 int count = 0;
493 std::string result;
494 tmp << "DROP TABLE IF EXISTS Person", now;
495 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
496
497 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)",
498 bind("lastname"),
499 bind("firstname"),
500 bind("Address"),
501 bind(133132), now;
502 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
503 assertTrue (count == 1);
504 Statement stmt1 = (tmp << "SELECT LastName FROM PERSON", into(result));
505 stmt1.execute();
506 assertTrue (lastName == result);
507 count = 0;
508 Statement stmt2 = (tmp << "SELECT Age FROM PERSON", into(count));
509 stmt2.execute();
510 assertTrue (count == age);
511 }
512
513
testComplexType()514 void SQLiteTest::testComplexType()
515 {
516 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
517 Person p1("LN1", "FN1", "ADDR1", 1);
518 Person p2("LN2", "FN2", "ADDR2", 2);
519 tmp << "DROP TABLE IF EXISTS Person", now;
520 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
521 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p1), now;
522 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p2), now;
523 int count = 0;
524 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
525 assertTrue (count == 2);
526
527 Person c1;
528 Person c2;
529 tmp << "SELECT * FROM PERSON WHERE LASTNAME = :ln", into(c1), useRef(p1.getLastName()), now;
530 assertTrue (c1 == p1);
531
532 tmp << "DROP TABLE IF EXISTS Person", now;
533 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName1 VARCHAR(30), FirstName1 VARCHAR, Address1 VARCHAR, Age1 INTEGER(3),"
534 "LastName2 VARCHAR(30), FirstName2 VARCHAR, Address2 VARCHAR, Age2 INTEGER(3))", now;
535
536 Tuple<Person,Person> t(p1,p2);
537
538 tmp << "INSERT INTO PERSON VALUES(:ln1, :fn1, :ad1, :age1, :ln2, :fn2, :ad2, :age2)", use(t), now;
539
540 Tuple<Person,Person> ret;
541 assertTrue (ret != t);
542 tmp << "SELECT * FROM PERSON", into(ret), now;
543 assertTrue (ret == t);
544 }
545
546
547
testSimpleAccessVector()548 void SQLiteTest::testSimpleAccessVector()
549 {
550 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
551 std::vector<std::string> lastNames;
552 std::vector<std::string> firstNames;
553 std::vector<std::string> addresses;
554 std::vector<int> ages;
555 std::string tableName("Person");
556 lastNames.push_back("LN1");
557 lastNames.push_back("LN2");
558 firstNames.push_back("FN1");
559 firstNames.push_back("FN2");
560 addresses.push_back("ADDR1");
561 addresses.push_back("ADDR2");
562 ages.push_back(1);
563 ages.push_back(2);
564 int count = 0;
565 std::string result;
566 tmp << "DROP TABLE IF EXISTS Person", now;
567 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
568
569 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
570 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
571 assertTrue (count == 2);
572
573 std::vector<std::string> lastNamesR;
574 std::vector<std::string> firstNamesR;
575 std::vector<std::string> addressesR;
576 std::vector<int> agesR;
577 tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now;
578 assertTrue (ages == agesR);
579 assertTrue (lastNames == lastNamesR);
580 assertTrue (firstNames == firstNamesR);
581 assertTrue (addresses == addressesR);
582 }
583
584
testComplexTypeVector()585 void SQLiteTest::testComplexTypeVector()
586 {
587 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
588 std::vector<Person> people;
589 people.push_back(Person("LN1", "FN1", "ADDR1", 1));
590 people.push_back(Person("LN2", "FN2", "ADDR2", 2));
591 tmp << "DROP TABLE IF EXISTS Person", now;
592 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
593 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
594 int count = 0;
595 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
596 assertTrue (count == 2);
597
598 std::vector<Person> result;
599 tmp << "SELECT * FROM PERSON", into(result), now;
600 assertTrue (result == people);
601 }
602
603
testSharedPtrComplexTypeVector()604 void SQLiteTest::testSharedPtrComplexTypeVector()
605 {
606 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
607 std::vector<Poco::SharedPtr<Person> > people;
608 people.push_back(new Person("LN1", "FN1", "ADDR1", 1));
609 people.push_back(new Person("LN2", "FN2", "ADDR2", 2));
610 tmp << "DROP TABLE IF EXISTS Person", now;
611 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
612 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
613 int count = 0;
614 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
615 assertTrue (count == 2);
616
617 std::vector<Poco::SharedPtr<Person> > result;
618 tmp << "SELECT * FROM PERSON", into(result), now;
619 assertTrue (*result[0] == *people[0]);
620 assertTrue (*result[1] == *people[1]);
621 }
622
623
testInsertVector()624 void SQLiteTest::testInsertVector()
625 {
626 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
627 std::vector<std::string> str;
628 str.push_back("s1");
629 str.push_back("s2");
630 str.push_back("s3");
631 str.push_back("s3");
632 int count = 100;
633 tmp << "DROP TABLE IF EXISTS Strings", now;
634 tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now;
635 {
636 Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(str)));
637 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
638 assertTrue (count == 0);
639 stmt.execute();
640 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
641 assertTrue (count == 4);
642 }
643 count = 0;
644 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
645 assertTrue (count == 4);
646 }
647
648
testInsertEmptyVector()649 void SQLiteTest::testInsertEmptyVector()
650 {
651 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
652 std::vector<std::string> str;
653
654 tmp << "DROP TABLE IF EXISTS Strings", now;
655 tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now;
656 try
657 {
658 tmp << "INSERT INTO Strings VALUES(:str)", use(str), now;
659 fail("empty collectons should not work");
660 }
661 catch (Poco::Exception&)
662 {
663 }
664 }
665
666
testAffectedRows()667 void SQLiteTest::testAffectedRows()
668 {
669 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
670 std::vector<std::string> str;
671 str.push_back("s1");
672 str.push_back("s2");
673 str.push_back("s3");
674 str.push_back("s3");
675 int count = 100;
676 tmp << "DROP TABLE IF EXISTS Strings", now;
677 tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now;
678
679 Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(str)));
680 count = -1;
681 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
682 assertTrue (count == 0);
683 assertTrue (4 == stmt.execute());
684 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
685 assertTrue (count == 4);
686
687 Statement stmt0(tmp << "DELETE FROM Strings");
688 assertTrue (4 == stmt0.execute());
689 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
690 assertTrue (count == 0);
691
692 Statement stmt1((tmp << "SELECT * FROM Strings"));
693 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
694 assertTrue (count == 0);
695 assertTrue (0 == stmt1.execute());
696
697 Statement stmt2((tmp << "INSERT INTO Strings VALUES(:str)", use(str)));
698 count = -1;
699 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
700 assertTrue (count == 0);
701 assertTrue (4 == stmt2.execute());
702 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
703 assertTrue (count == 4);
704
705 Statement stmt3(tmp << "UPDATE Strings SET str = 's4' WHERE str = 's3'");
706 assertTrue (2 == stmt3.execute());
707
708 Statement stmt4(tmp << "DELETE FROM Strings WHERE str = 's1'");
709 assertTrue (1 == stmt4.execute());
710
711 Statement stmt5(tmp << "DELETE FROM Strings WHERE str = 'bad value'");
712 assertTrue (0 == stmt5.execute());
713
714 Statement stmt6(tmp << "DELETE FROM Strings");
715 assertTrue (3 == stmt6.execute());
716 }
717
718
testInsertSingleBulk()719 void SQLiteTest::testInsertSingleBulk()
720 {
721 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
722 tmp << "DROP TABLE IF EXISTS Strings", now;
723 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
724 std::size_t x = 0;
725 Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(x)));
726
727 for (std::size_t i = 0; x < 100; ++x)
728 {
729 i = stmt.execute();
730 assertTrue (1 == i);
731 }
732
733 int count = 0;
734 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
735 assertTrue (count == 100);
736 tmp << "SELECT SUM(str) FROM Strings", into(count), now;
737 assertTrue (count == ((0+99)*100/2));
738 }
739
740
testInsertSingleBulkVec()741 void SQLiteTest::testInsertSingleBulkVec()
742 {
743 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
744 tmp << "DROP TABLE IF EXISTS Strings", now;
745 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
746 std::vector<int> data;
747 data.push_back(0);
748 data.push_back(1);
749
750 Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data)));
751
752 for (int x = 0; x < 100; x += 2)
753 {
754 data[0] = x;
755 data[1] = x+1;
756 stmt.execute();
757 }
758 int count = 0;
759 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
760 assertTrue (count == 100);
761 tmp << "SELECT SUM(str) FROM Strings", into(count), now;
762 assertTrue (count == ((0+99)*100/2));
763 }
764
765
testLimit()766 void SQLiteTest::testLimit()
767 {
768 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
769 tmp << "DROP TABLE IF EXISTS Strings", now;
770 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
771 std::vector<int> data;
772 for (int x = 0; x < 100; ++x)
773 {
774 data.push_back(x);
775 }
776
777 tmp << "INSERT INTO Strings VALUES(:str)", use(data), now;
778 std::vector<int> retData;
779 tmp << "SELECT * FROM Strings", into(retData), limit(50), now;
780 assertTrue (retData.size() == 50);
781 for (int x = 0; x < 50; ++x)
782 {
783 assertTrue (data[x] == retData[x]);
784 }
785 }
786
787
testLimitZero()788 void SQLiteTest::testLimitZero()
789 {
790 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
791 tmp << "DROP TABLE IF EXISTS Strings", now;
792 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
793 std::vector<int> data;
794 for (int x = 0; x < 100; ++x)
795 {
796 data.push_back(x);
797 }
798
799 tmp << "INSERT INTO Strings VALUES(:str)", use(data), now;
800 std::vector<int> retData;
801 tmp << "SELECT * FROM Strings", into(retData), limit(0), now; // stupid test, but at least we shouldn't crash
802 assertTrue (retData.size() == 0);
803 }
804
805
testLimitOnce()806 void SQLiteTest::testLimitOnce()
807 {
808 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
809 tmp << "DROP TABLE IF EXISTS Strings", now;
810 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
811 std::vector<int> data;
812 for (int x = 0; x < 101; ++x)
813 {
814 data.push_back(x);
815 }
816
817 tmp << "INSERT INTO Strings VALUES(:str)", use(data), now;
818 std::vector<int> retData;
819 Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50), now);
820 assertTrue (!stmt.done());
821 assertTrue (retData.size() == 50);
822 stmt.execute();
823 assertTrue (!stmt.done());
824 assertTrue (retData.size() == 100);
825 stmt.execute();
826 assertTrue (stmt.done());
827 assertTrue (retData.size() == 101);
828
829 for (int x = 0; x < 101; ++x)
830 {
831 assertTrue (data[x] == retData[x]);
832 }
833 }
834
835
testLimitPrepare()836 void SQLiteTest::testLimitPrepare()
837 {
838 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
839 tmp << "DROP TABLE IF EXISTS Strings", now;
840 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
841 std::vector<int> data;
842 for (int x = 0; x < 100; ++x)
843 {
844 data.push_back(x);
845 }
846
847 Statement stmtIns = (tmp << "INSERT INTO Strings VALUES(:str)", use(data));
848 assertTrue (100 == stmtIns.execute());
849
850 std::vector<int> retData;
851 Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50));
852 assertTrue (retData.size() == 0);
853 assertTrue (!stmt.done());
854 std::size_t rows = stmt.execute();
855 assertTrue (50 == rows);
856 assertTrue (!stmt.done());
857 assertTrue (retData.size() == 50);
858 rows = stmt.execute();
859 assertTrue (50 == rows);
860 assertTrue (stmt.done());
861 assertTrue (retData.size() == 100);
862 rows = stmt.execute(); // will restart execution!
863 assertTrue (50 == rows);
864 assertTrue (!stmt.done());
865 assertTrue (retData.size() == 150);
866 for (int x = 0; x < 150; ++x)
867 {
868 assertTrue (data[x%100] == retData[x]);
869 }
870 }
871
872
873
testPrepare()874 void SQLiteTest::testPrepare()
875 {
876 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
877 tmp << "DROP TABLE IF EXISTS Strings", now;
878 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
879 std::vector<int> data;
880 for (int x = 0; x < 100; x += 2)
881 {
882 data.push_back(x);
883 }
884
885 {
886 Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data)));
887 }
888 // stmt should not have been executed when destroyed
889 int count = 100;
890 tmp << "SELECT COUNT(*) FROM Strings", into(count), now;
891 assertTrue (count == 0);
892 }
893
894
testSetSimple()895 void SQLiteTest::testSetSimple()
896 {
897 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
898 std::set<std::string> lastNames;
899 std::set<std::string> firstNames;
900 std::set<std::string> addresses;
901 std::set<int> ages;
902 std::string tableName("Person");
903 lastNames.insert("LN1");
904 lastNames.insert("LN2");
905 firstNames.insert("FN1");
906 firstNames.insert("FN2");
907 addresses.insert("ADDR1");
908 addresses.insert("ADDR2");
909 ages.insert(1);
910 ages.insert(2);
911 int count = 0;
912 std::string result;
913 tmp << "DROP TABLE IF EXISTS Person", now;
914 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
915
916 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
917 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
918 assertTrue (count == 2);
919
920 std::set<std::string> lastNamesR;
921 std::set<std::string> firstNamesR;
922 std::set<std::string> addressesR;
923 std::set<int> agesR;
924 tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now;
925 assertTrue (ages == agesR);
926 assertTrue (lastNames == lastNamesR);
927 assertTrue (firstNames == firstNamesR);
928 assertTrue (addresses == addressesR);
929 }
930
931
testSetComplex()932 void SQLiteTest::testSetComplex()
933 {
934 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
935 std::set<Person> people;
936 people.insert(Person("LN1", "FN1", "ADDR1", 1));
937 people.insert(Person("LN2", "FN2", "ADDR2", 2));
938 tmp << "DROP TABLE IF EXISTS Person", now;
939 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
940 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
941 int count = 0;
942 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
943 assertTrue (count == 2);
944
945 std::set<Person> result;
946 tmp << "SELECT * FROM PERSON", into(result), now;
947 assertTrue (result == people);
948 }
949
950
testSetComplexUnique()951 void SQLiteTest::testSetComplexUnique()
952 {
953 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
954 std::vector<Person> people;
955 Person p1("LN1", "FN1", "ADDR1", 1);
956 people.push_back(p1);
957 people.push_back(p1);
958 people.push_back(p1);
959 people.push_back(p1);
960 Person p2("LN2", "FN2", "ADDR2", 2);
961 people.push_back(p2);
962
963 tmp << "DROP TABLE IF EXISTS Person", now;
964 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
965 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
966 int count = 0;
967 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
968 assertTrue (count == 5);
969
970 std::set<Person> result;
971 tmp << "SELECT * FROM PERSON", into(result), now;
972 assertTrue (result.size() == 2);
973 assertTrue (*result.begin() == p1);
974 assertTrue (*++result.begin() == p2);
975 }
976
testMultiSetSimple()977 void SQLiteTest::testMultiSetSimple()
978 {
979 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
980 std::multiset<std::string> lastNames;
981 std::multiset<std::string> firstNames;
982 std::multiset<std::string> addresses;
983 std::multiset<int> ages;
984 std::string tableName("Person");
985 lastNames.insert("LN1");
986 lastNames.insert("LN2");
987 firstNames.insert("FN1");
988 firstNames.insert("FN2");
989 addresses.insert("ADDR1");
990 addresses.insert("ADDR2");
991 ages.insert(1);
992 ages.insert(2);
993 int count = 0;
994 std::string result;
995 tmp << "DROP TABLE IF EXISTS Person", now;
996 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
997
998 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
999 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1000 assertTrue (count == 2);
1001
1002 std::multiset<std::string> lastNamesR;
1003 std::multiset<std::string> firstNamesR;
1004 std::multiset<std::string> addressesR;
1005 std::multiset<int> agesR;
1006 tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now;
1007 assertTrue (ages.size() == agesR.size());
1008 assertTrue (lastNames.size() == lastNamesR.size());
1009 assertTrue (firstNames.size() == firstNamesR.size());
1010 assertTrue (addresses.size() == addressesR.size());
1011 }
1012
1013
testMultiSetComplex()1014 void SQLiteTest::testMultiSetComplex()
1015 {
1016 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1017 std::multiset<Person> people;
1018 Person p1("LN1", "FN1", "ADDR1", 1);
1019 people.insert(p1);
1020 people.insert(p1);
1021 people.insert(p1);
1022 people.insert(p1);
1023 Person p2("LN2", "FN2", "ADDR2", 2);
1024 people.insert(p2);
1025
1026 tmp << "DROP TABLE IF EXISTS Person", now;
1027 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1028 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1029 int count = 0;
1030 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1031 assertTrue (count == 5);
1032
1033 std::multiset<Person> result;
1034 tmp << "SELECT * FROM PERSON", into(result), now;
1035 assertTrue (result.size() == people.size());
1036 }
1037
1038
testMapComplex()1039 void SQLiteTest::testMapComplex()
1040 {
1041 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1042 std::map<std::string, Person> people;
1043 Person p1("LN1", "FN1", "ADDR1", 1);
1044 Person p2("LN2", "FN2", "ADDR2", 2);
1045 people.insert(std::make_pair("LN1", p1));
1046 people.insert(std::make_pair("LN2", p2));
1047 tmp << "DROP TABLE IF EXISTS Person", now;
1048 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1049 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1050 int count = 0;
1051 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1052 assertTrue (count == 2);
1053
1054 std::map<std::string, Person> result;
1055 tmp << "SELECT * FROM PERSON", into(result), now;
1056 assertTrue (result == people);
1057 }
1058
1059
testMapComplexUnique()1060 void SQLiteTest::testMapComplexUnique()
1061 {
1062 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1063 std::multimap<std::string, Person> people;
1064 Person p1("LN1", "FN1", "ADDR1", 1);
1065 Person p2("LN2", "FN2", "ADDR2", 2);
1066 people.insert(std::make_pair("LN1", p1));
1067 people.insert(std::make_pair("LN1", p1));
1068 people.insert(std::make_pair("LN1", p1));
1069 people.insert(std::make_pair("LN1", p1));
1070 people.insert(std::make_pair("LN2", p2));
1071 tmp << "DROP TABLE IF EXISTS Person", now;
1072 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1073 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1074 int count = 0;
1075 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1076 assertTrue (count == 5);
1077
1078 std::map<std::string, Person> result;
1079 tmp << "SELECT * FROM PERSON", into(result), now;
1080 assertTrue (result.size() == 2);
1081 }
1082
1083
testMultiMapComplex()1084 void SQLiteTest::testMultiMapComplex()
1085 {
1086 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1087 std::multimap<std::string, Person> people;
1088 Person p1("LN1", "FN1", "ADDR1", 1);
1089 Person p2("LN2", "FN2", "ADDR2", 2);
1090 people.insert(std::make_pair("LN1", p1));
1091 people.insert(std::make_pair("LN1", p1));
1092 people.insert(std::make_pair("LN1", p1));
1093 people.insert(std::make_pair("LN1", p1));
1094 people.insert(std::make_pair("LN2", p2));
1095 tmp << "DROP TABLE IF EXISTS Person", now;
1096 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1097 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1098 int count = 0;
1099 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1100 assertTrue (count == 5);
1101
1102 std::multimap<std::string, Person> result;
1103 tmp << "SELECT * FROM PERSON", into(result), now;
1104 assertTrue (result.size() == people.size());
1105 }
1106
1107
testSelectIntoSingle()1108 void SQLiteTest::testSelectIntoSingle()
1109 {
1110 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1111 std::multimap<std::string, Person> people;
1112 Person p1("LN1", "FN1", "ADDR1", 1);
1113 Person p2("LN2", "FN2", "ADDR2", 2);
1114 people.insert(std::make_pair("LN1", p1));
1115 people.insert(std::make_pair("LN1", p2));
1116 tmp << "DROP TABLE IF EXISTS Person", now;
1117 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1118 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1119 int count = 0;
1120 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1121 assertTrue (count == 2);
1122 Person result;
1123 tmp << "SELECT * FROM PERSON", into(result), limit(1), now; // will return 1 object into one single result
1124 assertTrue (result == p1);
1125 }
1126
1127
testSelectIntoSingleStep()1128 void SQLiteTest::testSelectIntoSingleStep()
1129 {
1130 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1131 std::multimap<std::string, Person> people;
1132 Person p1("LN1", "FN1", "ADDR1", 1);
1133 Person p2("LN2", "FN2", "ADDR2", 2);
1134 people.insert(std::make_pair("LN1", p1));
1135 people.insert(std::make_pair("LN1", p2));
1136 tmp << "DROP TABLE IF EXISTS Person", now;
1137 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1138 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1139 int count = 0;
1140 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1141 assertTrue (count == 2);
1142 Person result;
1143 Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1));
1144 stmt.execute();
1145 assertTrue (result == p1);
1146 assertTrue (!stmt.done());
1147 stmt.execute();
1148 assertTrue (result == p2);
1149 assertTrue (stmt.done());
1150 }
1151
1152
testSelectIntoSingleFail()1153 void SQLiteTest::testSelectIntoSingleFail()
1154 {
1155 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1156 std::multimap<std::string, Person> people;
1157 Person p1("LN1", "FN1", "ADDR1", 1);
1158 Person p2("LN2", "FN2", "ADDR2", 2);
1159 people.insert(std::make_pair("LN1", p1));
1160 people.insert(std::make_pair("LN1", p2));
1161 tmp << "DROP TABLE IF EXISTS Person", now;
1162 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1163 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1164 int count = 0;
1165 tmp << "SELECT COUNT(*) FROM PERSON", into(count), limit(2, true), now;
1166 assertTrue (count == 2);
1167 Person result;
1168 try
1169 {
1170 tmp << "SELECT * FROM PERSON", into(result), limit(1, true), now; // will fail now
1171 fail("hardLimit is set: must fail");
1172 }
1173 catch(Poco::Data::LimitException&)
1174 {
1175 }
1176 }
1177
1178
testLowerLimitOk()1179 void SQLiteTest::testLowerLimitOk()
1180 {
1181 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1182 std::multimap<std::string, Person> people;
1183 Person p1("LN1", "FN1", "ADDR1", 1);
1184 Person p2("LN2", "FN2", "ADDR2", 2);
1185 people.insert(std::make_pair("LN1", p1));
1186 people.insert(std::make_pair("LN1", p2));
1187 tmp << "DROP TABLE IF EXISTS Person", now;
1188 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1189 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1190 int count = 0;
1191 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1192 assertTrue (count == 2);
1193 Person result;
1194 try
1195 {
1196 tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one!
1197 fail("Not enough space for results");
1198 }
1199 catch(Poco::Exception&)
1200 {
1201 }
1202 }
1203
1204
testSingleSelect()1205 void SQLiteTest::testSingleSelect()
1206 {
1207 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1208 std::multimap<std::string, Person> people;
1209 Person p1("LN1", "FN1", "ADDR1", 1);
1210 Person p2("LN2", "FN2", "ADDR2", 2);
1211 people.insert(std::make_pair("LN1", p1));
1212 people.insert(std::make_pair("LN1", p2));
1213 tmp << "DROP TABLE IF EXISTS Person", now;
1214 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1215 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1216 int count = 0;
1217 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1218 assertTrue (count == 2);
1219 Person result;
1220 Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1));
1221 stmt.execute();
1222 assertTrue (result == p1);
1223 assertTrue (!stmt.done());
1224 stmt.execute();
1225 assertTrue (result == p2);
1226 assertTrue (stmt.done());
1227 }
1228
1229
testLowerLimitFail()1230 void SQLiteTest::testLowerLimitFail()
1231 {
1232 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1233 std::multimap<std::string, Person> people;
1234 Person p1("LN1", "FN1", "ADDR1", 1);
1235 Person p2("LN2", "FN2", "ADDR2", 2);
1236 people.insert(std::make_pair("LN1", p1));
1237 people.insert(std::make_pair("LN1", p2));
1238 tmp << "DROP TABLE IF EXISTS Person", now;
1239 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1240 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1241 int count = 0;
1242 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1243 assertTrue (count == 2);
1244 Person result;
1245 try
1246 {
1247 tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), now; // will fail
1248 fail("should fail. not enough data");
1249 }
1250 catch(Poco::Exception&)
1251 {
1252 }
1253 }
1254
1255
testCombinedLimits()1256 void SQLiteTest::testCombinedLimits()
1257 {
1258 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1259 std::multimap<std::string, Person> people;
1260 Person p1("LN1", "FN1", "ADDR1", 1);
1261 Person p2("LN2", "FN2", "ADDR2", 2);
1262 people.insert(std::make_pair("LN1", p1));
1263 people.insert(std::make_pair("LN1", p2));
1264 tmp << "DROP TABLE IF EXISTS Person", now;
1265 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1266 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1267
1268 std::string a, b, c;
1269 Statement stmt = (tmp << "SELECT LastName, FirstName, Address FROM Person WHERE Address = 'invalid value'",
1270 into(a), into(b), into(c), limit(1));
1271 assertTrue (!stmt.done() && stmt.execute() == 0);
1272
1273 int count = 0;
1274 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1275 assertTrue (count == 2);
1276 std::vector <Person> result;
1277 tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), upperLimit(2), now; // will return 2 objects
1278 assertTrue (result.size() == 2);
1279 assertTrue (result[0] == p1);
1280 assertTrue (result[1] == p2);
1281 }
1282
1283
1284
testRange()1285 void SQLiteTest::testRange()
1286 {
1287 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1288 std::multimap<std::string, Person> people;
1289 Person p1("LN1", "FN1", "ADDR1", 1);
1290 Person p2("LN2", "FN2", "ADDR2", 2);
1291 people.insert(std::make_pair("LN1", p1));
1292 people.insert(std::make_pair("LN1", p2));
1293 tmp << "DROP TABLE IF EXISTS Person", now;
1294 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1295 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1296 int count = 0;
1297 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1298 assertTrue (count == 2);
1299 std::vector <Person> result;
1300 tmp << "SELECT * FROM PERSON", into(result), range(2, 2), now; // will return 2 objects
1301 assertTrue (result.size() == 2);
1302 assertTrue (result[0] == p1);
1303 assertTrue (result[1] == p2);
1304 }
1305
1306
testCombinedIllegalLimits()1307 void SQLiteTest::testCombinedIllegalLimits()
1308 {
1309 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1310 std::multimap<std::string, Person> people;
1311 Person p1("LN1", "FN1", "ADDR1", 1);
1312 Person p2("LN2", "FN2", "ADDR2", 2);
1313 people.insert(std::make_pair("LN1", p1));
1314 people.insert(std::make_pair("LN1", p2));
1315 tmp << "DROP TABLE IF EXISTS Person", now;
1316 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1317 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1318 int count = 0;
1319 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1320 assertTrue (count == 2);
1321 Person result;
1322 try
1323 {
1324 tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), upperLimit(2), now;
1325 fail("lower > upper is not allowed");
1326 }
1327 catch(LimitException&)
1328 {
1329 }
1330 }
1331
1332
1333
testIllegalRange()1334 void SQLiteTest::testIllegalRange()
1335 {
1336 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1337 std::multimap<std::string, Person> people;
1338 Person p1("LN1", "FN1", "ADDR1", 1);
1339 Person p2("LN2", "FN2", "ADDR2", 2);
1340 people.insert(std::make_pair("LN1", p1));
1341 people.insert(std::make_pair("LN1", p2));
1342 tmp << "DROP TABLE IF EXISTS Person", now;
1343 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1344 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now;
1345 int count = 0;
1346 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1347 assertTrue (count == 2);
1348 Person result;
1349 try
1350 {
1351 tmp << "SELECT * FROM PERSON", into(result), range(3, 2), now;
1352 fail("lower > upper is not allowed");
1353 }
1354 catch(LimitException&)
1355 {
1356 }
1357 }
1358
1359
testEmptyDB()1360 void SQLiteTest::testEmptyDB()
1361 {
1362 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1363
1364 tmp << "DROP TABLE IF EXISTS Person", now;
1365 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
1366 int count = 0;
1367 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1368 assertTrue (count == 0);
1369 Person result;
1370 Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1));
1371 stmt.execute();
1372 assertTrue (result.getFirstName().empty());
1373 assertTrue (stmt.done());
1374 }
1375
1376
testCLOB()1377 void SQLiteTest::testCLOB()
1378 {
1379 std::string lastName("lastname");
1380 std::string firstName("firstname");
1381 std::string address("Address");
1382 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1383 tmp << "DROP TABLE IF EXISTS Person", now;
1384 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now;
1385 CLOB img("0123456789", 10);
1386 int count = 0;
1387 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use(lastName), use(firstName), use(address), use(img), now;
1388 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
1389 assertTrue (count == 1);
1390 CLOB res;
1391 poco_assert (res.size() == 0);
1392
1393 tmp << "SELECT Image FROM Person WHERE LastName == :ln", bind("lastname"), into(res), now;
1394 poco_assert (res == img);
1395
1396 tmp << "DROP TABLE IF EXISTS BlobTest", now;
1397 std::vector<CLOB> resVec;
1398 const int arrSize = 10;
1399 char val[arrSize];
1400 for (int i = 0; i < arrSize; ++i)
1401 {
1402 val[i] = (char) (0x30 + i);
1403 }
1404
1405 for (int i = 0; i < arrSize; ++i)
1406 {
1407 tmp << "CREATE TABLE IF NOT EXISTS BlobTest (idx INTEGER(2), Image BLOB)", now;
1408 val[0] = (char) (0x30 + i);
1409 img.assignRaw(val, arrSize);
1410 tmp << "INSERT INTO BlobTest VALUES(?, ?)", use(i), use(img), now;
1411 }
1412 tmp << "SELECT Image FROM BlobTest", into(resVec), now;
1413 poco_assert (resVec.size() == arrSize);
1414 for (int i = 0; i < arrSize; ++i)
1415 {
1416 poco_assert (*resVec[i].begin() == (char) (0x30 + i));
1417 }
1418 }
1419
1420
testTuple10()1421 void SQLiteTest::testTuple10()
1422 {
1423 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1424 tmp << "DROP TABLE IF EXISTS Tuples", now;
1425 tmp << "CREATE TABLE Tuples "
1426 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1427 "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now;
1428
1429 Tuple<int,int,int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7,8,9);
1430
1431 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(t), now;
1432
1433 Tuple<int,int,int,int,int,int,int,int,int,int> ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19);
1434 assertTrue (ret != t);
1435 tmp << "SELECT * FROM Tuples", into(ret), now;
1436 assertTrue (ret == t);
1437 }
1438
1439
testTupleVector10()1440 void SQLiteTest::testTupleVector10()
1441 {
1442 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1443 tmp << "DROP TABLE IF EXISTS Tuples", now;
1444 tmp << "CREATE TABLE Tuples "
1445 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1446 "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now;
1447
1448 Tuple<int,int,int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7,8,9);
1449 Tuple<int,int,int,int,int,int,int,int,int,int> t10(10,11,12,13,14,15,16,17,18,19);
1450 Tuple<int,int,int,int,int,int,int,int,int,int> t100(100,101,102,103,104,105,106,107,108,109);
1451 std::vector<Tuple<int,int,int,int,int,int,int,int,int,int> > v;
1452 v.push_back(t);
1453 v.push_back(t10);
1454 v.push_back(t100);
1455
1456 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(v), now;
1457
1458 int count = 0;
1459 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1460 assertTrue (v.size() == count);
1461
1462 std::vector<Tuple<int,int,int,int,int,int,int,int,int,int> > ret;
1463 assertTrue (ret != v);
1464 tmp << "SELECT * FROM Tuples", into(ret), now;
1465 assertTrue (ret == v);
1466 }
1467
1468
testTuple9()1469 void SQLiteTest::testTuple9()
1470 {
1471 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1472 tmp << "DROP TABLE IF EXISTS Tuples", now;
1473 tmp << "CREATE TABLE Tuples "
1474 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1475 "int7 INTEGER, int8 INTEGER)", now;
1476
1477 Tuple<int,int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7,8);
1478
1479 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(t), now;
1480
1481 Tuple<int,int,int,int,int,int,int,int,int> ret(-10,-11,-12,-13,-14,-15,-16,-17,-18);
1482 assertTrue (ret != t);
1483 tmp << "SELECT * FROM Tuples", into(ret), now;
1484 assertTrue (ret == t);
1485 }
1486
1487
testTupleVector9()1488 void SQLiteTest::testTupleVector9()
1489 {
1490 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1491 tmp << "DROP TABLE IF EXISTS Tuples", now;
1492 tmp << "CREATE TABLE Tuples "
1493 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1494 "int7 INTEGER, int8 INTEGER)", now;
1495
1496 Tuple<int,int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7,8);
1497 Tuple<int,int,int,int,int,int,int,int,int> t10(10,11,12,13,14,15,16,17,18);
1498 Tuple<int,int,int,int,int,int,int,int,int> t100(100,101,102,103,104,105,106,107,108);
1499 std::vector<Tuple<int,int,int,int,int,int,int,int,int> > v;
1500 v.push_back(t);
1501 v.push_back(t10);
1502 v.push_back(t100);
1503
1504 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(v), now;
1505
1506 int count = 0;
1507 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1508 assertTrue (v.size() == count);
1509
1510 std::vector<Tuple<int,int,int,int,int,int,int,int,int> > ret;
1511 assertTrue (ret != v);
1512 tmp << "SELECT * FROM Tuples", into(ret), now;
1513 assertTrue (ret == v);
1514 }
1515
1516
testTuple8()1517 void SQLiteTest::testTuple8()
1518 {
1519 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1520 tmp << "DROP TABLE IF EXISTS Tuples", now;
1521 tmp << "CREATE TABLE Tuples "
1522 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1523 "int7 INTEGER)", now;
1524
1525 Tuple<int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7);
1526
1527 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(t), now;
1528
1529 Tuple<int,int,int,int,int,int,int,int> ret(-10,-11,-12,-13,-14,-15,-16,-17);
1530 assertTrue (ret != t);
1531 tmp << "SELECT * FROM Tuples", into(ret), now;
1532 assertTrue (ret == t);
1533 }
1534
1535
testTupleVector8()1536 void SQLiteTest::testTupleVector8()
1537 {
1538 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1539 tmp << "DROP TABLE IF EXISTS Tuples", now;
1540 tmp << "CREATE TABLE Tuples "
1541 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
1542 "int7 INTEGER)", now;
1543
1544 Tuple<int,int,int,int,int,int,int,int> t(0,1,2,3,4,5,6,7);
1545 Tuple<int,int,int,int,int,int,int,int> t10(10,11,12,13,14,15,16,17);
1546 Tuple<int,int,int,int,int,int,int,int> t100(100,101,102,103,104,105,106,107);
1547 std::vector<Tuple<int,int,int,int,int,int,int,int> > v;
1548 v.push_back(t);
1549 v.push_back(t10);
1550 v.push_back(t100);
1551
1552 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(v), now;
1553
1554 int count = 0;
1555 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1556 assertTrue (v.size() == count);
1557
1558 std::vector<Tuple<int,int,int,int,int,int,int,int> > ret;
1559 assertTrue (ret != v);
1560 tmp << "SELECT * FROM Tuples", into(ret), now;
1561 assertTrue (ret == v);
1562 }
1563
1564
testTuple7()1565 void SQLiteTest::testTuple7()
1566 {
1567 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1568 tmp << "DROP TABLE IF EXISTS Tuples", now;
1569 tmp << "CREATE TABLE Tuples "
1570 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now;
1571
1572 Tuple<int,int,int,int,int,int,int> t(0,1,2,3,4,5,6);
1573
1574 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(t), now;
1575
1576 Tuple<int,int,int,int,int,int,int> ret(-10,-11,-12,-13,-14,-15,-16);
1577 assertTrue (ret != t);
1578 tmp << "SELECT * FROM Tuples", into(ret), now;
1579 assertTrue (ret == t);
1580 }
1581
1582
testTupleVector7()1583 void SQLiteTest::testTupleVector7()
1584 {
1585 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1586 tmp << "DROP TABLE IF EXISTS Tuples", now;
1587 tmp << "CREATE TABLE Tuples "
1588 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now;
1589
1590 Tuple<int,int,int,int,int,int,int> t(0,1,2,3,4,5,6);
1591 Tuple<int,int,int,int,int,int,int> t10(10,11,12,13,14,15,16);
1592 Tuple<int,int,int,int,int,int,int> t100(100,101,102,103,104,105,106);
1593 std::vector<Tuple<int,int,int,int,int,int,int> > v;
1594 v.push_back(t);
1595 v.push_back(t10);
1596 v.push_back(t100);
1597
1598 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(v), now;
1599
1600 int count = 0;
1601 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1602 assertTrue (v.size() == count);
1603
1604 std::vector<Tuple<int,int,int,int,int,int,int> > ret;
1605 assertTrue (ret != v);
1606 tmp << "SELECT * FROM Tuples", into(ret), now;
1607 assertTrue (ret == v);
1608 }
1609
1610
testTuple6()1611 void SQLiteTest::testTuple6()
1612 {
1613 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1614 tmp << "DROP TABLE IF EXISTS Tuples", now;
1615 tmp << "CREATE TABLE Tuples "
1616 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now;
1617
1618 Tuple<int,int,int,int,int,int> t(0,1,2,3,4,5);
1619
1620 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(t), now;
1621
1622 Tuple<int,int,int,int,int,int> ret(-10,-11,-12,-13,-14,-15);
1623 assertTrue (ret != t);
1624 tmp << "SELECT * FROM Tuples", into(ret), now;
1625 assertTrue (ret == t);
1626 }
1627
1628
testTupleVector6()1629 void SQLiteTest::testTupleVector6()
1630 {
1631 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1632 tmp << "DROP TABLE IF EXISTS Tuples", now;
1633 tmp << "CREATE TABLE Tuples "
1634 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now;
1635
1636 Tuple<int,int,int,int,int,int> t(0,1,2,3,4,5);
1637 Tuple<int,int,int,int,int,int> t10(10,11,12,13,14,15);
1638 Tuple<int,int,int,int,int,int> t100(100,101,102,103,104,105);
1639 std::vector<Tuple<int,int,int,int,int,int> > v;
1640 v.push_back(t);
1641 v.push_back(t10);
1642 v.push_back(t100);
1643
1644 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(v), now;
1645
1646 int count = 0;
1647 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1648 assertTrue (v.size() == count);
1649
1650 std::vector<Tuple<int,int,int,int,int,int> > ret;
1651 assertTrue (ret != v);
1652 tmp << "SELECT * FROM Tuples", into(ret), now;
1653 assertTrue (ret == v);
1654 }
1655
1656
testTuple5()1657 void SQLiteTest::testTuple5()
1658 {
1659 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1660 tmp << "DROP TABLE IF EXISTS Tuples", now;
1661 tmp << "CREATE TABLE Tuples "
1662 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now;
1663
1664 Tuple<int,int,int,int,int> t(0,1,2,3,4);
1665
1666 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(t), now;
1667
1668 Tuple<int,int,int,int,int> ret(-10,-11,-12,-13,-14);
1669 assertTrue (ret != t);
1670 tmp << "SELECT * FROM Tuples", into(ret), now;
1671 assertTrue (ret == t);
1672 }
1673
1674
testTupleVector5()1675 void SQLiteTest::testTupleVector5()
1676 {
1677 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1678 tmp << "DROP TABLE IF EXISTS Tuples", now;
1679 tmp << "CREATE TABLE Tuples "
1680 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now;
1681
1682 Tuple<int,int,int,int,int> t(0,1,2,3,4);
1683 Tuple<int,int,int,int,int> t10(10,11,12,13,14);
1684 Tuple<int,int,int,int,int> t100(100,101,102,103,104);
1685 std::vector<Tuple<int,int,int,int,int> > v;
1686 v.push_back(t);
1687 v.push_back(t10);
1688 v.push_back(t100);
1689
1690 tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(v), now;
1691
1692 int count = 0;
1693 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1694 assertTrue (v.size() == count);
1695
1696 std::vector<Tuple<int,int,int,int,int> > ret;
1697 assertTrue (ret != v);
1698 tmp << "SELECT * FROM Tuples", into(ret), now;
1699 assertTrue (ret == v);
1700 }
1701
1702
testTuple4()1703 void SQLiteTest::testTuple4()
1704 {
1705 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1706 tmp << "DROP TABLE IF EXISTS Tuples", now;
1707 tmp << "CREATE TABLE Tuples "
1708 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now;
1709
1710 Tuple<int,int,int,int> t(0,1,2,3);
1711
1712 tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(t), now;
1713
1714 Tuple<int,int,int,int> ret(-10,-11,-12,-13);
1715 assertTrue (ret != t);
1716 tmp << "SELECT * FROM Tuples", into(ret), now;
1717 assertTrue (ret == t);
1718 }
1719
1720
testTupleVector4()1721 void SQLiteTest::testTupleVector4()
1722 {
1723 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1724 tmp << "DROP TABLE IF EXISTS Tuples", now;
1725 tmp << "CREATE TABLE Tuples "
1726 "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now;
1727
1728 Tuple<int,int,int,int> t(0,1,2,3);
1729 Tuple<int,int,int,int> t10(10,11,12,13);
1730 Tuple<int,int,int,int> t100(100,101,102,103);
1731 std::vector<Tuple<int,int,int,int> > v;
1732 v.push_back(t);
1733 v.push_back(t10);
1734 v.push_back(t100);
1735
1736 tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(v), now;
1737
1738 int count = 0;
1739 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1740 assertTrue (v.size() == count);
1741
1742 std::vector<Tuple<int,int,int,int> > ret;
1743 assertTrue (ret != v);
1744 tmp << "SELECT * FROM Tuples", into(ret), now;
1745 assertTrue (ret == v);
1746 }
1747
1748
testTuple3()1749 void SQLiteTest::testTuple3()
1750 {
1751 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1752 tmp << "DROP TABLE IF EXISTS Tuples", now;
1753 tmp << "CREATE TABLE Tuples "
1754 "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now;
1755
1756 Tuple<int,int,int> t(0,1,2);
1757
1758 tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(t), now;
1759
1760 Tuple<int,int,int> ret(-10,-11,-12);
1761 assertTrue (ret != t);
1762 tmp << "SELECT * FROM Tuples", into(ret), now;
1763 assertTrue (ret == t);
1764 }
1765
1766
testTupleVector3()1767 void SQLiteTest::testTupleVector3()
1768 {
1769 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1770 tmp << "DROP TABLE IF EXISTS Tuples", now;
1771 tmp << "CREATE TABLE Tuples "
1772 "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now;
1773
1774 Tuple<int,int,int> t(0,1,2);
1775 Tuple<int,int,int> t10(10,11,12);
1776 Tuple<int,int,int> t100(100,101,102);
1777 std::vector<Tuple<int,int,int> > v;
1778 v.push_back(t);
1779 v.push_back(t10);
1780 v.push_back(t100);
1781
1782 tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(v), now;
1783
1784 int count = 0;
1785 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1786 assertTrue (v.size() == count);
1787
1788 std::vector<Tuple<int,int,int> > ret;
1789 assertTrue (ret != v);
1790 tmp << "SELECT * FROM Tuples", into(ret), now;
1791 assertTrue (ret == v);
1792 }
1793
1794
testTuple2()1795 void SQLiteTest::testTuple2()
1796 {
1797 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1798 tmp << "DROP TABLE IF EXISTS Tuples", now;
1799 tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now;
1800
1801 Tuple<int,int> t(0,1);
1802
1803 tmp << "INSERT INTO Tuples VALUES (?,?)", use(t), now;
1804
1805 Tuple<int,int> ret(-10,-11);
1806 assertTrue (ret != t);
1807 tmp << "SELECT * FROM Tuples", into(ret), now;
1808 assertTrue (ret == t);
1809 }
1810
1811
testTupleVector2()1812 void SQLiteTest::testTupleVector2()
1813 {
1814 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1815 tmp << "DROP TABLE IF EXISTS Tuples", now;
1816 tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now;
1817
1818 Tuple<int,int> t(0,1);
1819 Tuple<int,int> t10(10,11);
1820 Tuple<int,int> t100(100,101);
1821 std::vector<Tuple<int,int> > v;
1822 v.push_back(t);
1823 v.push_back(t10);
1824 v.push_back(t100);
1825
1826 tmp << "INSERT INTO Tuples VALUES (?,?)", use(v), now;
1827
1828 int count = 0;
1829 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1830 assertTrue (v.size() == count);
1831
1832 std::vector<Tuple<int,int> > ret;
1833 assertTrue (ret != v);
1834 tmp << "SELECT * FROM Tuples", into(ret), now;
1835 assertTrue (ret == v);
1836 }
1837
1838
testTuple1()1839 void SQLiteTest::testTuple1()
1840 {
1841 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1842 tmp << "DROP TABLE IF EXISTS Tuples", now;
1843 tmp << "CREATE TABLE Tuples (int0 INTEGER)", now;
1844
1845 Tuple<int> t(0);
1846
1847 tmp << "INSERT INTO Tuples VALUES (?)", use(t), now;
1848
1849 Tuple<int> ret(-10);
1850 assertTrue (ret != t);
1851 tmp << "SELECT * FROM Tuples", into(ret), now;
1852 assertTrue (ret == t);
1853 }
1854
1855
testTupleVector1()1856 void SQLiteTest::testTupleVector1()
1857 {
1858 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1859 tmp << "DROP TABLE IF EXISTS Tuples", now;
1860 tmp << "CREATE TABLE Tuples (int0 INTEGER)", now;
1861
1862 Tuple<int> t(0);
1863 Tuple<int> t10(10);
1864 Tuple<int> t100(100);
1865 std::vector<Tuple<int> > v;
1866 v.push_back(t);
1867 v.push_back(t10);
1868 v.push_back(t100);
1869
1870 tmp << "INSERT INTO Tuples VALUES (?)", use(v), now;
1871
1872 int count = 0;
1873 tmp << "SELECT COUNT(*) FROM Tuples", into(count), now;
1874 assertTrue (v.size() == count);
1875
1876 std::vector<Tuple<int> > ret;
1877 assertTrue (ret != v);
1878 tmp << "SELECT * FROM Tuples", into(ret), now;
1879 assertTrue (ret == v);
1880 }
1881
1882
testDateTime()1883 void SQLiteTest::testDateTime()
1884 {
1885 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1886 tmp << "DROP TABLE IF EXISTS DateTimes", now;
1887 tmp << "CREATE TABLE DateTimes (dt0 DATE)", now;
1888
1889 DateTime dt(1965, 6, 18, 5, 35, 1);
1890 tmp << "INSERT INTO DateTimes VALUES (?)", use(dt), now;
1891
1892 DateTime rdt;
1893 assertTrue (rdt != dt);
1894 tmp << "SELECT * FROM DateTimes", into(rdt), now;
1895 assertTrue (rdt == dt);
1896
1897 tmp << "DELETE FROM DateTimes", now;
1898
1899 Date d(dt);
1900 tmp << "INSERT INTO DateTimes VALUES (?)", use(d), now;
1901
1902 Date rd;
1903 assertTrue (rd != d);
1904 tmp << "SELECT * FROM DateTimes", into(rd), now;
1905 assertTrue (rd == d);
1906
1907 tmp << "DELETE FROM DateTimes", now;
1908
1909 Time t(dt);
1910 tmp << "INSERT INTO DateTimes VALUES (?)", use(t), now;
1911
1912 Time rt;
1913 assertTrue (rt != t);
1914 tmp << "SELECT * FROM DateTimes", into(rt), now;
1915 assertTrue (rt == t);
1916 }
1917
1918
testInternalExtraction()1919 void SQLiteTest::testInternalExtraction()
1920 {
1921 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1922 tmp << "DROP TABLE IF EXISTS Vectors", now;
1923 tmp << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now;
1924
1925 std::vector<Tuple<int, double, std::string> > v;
1926 v.push_back(Tuple<int, double, std::string>(1, 1.5, "3"));
1927 v.push_back(Tuple<int, double, std::string>(2, 2.5, "4"));
1928 v.push_back(Tuple<int, double, std::string>(3, 3.5, "5"));
1929 v.push_back(Tuple<int, double, std::string>(4, 4.5, "6"));
1930
1931 tmp << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now;
1932
1933 Statement stmt = (tmp << "SELECT * FROM Vectors", now);
1934 RecordSet rset(stmt);
1935 assertTrue (3 == rset.columnCount());
1936 assertTrue (4 == rset.rowCount());
1937
1938 RecordSet rset2(rset);
1939 assertTrue (3 == rset2.columnCount());
1940 assertTrue (4 == rset2.rowCount());
1941
1942 Int32 a = static_cast<Int32>(rset.value<Int64>(0,2));
1943 assertTrue (3 == a);
1944
1945 int c = rset2.value(0);
1946 assertTrue (1 == c);
1947
1948 Int32 b = static_cast<Int32>(rset2.value<Int64>("InT0",2));
1949 assertTrue (3 == b);
1950
1951 double d = rset.value<double>(1,0);
1952 assertTrue (1.5 == d);
1953
1954 std::string s = rset.value<std::string>(2,1);
1955 assertTrue ("4" == s);
1956
1957 typedef std::deque<Int64> IntDeq;
1958
1959 const Column<IntDeq>& col = rset.column<IntDeq>(0);
1960 assertTrue (col[0] == 1);
1961
1962 try { rset.column<IntDeq>(100); fail ("must fail"); }
1963 catch (RangeException&) { }
1964
1965 const Column<IntDeq>& col1 = rset.column<IntDeq>(0);
1966 assertTrue ("int0" == col1.name());
1967 Column<IntDeq>::Iterator it = col1.begin();
1968 Column<IntDeq>::Iterator itEnd = col1.end();
1969 int counter = 1;
1970 for (; it != itEnd; ++it, ++counter)
1971 assertTrue (counter == *it);
1972
1973 rset = (tmp << "SELECT COUNT(*) FROM Vectors", now);
1974 s = rset.value<std::string>(0,0);
1975 assertTrue ("4" == s);
1976
1977 stmt = (tmp << "DELETE FROM Vectors", now);
1978 rset = stmt;
1979
1980 try { rset.column<IntDeq>(0); fail ("must fail"); }
1981 catch (RangeException&) { }
1982 }
1983
1984
testPrimaryKeyConstraint()1985 void SQLiteTest::testPrimaryKeyConstraint()
1986 {
1987 Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db");
1988 ses << "DROP TABLE IF EXISTS LogTest", now;
1989 ses << "CREATE TABLE LogTest (Id INTEGER PRIMARY KEY, Time INTEGER, Value INTEGER)", now;
1990 const double value = -200000000000.0;
1991 const Poco::Int64 timeIn = static_cast<Poco::Int64>(22329988776655.0);
1992 int id = 1;
1993
1994 ses.begin();
1995
1996 for(int i = 0; i < 10; i++)
1997 {
1998 try
1999 {
2000 ses << "INSERT INTO LogTest (Id, [Time], Value) VALUES (:id, :time, :value)", use(id), bind(timeIn), bind(value), now; //lint !e1058
2001 if (i > 0)
2002 fail("must fail");
2003 }
2004 catch(Poco::Exception&)
2005 {
2006 if (i == 0) // the very first insert must work
2007 throw;
2008 }
2009 }
2010
2011 ses.commit();
2012 }
2013
2014
testNullable()2015 void SQLiteTest::testNullable()
2016 {
2017 Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2018 ses << "DROP TABLE IF EXISTS NullableTest", now;
2019
2020 ses << "CREATE TABLE NullableTest (i INTEGER, r REAL, s VARCHAR, d DATETIME)", now;
2021
2022 ses << "INSERT INTO NullableTest VALUES(:i, :r, :s, :d)", use(null), use(null), use(null), use(null), now;
2023
2024 Nullable<int> i = 1;
2025 Nullable<double> f = 1.5;
2026 Nullable<std::string> s = std::string("abc");
2027 Nullable<DateTime> d = DateTime();
2028
2029 assertTrue (!i.isNull());
2030 assertTrue (!f.isNull());
2031 assertTrue (!s.isNull());
2032 assertTrue (!d.isNull());
2033
2034 ses << "SELECT i, r, s, d FROM NullableTest", into(i), into(f), into(s), into(d), now;
2035
2036 assertTrue (i.isNull());
2037 assertTrue (f.isNull());
2038 assertTrue (s.isNull());
2039 assertTrue (d.isNull());
2040
2041 RecordSet rs(ses, "SELECT * FROM NullableTest");
2042
2043 rs.moveFirst();
2044 assertTrue (rs.isNull("i"));
2045 assertTrue (rs.isNull("r"));
2046 assertTrue (rs.isNull("s"));
2047 assertTrue (rs.isNull("d"));
2048
2049 Var di = 1;
2050 Var df = 1.5;
2051 Var ds = "abc";
2052 Var dd = DateTime();
2053
2054 assertTrue (!di.isEmpty());
2055 assertTrue (!df.isEmpty());
2056 assertTrue (!ds.isEmpty());
2057 assertTrue (!dd.isEmpty());
2058
2059 ses << "SELECT i, r, s, d FROM NullableTest", into(di), into(df), into(ds), into(dd), now;
2060
2061 assertTrue (di.isEmpty());
2062 assertTrue (df.isEmpty());
2063 assertTrue (ds.isEmpty());
2064 assertTrue (dd.isEmpty());
2065 }
2066
2067
testNulls()2068 void SQLiteTest::testNulls()
2069 {
2070 Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2071 ses << "DROP TABLE IF EXISTS NullTest", now;
2072
2073 ses << "CREATE TABLE NullTest (i INTEGER NOT NULL)", now;
2074
2075 try
2076 {
2077 ses << "INSERT INTO NullTest VALUES(:i)", use(null), now;
2078 fail ("must fail");
2079 }catch (ConstraintViolationException&) { }
2080
2081 ses << "DROP TABLE IF EXISTS NullTest", now;
2082 ses << "CREATE TABLE NullTest (i INTEGER, r REAL, v VARCHAR)", now;
2083
2084 ses << "INSERT INTO NullTest VALUES(:i, :r, :v)", use(null), use(null), use(null), now;
2085
2086 RecordSet rs(ses, "SELECT i, r, v, null as e FROM NullTest");
2087 rs.moveFirst();
2088 assertTrue (rs.isNull("i"));
2089 assertTrue (rs["i"].isEmpty());
2090 assertTrue (rs.isNull("r"));
2091 assertTrue (rs.isNull("v"));
2092 assertTrue (rs["v"].isEmpty());
2093 assertTrue (rs["e"].isEmpty());
2094
2095 assertTrue (rs[0].isEmpty());
2096 assertTrue (rs[1].isEmpty());
2097 assertTrue (rs[2].isEmpty());
2098 assertTrue (rs[3].isEmpty());
2099
2100 ses << "DROP TABLE IF EXISTS NullTest", now;
2101 ses << "CREATE TABLE NullTest (i INTEGER, r REAL, v VARCHAR)", now;
2102 int i = 1;
2103 double f = 1.2;
2104 std::string s = "123";
2105
2106 ses << "INSERT INTO NullTest (i, r, v) VALUES (:i, :r, :v)", use(i), use(f), use(s), now;
2107 rs = (ses << "SELECT * FROM NullTest", now);
2108 rs.moveFirst();
2109 assertTrue (!rs.isNull("i"));
2110 assertTrue (rs["i"] == 1);
2111 assertTrue (!rs.isNull("v"));
2112 assertTrue (!rs.isNull("r"));
2113 assertTrue (rs["v"] == "123");
2114
2115 ses << "UPDATE NullTest SET v = :n WHERE i == :i", use(null), use(i), now;
2116 i = 2;
2117 f = 3.4;
2118 ses << "INSERT INTO NullTest (i, r, v) VALUES (:i, :r, :v)", use(i), use(null), use(null), now;
2119 rs = (ses << "SELECT i, r, v FROM NullTest ORDER BY i ASC", now);
2120 rs.moveFirst();
2121 assertTrue (!rs.isNull("i"));
2122 assertTrue (rs["i"] == 1);
2123 assertTrue (!rs.isNull("r"));
2124 assertTrue (rs.isNull("v"));
2125 assertTrue (rs["v"].isEmpty());
2126
2127 assertTrue (rs.moveNext());
2128 assertTrue (!rs.isNull("i"));
2129 assertTrue (rs["i"] == 2);
2130 Poco::Int64 i64 = 0;
2131 assertTrue (rs.nvl("i", i64) == 2);
2132 assertTrue (rs.nvl("i", 123) == 2);
2133
2134 assertTrue (rs.isNull("r"));
2135 assertTrue (rs.nvl("r", 123) == 123);
2136 assertTrue (rs.nvl("r", 1.5) == 1.5);
2137
2138 assertTrue (rs.isNull("v"));
2139 assertTrue (rs["v"].isEmpty());
2140 assertTrue (rs.nvl("v", s) == "123");
2141 }
2142
2143
testRowIterator()2144 void SQLiteTest::testRowIterator()
2145 {
2146 Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2147 ses << "DROP TABLE IF EXISTS Vectors", now;
2148 ses << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now;
2149
2150 std::vector<Tuple<int, double, std::string> > v;
2151 v.push_back(Tuple<int, double, std::string>(1, 1.5f, "3"));
2152 v.push_back(Tuple<int, double, std::string>(2, 2.5f, "4"));
2153 v.push_back(Tuple<int, double, std::string>(3, 3.5f, "5"));
2154 v.push_back(Tuple<int, double, std::string>(4, 4.5f, "6"));
2155
2156 ses << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now;
2157
2158 RecordSet rset(ses, "SELECT * FROM Vectors");
2159
2160 std::ostringstream osLoop;
2161 RecordSet::ConstIterator it = rset.begin();
2162 RecordSet::ConstIterator end = rset.end();
2163 for (int i = 1; it != end; ++it, ++i)
2164 {
2165 assertTrue (it->get(0) == i);
2166 osLoop << *it;
2167 }
2168 assertTrue (!osLoop.str().empty());
2169
2170 std::ostringstream osCopy;
2171 std::copy(rset.begin(), rset.end(), std::ostream_iterator<Row>(osCopy));
2172 assertTrue (osLoop.str() == osCopy.str());
2173 }
2174
2175
testAsync()2176 void SQLiteTest::testAsync()
2177 {
2178 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2179 tmp << "DROP TABLE IF EXISTS Strings", now;
2180 tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now;
2181
2182 int rowCount = 500;
2183 std::vector<int> data(rowCount);
2184 Statement stmt = (tmp << "INSERT INTO Strings VALUES(:str)", use(data));
2185 Statement::Result result = stmt.executeAsync();
2186 assertTrue (!stmt.isAsync());
2187 result.wait();
2188 assertTrue (500 == result.data());
2189
2190 Statement stmt1 = (tmp << "SELECT * FROM Strings", into(data), async, now);
2191 assertTrue (stmt1.isAsync());
2192 assertTrue (stmt1.wait() == rowCount);
2193
2194 stmt1.execute();
2195 try
2196 {
2197 stmt1.execute();
2198 fail ("must fail");
2199 }
2200 catch (InvalidAccessException&)
2201 {
2202 stmt1.wait();
2203 stmt1.execute();
2204 stmt1.wait();
2205 }
2206
2207 stmt = tmp << "SELECT * FROM Strings", into(data), async, now;
2208 assertTrue (stmt.isAsync());
2209 stmt.wait();
2210
2211 assertTrue (stmt.execute() == 0);
2212 assertTrue (stmt.isAsync());
2213 try
2214 {
2215 result = stmt.executeAsync();
2216 fail ("must fail");
2217 }
2218 catch (InvalidAccessException&)
2219 {
2220 stmt.wait();
2221 result = stmt.executeAsync();
2222 }
2223
2224 assertTrue (stmt.wait() == rowCount);
2225 assertTrue (result.data() == rowCount);
2226 stmt.setAsync(false);
2227 assertTrue (!stmt.isAsync());
2228 assertTrue (stmt.execute() == rowCount);
2229
2230 stmt = tmp << "SELECT * FROM Strings", into(data), sync, now;
2231 assertTrue (!stmt.isAsync());
2232 assertTrue (stmt.wait() == 0);
2233 assertTrue (stmt.execute() == rowCount);
2234 result = stmt.executeAsync();
2235 assertTrue (!stmt.isAsync());
2236 result.wait();
2237 assertTrue (result.data() == rowCount);
2238
2239 assertTrue (0 == rowCount % 10);
2240 int step = (int) (rowCount/10);
2241 data.clear();
2242 Statement stmt2 = (tmp << "SELECT * FROM Strings", into(data), async, limit(step));
2243 assertTrue (data.size() == 0);
2244 assertTrue (!stmt2.done());
2245 std::size_t rows = 0;
2246
2247 for (int i = 0; !stmt2.done(); i += step)
2248 {
2249 stmt2.execute();
2250 rows = stmt2.wait();
2251 assertTrue (step == rows);
2252 assertTrue (step + i == data.size());
2253 }
2254 assertTrue (stmt2.done());
2255 assertTrue (rowCount == data.size());
2256
2257 stmt2 = tmp << "SELECT * FROM Strings", reset;
2258 assertTrue (!stmt2.isAsync());
2259 assertTrue ("deque" == stmt2.getStorage());
2260 assertTrue (stmt2.execute() == rowCount);
2261 }
2262
2263
testAny()2264 void SQLiteTest::testAny()
2265 {
2266 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2267 tmp << "DROP TABLE IF EXISTS Anys", now;
2268 tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now;
2269
2270 Any i = Int32(42);
2271 Any f = double(42.5);
2272 Any s = std::string("42");
2273
2274 tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now;
2275
2276 int count = 0;
2277 tmp << "SELECT COUNT(*) FROM Anys", into(count), now;
2278 assertTrue (1 == count);
2279
2280 i = 0;
2281 f = 0.0;
2282 s = std::string("");
2283 tmp << "SELECT * FROM Anys", into(i), into(f), into(s), now;
2284 assertTrue (AnyCast<Int64>(i) == 42);
2285 assertTrue (AnyCast<double>(f) == 42.5);
2286 assertTrue (AnyCast<std::string>(s) == "42");
2287 }
2288
2289
testDynamicAny()2290 void SQLiteTest::testDynamicAny()
2291 {
2292 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2293 tmp << "DROP TABLE IF EXISTS Anys", now;
2294 tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR, empty INTEGER)", now;
2295
2296 DynamicAny i = Int32(42);
2297 DynamicAny f = double(42.5);
2298 DynamicAny s = std::string("42");
2299 DynamicAny e;
2300 assertTrue (e.isEmpty());
2301
2302 tmp << "INSERT INTO Anys VALUES (?, ?, ?, null)", use(i), use(f), use(s), now;
2303
2304 int count = 0;
2305 tmp << "SELECT COUNT(*) FROM Anys", into(count), now;
2306 assertTrue (1 == count);
2307
2308 i = 0;
2309 f = 0.0;
2310 s = std::string("");
2311 e = 1;
2312 assertTrue (!e.isEmpty());
2313 tmp << "SELECT * FROM Anys", into(i), into(f), into(s), into(e), now;
2314 assertTrue (42 == i);
2315 assertTrue (42.5 == f);
2316 assertTrue ("42" == s);
2317 assertTrue (e.isEmpty());
2318 }
2319
2320
testPair()2321 void SQLiteTest::testPair()
2322 {
2323 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2324 assertTrue (tmp.isConnected());
2325 std::string tableName("Simpsons");
2326 std::pair<std::string, int> junior = std::make_pair("Junior", 12);
2327 std::pair<std::string, int> senior = std::make_pair("Senior", 99);
2328
2329 int count = 0;
2330 std::string result;
2331
2332 tmp << "DROP TABLE IF EXISTS Simpsons", now;
2333 tmp << "CREATE TABLE IF NOT EXISTS Simpsons (LastName VARCHAR(30), Age INTEGER(3))", now;
2334 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
2335 assertTrue (result == tableName);
2336
2337 // these are fine
2338 tmp << "INSERT INTO Simpsons VALUES(?, ?)", use(junior), now;
2339 tmp << "INSERT INTO Simpsons VALUES(?, ?)", useRef(senior), now;
2340
2341 tmp << "SELECT COUNT(*) FROM Simpsons", into(count), now;
2342 assertTrue (2 == count);
2343
2344 std::vector<std::pair<std::string, int> > ret;
2345 tmp << "SELECT * FROM Simpsons", into(ret), range(2,2), now;
2346 assertTrue (ret[0].second == 12 || ret[1].second == 12);
2347 assertTrue (ret[0].second == 99 || ret[1].second == 99);
2348 assertTrue (ret[0].first == "Junior" || ret[1].first == "Junior");
2349 assertTrue (ret[0].first == "Senior" || ret[1].first == "Senior");
2350 }
2351
2352
testSQLChannel()2353 void SQLiteTest::testSQLChannel()
2354 {
2355 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2356 tmp << "DROP TABLE IF EXISTS T_POCO_LOG", now;
2357 tmp << "CREATE TABLE T_POCO_LOG (Source VARCHAR,"
2358 "Name VARCHAR,"
2359 "ProcessId INTEGER,"
2360 "Thread VARCHAR, "
2361 "ThreadId INTEGER,"
2362 "Priority INTEGER,"
2363 "Text VARCHAR,"
2364 "DateTime DATE)", now;
2365
2366 tmp << "DROP TABLE IF EXISTS T_POCO_LOG_ARCHIVE", now;
2367 tmp << "CREATE TABLE T_POCO_LOG_ARCHIVE (Source VARCHAR,"
2368 "Name VARCHAR,"
2369 "ProcessId INTEGER,"
2370 "Thread VARCHAR, "
2371 "ThreadId INTEGER,"
2372 "Priority INTEGER,"
2373 "Text VARCHAR,"
2374 "DateTime DATE)", now;
2375
2376 AutoPtr<SQLChannel> pChannel = new SQLChannel(Poco::Data::SQLite::Connector::KEY, "dummy.db", "TestSQLChannel");
2377 pChannel->setProperty("keep", "2 seconds");
2378
2379 Message msgInf("InformationSource", "a Informational async message", Message::PRIO_INFORMATION);
2380 pChannel->log(msgInf);
2381 Message msgWarn("WarningSource", "b Warning async message", Message::PRIO_WARNING);
2382 pChannel->log(msgWarn);
2383 pChannel->wait();
2384
2385 pChannel->setProperty("async", "false");
2386 Message msgInfS("InformationSource", "c Informational sync message", Message::PRIO_INFORMATION);
2387 pChannel->log(msgInfS);
2388 Message msgWarnS("WarningSource", "d Warning sync message", Message::PRIO_WARNING);
2389 pChannel->log(msgWarnS);
2390
2391 RecordSet rs(tmp, "SELECT * FROM T_POCO_LOG ORDER by Text");
2392 assertTrue (4 == rs.rowCount());
2393 assertTrue ("InformationSource" == rs["Source"]);
2394 assertTrue ("a Informational async message" == rs["Text"]);
2395 rs.moveNext();
2396 assertTrue ("WarningSource" == rs["Source"]);
2397 assertTrue ("b Warning async message" == rs["Text"]);
2398 rs.moveNext();
2399 assertTrue ("InformationSource" == rs["Source"]);
2400 assertTrue ("c Informational sync message" == rs["Text"]);
2401 rs.moveNext();
2402 assertTrue ("WarningSource" == rs["Source"]);
2403 assertTrue ("d Warning sync message" == rs["Text"]);
2404
2405 Thread::sleep(3000);
2406
2407 Message msgInfA("InformationSource", "e Informational sync message", Message::PRIO_INFORMATION);
2408 pChannel->log(msgInfA);
2409 Message msgWarnA("WarningSource", "f Warning sync message", Message::PRIO_WARNING);
2410 pChannel->log(msgWarnA);
2411
2412 RecordSet rs1(tmp, "SELECT * FROM T_POCO_LOG_ARCHIVE");
2413 assertTrue (4 == rs1.rowCount());
2414
2415 pChannel->setProperty("keep", "");
2416 assertTrue ("forever" == pChannel->getProperty("keep"));
2417 RecordSet rs2(tmp, "SELECT * FROM T_POCO_LOG ORDER by Text");
2418 assertTrue (2 == rs2.rowCount());
2419 assertTrue ("InformationSource" == rs2["Source"]);
2420 assertTrue ("e Informational sync message" == rs2["Text"]);
2421 rs2.moveNext();
2422 assertTrue ("WarningSource" == rs2["Source"]);
2423 assertTrue ("f Warning sync message" == rs2["Text"]);
2424 }
2425
2426
testSQLLogger()2427 void SQLiteTest::testSQLLogger()
2428 {
2429 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2430 tmp << "DROP TABLE IF EXISTS T_POCO_LOG", now;
2431 tmp << "CREATE TABLE T_POCO_LOG (Source VARCHAR,"
2432 "Name VARCHAR,"
2433 "ProcessId INTEGER,"
2434 "Thread VARCHAR, "
2435 "ThreadId INTEGER,"
2436 "Priority INTEGER,"
2437 "Text VARCHAR,"
2438 "DateTime DATE)", now;
2439
2440 {
2441 AutoPtr<SQLChannel> pChannel = new SQLChannel(Poco::Data::SQLite::Connector::KEY, "dummy.db", "TestSQLChannel");
2442 Logger& root = Logger::root();
2443 root.setChannel(pChannel);
2444 root.setLevel(Message::PRIO_INFORMATION);
2445
2446 root.information("Informational message");
2447 root.warning("Warning message");
2448 root.debug("Debug message");
2449 }
2450
2451 Thread::sleep(100);
2452 RecordSet rs(tmp, "SELECT * FROM T_POCO_LOG ORDER by DateTime");
2453 assertTrue (2 == rs.rowCount());
2454 assertTrue ("TestSQLChannel" == rs["Source"]);
2455 assertTrue ("Informational message" == rs["Text"]);
2456 rs.moveNext();
2457 assertTrue ("TestSQLChannel" == rs["Source"]);
2458 assertTrue ("Warning message" == rs["Text"]);
2459 }
2460
2461
testExternalBindingAndExtraction()2462 void SQLiteTest::testExternalBindingAndExtraction()
2463 {
2464 AbstractExtractionVecVec extractionVec;
2465 AbstractExtractionVec extraction;
2466 AbstractBindingVec binding;
2467
2468 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2469
2470 tmp << "DROP TABLE IF EXISTS Ints", now;
2471 tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now;
2472
2473 int x = 1, y = 2, z = 3;
2474 binding.push_back(use(x));
2475 binding.push_back(use(y));
2476 binding.push_back(use(z));
2477
2478 tmp << "INSERT INTO Ints VALUES (?,?,?)", use(binding), now;
2479
2480 Poco::Int64 a = 0, b = 0, c = 0;
2481 extraction.push_back(into(a));
2482 extraction.push_back(into(b));
2483 extraction.push_back(into(c));
2484 tmp << "SELECT * FROM Ints", into(extraction), now;
2485 assertTrue (a == x);
2486 assertTrue (b == y);
2487 assertTrue (c == z);
2488
2489 a = 0, b = 0, c = 0;
2490 extractionVec.push_back(extraction);
2491 tmp << "SELECT * FROM Ints", into(extractionVec), now;
2492 assertTrue (a == x);
2493 assertTrue (b == y);
2494 assertTrue (c == z);
2495 }
2496
2497
testBindingCount()2498 void SQLiteTest::testBindingCount()
2499 {
2500 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2501
2502 tmp << "DROP TABLE IF EXISTS Ints", now;
2503 tmp << "CREATE TABLE Ints (int0 INTEGER)", now;
2504
2505 int i = 42;
2506 try { tmp << "INSERT INTO Ints VALUES (?)", now; fail("must fail"); }
2507 catch (ParameterCountMismatchException&) { }
2508 tmp << "INSERT INTO Ints VALUES (?)", use(i), now;
2509
2510 i = 0;
2511 try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; fail("must fail"); }
2512 catch (ParameterCountMismatchException&) { }
2513 tmp << "SELECT int0 from Ints where int0 = ?", bind(42), into(i), now;
2514 assertTrue (42 == i);
2515
2516 tmp << "DROP TABLE IF EXISTS Ints", now;
2517 tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now;
2518
2519 try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; fail("must fail"); }
2520 catch (ParameterCountMismatchException&) { }
2521 }
2522
2523
testMultipleResults()2524 void SQLiteTest::testMultipleResults()
2525 {
2526 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2527
2528 tmp << "DROP TABLE IF EXISTS Person", now;
2529 tmp << "CREATE TABLE Person (LastName VARCHAR(30),"
2530 "FirstName VARCHAR(30),"
2531 "Address VARCHAR(30),"
2532 "Age INTEGER)", now;
2533
2534 typedef Tuple<std::string, std::string, std::string, Poco::UInt32> Person;
2535 std::vector<Person> people, people2;
2536 people.push_back(Person("Simpson", "Homer", "Springfield", 42));
2537 people.push_back(Person("Simpson", "Bart", "Springfield", 12));
2538 people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
2539
2540 Person pHomer;
2541 int aHomer = 42, aLisa = 10;
2542 Poco::UInt32 aBart = 0;
2543
2544 Poco::UInt32 pos1 = 1;
2545 int pos2 = 2;
2546
2547 Statement stmt(tmp);
2548 stmt << "INSERT INTO Person VALUES (?, ?, ?, ?);"
2549 "SELECT * FROM Person WHERE Age = ?; "
2550 "SELECT Age FROM Person WHERE FirstName = 'Bart'; "
2551 "SELECT * FROM Person WHERE Age = ? OR Age = ? ORDER BY Age;"
2552 , use(people)
2553 , into(pHomer, from(0)), use(aHomer)
2554 , into(aBart, pos1)
2555 , into(people2, from(pos2)), use(aLisa), use(aHomer);
2556
2557 assertTrue (7 == stmt.execute());
2558 assertTrue (Person("Simpson", "Homer", "Springfield", 42) == pHomer);
2559 assertTrue (12 == aBart);
2560 assertTrue (2 == people2.size());
2561 assertTrue (Person("Simpson", "Lisa", "Springfield", 10) == people2[0]);
2562 assertTrue (Person("Simpson", "Homer", "Springfield", 42) == people2[1]);
2563 }
2564
2565
testReconnect()2566 void SQLiteTest::testReconnect()
2567 {
2568 Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2569
2570 session << "DROP TABLE IF EXISTS Person", now;
2571 session << "CREATE TABLE Person (LastName VARCHAR(30),"
2572 "FirstName VARCHAR(30),"
2573 "Address VARCHAR(30),"
2574 "Age INTEGER)", now;
2575
2576 std::string lastName = "lastName";
2577 std::string firstName("firstName");
2578 std::string address("Address");
2579 int age = 133132;
2580 int count = 0;
2581 std::string result;
2582
2583 session << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age), now;
2584
2585 count = 0;
2586 session << "SELECT COUNT(*) FROM PERSON", into(count), now;
2587 assertTrue (count == 1);
2588
2589 assertTrue (session.isConnected());
2590 session.close();
2591 assertTrue (!session.isConnected());
2592 try
2593 {
2594 session << "SELECT LastName FROM PERSON", into(result), now;
2595 fail ("must fail");
2596 }
2597 catch(NotConnectedException&){ }
2598 assertTrue (!session.isConnected());
2599
2600 session.open();
2601 assertTrue (session.isConnected());
2602 session << "SELECT Age FROM PERSON", into(count), now;
2603 assertTrue (count == age);
2604 assertTrue (session.isConnected());
2605 }
2606
2607
testThreadModes()2608 void SQLiteTest::testThreadModes()
2609 {
2610 using namespace Poco::Data::SQLite;
2611 typedef std::vector<int> ModeVec;
2612
2613 assertTrue (Utility::isThreadSafe());
2614 assertTrue (Utility::getThreadMode() == Utility::THREAD_MODE_SERIAL);
2615
2616 const int datasize = 100;
2617 ModeVec mode;
2618 mode.push_back(Utility::THREAD_MODE_SINGLE);
2619 mode.push_back(Utility::THREAD_MODE_MULTI);
2620 mode.push_back(Utility::THREAD_MODE_SERIAL);
2621
2622 Poco::Stopwatch sw;
2623 ModeVec::iterator it = mode.begin();
2624 ModeVec::iterator end = mode.end();
2625 for (; it != end; ++it)
2626 {
2627 sw.restart();
2628 assertTrue (Utility::setThreadMode(*it));
2629 {
2630 Session tmp (Connector::KEY, "dummy.db");
2631 std::vector<int> iv(datasize);
2632 int count = 0;
2633
2634 tmp << "DROP TABLE IF EXISTS Ints", now;
2635 tmp << "CREATE TABLE IF NOT EXISTS Ints (theInt INTEGER)", now;
2636 Statement stmt((tmp << "INSERT INTO Ints VALUES(?)", use(iv)));
2637 tmp << "SELECT COUNT(*) FROM Ints", into(count), now;
2638 assertTrue (count == 0);
2639 stmt.execute();
2640 tmp << "SELECT COUNT(*) FROM Ints", into(count), now;
2641 assertTrue (count == datasize);
2642 count = 0;
2643 tmp << "SELECT COUNT(*) FROM Ints", into(count), now;
2644 assertTrue (count == datasize);
2645 }
2646 sw.stop();
2647 std::cout << "Mode: " << ((*it == Utility::THREAD_MODE_SINGLE) ? "single,"
2648 :(*it == Utility::THREAD_MODE_MULTI) ? "multi,"
2649 :(*it == Utility::THREAD_MODE_SERIAL) ? "serial,"
2650 : "unknown,") << " Time: " << sw.elapsed() / 1000.0 << " [ms]" << std::endl;
2651 }
2652
2653 assertTrue (Utility::setThreadMode(Utility::THREAD_MODE_SERIAL));
2654 assertTrue (Utility::isThreadSafe());
2655 assertTrue (Utility::getThreadMode() == Utility::THREAD_MODE_SERIAL);
2656 }
2657
2658
sqliteUpdateCallbackFn(void * pVal,int opCode,const char * pDB,const char * pTable,Poco::Int64 row)2659 void SQLiteTest::sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, const char* pTable, Poco::Int64 row)
2660 {
2661 poco_check_ptr(pVal);
2662 Poco::Int64* pV = reinterpret_cast<Poco::Int64*>(pVal);
2663 if (opCode == Utility::OPERATION_INSERT)
2664 {
2665 poco_assert (*pV == 2);
2666 poco_assert (row == 1);
2667 std::cout << "Inserted " << pDB << '.' << pTable << ", RowID=" << row << std::endl;
2668 ++_insertCounter;
2669 }
2670 else if (opCode == Utility::OPERATION_UPDATE)
2671 {
2672 poco_assert (*pV == 3);
2673 poco_assert (row == 1);
2674 std::cout << "Updated " << pDB << '.' << pTable << ", RowID=" << row << std::endl;
2675 ++_updateCounter;
2676 }
2677 else if (opCode == Utility::OPERATION_DELETE)
2678 {
2679 poco_assert (*pV == 4);
2680 poco_assert (row == 1);
2681 std::cout << "Deleted " << pDB << '.' << pTable << ", RowID=" << row << std::endl;
2682 ++_deleteCounter;
2683 }
2684 }
2685
2686
testUpdateCallback()2687 void SQLiteTest::testUpdateCallback()
2688 {
2689 // will be updated by callback
2690 _insertCounter = 0;
2691 _updateCounter = 0;
2692 _deleteCounter = 0;
2693
2694 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2695 assertTrue (tmp.isConnected());
2696 Poco::Int64 val = 1;
2697 assertTrue (Utility::registerUpdateHandler(tmp, &sqliteUpdateCallbackFn, &val));
2698
2699 std::string tableName("Person");
2700 std::string lastName("lastname");
2701 std::string firstName("firstname");
2702 std::string address("Address");
2703 int age = 133132;
2704 int count = 0;
2705 std::string result;
2706 tmp << "DROP TABLE IF EXISTS Person", now;
2707 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2708 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
2709 assertTrue (result == tableName);
2710
2711 // insert
2712 val = 2;
2713 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2714 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
2715 assertTrue (count == 1);
2716 assertTrue (_insertCounter == 1);
2717 tmp << "SELECT LastName FROM PERSON", into(result), now;
2718 assertTrue (lastName == result);
2719 tmp << "SELECT Age FROM PERSON", into(count), now;
2720 assertTrue (count == age);
2721
2722 // update
2723 val = 3;
2724 tmp << "UPDATE PERSON SET Age = -1", now;
2725 tmp << "SELECT Age FROM PERSON", into(age), now;
2726 assertTrue (-1 == age);
2727 assertTrue (_updateCounter == 1);
2728
2729 // delete
2730 val =4;
2731 tmp << "DELETE FROM Person WHERE Age = -1", now;
2732 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
2733 assertTrue (count == 0);
2734 assertTrue (_deleteCounter == 1);
2735
2736 // disarm callback and do the same drill
2737 assertTrue (Utility::registerUpdateHandler(tmp, (Utility::UpdateCallbackType) 0, &val));
2738
2739 tmp << "DROP TABLE IF EXISTS Person", now;
2740 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2741 tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now;
2742 assertTrue (result == tableName);
2743
2744 // must remain zero now
2745 _insertCounter = 0;
2746 _updateCounter = 0;
2747 _deleteCounter = 0;
2748
2749 // insert
2750 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2751 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
2752 assertTrue (count == 1);
2753 assertTrue (_insertCounter == 0);
2754 tmp << "SELECT LastName FROM PERSON", into(result), now;
2755 assertTrue (lastName == result);
2756 tmp << "SELECT Age FROM PERSON", into(count), now;
2757 assertTrue (count == age);
2758
2759 // update
2760 tmp << "UPDATE PERSON SET Age = -1", now;
2761 tmp << "SELECT Age FROM PERSON", into(age), now;
2762 assertTrue (-1 == age);
2763 assertTrue (_updateCounter == 0);
2764
2765 // delete
2766 tmp << "DELETE FROM Person WHERE Age = -1", now;
2767 tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
2768 assertTrue (count == 0);
2769 assertTrue (_deleteCounter == 0);
2770
2771 tmp.close();
2772 assertTrue (!tmp.isConnected());
2773 }
2774
2775
sqliteCommitCallbackFn(void * pVal)2776 int SQLiteTest::sqliteCommitCallbackFn(void* pVal)
2777 {
2778 poco_check_ptr(pVal);
2779 Poco::Int64* pV = reinterpret_cast<Poco::Int64*>(pVal);
2780 poco_assert ((*pV) == 1);
2781 ++(*pV);
2782 return 0;
2783 }
2784
2785
testCommitCallback()2786 void SQLiteTest::testCommitCallback()
2787 {
2788 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2789 assertTrue (tmp.isConnected());
2790 Poco::Int64 val = 1;
2791 assertTrue (Utility::registerUpdateHandler(tmp, &sqliteCommitCallbackFn, &val));
2792
2793 std::string tableName("Person");
2794 std::string lastName("lastname");
2795 std::string firstName("firstname");
2796 std::string address("Address");
2797 int age = 133132;
2798 std::string result;
2799 tmp.begin();
2800 tmp << "DROP TABLE IF EXISTS Person", now;
2801 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2802 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2803 tmp.commit();
2804 assertTrue (val == 2);
2805
2806 assertTrue (Utility::registerUpdateHandler(tmp, (Utility::CommitCallbackType) 0, &val));
2807 val = 0;
2808 tmp.begin();
2809 tmp << "DROP TABLE IF EXISTS Person", now;
2810 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2811 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2812 tmp.commit();
2813 assertTrue (val == 0);
2814
2815 }
2816
2817
sqliteRollbackCallbackFn(void * pVal)2818 void SQLiteTest::sqliteRollbackCallbackFn(void* pVal)
2819 {
2820 poco_check_ptr(pVal);
2821 Poco::Int64* pV = reinterpret_cast<Poco::Int64*>(pVal);
2822 poco_assert ((*pV) == 1);
2823 ++(*pV);
2824 }
2825
2826
testRollbackCallback()2827 void SQLiteTest::testRollbackCallback()
2828 {
2829 Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2830 assertTrue (tmp.isConnected());
2831 Poco::Int64 val = 1;
2832 assertTrue (Utility::registerUpdateHandler(tmp, &sqliteRollbackCallbackFn, &val));
2833
2834 std::string tableName("Person");
2835 std::string lastName("lastname");
2836 std::string firstName("firstname");
2837 std::string address("Address");
2838 int age = 133132;
2839 std::string result;
2840 tmp.begin();
2841 tmp << "DROP TABLE IF EXISTS Person", now;
2842 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2843 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2844 tmp.rollback();
2845 assertTrue (val == 2);
2846
2847 assertTrue (Utility::registerUpdateHandler(tmp, (Utility::RollbackCallbackType) 0, &val));
2848 val = 0;
2849 tmp.begin();
2850 tmp << "DROP TABLE IF EXISTS Person", now;
2851 tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2852 tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now;
2853 tmp.rollback();
2854 assertTrue (val == 0);
2855 }
2856
2857
testNotifier()2858 void SQLiteTest::testNotifier()
2859 {
2860 Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
2861 assertTrue (session.isConnected());
2862 session << "DROP TABLE IF EXISTS Person", now;
2863 session << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
2864
2865 Notifier notifier(session);
2866 notifier.insert += delegate(this, &SQLiteTest::onInsert);
2867 notifier.update += delegate(this, &SQLiteTest::onUpdate);
2868 notifier.erase += delegate(this, &SQLiteTest::onDelete);
2869
2870 _insertCounter = 0;
2871 _updateCounter = 0;
2872 _deleteCounter = 0;
2873
2874 session << "INSERT INTO PERSON VALUES('Simpson', 'Bart', 'Springfield', 12)", now;
2875 assertTrue (_insertCounter == 1);
2876 assertTrue (notifier.getRow() == 1);
2877 session << "INSERT INTO PERSON VALUES('Simpson', 'Lisa', 'Springfield', 10)", now;
2878 assertTrue (_insertCounter == 2);
2879 assertTrue (notifier.getRow() == 2);
2880 session << "INSERT INTO PERSON VALUES('Simpson', 'Homer', 'Springfield', 42)", now;
2881 assertTrue (_insertCounter == 3);
2882 assertTrue (notifier.getRow() == 3);
2883 assertTrue (notifier.getTable() == "Person");
2884
2885 session << "UPDATE PERSON SET Age = 11 WHERE FirstName = 'Bart'", now;
2886 assertTrue (_updateCounter == 1);
2887 assertTrue (notifier.getRow() == 1);
2888 session << "UPDATE PERSON SET Age = 9 WHERE FirstName = 'Lisa'", now;
2889 assertTrue (_updateCounter == 2);
2890 assertTrue (notifier.getRow() == 2);
2891 session << "UPDATE PERSON SET Age = 41 WHERE FirstName = 'Homer'", now;
2892 assertTrue (_updateCounter == 3);
2893 assertTrue (notifier.getRow() == 3);
2894
2895 notifier.setRow(0);
2896 // SQLite optimizes DELETE so here we must have
2897 // the WHERE clause to trigger per-row notifications
2898 session << "DELETE FROM PERSON WHERE 1=1", now;
2899 assertTrue (_deleteCounter == 3);
2900 assertTrue (notifier.getRow() == 3);
2901
2902 notifier.insert -= delegate(this, &SQLiteTest::onInsert);
2903 notifier.update -= delegate(this, &SQLiteTest::onUpdate);
2904 notifier.erase -= delegate(this, &SQLiteTest::onDelete);
2905
2906 notifier.disableUpdate();
2907
2908 notifier.setRow(0);
2909 _commitCounter = 0;
2910 notifier.commit += delegate(this, &SQLiteTest::onCommit);
2911 session.begin();
2912 session << "INSERT INTO PERSON VALUES('Simpson', 'Bart', 'Springfield', 12)", now;
2913 session << "INSERT INTO PERSON VALUES('Simpson', 'Lisa', 'Springfield', 10)", now;
2914 session << "INSERT INTO PERSON VALUES('Simpson', 'Homer', 'Springfield', 42)", now;
2915 session.commit();
2916 assertTrue (_commitCounter == 1);
2917 assertTrue (notifier.getRow() == 0);
2918 notifier.commit -= delegate(this, &SQLiteTest::onCommit);
2919
2920 session << "DELETE FROM PERSON", now;
2921
2922 notifier.setRow(0);
2923 _rollbackCounter = 0;
2924 notifier.rollback += delegate(this, &SQLiteTest::onRollback);
2925 session.begin();
2926 session << "INSERT INTO PERSON VALUES('Simpson', 'Bart', 'Springfield', 12)", now;
2927 session << "INSERT INTO PERSON VALUES('Simpson', 'Lisa', 'Springfield', 10)", now;
2928 session << "INSERT INTO PERSON VALUES('Simpson', 'Homer', 'Springfield', 42)", now;
2929 session.rollback();
2930 assertTrue (_rollbackCounter == 1);
2931 assertTrue (notifier.getRow() == 0);
2932 notifier.rollback -= delegate(this, &SQLiteTest::onRollback);
2933 }
2934
2935
onInsert(const void * pSender)2936 void SQLiteTest::onInsert(const void* pSender)
2937 {
2938 Notifier* pN = reinterpret_cast<Notifier*>(const_cast<void*>(pSender));
2939 std::cout << "onInsert, table:" << pN->getTable() << ", row:" << pN->getRow() << std::endl;
2940 ++_insertCounter;
2941 }
2942
2943
onUpdate(const void * pSender)2944 void SQLiteTest::onUpdate(const void* pSender)
2945 {
2946 Notifier* pN = reinterpret_cast<Notifier*>(const_cast<void*>(pSender));
2947 std::cout << "onUpdate, table:" << pN->getTable() << ", row:" << pN->getRow() << std::endl;
2948 ++_updateCounter;
2949 }
2950
2951
onDelete(const void * pSender)2952 void SQLiteTest::onDelete(const void* pSender)
2953 {
2954 Notifier* pN = reinterpret_cast<Notifier*>(const_cast<void*>(pSender));
2955 std::cout << "onDelete, table:" << pN->getTable() << ", row:" << pN->getRow() << std::endl;
2956 ++_deleteCounter;
2957 }
2958
2959
onCommit(const void * pSender)2960 void SQLiteTest::onCommit(const void* pSender)
2961 {
2962 Notifier* pN = reinterpret_cast<Notifier*>(const_cast<void*>(pSender));
2963 std::cout << "onCommit, table:" << pN->getTable() << ", row:" << pN->getRow() << std::endl;
2964 ++_commitCounter;
2965 }
2966
2967
onRollback(const void * pSender)2968 void SQLiteTest::onRollback(const void* pSender)
2969 {
2970 Notifier* pN = reinterpret_cast<Notifier*>(const_cast<void*>(pSender));
2971 std::cout << "onRollback, table:" << pN->getTable() << ", row:" << pN->getRow() << std::endl;
2972 ++_rollbackCounter;
2973 }
2974
2975
setTransactionIsolation(Session & session,Poco::UInt32 ti)2976 void SQLiteTest::setTransactionIsolation(Session& session, Poco::UInt32 ti)
2977 {
2978 if (session.hasTransactionIsolation(ti))
2979 {
2980 std::string funct = "setTransactionIsolation()";
2981
2982 try
2983 {
2984 Transaction t(session, false);
2985 t.setIsolation(ti);
2986
2987 assertTrue (ti == t.getIsolation());
2988 assertTrue (t.isIsolation(ti));
2989
2990 assertTrue (ti == session.getTransactionIsolation());
2991 assertTrue (session.isTransactionIsolation(ti));
2992 }
2993 catch(Poco::Exception& e){ std::cout << funct << ':' << e.displayText() << std::endl;}
2994 }
2995 else
2996 {
2997 std::cerr << '[' << name() << ']' << " Warning, transaction isolation not supported: ";
2998 switch (ti)
2999 {
3000 case Session::TRANSACTION_READ_COMMITTED:
3001 std::cerr << "READ COMMITTED"; break;
3002 case Session::TRANSACTION_READ_UNCOMMITTED:
3003 std::cerr << "READ UNCOMMITTED"; break;
3004 case Session::TRANSACTION_REPEATABLE_READ:
3005 std::cerr << "REPEATABLE READ"; break;
3006 case Session::TRANSACTION_SERIALIZABLE:
3007 std::cerr << "SERIALIZABLE"; break;
3008 default:
3009 std::cerr << "UNKNOWN"; break;
3010 }
3011 std::cerr << std::endl;
3012 }
3013 }
3014
3015
testSessionTransaction()3016 void SQLiteTest::testSessionTransaction()
3017 {
3018 Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
3019 assertTrue (session.isConnected());
3020
3021 session << "DROP TABLE IF EXISTS Person", now;
3022 session << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
3023
3024 if (!session.canTransact())
3025 {
3026 std::cout << "Session not capable of transactions." << std::endl;
3027 return;
3028 }
3029
3030 Session local (Poco::Data::SQLite::Connector::KEY, "dummy.db");
3031 assertTrue (local.isConnected());
3032
3033 try
3034 {
3035 local.setFeature("autoCommit", true);
3036 fail ("Setting SQLite auto-commit explicitly must fail!");
3037 }
3038 catch (NotImplementedException&) { }
3039 assertTrue (local.getFeature("autoCommit"));
3040
3041 std::string funct = "transaction()";
3042 std::vector<std::string> lastNames;
3043 std::vector<std::string> firstNames;
3044 std::vector<std::string> addresses;
3045 std::vector<int> ages;
3046 std::string tableName("Person");
3047 lastNames.push_back("LN1");
3048 lastNames.push_back("LN2");
3049 firstNames.push_back("FN1");
3050 firstNames.push_back("FN2");
3051 addresses.push_back("ADDR1");
3052 addresses.push_back("ADDR2");
3053 ages.push_back(1);
3054 ages.push_back(2);
3055 int count = 0, locCount = 0;
3056 std::string result;
3057
3058 setTransactionIsolation(session, Session::TRANSACTION_READ_COMMITTED);
3059
3060 session.begin();
3061 assertTrue (!session.getFeature("autoCommit"));
3062 assertTrue (session.isTransaction());
3063 session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
3064 assertTrue (session.isTransaction());
3065
3066 Statement stmt = (local << "SELECT COUNT(*) FROM Person", into(locCount), async, now);
3067
3068 session << "SELECT COUNT(*) FROM Person", into(count), now;
3069 assertTrue (2 == count);
3070 assertTrue (session.isTransaction());
3071 session.rollback();
3072 assertTrue (!session.isTransaction());
3073 assertTrue (session.getFeature("autoCommit"));
3074
3075 stmt.wait();
3076 assertTrue (0 == locCount);
3077
3078 session << "SELECT count(*) FROM Person", into(count), now;
3079 assertTrue (0 == count);
3080 assertTrue (!session.isTransaction());
3081
3082 session.begin();
3083 session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
3084 assertTrue (session.isTransaction());
3085 assertTrue (!session.getFeature("autoCommit"));
3086
3087 Statement stmt1 = (local << "SELECT COUNT(*) FROM Person", into(locCount), now);
3088 assertTrue (0 == locCount);
3089
3090 session << "SELECT count(*) FROM Person", into(count), now;
3091 assertTrue (2 == count);
3092
3093 session.commit();
3094 assertTrue (!session.isTransaction());
3095 assertTrue (session.getFeature("autoCommit"));
3096
3097 session << "SELECT count(*) FROM Person", into(count), now;
3098 assertTrue (2 == count);
3099
3100 /* TODO: see http://www.sqlite.org/pragma.html#pragma_read_uncommitted
3101 setTransactionIsolation(session, Session::TRANSACTION_READ_UNCOMMITTED);
3102 */
3103
3104 session.close();
3105 assertTrue (!session.isConnected());
3106
3107 local.close();
3108 assertTrue (!local.isConnected());
3109 }
3110
3111
testTransaction()3112 void SQLiteTest::testTransaction()
3113 {
3114 Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
3115 assertTrue (session.isConnected());
3116
3117 session << "DROP TABLE IF EXISTS Person", now;
3118 session << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
3119
3120 if (!session.canTransact())
3121 {
3122 std::cout << "Session not transaction-capable." << std::endl;
3123 return;
3124 }
3125
3126 Session local(Poco::Data::SQLite::Connector::KEY, "dummy.db");
3127
3128 setTransactionIsolation(session, Session::TRANSACTION_READ_COMMITTED);
3129
3130 std::string funct = "transaction()";
3131 std::vector<std::string> lastNames;
3132 std::vector<std::string> firstNames;
3133 std::vector<std::string> addresses;
3134 std::vector<int> ages;
3135 std::string tableName("Person");
3136 lastNames.push_back("LN1");
3137 lastNames.push_back("LN2");
3138 firstNames.push_back("FN1");
3139 firstNames.push_back("FN2");
3140 addresses.push_back("ADDR1");
3141 addresses.push_back("ADDR2");
3142 ages.push_back(1);
3143 ages.push_back(2);
3144 int count = 0, locCount = 0;
3145 std::string result;
3146
3147 session.setTransactionIsolation(Session::TRANSACTION_READ_COMMITTED);
3148
3149 {
3150 Transaction trans(session);
3151 assertTrue (trans.isActive());
3152 assertTrue (session.isTransaction());
3153
3154 session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
3155
3156 assertTrue (session.isTransaction());
3157 assertTrue (trans.isActive());
3158
3159 session << "SELECT COUNT(*) FROM Person", into(count), now;
3160 assertTrue (2 == count);
3161 assertTrue (session.isTransaction());
3162 assertTrue (trans.isActive());
3163 // no explicit commit, so transaction RAII must roll back here
3164 }
3165 assertTrue (!session.isTransaction());
3166
3167 session << "SELECT count(*) FROM Person", into(count), now;
3168 assertTrue (0 == count);
3169 assertTrue (!session.isTransaction());
3170
3171 {
3172 Transaction trans(session);
3173 session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now;
3174
3175 Statement stmt1 = (local << "SELECT COUNT(*) FROM Person", into(locCount), now);
3176
3177 assertTrue (session.isTransaction());
3178 assertTrue (trans.isActive());
3179 trans.commit();
3180 assertTrue (!session.isTransaction());
3181 assertTrue (!trans.isActive());
3182 assertTrue (0 == locCount);
3183 }
3184
3185 session << "SELECT count(*) FROM Person", into(count), now;
3186 assertTrue (2 == count);
3187 local << "SELECT count(*) FROM Person", into(count), now;
3188 assertTrue (2 == count);
3189
3190 session << "DELETE FROM Person", now;
3191
3192 std::string sql1 = format("INSERT INTO Person VALUES ('%s','%s','%s',%d)", lastNames[0], firstNames[0], addresses[0], ages[0]);
3193 std::string sql2 = format("INSERT INTO Person VALUES ('%s','%s','%s',%d)", lastNames[1], firstNames[1], addresses[1], ages[1]);
3194 std::vector<std::string> sql;
3195 sql.push_back(sql1);
3196 sql.push_back(sql2);
3197
3198 Transaction trans(session);
3199
3200 trans.execute(sql1, false);
3201 session << "SELECT count(*) FROM Person", into(count), now;
3202 assertTrue (1 == count);
3203 trans.execute(sql2, false);
3204 session << "SELECT count(*) FROM Person", into(count), now;
3205 assertTrue (2 == count);
3206
3207 Statement stmt2 = (local << "SELECT COUNT(*) FROM Person", into(locCount), now);
3208 assertTrue (0 == locCount);
3209
3210 trans.rollback();
3211
3212 session << "SELECT count(*) FROM Person", into(count), now;
3213 assertTrue (0 == count);
3214
3215 trans.execute(sql);
3216
3217 Statement stmt3 = (local << "SELECT COUNT(*) FROM Person", into(locCount), now);
3218 assertTrue (2 == locCount);
3219
3220 session << "SELECT count(*) FROM Person", into(count), now;
3221 assertTrue (2 == count);
3222
3223 session.close();
3224 assertTrue (!session.isConnected());
3225
3226 local.close();
3227 assertTrue (!local.isConnected());
3228 }
3229
3230
3231 struct TestCommitTransactor
3232 {
operator ()TestCommitTransactor3233 void operator () (Session& session) const
3234 {
3235 session << "INSERT INTO Person VALUES ('lastName','firstName','address',10)", now;
3236 }
3237 };
3238
3239
3240 struct TestRollbackTransactor
3241 {
operator ()TestRollbackTransactor3242 void operator () (Session& session) const
3243 {
3244 session << "INSERT INTO Person VALUES ('lastName','firstName','address',10)", now;
3245 throw Poco::Exception("test");
3246 }
3247 };
3248
3249
testTransactor()3250 void SQLiteTest::testTransactor()
3251 {
3252 Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
3253 assertTrue (session.isConnected());
3254
3255 session << "DROP TABLE IF EXISTS Person", now;
3256 session << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now;
3257
3258 std::string funct = "transaction()";
3259 int count = 0;
3260
3261 assertTrue (session.getFeature("autoCommit"));
3262 session.setTransactionIsolation(Session::TRANSACTION_READ_COMMITTED);
3263
3264 TestCommitTransactor ct;
3265 Transaction t1(session, ct);
3266
3267 session << "SELECT count(*) FROM Person", into(count), now;
3268 assertTrue (1 == count);
3269
3270 session << "DELETE FROM Person", now;
3271 session << "SELECT count(*) FROM Person", into(count), now;
3272 assertTrue (0 == count);
3273
3274 try
3275 {
3276 TestRollbackTransactor rt;
3277 Transaction t(session, rt);
3278 fail ("must fail");
3279 } catch (Poco::Exception&) { }
3280
3281 session << "SELECT count(*) FROM Person", into(count), now;
3282 assertTrue (0 == count);
3283
3284 try
3285 {
3286 TestRollbackTransactor rt;
3287 Transaction t(session);
3288 t.transact(rt);
3289 fail ("must fail");
3290 } catch (Poco::Exception&) { }
3291
3292 session << "SELECT count(*) FROM Person", into(count), now;
3293 assertTrue (0 == count);
3294
3295 try
3296 {
3297 TestRollbackTransactor rt;
3298 Transaction t(session, false);
3299 t.transact(rt);
3300 fail ("must fail");
3301 } catch (Poco::Exception&) { }
3302
3303 session << "SELECT count(*) FROM Person", into(count), now;
3304 assertTrue (0 == count);
3305
3306 try
3307 {
3308 TestRollbackTransactor rt;
3309 Transaction t(session, true);
3310 t.transact(rt);
3311 fail ("must fail");
3312 } catch (Poco::Exception&) { }
3313
3314 session << "SELECT count(*) FROM Person", into(count), now;
3315 assertTrue (0 == count);
3316
3317 session.close();
3318 assertTrue (!session.isConnected());
3319 }
3320
3321
testFTS3()3322 void SQLiteTest::testFTS3()
3323 {
3324 #ifdef SQLITE_ENABLE_FTS3
3325 Session session(Poco::Data::SQLite::Connector::KEY, "dummy.db");
3326 assertTrue (session.isConnected());
3327
3328 session << "DROP TABLE IF EXISTS docs", now;
3329 session << "CREATE VIRTUAL TABLE docs USING fts3()", now;
3330
3331 session << "INSERT INTO docs(docid, content) VALUES(1, 'a database is a software system')", now;
3332 session << "INSERT INTO docs(docid, content) VALUES(2, 'sqlite is a software system')", now;
3333 session << "INSERT INTO docs(docid, content) VALUES(3, 'sqlite is a database')", now;
3334
3335 int docid = 0;
3336 session << "SELECT docid FROM docs WHERE docs MATCH 'sqlite AND database'", into(docid), now;
3337 assertTrue (docid == 3);
3338
3339 docid = 0;
3340 session << "SELECT docid FROM docs WHERE docs MATCH 'database sqlite'", into(docid), now;
3341 assertTrue (docid == 3);
3342
3343 std::vector<int> docids;
3344 session << "SELECT docid FROM docs WHERE docs MATCH 'sqlite OR database' ORDER BY docid",
3345 into(docids), now;
3346 assertTrue (docids.size() == 3);
3347 assertTrue (docids[0] == 1);
3348 assertTrue (docids[1] == 2);
3349 assertTrue (docids[2] == 3);
3350
3351 std::string content;
3352 docid = 0;
3353 session << "SELECT docid, content FROM docs WHERE docs MATCH 'database NOT sqlite'",
3354 into(docid), into(content), now;
3355 assertTrue (docid == 1);
3356 assertTrue (content == "a database is a software system");
3357
3358 docid = 0;
3359 session << "SELECT count(*) FROM docs WHERE docs MATCH 'database and sqlite'", into(docid), now;
3360 assertTrue (docid == 0);
3361 #else
3362 std::cout << "SQLite FTS not enabled, test not executed." << std::endl;
3363 #endif // SQLITE_ENABLE_FTS3
3364 }
3365
3366
testIllegalFilePath()3367 void SQLiteTest::testIllegalFilePath()
3368 {
3369 try
3370 {
3371 Session tmp(Poco::Data::SQLite::Connector::KEY, "\\/some\\/illegal\\/path\\/dummy.db", 1);
3372 fail("must fail");
3373 }
3374 catch (ConnectionFailedException&)
3375 {
3376 }
3377 }
3378
3379
setUp()3380 void SQLiteTest::setUp()
3381 {
3382 }
3383
3384
tearDown()3385 void SQLiteTest::tearDown()
3386 {
3387 }
3388
3389
suite()3390 CppUnit::Test* SQLiteTest::suite()
3391 {
3392 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTest");
3393
3394 CppUnit_addTest(pSuite, SQLiteTest, testBinding);
3395 CppUnit_addTest(pSuite, SQLiteTest, testZeroRows);
3396 CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccess);
3397 CppUnit_addTest(pSuite, SQLiteTest, testInMemory);
3398 CppUnit_addTest(pSuite, SQLiteTest, testNullCharPointer);
3399 CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer);
3400 CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer2);
3401 CppUnit_addTest(pSuite, SQLiteTest, testComplexType);
3402 CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccessVector);
3403 CppUnit_addTest(pSuite, SQLiteTest, testComplexTypeVector);
3404 CppUnit_addTest(pSuite, SQLiteTest, testSharedPtrComplexTypeVector);
3405 CppUnit_addTest(pSuite, SQLiteTest, testInsertVector);
3406 CppUnit_addTest(pSuite, SQLiteTest, testInsertEmptyVector);
3407 CppUnit_addTest(pSuite, SQLiteTest, testAffectedRows);
3408 CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulk);
3409 CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulkVec);
3410 CppUnit_addTest(pSuite, SQLiteTest, testLimit);
3411 CppUnit_addTest(pSuite, SQLiteTest, testLimitOnce);
3412 CppUnit_addTest(pSuite, SQLiteTest, testLimitPrepare);
3413 CppUnit_addTest(pSuite, SQLiteTest, testLimitZero);
3414 CppUnit_addTest(pSuite, SQLiteTest, testPrepare);
3415 CppUnit_addTest(pSuite, SQLiteTest, testSetSimple);
3416 CppUnit_addTest(pSuite, SQLiteTest, testSetComplex);
3417 CppUnit_addTest(pSuite, SQLiteTest, testSetComplexUnique);
3418 CppUnit_addTest(pSuite, SQLiteTest, testMultiSetSimple);
3419 CppUnit_addTest(pSuite, SQLiteTest, testMultiSetComplex);
3420 CppUnit_addTest(pSuite, SQLiteTest, testMapComplex);
3421 CppUnit_addTest(pSuite, SQLiteTest, testMapComplexUnique);
3422 CppUnit_addTest(pSuite, SQLiteTest, testMultiMapComplex);
3423 CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingle);
3424 CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleStep);
3425 CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleFail);
3426 CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitOk);
3427 CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitFail);
3428 CppUnit_addTest(pSuite, SQLiteTest, testCombinedLimits);
3429 CppUnit_addTest(pSuite, SQLiteTest, testCombinedIllegalLimits);
3430 CppUnit_addTest(pSuite, SQLiteTest, testRange);
3431 CppUnit_addTest(pSuite, SQLiteTest, testIllegalRange);
3432 CppUnit_addTest(pSuite, SQLiteTest, testSingleSelect);
3433 CppUnit_addTest(pSuite, SQLiteTest, testEmptyDB);
3434 CppUnit_addTest(pSuite, SQLiteTest, testCLOB);
3435 CppUnit_addTest(pSuite, SQLiteTest, testTuple10);
3436 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector10);
3437 CppUnit_addTest(pSuite, SQLiteTest, testTuple9);
3438 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector9);
3439 CppUnit_addTest(pSuite, SQLiteTest, testTuple8);
3440 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector8);
3441 CppUnit_addTest(pSuite, SQLiteTest, testTuple7);
3442 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector7);
3443 CppUnit_addTest(pSuite, SQLiteTest, testTuple6);
3444 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector6);
3445 CppUnit_addTest(pSuite, SQLiteTest, testTuple5);
3446 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector5);
3447 CppUnit_addTest(pSuite, SQLiteTest, testTuple4);
3448 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector4);
3449 CppUnit_addTest(pSuite, SQLiteTest, testTuple3);
3450 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector3);
3451 CppUnit_addTest(pSuite, SQLiteTest, testTuple2);
3452 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector2);
3453 CppUnit_addTest(pSuite, SQLiteTest, testTuple1);
3454 CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1);
3455 CppUnit_addTest(pSuite, SQLiteTest, testDateTime);
3456 CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction);
3457 CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint);
3458 CppUnit_addTest(pSuite, SQLiteTest, testNullable);
3459 CppUnit_addTest(pSuite, SQLiteTest, testNulls);
3460 CppUnit_addTest(pSuite, SQLiteTest, testRowIterator);
3461 CppUnit_addTest(pSuite, SQLiteTest, testAsync);
3462 CppUnit_addTest(pSuite, SQLiteTest, testAny);
3463 CppUnit_addTest(pSuite, SQLiteTest, testDynamicAny);
3464 CppUnit_addTest(pSuite, SQLiteTest, testSQLChannel);
3465 CppUnit_addTest(pSuite, SQLiteTest, testSQLLogger);
3466 CppUnit_addTest(pSuite, SQLiteTest, testExternalBindingAndExtraction);
3467 CppUnit_addTest(pSuite, SQLiteTest, testBindingCount);
3468 CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults);
3469 CppUnit_addTest(pSuite, SQLiteTest, testPair);
3470 CppUnit_addTest(pSuite, SQLiteTest, testReconnect);
3471 CppUnit_addTest(pSuite, SQLiteTest, testThreadModes);
3472 CppUnit_addTest(pSuite, SQLiteTest, testUpdateCallback);
3473 CppUnit_addTest(pSuite, SQLiteTest, testCommitCallback);
3474 CppUnit_addTest(pSuite, SQLiteTest, testRollbackCallback);
3475 CppUnit_addTest(pSuite, SQLiteTest, testNotifier);
3476 CppUnit_addTest(pSuite, SQLiteTest, testSessionTransaction);
3477 CppUnit_addTest(pSuite, SQLiteTest, testTransaction);
3478 CppUnit_addTest(pSuite, SQLiteTest, testTransactor);
3479 CppUnit_addTest(pSuite, SQLiteTest, testFTS3);
3480 CppUnit_addTest(pSuite, SQLiteTest, testIllegalFilePath);
3481
3482 return pSuite;
3483 }
3484