mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-29 12:45:22 +01:00
fix for SF 1871946 (no exception thrown on error)
This commit is contained in:
parent
4d0817e8f9
commit
48d0d9fef9
@ -69,6 +69,7 @@ POCO_DECLARE_EXCEPTION(SQLite_API, SchemaDiffersException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, RowTooBigException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, ConstraintViolationException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, DataTypeMismatchException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, ParameterCountMismatchException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, InvalidLibraryUseException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, OSFeaturesMissingException, SQLiteException)
|
||||
POCO_DECLARE_EXCEPTION(SQLite_API, AuthorizationDeniedException, SQLiteException)
|
||||
|
@ -63,6 +63,7 @@ POCO_IMPLEMENT_EXCEPTION(SchemaDiffersException, SQLiteException, "The database
|
||||
POCO_IMPLEMENT_EXCEPTION(RowTooBigException, SQLiteException, "Too much data for one row of a table")
|
||||
POCO_IMPLEMENT_EXCEPTION(ConstraintViolationException, SQLiteException, "Abort due to constraint violation")
|
||||
POCO_IMPLEMENT_EXCEPTION(DataTypeMismatchException, SQLiteException, "Data type mismatch")
|
||||
POCO_IMPLEMENT_EXCEPTION(ParameterCountMismatchException, SQLiteException, "Parameter count mismatch")
|
||||
POCO_IMPLEMENT_EXCEPTION(InvalidLibraryUseException, SQLiteException, "Library used incorrectly")
|
||||
POCO_IMPLEMENT_EXCEPTION(OSFeaturesMissingException, SQLiteException, "Uses OS features not supported on host")
|
||||
POCO_IMPLEMENT_EXCEPTION(AuthorizationDeniedException, SQLiteException, "Authorization denied")
|
||||
|
@ -81,7 +81,7 @@ void SQLiteStatementImpl::compileImpl()
|
||||
|
||||
while (rc == SQLITE_OK && !pStmt && !queryFound)
|
||||
{
|
||||
rc = sqlite3_prepare(_pDB, pSql, -1, &pStmt, &pLeftover);
|
||||
rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
if (pStmt)
|
||||
@ -145,8 +145,13 @@ void SQLiteStatementImpl::bindImpl()
|
||||
|
||||
// bind
|
||||
Bindings& binds = bindings();
|
||||
if (binds.empty()) return;
|
||||
|
||||
int pc = sqlite3_bind_parameter_count(_pStmt);
|
||||
if (binds.empty() && 0 == pc) return;
|
||||
else if (binds.empty() && pc > 0)
|
||||
throw ParameterCountMismatchException();
|
||||
else if (!binds.empty() && binds.size() * (*binds.begin())->numOfColumnsHandled() != pc)
|
||||
throw ParameterCountMismatchException();
|
||||
|
||||
std::size_t pos = 1; // sqlite starts with 1 not 0!
|
||||
|
||||
Bindings::iterator it = binds.begin();
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -69,7 +70,9 @@ using Poco::InvalidAccessException;
|
||||
using Poco::RangeException;
|
||||
using Poco::BadCastException;
|
||||
using Poco::NotFoundException;
|
||||
using Poco::Data::SQLite::InvalidSQLStatementException;
|
||||
using Poco::NullPointerException;
|
||||
using Poco::Data::SQLite::ConstraintViolationException;
|
||||
using Poco::Data::SQLite::ParameterCountMismatchException;
|
||||
using Poco::Int64;
|
||||
|
||||
|
||||
@ -212,6 +215,48 @@ void SQLiteTest::testSimpleAccess()
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::testNullCharPointer()
|
||||
{
|
||||
Session tmp (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 (SQLite::Connector::KEY, "dummy.db");
|
||||
@ -225,7 +270,25 @@ void SQLiteTest::testInsertCharPointer()
|
||||
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("lastname"), use("firstname"), use("Address"), use(133132), 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));
|
||||
|
||||
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;
|
||||
@ -249,7 +312,11 @@ void SQLiteTest::testInsertCharPointer2()
|
||||
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("lastname"), use("firstname"), use("Address"), use(133132), now;
|
||||
tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)",
|
||||
bind("lastname"),
|
||||
bind("firstname", "FN"),
|
||||
bind("Address", "Addr"),
|
||||
bind(133132), now;
|
||||
tmp << "SELECT COUNT(*) FROM PERSON", into(count), now;
|
||||
assert (count == 1);
|
||||
Statement stmt1 = (tmp << "SELECT LastName FROM PERSON", into(result));
|
||||
@ -1080,7 +1147,8 @@ void SQLiteTest::testBLOB()
|
||||
assert (count == 1);
|
||||
BLOB res;
|
||||
poco_assert (res.size() == 0);
|
||||
tmp << "SELECT Image FROM Person WHERE LastName == :ln", use("lastname"), into(res), now;
|
||||
|
||||
tmp << "SELECT Image FROM Person WHERE LastName == :ln", bind("lastname"), into(res), now;
|
||||
poco_assert (res == img);
|
||||
}
|
||||
|
||||
@ -1664,7 +1732,7 @@ void SQLiteTest::testPrimaryKeyConstraint()
|
||||
{
|
||||
try
|
||||
{
|
||||
ses << "INSERT INTO LogTest (Id, [Time], Value) VALUES (:id, :time, :value)", use(id), use(timeIn), use(value), now; //lint !e1058
|
||||
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");
|
||||
}
|
||||
@ -1690,7 +1758,7 @@ void SQLiteTest::testNull()
|
||||
{
|
||||
ses << "INSERT INTO NullTest VALUES(:i)", use(null), now;
|
||||
fail ("must fail");
|
||||
}catch (InvalidSQLStatementException&) { }
|
||||
}catch (ConstraintViolationException&) { }
|
||||
|
||||
ses << "DROP TABLE IF EXISTS NullTest", now;
|
||||
ses << "CREATE TABLE NullTest (i INTEGER, r REAL, v VARCHAR)", now;
|
||||
@ -2026,6 +2094,65 @@ void SQLiteTest::testSQLLogger()
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::testExternalBindingAndExtraction()
|
||||
{
|
||||
AbstractExtractionVecVec extractionVec;
|
||||
AbstractExtractionVec extraction;
|
||||
AbstractBindingVec binding;
|
||||
|
||||
Session tmp (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 (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&) { }
|
||||
|
||||
try { tmp << "INSERT INTO Ints VALUES (?)", bind(42), bind(42), 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);
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -2041,6 +2168,7 @@ CppUnit::Test* SQLiteTest::suite()
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTest");
|
||||
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccess);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testNullCharPointer);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testInsertCharPointer2);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testComplexType);
|
||||
@ -2106,6 +2234,8 @@ CppUnit::Test* SQLiteTest::suite()
|
||||
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);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
~SQLiteTest();
|
||||
|
||||
void testSimpleAccess();
|
||||
void testNullCharPointer();
|
||||
void testInsertCharPointer();
|
||||
void testInsertCharPointer2();
|
||||
void testComplexType();
|
||||
@ -121,6 +122,9 @@ public:
|
||||
void testSQLChannel();
|
||||
void testSQLLogger();
|
||||
|
||||
void testExternalBindingAndExtraction();
|
||||
void testBindingCount();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user