// // SQLiteTest.cpp // // $Id: //poco/Main/Data/SQLite/testsuite/src/SQLiteTest.cpp#7 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #include "SQLiteTest.h" #include "CppUnit/TestCaller.h" #include "CppUnit/TestSuite.h" #include "Poco/Data/Date.h" #include "Poco/Data/Time.h" #include "Poco/Data/LOB.h" #include "Poco/Data/Statement.h" #include "Poco/Data/RecordSet.h" #include "Poco/Data/SQLChannel.h" #include "Poco/Data/SessionFactory.h" #include "Poco/Data/SQLite/Connector.h" #include "Poco/Data/SQLite/Utility.h" #include "Poco/Dynamic/Var.h" #include "Poco/Data/TypeHandler.h" #include "Poco/Nullable.h" #include "Poco/Data/DataException.h" #include "Poco/Data/SQLite/SQLiteException.h" #include "Poco/Tuple.h" #include "Poco/Any.h" #include "Poco/SharedPtr.h" #include "Poco/DynamicAny.h" #include "Poco/DateTime.h" #include "Poco/Logger.h" #include "Poco/Message.h" #include "Poco/Thread.h" #include "Poco/AutoPtr.h" #include "Poco/Exception.h" #include "Poco/RefCountedObject.h" #include using namespace Poco::Data::Keywords; using Poco::Data::Session; using Poco::Data::Statement; using Poco::Data::RecordSet; using Poco::Data::Column; using Poco::Data::Row; using Poco::Data::SQLChannel; using Poco::Data::LimitException; using Poco::Data::CLOB; using Poco::Data::Date; using Poco::Data::Time; using Poco::Data::AbstractExtractionVec; using Poco::Data::AbstractExtractionVecVec; using Poco::Data::AbstractBindingVec; using Poco::Data::NotConnectedException; using Poco::Nullable; using Poco::Tuple; using Poco::Any; using Poco::AnyCast; using Poco::DynamicAny; using Poco::DateTime; using Poco::Logger; using Poco::Message; using Poco::AutoPtr; using Poco::Thread; using Poco::InvalidAccessException; using Poco::RangeException; using Poco::BadCastException; using Poco::NotFoundException; using Poco::NullPointerException; using Poco::Data::SQLite::ConstraintViolationException; using Poco::Data::SQLite::ParameterCountMismatchException; using Poco::Int32; using Poco::Dynamic::Var; class Person { public: Person(){_age = 0;} Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):_lastName(ln), _firstName(fn), _address(adr), _age(a) { } bool operator==(const Person& other) const { return _lastName == other._lastName && _firstName == other._firstName && _address == other._address && _age == other._age; } bool operator < (const Person& p) const { if (_age < p._age) return true; if (_lastName < p._lastName) return true; if (_firstName < p._firstName) return true; return (_address < p._address); } const std::string& operator () () const /// This method is required so we can extract data to a map! { // we choose the lastName as examplary key return _lastName; } const std::string& getLastName() const { return _lastName; } void setLastName(const std::string& lastName) { _lastName = lastName; } const std::string& getFirstName() const { return _firstName; } void setFirstName(const std::string& firstName) { _firstName = firstName; } const std::string& getAddress() const { return _address; } void setAddress(const std::string& address) { _address = address; } const int& getAge() const { return _age; } void setAge(const int& age) { _age = age; } private: std::string _lastName; std::string _firstName; std::string _address; int _age; }; namespace Poco { namespace Data { template <> class TypeHandler { public: static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir) { // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) poco_assert_dbg (pBinder != 0); pBinder->bind(pos++, obj.getLastName(), dir); pBinder->bind(pos++, obj.getFirstName(), dir); pBinder->bind(pos++, obj.getAddress(), dir); pBinder->bind(pos++, obj.getAge(), dir); } static void prepare(std::size_t pos, const Person& obj, AbstractPreparator* pPrepare) { // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) poco_assert_dbg (pPrepare != 0); pPrepare->prepare(pos++, obj.getLastName()); pPrepare->prepare(pos++, obj.getFirstName()); pPrepare->prepare(pos++, obj.getAddress()); pPrepare->prepare(pos++, obj.getAge()); } static std::size_t size() { return 4; } static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt) { poco_assert_dbg (pExt != 0); std::string lastName; std::string firstName; std::string address; int age; if (pExt->extract(pos++, lastName)) obj.setLastName(lastName); else obj.setLastName(defVal.getLastName()); if (pExt->extract(pos++, firstName)) obj.setFirstName(firstName); else obj.setFirstName(defVal.getFirstName()); if (pExt->extract(pos++, address)) obj.setAddress(address); else obj.setAddress(defVal.getAddress()); if (pExt->extract(pos++, age)) obj.setAge(age); else obj.setAge(defVal.getAge()); } private: TypeHandler(); ~TypeHandler(); TypeHandler(const TypeHandler&); TypeHandler& operator=(const TypeHandler&); }; } } // namespace Poco::Data SQLiteTest::SQLiteTest(const std::string& name): CppUnit::TestCase(name) { Poco::Data::SQLite::Connector::registerConnector(); } SQLiteTest::~SQLiteTest() { Poco::Data::SQLite::Connector::unregisterConnector(); } void SQLiteTest::testBinding() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); assert (tmp.isConnected()); std::string tableName("Simpsons"); std::string lastName("Simpson"); std::string firstName("Bart"); std::string address("Springfield"); int age = 12; std::string& rLastName(lastName); std::string& rFirstName(firstName); std::string& rAddress(address); int& rAge = age; const std::string& crLastName(lastName); const std::string& crFirstName(firstName); const std::string& crAddress(address); const int& crAge = age; int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Simpsons", now; tmp << "CREATE TABLE IF NOT EXISTS Simpsons (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; assert (result == tableName); // following should not compile: //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use("Simpson"), use("Bart"), use("Springfield"), use(age), now; //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(lastName), use(firstName), use(address), use(12), now; //tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef(lastName), useRef(firstName), useRef(address), useRef(12), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef("Simpson"), useRef("Bart"), useRef("Springfield"), useRef(age), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", use(rLastName), use(rFirstName), use(rAddress), use(rAge), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", useRef(crLastName), useRef(crFirstName), useRef(crAddress), useRef(crAge), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind("Simpson"), bind("Bart"), bind("Springfield"), bind(12), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind(rLastName), bind(rFirstName), bind(rAddress), bind(rAge), now; tmp << "INSERT INTO Simpsons VALUES(?, ?, ?, ?)", bind(crLastName), bind(crFirstName), bind(crAddress), bind(crAge), now; tmp << "SELECT COUNT(*) FROM Simpsons", into(count), now; assert (6 == count); } void SQLiteTest::testSimpleAccess() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); assert (tmp.isConnected()); std::string tableName("Person"); std::string lastName("lastname"); std::string firstName("firstname"); std::string address("Address"); int age = 133132; int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; assert (result == tableName); tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); tmp << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); tmp << "SELECT Age FROM PERSON", into(count), now; assert (count == age); tmp << "UPDATE PERSON SET Age = -1", now; tmp << "SELECT Age FROM PERSON", into(age), now; assert (-1 == age); tmp.close(); assert (!tmp.isConnected()); } void SQLiteTest::testInMemory() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); assert (tmp.isConnected()); std::string tableName("Person"); std::string lastName("lastname"); std::string firstName("firstname"); std::string address("Address"); int age = 133132; int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; assert (result == tableName); tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now; // load db from file to memory Session mem (Poco::Data::SQLite::Connector::KEY, ":memory:"); sqlite3* p = 0; Any a = p; // ??? clang generated code fails to AnyCast without these sqlite3* pMemHandle = AnyCast(mem.getProperty("handle")); assert (Poco::Data::SQLite::Utility::fileToMemory(pMemHandle, "dummy.db")); mem << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); mem << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); mem << "SELECT Age FROM PERSON", into(count), now; assert (count == age); mem << "UPDATE PERSON SET Age = -1", now; mem << "SELECT Age FROM PERSON", into(age), now; assert (-1 == age); // save db from memory to file on the disk Session dsk (Poco::Data::SQLite::Connector::KEY, "dsk.db"); assert (Poco::Data::SQLite::Utility::memoryToFile("dsk.db", pMemHandle)); dsk << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); dsk << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); dsk << "SELECT Age FROM PERSON", into(count), now; assert (count == age); dsk << "UPDATE PERSON SET Age = -1", now; dsk << "SELECT Age FROM PERSON", into(age), now; assert (-1 == age); tmp.close(); mem.close(); dsk.close(); assert (!tmp.isConnected()); assert (!mem.isConnected()); assert (!dsk.isConnected()); } void SQLiteTest::testNullCharPointer() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::string lastName("lastname"); int age = 100; int count = 100; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind(lastName), bind("firstname"), bind("Address"), bind(0), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); tmp << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); tmp << "SELECT Age FROM PERSON", into(age), now; assert (0 == age); try { const char* pc = 0; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind("lastname"), bind("firstname"), bind("Address"), bind(pc), now; fail ("must fail"); } catch (NullPointerException&) { } tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); tmp << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); tmp << "SELECT Age FROM PERSON", into(age), now; assert (0 == age); } void SQLiteTest::testInsertCharPointer() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::string tableName("Person"); std::string lastName("lastname"); std::string firstName("firstname"); std::string address("Address"); int age = 133132; int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; const char* pc = 0; try { tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind(pc), now; fail ("must fail"); } catch (NullPointerException&) { } pc = (const char*) std::calloc(9, sizeof(char)); poco_check_ptr (pc); std::strncpy((char*) pc, "lastname", 8); Statement stmt = (tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind(pc), bind("firstname"), bind("Address"), bind(133132)); std::free((void*) pc); pc = 0; assert (1 == stmt.execute()); tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); tmp << "SELECT LastName FROM PERSON", into(result), now; assert (lastName == result); tmp << "SELECT Age FROM PERSON", into(count), now; assert (count == age); } void SQLiteTest::testInsertCharPointer2() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::string tableName("Person"); std::string lastName("lastname"); std::string firstName("firstname"); std::string address("Address"); int age = 133132; int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind("lastname"), bind("firstname"), bind("Address"), bind(133132), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); Statement stmt1 = (tmp << "SELECT LastName FROM PERSON", into(result)); stmt1.execute(); assert (lastName == result); count = 0; Statement stmt2 = (tmp << "SELECT Age FROM PERSON", into(count)); stmt2.execute(); assert (count == age); } void SQLiteTest::testComplexType() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p1), now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p2), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person c1; Person c2; tmp << "SELECT * FROM PERSON WHERE LASTNAME = :ln", into(c1), useRef(p1.getLastName()), now; assert (c1 == p1); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName1 VARCHAR(30), FirstName1 VARCHAR, Address1 VARCHAR, Age1 INTEGER(3)," "LastName2 VARCHAR(30), FirstName2 VARCHAR, Address2 VARCHAR, Age2 INTEGER(3))", now; Tuple t(p1,p2); tmp << "INSERT INTO PERSON VALUES(:ln1, :fn1, :ad1, :age1, :ln2, :fn2, :ad2, :age2)", use(t), now; Tuple ret; assert (ret != t); tmp << "SELECT * FROM PERSON", into(ret), now; assert (ret == t); } void SQLiteTest::testSimpleAccessVector() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector lastNames; std::vector firstNames; std::vector addresses; std::vector ages; std::string tableName("Person"); lastNames.push_back("LN1"); lastNames.push_back("LN2"); firstNames.push_back("FN1"); firstNames.push_back("FN2"); addresses.push_back("ADDR1"); addresses.push_back("ADDR2"); ages.push_back(1); ages.push_back(2); int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::vector lastNamesR; std::vector firstNamesR; std::vector addressesR; std::vector agesR; tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; assert (ages == agesR); assert (lastNames == lastNamesR); assert (firstNames == firstNamesR); assert (addresses == addressesR); } void SQLiteTest::testComplexTypeVector() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector people; people.push_back(Person("LN1", "FN1", "ADDR1", 1)); people.push_back(Person("LN2", "FN2", "ADDR2", 2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::vector result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result == people); } void SQLiteTest::testSharedPtrComplexTypeVector() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector > people; people.push_back(new Person("LN1", "FN1", "ADDR1", 1)); people.push_back(new Person("LN2", "FN2", "ADDR2", 2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::vector > result; tmp << "SELECT * FROM PERSON", into(result), now; assert (*result[0] == *people[0]); assert (*result[1] == *people[1]); } void SQLiteTest::testInsertVector() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector str; str.push_back("s1"); str.push_back("s2"); str.push_back("s3"); str.push_back("s3"); int count = 100; tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; { Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(str))); tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 0); stmt.execute(); tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 4); } count = 0; tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 4); } void SQLiteTest::testInsertEmptyVector() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector str; tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; try { tmp << "INSERT INTO Strings VALUES(:str)", use(str), now; fail("empty collectons should not work"); } catch (Poco::Exception&) { } } void SQLiteTest::testAffectedRows() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector str; str.push_back("s1"); str.push_back("s2"); str.push_back("s3"); str.push_back("s3"); int count = 100; tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; Statement stmt((tmp << "SELECT * FROM Strings")); tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 0); assert (0 == stmt.execute()); Statement stmt1((tmp << "INSERT INTO Strings VALUES(:str)", use(str))); tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 0); assert (4 == stmt1.execute()); tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 4); Statement stmt2(tmp << "UPDATE Strings SET str = 's4' WHERE str = 's3'"); assert (2 == stmt2.execute()); Statement stmt3(tmp << "DELETE FROM Strings WHERE str = 's1'"); assert (1 == stmt3.execute()); // see SQLiteStatementImpl::affectedRows() documentation for explanation // why "WHERE 1" is necessary here Statement stmt4(tmp << "DELETE FROM Strings WHERE 1"); assert (3 == stmt4.execute()); } void SQLiteTest::testInsertSingleBulk() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; int x = 0; Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(x))); for (int i = 0; x < 100; ++x) { i = stmt.execute(); assert (1 == i); } int count = 0; tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 100); tmp << "SELECT SUM(str) FROM Strings", into(count), now; assert (count == ((0+99)*100/2)); } void SQLiteTest::testInsertSingleBulkVec() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; data.push_back(0); data.push_back(1); Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); for (int x = 0; x < 100; x += 2) { data[0] = x; data[1] = x+1; stmt.execute(); } int count = 0; tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 100); tmp << "SELECT SUM(str) FROM Strings", into(count), now; assert (count == ((0+99)*100/2)); } void SQLiteTest::testLimit() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; for (int x = 0; x < 100; ++x) { data.push_back(x); } tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; std::vector retData; tmp << "SELECT * FROM Strings", into(retData), limit(50), now; assert (retData.size() == 50); for (int x = 0; x < 50; ++x) { assert(data[x] == retData[x]); } } void SQLiteTest::testLimitZero() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; for (int x = 0; x < 100; ++x) { data.push_back(x); } tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; std::vector retData; tmp << "SELECT * FROM Strings", into(retData), limit(0), now; // stupid test, but at least we shouldn't crash assert (retData.size() == 0); } void SQLiteTest::testLimitOnce() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; for (int x = 0; x < 101; ++x) { data.push_back(x); } tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; std::vector retData; Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50), now); assert (!stmt.done()); assert (retData.size() == 50); stmt.execute(); assert (!stmt.done()); assert (retData.size() == 100); stmt.execute(); assert (stmt.done()); assert (retData.size() == 101); for (int x = 0; x < 101; ++x) { assert(data[x] == retData[x]); } } void SQLiteTest::testLimitPrepare() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; for (int x = 0; x < 100; ++x) { data.push_back(x); } Statement stmtIns = (tmp << "INSERT INTO Strings VALUES(:str)", use(data)); assert (100 == stmtIns.execute()); std::vector retData; Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50)); assert (retData.size() == 0); assert (!stmt.done()); Poco::UInt32 rows = stmt.execute(); assert (50 == rows); assert (!stmt.done()); assert (retData.size() == 50); rows = stmt.execute(); assert (50 == rows); assert (stmt.done()); assert (retData.size() == 100); rows = stmt.execute(); // will restart execution! assert (50 == rows); assert (!stmt.done()); assert (retData.size() == 150); for (int x = 0; x < 150; ++x) { assert(data[x%100] == retData[x]); } } void SQLiteTest::testPrepare() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; std::vector data; for (int x = 0; x < 100; x += 2) { data.push_back(x); } { Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); } // stmt should not have been executed when destroyed int count = 100; tmp << "SELECT COUNT(*) FROM Strings", into(count), now; assert (count == 0); } void SQLiteTest::testSetSimple() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::set lastNames; std::set firstNames; std::set addresses; std::set ages; std::string tableName("Person"); lastNames.insert("LN1"); lastNames.insert("LN2"); firstNames.insert("FN1"); firstNames.insert("FN2"); addresses.insert("ADDR1"); addresses.insert("ADDR2"); ages.insert(1); ages.insert(2); int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::set lastNamesR; std::set firstNamesR; std::set addressesR; std::set agesR; tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; assert (ages == agesR); assert (lastNames == lastNamesR); assert (firstNames == firstNamesR); assert (addresses == addressesR); } void SQLiteTest::testSetComplex() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::set people; people.insert(Person("LN1", "FN1", "ADDR1", 1)); people.insert(Person("LN2", "FN2", "ADDR2", 2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::set result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result == people); } void SQLiteTest::testSetComplexUnique() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::vector people; Person p1("LN1", "FN1", "ADDR1", 1); people.push_back(p1); people.push_back(p1); people.push_back(p1); people.push_back(p1); Person p2("LN2", "FN2", "ADDR2", 2); people.push_back(p2); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 5); std::set result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result.size() == 2); assert (*result.begin() == p1); assert (*++result.begin() == p2); } void SQLiteTest::testMultiSetSimple() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multiset lastNames; std::multiset firstNames; std::multiset addresses; std::multiset ages; std::string tableName("Person"); lastNames.insert("LN1"); lastNames.insert("LN2"); firstNames.insert("FN1"); firstNames.insert("FN2"); addresses.insert("ADDR1"); addresses.insert("ADDR2"); ages.insert(1); ages.insert(2); int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::multiset lastNamesR; std::multiset firstNamesR; std::multiset addressesR; std::multiset agesR; tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; assert (ages.size() == agesR.size()); assert (lastNames.size() == lastNamesR.size()); assert (firstNames.size() == firstNamesR.size()); assert (addresses.size() == addressesR.size()); } void SQLiteTest::testMultiSetComplex() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multiset people; Person p1("LN1", "FN1", "ADDR1", 1); people.insert(p1); people.insert(p1); people.insert(p1); people.insert(p1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(p2); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 5); std::multiset result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result.size() == people.size()); } void SQLiteTest::testMapComplex() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::map people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN2", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::map result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result == people); } void SQLiteTest::testMapComplexUnique() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN2", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 5); std::map result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result.size() == 2); } void SQLiteTest::testMultiMapComplex() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN2", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 5); std::multimap result; tmp << "SELECT * FROM PERSON", into(result), now; assert (result.size() == people.size()); } void SQLiteTest::testSelectIntoSingle() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; tmp << "SELECT * FROM PERSON", into(result), limit(1), now; // will return 1 object into one single result assert (result == p1); } void SQLiteTest::testSelectIntoSingleStep() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); stmt.execute(); assert (result == p1); assert (!stmt.done()); stmt.execute(); assert (result == p2); assert (stmt.done()); } void SQLiteTest::testSelectIntoSingleFail() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), limit(2, true), now; assert (count == 2); Person result; try { tmp << "SELECT * FROM PERSON", into(result), limit(1, true), now; // will fail now fail("hardLimit is set: must fail"); } catch(Poco::Data::LimitException&) { } } void SQLiteTest::testLowerLimitOk() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; try { tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one! fail("Not enough space for results"); } catch(Poco::Exception&) { } } void SQLiteTest::testSingleSelect() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); stmt.execute(); assert (result == p1); assert (!stmt.done()); stmt.execute(); assert (result == p2); assert (stmt.done()); } void SQLiteTest::testLowerLimitFail() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; try { tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), now; // will fail fail("should fail. not enough data"); } catch(Poco::Exception&) { } } void SQLiteTest::testCombinedLimits() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; std::string a, b, c; Statement stmt = (tmp << "SELECT LastName, FirstName, Address FROM Person WHERE Address = 'invalid value'", into(a), into(b), into(c), limit(1)); assert (!stmt.done() && stmt.execute() == 0); int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::vector result; tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), upperLimit(2), now; // will return 2 objects assert (result.size() == 2); assert (result[0] == p1); assert (result[1] == p2); } void SQLiteTest::testRange() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); std::vector result; tmp << "SELECT * FROM PERSON", into(result), range(2, 2), now; // will return 2 objects assert (result.size() == 2); assert (result[0] == p1); assert (result[1] == p2); } void SQLiteTest::testCombinedIllegalLimits() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; try { tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), upperLimit(2), now; fail("lower > upper is not allowed"); } catch(LimitException&) { } } void SQLiteTest::testIllegalRange() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); std::multimap people; Person p1("LN1", "FN1", "ADDR1", 1); Person p2("LN2", "FN2", "ADDR2", 2); people.insert(std::make_pair("LN1", p1)); people.insert(std::make_pair("LN1", p2)); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 2); Person result; try { tmp << "SELECT * FROM PERSON", into(result), range(3, 2), now; fail("lower > upper is not allowed"); } catch(LimitException&) { } } void SQLiteTest::testEmptyDB() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; int count = 0; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 0); Person result; Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); stmt.execute(); assert (result.getFirstName().empty()); assert (stmt.done()); } void SQLiteTest::testCLOB() { std::string lastName("lastname"); std::string firstName("firstname"); std::string address("Address"); Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; CLOB img("0123456789", 10); int count = 0; tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use(lastName), use(firstName), use(address), use(img), now; tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); CLOB res; poco_assert (res.size() == 0); tmp << "SELECT Image FROM Person WHERE LastName == :ln", bind("lastname"), into(res), now; poco_assert (res == img); } void SQLiteTest::testTuple10() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7,8,9); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector10() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7,8,9); Tuple t10(10,11,12,13,14,15,16,17,18,19); Tuple t100(100,101,102,103,104,105,106,107,108,109); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple9() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER, int8 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7,8); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector9() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER, int8 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7,8); Tuple t10(10,11,12,13,14,15,16,17,18); Tuple t100(100,101,102,103,104,105,106,107,108); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple8() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector8() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " "int7 INTEGER)", now; Tuple t(0,1,2,3,4,5,6,7); Tuple t10(10,11,12,13,14,15,16,17); Tuple t100(100,101,102,103,104,105,106,107); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple7() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; Tuple t(0,1,2,3,4,5,6); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14,-15,-16); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector7() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; Tuple t(0,1,2,3,4,5,6); Tuple t10(10,11,12,13,14,15,16); Tuple t100(100,101,102,103,104,105,106); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple6() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; Tuple t(0,1,2,3,4,5); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14,-15); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector6() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; Tuple t(0,1,2,3,4,5); Tuple t10(10,11,12,13,14,15); Tuple t100(100,101,102,103,104,105); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple5() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; Tuple t(0,1,2,3,4); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13,-14); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector5() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; Tuple t(0,1,2,3,4); Tuple t10(10,11,12,13,14); Tuple t100(100,101,102,103,104); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple4() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; Tuple t(0,1,2,3); tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(t), now; Tuple ret(-10,-11,-12,-13); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector4() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; Tuple t(0,1,2,3); Tuple t10(10,11,12,13); Tuple t100(100,101,102,103); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple3() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; Tuple t(0,1,2); tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(t), now; Tuple ret(-10,-11,-12); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector3() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples " "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; Tuple t(0,1,2); Tuple t10(10,11,12); Tuple t100(100,101,102); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple2() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; Tuple t(0,1); tmp << "INSERT INTO Tuples VALUES (?,?)", use(t), now; Tuple ret(-10,-11); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector2() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; Tuple t(0,1); Tuple t10(10,11); Tuple t100(100,101); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?,?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testTuple1() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; Tuple t(0); tmp << "INSERT INTO Tuples VALUES (?)", use(t), now; Tuple ret(-10); assert (ret != t); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == t); } void SQLiteTest::testTupleVector1() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Tuples", now; tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; Tuple t(0); Tuple t10(10); Tuple t100(100); std::vector > v; v.push_back(t); v.push_back(t10); v.push_back(t100); tmp << "INSERT INTO Tuples VALUES (?)", use(v), now; int count = 0; tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; assert (v.size() == count); std::vector > ret; assert (ret != v); tmp << "SELECT * FROM Tuples", into(ret), now; assert (ret == v); } void SQLiteTest::testDateTime() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS DateTimes", now; tmp << "CREATE TABLE DateTimes (dt0 DATE)", now; DateTime dt(1965, 6, 18, 5, 35, 1); tmp << "INSERT INTO DateTimes VALUES (?)", use(dt), now; DateTime rdt; assert (rdt != dt); tmp << "SELECT * FROM DateTimes", into(rdt), now; assert (rdt == dt); tmp << "DELETE FROM DateTimes", now; Date d(dt); tmp << "INSERT INTO DateTimes VALUES (?)", use(d), now; Date rd; assert (rd != d); tmp << "SELECT * FROM DateTimes", into(rd), now; assert (rd == d); tmp << "DELETE FROM DateTimes", now; Time t(dt); tmp << "INSERT INTO DateTimes VALUES (?)", use(t), now; Time rt; assert (rt != t); tmp << "SELECT * FROM DateTimes", into(rt), now; assert (rt == t); } void SQLiteTest::testInternalExtraction() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Vectors", now; tmp << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; std::vector > v; v.push_back(Tuple(1, 1.5, "3")); v.push_back(Tuple(2, 2.5, "4")); v.push_back(Tuple(3, 3.5, "5")); v.push_back(Tuple(4, 4.5, "6")); tmp << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; Statement stmt = (tmp << "SELECT * FROM Vectors", now); RecordSet rset(stmt); assert (3 == rset.columnCount()); assert (4 == rset.rowCount()); RecordSet rset2(rset); assert (3 == rset2.columnCount()); assert (4 == rset2.rowCount()); Int32 a = rset.value(0,2); assert (3 == a); int c = rset2.value(0); assert (1 == c); Int32 b = rset2.value("InT0",2); assert (3 == b); double d = rset.value(1,0); assert (1.5 == d); std::string s = rset.value(2,1); assert ("4" == s); typedef std::deque IntDeq; const Column& col = rset.column(0); assert (col[0] == 1); try { rset.column(100); fail ("must fail"); } catch (RangeException&) { } const Column& col1 = rset.column(0); assert ("int0" == col1.name()); Column::Iterator it = col1.begin(); Column::Iterator itEnd = col1.end(); int counter = 1; for (; it != itEnd; ++it, ++counter) assert (counter == *it); rset = (tmp << "SELECT COUNT(*) FROM Vectors", now); s = rset.value(0,0); assert ("4" == s); stmt = (tmp << "DELETE FROM Vectors", now); rset = stmt; try { rset.column(0); fail ("must fail"); } catch (RangeException&) { } } void SQLiteTest::testPrimaryKeyConstraint() { Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db"); ses << "DROP TABLE IF EXISTS LogTest", now; ses << "CREATE TABLE LogTest (Id INTEGER PRIMARY KEY, Time INTEGER, Value INTEGER)", now; const double value = -200000000000.0; const Poco::Int64 timeIn = static_cast(22329988776655.0); int id = 1; ses.begin(); for(int i = 0; i < 10; i++) { try { ses << "INSERT INTO LogTest (Id, [Time], Value) VALUES (:id, :time, :value)", use(id), bind(timeIn), bind(value), now; //lint !e1058 if (i > 0) fail("must fail"); } catch(Poco::Exception&) { if (i == 0) // the very first insert must work throw; } } ses.commit(); } void SQLiteTest::testNullable() { Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db"); ses << "DROP TABLE IF EXISTS NullableTest", now; ses << "CREATE TABLE NullableTest (i INTEGER, r REAL, s VARCHAR, d DATETIME)", now; ses << "INSERT INTO NullableTest VALUES(:i, :r, :s, :d)", use(null), use(null), use(null), use(null), now; Nullable i = 1; Nullable f = 1.5; Nullable s = std::string("abc"); Nullable d = DateTime(); assert (!i.isNull()); assert (!f.isNull()); assert (!s.isNull()); assert (!d.isNull()); ses << "SELECT i, r, s, d FROM NullableTest", into(i), into(f), into(s), into(d), now; assert (i.isNull()); assert (f.isNull()); assert (s.isNull()); assert (d.isNull()); RecordSet rs(ses, "SELECT * FROM NullableTest"); rs.moveFirst(); assert (rs.isNull("i")); assert (rs.isNull("r")); assert (rs.isNull("s")); assert (rs.isNull("d")); Var di = 1; Var df = 1.5; Var ds = "abc"; Var dd = DateTime(); assert (!di.isEmpty()); assert (!df.isEmpty()); assert (!ds.isEmpty()); assert (!dd.isEmpty()); ses << "SELECT i, r, s, d FROM NullableTest", into(di), into(df), into(ds), into(dd), now; assert (di.isEmpty()); assert (df.isEmpty()); assert (ds.isEmpty()); assert (dd.isEmpty()); } void SQLiteTest::testNull() { Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db"); ses << "DROP TABLE IF EXISTS NullTest", now; ses << "CREATE TABLE NullTest (i INTEGER NOT NULL)", now; try { ses << "INSERT INTO NullTest VALUES(:i)", use(null), now; fail ("must fail"); }catch (ConstraintViolationException&) { } ses << "DROP TABLE IF EXISTS NullTest", now; ses << "CREATE TABLE NullTest (i INTEGER, r REAL, v VARCHAR)", now; ses << "INSERT INTO NullTest VALUES(:i, :r, :v)", use(null), use(null), use(null), now; RecordSet rs(ses, "SELECT * FROM NullTest"); rs.moveFirst(); assert (rs.isNull("i")); assert (rs["i"].isEmpty()); assert (rs.isNull("r")); assert (rs.isNull("v")); assert (rs["v"].isEmpty()); ses << "DROP TABLE IF EXISTS NullTest", now; ses << "CREATE TABLE NullTest (i INTEGER, r REAL, v VARCHAR)", now; int i = 1; double f = 1.2; std::string s = "123"; ses << "INSERT INTO NullTest (i, r, v) VALUES (:i, :r, :v)", use(i), use(f), use(s), now; rs = (ses << "SELECT * FROM NullTest", now); rs.moveFirst(); assert (!rs.isNull("i")); assert (rs["i"] == 1); assert (!rs.isNull("v")); assert (!rs.isNull("r")); assert (rs["v"] == "123"); ses << "UPDATE NullTest SET v = :n WHERE i == :i", use(null), use(i), now; i = 2; f = 3.4; ses << "INSERT INTO NullTest (i, r, v) VALUES (:i, :r, :v)", use(i), use(null), use(null), now; rs = (ses << "SELECT i, r, v FROM NullTest ORDER BY i ASC", now); rs.moveFirst(); assert (!rs.isNull("i")); assert (rs["i"] == 1); assert (!rs.isNull("r")); assert (rs.isNull("v")); assert (rs["v"].isEmpty()); assert (rs.moveNext()); assert (!rs.isNull("i")); assert (rs["i"] == 2); Poco::Int64 i64 = 0; assert (rs.nvl("i", i64) == 2); assert (rs.nvl("i", 123) == 2); assert (rs.isNull("r")); assert (rs.nvl("r", 123) == 123); assert (rs.nvl("r", 1.5) == 1.5); assert (rs.isNull("v")); assert (rs["v"].isEmpty()); assert (rs.nvl("v", s) == "123"); } void SQLiteTest::testRowIterator() { Session ses (Poco::Data::SQLite::Connector::KEY, "dummy.db"); ses << "DROP TABLE IF EXISTS Vectors", now; ses << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; std::vector > v; v.push_back(Tuple(1, 1.5f, "3")); v.push_back(Tuple(2, 2.5f, "4")); v.push_back(Tuple(3, 3.5f, "5")); v.push_back(Tuple(4, 4.5f, "6")); ses << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; RecordSet rset(ses, "SELECT * FROM Vectors"); std::ostringstream osLoop; RecordSet::ConstIterator it = rset.begin(); RecordSet::ConstIterator end = rset.end(); for (int i = 1; it != end; ++it, ++i) { assert (it->get(0) == i); osLoop << *it; } assert (!osLoop.str().empty()); std::ostringstream osCopy; std::copy(rset.begin(), rset.end(), std::ostream_iterator(osCopy)); assert (osLoop.str() == osCopy.str()); } void SQLiteTest::testAsync() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Strings", now; tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; int rowCount = 500; std::vector data(rowCount); Statement stmt = (tmp << "INSERT INTO Strings VALUES(:str)", use(data)); Statement::Result result = stmt.executeAsync(); assert (!stmt.isAsync()); result.wait(); assert (500 == result.data()); Statement stmt1 = (tmp << "SELECT * FROM Strings", into(data), async, now); assert (stmt1.isAsync()); assert (stmt1.wait() == rowCount); stmt1.execute(); try { stmt1.execute(); fail ("must fail"); } catch (InvalidAccessException&) { stmt1.wait(); stmt1.execute(); stmt1.wait(); } stmt = tmp << "SELECT * FROM Strings", into(data), async, now; assert (stmt.isAsync()); stmt.wait(); assert (stmt.execute() == 0); assert (stmt.isAsync()); try { result = stmt.executeAsync(); fail ("must fail"); } catch (InvalidAccessException&) { stmt.wait(); result = stmt.executeAsync(); } assert (stmt.wait() == rowCount); assert (result.data() == rowCount); stmt.setAsync(false); assert (!stmt.isAsync()); assert (stmt.execute() == rowCount); stmt = tmp << "SELECT * FROM Strings", into(data), sync, now; assert (!stmt.isAsync()); assert (stmt.wait() == 0); assert (stmt.execute() == rowCount); result = stmt.executeAsync(); assert (!stmt.isAsync()); result.wait(); assert (result.data() == rowCount); assert (0 == rowCount % 10); int step = (int) (rowCount/10); data.clear(); Statement stmt2 = (tmp << "SELECT * FROM Strings", into(data), async, limit(step)); assert (data.size() == 0); assert (!stmt2.done()); std::size_t rows = 0; for (int i = 0; !stmt2.done(); i += step) { stmt2.execute(); rows = stmt2.wait(); assert (step == rows); assert (step + i == data.size()); } assert (stmt2.done()); assert (rowCount == data.size()); stmt2 = tmp << "SELECT * FROM Strings", reset; assert (!stmt2.isAsync()); assert ("deque" == stmt2.getStorage()); assert (stmt2.execute() == rowCount); } void SQLiteTest::testAny() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Anys", now; tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; Any i = Int32(42); Any f = double(42.5); Any s = std::string("42"); tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now; int count = 0; tmp << "SELECT COUNT(*) FROM Anys", into(count), now; assert (1 == count); i = 0; f = 0.0; s = std::string(""); tmp << "SELECT * FROM Anys", into(i), into(f), into(s), now; assert (AnyCast(i) == 42); assert (AnyCast(f) == 42.5); assert (AnyCast(s) == "42"); } void SQLiteTest::testDynamicAny() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Anys", now; tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; DynamicAny i = Int32(42); DynamicAny f = double(42.5); DynamicAny s = std::string("42"); tmp << "INSERT INTO Anys VALUES (?, ?, ?)", use(i), use(f), use(s), now; int count = 0; tmp << "SELECT COUNT(*) FROM Anys", into(count), now; assert (1 == count); i = 0; f = 0.0; s = std::string(""); tmp << "SELECT * FROM Anys", into(i), into(f), into(s), now; assert (42 == i); assert (42.5 == f); assert ("42" == s); } void SQLiteTest::testPair() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); assert (tmp.isConnected()); std::string tableName("Simpsons"); std::pair junior = std::make_pair("Junior", 12); std::pair senior = std::make_pair("Senior", 99); int count = 0; std::string result; tmp << "DROP TABLE IF EXISTS Simpsons", now; tmp << "CREATE TABLE IF NOT EXISTS Simpsons (LastName VARCHAR(30), Age INTEGER(3))", now; tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; assert (result == tableName); // these are fine tmp << "INSERT INTO Simpsons VALUES(?, ?)", use(junior), now; tmp << "INSERT INTO Simpsons VALUES(?, ?)", useRef(senior), now; tmp << "SELECT COUNT(*) FROM Simpsons", into(count), now; assert (2 == count); std::vector > ret; tmp << "SELECT * FROM Simpsons", into(ret), range(2,2), now; assert (ret[0].second == 12 || ret[1].second == 12); assert (ret[0].second == 99 || ret[1].second == 99); assert (ret[0].first == "Junior" || ret[1].first == "Junior"); assert (ret[0].first == "Senior" || ret[1].first == "Senior"); } void SQLiteTest::testSQLChannel() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS T_POCO_LOG", now; tmp << "CREATE TABLE T_POCO_LOG (Source VARCHAR," "Name VARCHAR," "ProcessId INTEGER," "Thread VARCHAR, " "ThreadId INTEGER," "Priority INTEGER," "Text VARCHAR," "DateTime DATE)", now; tmp << "DROP TABLE IF EXISTS T_POCO_LOG_ARCHIVE", now; tmp << "CREATE TABLE T_POCO_LOG_ARCHIVE (Source VARCHAR," "Name VARCHAR," "ProcessId INTEGER," "Thread VARCHAR, " "ThreadId INTEGER," "Priority INTEGER," "Text VARCHAR," "DateTime DATE)", now; AutoPtr pChannel = new SQLChannel(Poco::Data::SQLite::Connector::KEY, "dummy.db", "TestSQLChannel"); pChannel->setProperty("keep", "2 seconds"); Message msgInf("InformationSource", "a Informational async message", Message::PRIO_INFORMATION); pChannel->log(msgInf); Message msgWarn("WarningSource", "b Warning async message", Message::PRIO_WARNING); pChannel->log(msgWarn); pChannel->wait(); pChannel->setProperty("async", "false"); Message msgInfS("InformationSource", "c Informational sync message", Message::PRIO_INFORMATION); pChannel->log(msgInfS); Message msgWarnS("WarningSource", "d Warning sync message", Message::PRIO_WARNING); pChannel->log(msgWarnS); RecordSet rs(tmp, "SELECT * FROM T_POCO_LOG ORDER by Text"); assert (4 == rs.rowCount()); assert ("InformationSource" == rs["Source"]); assert ("a Informational async message" == rs["Text"]); rs.moveNext(); assert ("WarningSource" == rs["Source"]); assert ("b Warning async message" == rs["Text"]); rs.moveNext(); assert ("InformationSource" == rs["Source"]); assert ("c Informational sync message" == rs["Text"]); rs.moveNext(); assert ("WarningSource" == rs["Source"]); assert ("d Warning sync message" == rs["Text"]); Thread::sleep(3000); Message msgInfA("InformationSource", "e Informational sync message", Message::PRIO_INFORMATION); pChannel->log(msgInfA); Message msgWarnA("WarningSource", "f Warning sync message", Message::PRIO_WARNING); pChannel->log(msgWarnA); RecordSet rs1(tmp, "SELECT * FROM T_POCO_LOG_ARCHIVE"); assert (4 == rs1.rowCount()); pChannel->setProperty("keep", ""); assert ("forever" == pChannel->getProperty("keep")); RecordSet rs2(tmp, "SELECT * FROM T_POCO_LOG ORDER by Text"); assert (2 == rs2.rowCount()); assert ("InformationSource" == rs2["Source"]); assert ("e Informational sync message" == rs2["Text"]); rs2.moveNext(); assert ("WarningSource" == rs2["Source"]); assert ("f Warning sync message" == rs2["Text"]); } void SQLiteTest::testSQLLogger() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS T_POCO_LOG", now; tmp << "CREATE TABLE T_POCO_LOG (Source VARCHAR," "Name VARCHAR," "ProcessId INTEGER," "Thread VARCHAR, " "ThreadId INTEGER," "Priority INTEGER," "Text VARCHAR," "DateTime DATE)", now; { AutoPtr pChannel = new SQLChannel(Poco::Data::SQLite::Connector::KEY, "dummy.db", "TestSQLChannel"); Logger& root = Logger::root(); root.setChannel(pChannel.get()); root.setLevel(Message::PRIO_INFORMATION); root.information("Informational message"); root.warning("Warning message"); root.debug("Debug message"); } Thread::sleep(100); RecordSet rs(tmp, "SELECT * FROM T_POCO_LOG ORDER by DateTime"); assert (2 == rs.rowCount()); assert ("TestSQLChannel" == rs["Source"]); assert ("Informational message" == rs["Text"]); rs.moveNext(); assert ("TestSQLChannel" == rs["Source"]); assert ("Warning message" == rs["Text"]); } void SQLiteTest::testExternalBindingAndExtraction() { AbstractExtractionVecVec extractionVec; AbstractExtractionVec extraction; AbstractBindingVec binding; Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Ints", now; tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; int x = 1, y = 2, z = 3; binding.push_back(use(x)); binding.push_back(use(y)); binding.push_back(use(z)); tmp << "INSERT INTO Ints VALUES (?,?,?)", use(binding), now; Poco::Int64 a = 0, b = 0, c = 0; extraction.push_back(into(a)); extraction.push_back(into(b)); extraction.push_back(into(c)); tmp << "SELECT * FROM Ints", into(extraction), now; assert (a == x); assert (b == y); assert (c == z); a = 0, b = 0, c = 0; extractionVec.push_back(extraction); tmp << "SELECT * FROM Ints", into(extractionVec), now; assert (a == x); assert (b == y); assert (c == z); } void SQLiteTest::testBindingCount() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Ints", now; tmp << "CREATE TABLE Ints (int0 INTEGER)", now; int i = 42; try { tmp << "INSERT INTO Ints VALUES (?)", now; } catch (ParameterCountMismatchException&) { } tmp << "INSERT INTO Ints VALUES (?)", use(i), now; i = 0; try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; } catch (ParameterCountMismatchException&) { } tmp << "SELECT int0 from Ints where int0 = ?", bind(42), into(i), now; assert (42 == i); tmp << "DROP TABLE IF EXISTS Ints", now; tmp << "CREATE TABLE Ints (int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; try { tmp << "INSERT INTO Ints VALUES (?,?,?)", bind(42), bind(42), now; } catch (ParameterCountMismatchException&) { } } void SQLiteTest::testMultipleResults() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); tmp << "DROP TABLE IF EXISTS Person", now; tmp << "CREATE TABLE Person (LastName VARCHAR(30)," "FirstName VARCHAR(30)," "Address VARCHAR(30)," "Age INTEGER)", now; typedef Tuple Person; std::vector people, people2; people.push_back(Person("Simpson", "Homer", "Springfield", 42)); people.push_back(Person("Simpson", "Bart", "Springfield", 12)); people.push_back(Person("Simpson", "Lisa", "Springfield", 10)); Person pHomer; int aHomer = 42, aLisa = 10; Poco::UInt32 aBart = 0; Poco::UInt32 pos1 = 1; int pos2 = 2; Statement stmt(tmp); stmt << "INSERT INTO Person VALUES (?, ?, ?, ?);" "SELECT * FROM Person WHERE Age = ?; " "SELECT Age FROM Person WHERE FirstName = 'Bart'; " "SELECT * FROM Person WHERE Age = ? OR Age = ? ORDER BY Age;" , use(people) , into(pHomer, from(0)), use(aHomer) , into(aBart, pos1) , into(people2, from(pos2)), use(aLisa), use(aHomer); assert (7 == stmt.execute()); assert (Person("Simpson", "Homer", "Springfield", 42) == pHomer); assert (12 == aBart); assert (2 == people2.size()); assert (Person("Simpson", "Lisa", "Springfield", 10) == people2[0]); assert (Person("Simpson", "Homer", "Springfield", 42) == people2[1]); } void SQLiteTest::testReconnect() { Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db"); session << "DROP TABLE IF EXISTS Person", now; session << "CREATE TABLE Person (LastName VARCHAR(30)," "FirstName VARCHAR(30)," "Address VARCHAR(30)," "Age INTEGER)", now; std::string lastName = "lastName"; std::string firstName("firstName"); std::string address("Address"); int age = 133132; int count = 0; std::string result; session << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age), now; count = 0; session << "SELECT COUNT(*) FROM PERSON", into(count), now; assert (count == 1); assert (session.isConnected()); session.close(); assert (!session.isConnected()); try { session << "SELECT LastName FROM PERSON", into(result), now; fail ("must fail"); } catch(NotConnectedException&){ } assert (!session.isConnected()); session.open(); assert (session.isConnected()); session << "SELECT Age FROM PERSON", into(count), now; assert (count == age); assert (session.isConnected()); } void SQLiteTest::testSystemTable() { Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db"); int cnt = -1; session << "SELECT count(*) FROM sys.dual", into(cnt), now; assert (0 == cnt); session << "INSERT INTO sys.dual VALUES ('test')", now; session << "SELECT count(*) FROM sys.dual", into(cnt), now; assert (1 == cnt); session << "DELETE FROM sys.dual", now; session << "SELECT count(*) FROM sys.dual", into(cnt), now; assert (0 == cnt); try { session << "DROP TABLE sys.dual", now; fail ("must throw"); } catch (InvalidAccessException&) { } } void SQLiteTest::setUp() { } void SQLiteTest::tearDown() { } CppUnit::Test* SQLiteTest::suite() { CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTest"); CppUnit_addTest(pSuite, SQLiteTest, testBinding); CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccess); CppUnit_addTest(pSuite, SQLiteTest, testInMemory); CppUnit_addTest(pSuite, SQLiteTest, testNullCharPointer); CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer); CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer2); CppUnit_addTest(pSuite, SQLiteTest, testComplexType); CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccessVector); CppUnit_addTest(pSuite, SQLiteTest, testComplexTypeVector); CppUnit_addTest(pSuite, SQLiteTest, testSharedPtrComplexTypeVector); CppUnit_addTest(pSuite, SQLiteTest, testInsertVector); CppUnit_addTest(pSuite, SQLiteTest, testInsertEmptyVector); CppUnit_addTest(pSuite, SQLiteTest, testAffectedRows); CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulk); CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulkVec); CppUnit_addTest(pSuite, SQLiteTest, testLimit); CppUnit_addTest(pSuite, SQLiteTest, testLimitOnce); CppUnit_addTest(pSuite, SQLiteTest, testLimitPrepare); CppUnit_addTest(pSuite, SQLiteTest, testLimitZero); CppUnit_addTest(pSuite, SQLiteTest, testPrepare); CppUnit_addTest(pSuite, SQLiteTest, testSetSimple); CppUnit_addTest(pSuite, SQLiteTest, testSetComplex); CppUnit_addTest(pSuite, SQLiteTest, testSetComplexUnique); CppUnit_addTest(pSuite, SQLiteTest, testMultiSetSimple); CppUnit_addTest(pSuite, SQLiteTest, testMultiSetComplex); CppUnit_addTest(pSuite, SQLiteTest, testMapComplex); CppUnit_addTest(pSuite, SQLiteTest, testMapComplexUnique); CppUnit_addTest(pSuite, SQLiteTest, testMultiMapComplex); CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingle); CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleStep); CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleFail); CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitOk); CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitFail); CppUnit_addTest(pSuite, SQLiteTest, testCombinedLimits); CppUnit_addTest(pSuite, SQLiteTest, testCombinedIllegalLimits); CppUnit_addTest(pSuite, SQLiteTest, testRange); CppUnit_addTest(pSuite, SQLiteTest, testIllegalRange); CppUnit_addTest(pSuite, SQLiteTest, testSingleSelect); CppUnit_addTest(pSuite, SQLiteTest, testEmptyDB); CppUnit_addTest(pSuite, SQLiteTest, testCLOB); CppUnit_addTest(pSuite, SQLiteTest, testTuple10); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector10); CppUnit_addTest(pSuite, SQLiteTest, testTuple9); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector9); CppUnit_addTest(pSuite, SQLiteTest, testTuple8); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector8); CppUnit_addTest(pSuite, SQLiteTest, testTuple7); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector7); CppUnit_addTest(pSuite, SQLiteTest, testTuple6); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector6); CppUnit_addTest(pSuite, SQLiteTest, testTuple5); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector5); CppUnit_addTest(pSuite, SQLiteTest, testTuple4); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector4); CppUnit_addTest(pSuite, SQLiteTest, testTuple3); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector3); CppUnit_addTest(pSuite, SQLiteTest, testTuple2); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector2); CppUnit_addTest(pSuite, SQLiteTest, testTuple1); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1); CppUnit_addTest(pSuite, SQLiteTest, testDateTime); CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction); CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint); CppUnit_addTest(pSuite, SQLiteTest, testNullable); CppUnit_addTest(pSuite, SQLiteTest, testNull); CppUnit_addTest(pSuite, SQLiteTest, testRowIterator); CppUnit_addTest(pSuite, SQLiteTest, testAsync); CppUnit_addTest(pSuite, SQLiteTest, testAny); CppUnit_addTest(pSuite, SQLiteTest, testDynamicAny); CppUnit_addTest(pSuite, SQLiteTest, testSQLChannel); CppUnit_addTest(pSuite, SQLiteTest, testSQLLogger); CppUnit_addTest(pSuite, SQLiteTest, testExternalBindingAndExtraction); CppUnit_addTest(pSuite, SQLiteTest, testBindingCount); CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults); CppUnit_addTest(pSuite, SQLiteTest, testPair); CppUnit_addTest(pSuite, SQLiteTest, testReconnect); CppUnit_addTest(pSuite, SQLiteTest, testSystemTable); return pSuite; }