mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-20 14:24:35 +01:00
Exception/ODBCException modifications to safely (SQLite ODBC tests were failing) propagate ODBC error messages up the hierarchy
SharedPtr/AutoPtr TypeHandler tests FreeTDS SQLServer tests changes from 1.3.3 Windows build scripts fixes from 1.3.3
This commit is contained in:
parent
9be2b5bd92
commit
fa02d5aa5b
@ -63,18 +63,18 @@ template <class H, SQLSMALLINT handleType>
|
||||
class HandleException: public ODBCException
|
||||
{
|
||||
public:
|
||||
HandleException(const H& handle):
|
||||
ODBCException(errorString(handle)),
|
||||
_error(handle)
|
||||
HandleException(const H& handle): _error(handle)
|
||||
/// Creates HandleException
|
||||
{
|
||||
message(_error.toString());
|
||||
}
|
||||
|
||||
HandleException(const H& handle, const std::string& msg):
|
||||
ODBCException(msg, errorString(handle)),
|
||||
ODBCException(msg),
|
||||
_error(handle)
|
||||
/// Creates HandleException
|
||||
{
|
||||
extendedMessage(_error.toString());
|
||||
}
|
||||
|
||||
HandleException(const H& handle, const std::string& msg, const std::string& arg):
|
||||
@ -142,9 +142,6 @@ public:
|
||||
|
||||
std::string toString() const
|
||||
/// Returns the formatted error diagnostics for the handle.
|
||||
/// Since it relies on the object being fully constructed at
|
||||
/// the time of its usage, this function should not be used
|
||||
/// by the constructor to pass diagnostic string to the parent.
|
||||
{
|
||||
return Poco::format("ODBC Error: %s\n===================\n%s\n",
|
||||
std::string(what()),
|
||||
@ -152,10 +149,7 @@ public:
|
||||
}
|
||||
|
||||
static std::string errorString(const H& handle)
|
||||
/// Returns the error diagnostics for the handle.
|
||||
/// This function is used by the constructor to pass diagnostic
|
||||
/// string to the parent. It can also be used as a "shortcut" to
|
||||
/// error information during troubleshooting.
|
||||
/// Returns the error diagnostics string for the handle.
|
||||
{
|
||||
return Error<H, handleType>(handle).toString();
|
||||
}
|
||||
|
@ -611,6 +611,8 @@ CppUnit::Test* ODBCDB2Test::suite()
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessList);
|
||||
|
@ -429,6 +429,8 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSimpleAccessList);
|
||||
|
@ -850,6 +850,8 @@ CppUnit::Test* ODBCOracleTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSimpleAccessList);
|
||||
|
@ -575,6 +575,8 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSimpleAccessList);
|
||||
|
@ -63,15 +63,43 @@ using Poco::DynamicAny;
|
||||
using Poco::DateTime;
|
||||
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
// uncomment to force FreeTDS on Windows
|
||||
//#define FORCE_FREE_TDS
|
||||
|
||||
// uncomment to use native SQL driver
|
||||
//#define POCO_ODBC_USE_SQL_NATIVE
|
||||
|
||||
// FreeTDS version selection guide (from http://www.freetds.org/userguide/choosingtdsprotocol.htm)
|
||||
// (see #define FREE_TDS_VERSION below)
|
||||
// Product TDS Version Comment
|
||||
// ---------------------------------------------------+------------+------------------------------------------------------------
|
||||
// Sybase before System 10, Microsoft SQL Server 6.x 4.2 Still works with all products, subject to its limitations.
|
||||
// Sybase System 10 and above 5.0 Still the most current protocol used by Sybase.
|
||||
// Sybase System SQL Anywhere 5.0 only Originally Watcom SQL Server, a completely separate codebase.
|
||||
// Our best information is that SQL Anywhere first supported TDS
|
||||
// in version 5.5.03 using the OpenServer Gateway (OSG), and native
|
||||
// TDS 5.0 support arrived with version 6.0.
|
||||
// Microsoft SQL Server 7.0 7.0 Includes support for the extended datatypes in SQL Server 7.0
|
||||
// (such as char/varchar fields of more than 255 characters), and
|
||||
// support for Unicode.
|
||||
// Microsoft SQL Server 2000 8.0 Include support for bigint (64 bit integers), variant and collation
|
||||
// on all fields. variant is not supported; collation is not widely used.
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(FORCE_FREE_TDS)
|
||||
#ifdef POCO_ODBC_USE_SQL_NATIVE
|
||||
#define MS_SQL_SERVER_ODBC_DRIVER "SQL Native Client"
|
||||
#else
|
||||
#define MS_SQL_SERVER_ODBC_DRIVER "SQL Server"
|
||||
#endif
|
||||
#pragma message ("Using " MS_SQL_SERVER_ODBC_DRIVER " driver")
|
||||
#else
|
||||
#define MS_SQL_SERVER_ODBC_DRIVER "FreeTDS"
|
||||
#define FREE_TDS_VERSION "8.0"
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#pragma message ("Using " MS_SQL_SERVER_ODBC_DRIVER " driver, version " FREE_TDS_VERSION)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MS_SQL_SERVER_DSN "PocoDataSQLServerTest"
|
||||
#define MS_SQL_SERVER_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
||||
#define MS_SQL_SERVER_PORT "1433"
|
||||
@ -92,8 +120,11 @@ std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRI
|
||||
"PWD=" MS_SQL_SERVER_PWD ";"
|
||||
"DATABASE=" MS_SQL_SERVER_DB ";"
|
||||
"SERVER=" MS_SQL_SERVER_SERVER ";"
|
||||
"PORT=" MS_SQL_SERVER_PORT ";";
|
||||
|
||||
"PORT=" MS_SQL_SERVER_PORT ";"
|
||||
#ifdef FREE_TDS_VERSION
|
||||
"TDS_Version=" FREE_TDS_VERSION ";"
|
||||
#endif
|
||||
;
|
||||
|
||||
ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name):
|
||||
ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
|
||||
@ -116,10 +147,14 @@ void ODBCSQLServerTest::testBareboneODBC()
|
||||
"Fifth FLOAT,"
|
||||
"Sixth DATETIME)";
|
||||
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString,
|
||||
SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL, true, "CONVERT(VARBINARY(30),?)");
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString,
|
||||
SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND, true, "CONVERT(VARBINARY(30),?)");
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString,
|
||||
SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, true, "CONVERT(VARBINARY(30),?)");
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString,
|
||||
SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, true, "CONVERT(VARBINARY(30),?)");
|
||||
|
||||
tableCreateString = "CREATE TABLE Test "
|
||||
"(First VARCHAR(30),"
|
||||
@ -141,7 +176,7 @@ void ODBCSQLServerTest::testBLOB()
|
||||
|
||||
try
|
||||
{
|
||||
executor().blob(maxFldSize);
|
||||
executor().blob(maxFldSize, "CONVERT(VARBINARY(MAX),?)");
|
||||
fail ("must fail");
|
||||
}
|
||||
catch (DataException&)
|
||||
@ -154,14 +189,14 @@ void ODBCSQLServerTest::testBLOB()
|
||||
recreatePersonBLOBTable();
|
||||
session().setFeature("autoBind", bindValue(i));
|
||||
session().setFeature("autoExtract", bindValue(i+1));
|
||||
executor().blob(maxFldSize);
|
||||
executor().blob(maxFldSize, "CONVERT(VARBINARY(MAX),?)");
|
||||
i += 2;
|
||||
}
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
try
|
||||
{
|
||||
executor().blob(maxFldSize+1);
|
||||
executor().blob(maxFldSize+1, "CONVERT(VARBINARY(MAX),?)");
|
||||
fail ("must fail");
|
||||
}
|
||||
catch (DataException&) { }
|
||||
@ -205,7 +240,7 @@ void ODBCSQLServerTest::testBulk()
|
||||
std::vector<BLOB>,
|
||||
std::vector<double>,
|
||||
std::vector<DateTime>,
|
||||
std::vector<bool> >(100);
|
||||
std::vector<bool> >(100, "CONVERT(VARBINARY(30),?)");
|
||||
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkWithBool<std::deque<int>,
|
||||
@ -213,7 +248,7 @@ void ODBCSQLServerTest::testBulk()
|
||||
std::deque<BLOB>,
|
||||
std::deque<double>,
|
||||
std::deque<DateTime>,
|
||||
std::deque<bool> >(100);
|
||||
std::deque<bool> >(100, "CONVERT(VARBINARY(30),?)");
|
||||
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkWithBool<std::list<int>,
|
||||
@ -221,7 +256,7 @@ void ODBCSQLServerTest::testBulk()
|
||||
std::list<BLOB>,
|
||||
std::list<double>,
|
||||
std::list<DateTime>,
|
||||
std::list<bool> >(100);
|
||||
std::list<bool> >(100, "CONVERT(VARBINARY(30),?)");
|
||||
}
|
||||
|
||||
|
||||
@ -704,6 +739,8 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSimpleAccessList);
|
||||
|
@ -178,7 +178,11 @@ void ODBCSQLiteTest::dropObject(const std::string& type, const std::string& name
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreError) throw;
|
||||
if (!ignoreError)
|
||||
{
|
||||
std::cout << ex.toString() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,6 +340,8 @@ CppUnit::Test* ODBCSQLiteTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSharedPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testAutoPtrComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSimpleAccessList);
|
||||
|
@ -158,6 +158,36 @@ void ODBCTest::testComplexTypeVector()
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testSharedPtrComplexTypeVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreatePersonTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->sharedPtrComplexTypeVector();
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testAutoPtrComplexTypeVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreatePersonTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->autoPtrComplexTypeVector();
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testInsertVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
@ -74,6 +74,8 @@ public:
|
||||
|
||||
virtual void testSimpleAccessVector();
|
||||
virtual void testComplexTypeVector();
|
||||
virtual void testSharedPtrComplexTypeVector();
|
||||
virtual void testAutoPtrComplexTypeVector();
|
||||
virtual void testInsertVector();
|
||||
virtual void testInsertEmptyVector();
|
||||
|
||||
|
@ -43,7 +43,9 @@
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
@ -141,6 +143,45 @@ struct Person
|
||||
};
|
||||
|
||||
|
||||
struct RefCountedPerson : public Poco::RefCountedObject
|
||||
{
|
||||
std::string lastName;
|
||||
std::string firstName;
|
||||
std::string address;
|
||||
int age;
|
||||
RefCountedPerson(){age = 0;}
|
||||
RefCountedPerson(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 RefCountedPerson& 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 the key
|
||||
return lastName;
|
||||
}
|
||||
|
||||
private:
|
||||
RefCountedPerson(const RefCountedPerson &);
|
||||
RefCountedPerson& operator = (const RefCountedPerson&);
|
||||
};
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
@ -196,6 +237,57 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class TypeHandler<RefCountedPerson>
|
||||
{
|
||||
public:
|
||||
static void bind(std::size_t pos,
|
||||
const RefCountedPerson& obj,
|
||||
AbstractBinder* pBinder,
|
||||
AbstractBinder::Direction dir = AbstractBinder::PD_IN)
|
||||
{
|
||||
// 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.lastName, dir);
|
||||
pBinder->bind(pos++, obj.firstName, dir);
|
||||
pBinder->bind(pos++, obj.address, dir);
|
||||
pBinder->bind(pos++, obj.age, dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, RefCountedPerson& obj, AbstractPreparation* 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.lastName);
|
||||
pPrepare->prepare(pos++, obj.firstName);
|
||||
pPrepare->prepare(pos++, obj.address);
|
||||
pPrepare->prepare(pos++, obj.age);
|
||||
}
|
||||
|
||||
static std::size_t size()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static void extract(std::size_t pos, RefCountedPerson& obj, const RefCountedPerson& defVal, AbstractExtractor* pExt)
|
||||
{
|
||||
poco_assert_dbg (pExt != 0);
|
||||
if (!pExt->extract(pos++, obj.lastName))
|
||||
obj.lastName = defVal.lastName;
|
||||
if (!pExt->extract(pos++, obj.firstName))
|
||||
obj.firstName = defVal.firstName;
|
||||
if (!pExt->extract(pos++, obj.address))
|
||||
obj.address = defVal.address;
|
||||
if (!pExt->extract(pos++, obj.age))
|
||||
obj.age = defVal.age;
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
@ -230,7 +322,8 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
const std::string& tableCreateString,
|
||||
SQLExecutor::DataBinding bindMode,
|
||||
SQLExecutor::DataExtraction extractMode,
|
||||
bool doTime)
|
||||
bool doTime,
|
||||
const std::string& blobPlaceholder)
|
||||
{
|
||||
SQLRETURN rc;
|
||||
SQLHENV henv = SQL_NULL_HENV;
|
||||
@ -305,7 +398,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
rc = SQLExecute(hstmt);
|
||||
poco_odbc_check_stmt (rc, hstmt);
|
||||
|
||||
sql = "INSERT INTO Test VALUES (?,?,?,?,?,?)";
|
||||
sql = format("INSERT INTO Test VALUES (?,?,%s,?,?,?)", blobPlaceholder);
|
||||
pStr = (SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
poco_odbc_check_stmt (rc, hstmt);
|
||||
@ -976,6 +1069,66 @@ void SQLExecutor::complexTypeVector()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::sharedPtrComplexTypeVector()
|
||||
{
|
||||
std::string funct = "sharedPtrComplexTypeVector()";
|
||||
std::vector<Poco::SharedPtr<Person> > people;
|
||||
people.push_back(new Person("LN1", "FN1", "ADDR1", 1));
|
||||
people.push_back(new Person("LN2", "FN2", "ADDR2", 2));
|
||||
|
||||
try { session() << "INSERT INTO PERSON VALUES (?,?,?,?)", use(people), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
int count = 0;
|
||||
try { session() << "SELECT COUNT(*) FROM PERSON", into(count), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (count == 2);
|
||||
|
||||
std::vector<Person> result;
|
||||
try { session() << "SELECT * FROM PERSON", into(result), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (2 == result.size());
|
||||
assert (result[0] == *people[0]);
|
||||
assert (result[1] == *people[1]);
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::autoPtrComplexTypeVector()
|
||||
{
|
||||
std::string funct = "sharedPtrComplexTypeVector()";
|
||||
std::vector<Poco::AutoPtr<RefCountedPerson> > people;
|
||||
people.push_back(new RefCountedPerson("LN1", "FN1", "ADDR1", 1));
|
||||
people.push_back(new RefCountedPerson("LN2", "FN2", "ADDR2", 2));
|
||||
|
||||
try { session() << "INSERT INTO PERSON VALUES (?,?,?,?)", use(people), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
int count = 0;
|
||||
try { session() << "SELECT COUNT(*) FROM PERSON", into(count), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (count == 2);
|
||||
|
||||
std::vector<Person> result;
|
||||
try { session() << "SELECT * FROM PERSON", into(result), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (2 == result.size());
|
||||
assert (result[0].address == people[0]->address);
|
||||
assert (result[0].age == people[0]->age);
|
||||
assert (result[0].firstName == people[0]->firstName);
|
||||
assert (result[0].lastName == people[0]->lastName);
|
||||
assert (result[1].address == people[1]->address);
|
||||
assert (result[1].age == people[1]->age);
|
||||
assert (result[1].firstName == people[1]->firstName);
|
||||
assert (result[1].lastName == people[1]->lastName);
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::insertVector()
|
||||
{
|
||||
std::string funct = "insertVector()";
|
||||
@ -2188,7 +2341,7 @@ void SQLExecutor::emptyDB()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::blob(int bigSize)
|
||||
void SQLExecutor::blob(int bigSize, const std::string& blobPlaceholder)
|
||||
{
|
||||
std::string funct = "blob()";
|
||||
std::string lastName("lastname");
|
||||
@ -2197,7 +2350,8 @@ void SQLExecutor::blob(int bigSize)
|
||||
|
||||
BLOB img("0123456789", 10);
|
||||
int count = 0;
|
||||
try { session() << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; }
|
||||
try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder),
|
||||
use(lastName), use(firstName), use(address), use(img), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
try { session() << "SELECT COUNT(*) FROM PERSON", into(count), now; }
|
||||
@ -2222,7 +2376,8 @@ void SQLExecutor::blob(int bigSize)
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
try { session() << "INSERT INTO PERSON VALUES(?,?,?,?)", use(lastName), use(firstName), use(address), use(big), now; }
|
||||
try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder),
|
||||
use(lastName), use(firstName), use(address), use(big), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
|
@ -115,7 +115,8 @@ public:
|
||||
const std::string& tableCreateString,
|
||||
DataBinding bindMode,
|
||||
DataExtraction extractMode,
|
||||
bool doTime=true);
|
||||
bool doTime=true,
|
||||
const std::string& blobPlaceholder="?");
|
||||
|
||||
void bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
const std::string& tableCreateString,
|
||||
@ -135,6 +136,8 @@ public:
|
||||
|
||||
void simpleAccessVector();
|
||||
void complexTypeVector();
|
||||
void sharedPtrComplexTypeVector();
|
||||
void autoPtrComplexTypeVector();
|
||||
void insertVector();
|
||||
void insertEmptyVector();
|
||||
|
||||
@ -160,7 +163,7 @@ public:
|
||||
void prepare();
|
||||
|
||||
template <typename C1, typename C2, typename C3, typename C4, typename C5, typename C6>
|
||||
void doBulkWithBool(Poco::UInt32 size)
|
||||
void doBulkWithBool(Poco::UInt32 size, const std::string& blobPlaceholder="?")
|
||||
{
|
||||
poco_data_using_statements;
|
||||
|
||||
@ -183,7 +186,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?,?)",
|
||||
session() <<
|
||||
format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
|
||||
use(strings),
|
||||
use(blobs),
|
||||
use(ints),
|
||||
@ -199,7 +203,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?,?)",
|
||||
session() <<
|
||||
format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
|
||||
use(strings, bulk),
|
||||
use(blobs, bulk),
|
||||
use(ints, bulk),
|
||||
@ -208,7 +213,7 @@ public:
|
||||
use(bools, bulk), now;
|
||||
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
|
||||
ints.clear();
|
||||
strings.clear();
|
||||
blobs.clear();
|
||||
@ -444,7 +449,7 @@ public:
|
||||
void singleSelect();
|
||||
void emptyDB();
|
||||
|
||||
void blob(int bigSize = 1024);
|
||||
void blob(int bigSize = 1024, const std::string& blobPlaceholder = "?");
|
||||
|
||||
template <typename C1, typename C2>
|
||||
void blobContainer(int size)
|
||||
|
@ -113,6 +113,12 @@ protected:
|
||||
Exception(int code = 0);
|
||||
/// Standard constructor.
|
||||
|
||||
void message(const std::string& msg);
|
||||
/// Sets the message for the exception.
|
||||
|
||||
void extendedMessage(const std::string& arg);
|
||||
/// Sets the extended message for the exception.
|
||||
|
||||
private:
|
||||
std::string _msg;
|
||||
Exception* _pNested;
|
||||
@ -135,6 +141,12 @@ inline const std::string& Exception::message() const
|
||||
}
|
||||
|
||||
|
||||
inline void Exception::message(const std::string& msg)
|
||||
{
|
||||
_msg = msg;
|
||||
}
|
||||
|
||||
|
||||
inline int Exception::code() const
|
||||
{
|
||||
return _code;
|
||||
|
@ -53,11 +53,7 @@ Exception::Exception(const std::string& msg, int code): _msg(msg), _pNested(0),
|
||||
|
||||
Exception::Exception(const std::string& msg, const std::string& arg, int code): _msg(msg), _pNested(0), _code(code)
|
||||
{
|
||||
if (!arg.empty())
|
||||
{
|
||||
_msg.append(": ");
|
||||
_msg.append(arg);
|
||||
}
|
||||
extendedMessage(arg);
|
||||
}
|
||||
|
||||
|
||||
@ -124,6 +120,16 @@ std::string Exception::displayText() const
|
||||
}
|
||||
|
||||
|
||||
void Exception::extendedMessage(const std::string& arg)
|
||||
{
|
||||
if (!arg.empty())
|
||||
{
|
||||
if (!_msg.empty()) _msg.append(": ");
|
||||
_msg.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Exception* Exception::clone() const
|
||||
{
|
||||
return new Exception(*this);
|
||||
|
2
build_vs71.cmd
Normal file
2
build_vs71.cmd
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
buildwin 71 build shared both yes
|
2
build_vs80.cmd
Normal file
2
build_vs80.cmd
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
buildwin 80 build shared both yes
|
2
build_vs90.cmd
Normal file
2
build_vs90.cmd
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
buildwin 90 build shared both yes
|
19
buildwin.cmd
19
buildwin.cmd
@ -8,8 +8,12 @@ rem command-line build script for MS Visual Studio
|
||||
rem
|
||||
rem Usage:
|
||||
rem ------
|
||||
rem buildwin VS_VERSION [ACTION] [LINKMODE] [CONFIGURATION] [SAMPLES]
|
||||
rem "buildwin {71|80|90} [build|rebuild|clean] [static|shared|both] [release|debug|both] [yes|no]"
|
||||
rem buildwin VS_VERSION [ACTION] [LINKMODE] [CONFIGURATION] [SAMPLES]
|
||||
rem VS_VERSION: 71|80|90
|
||||
rem ACTION: build|rebuild|clean
|
||||
rem LINKMODE: static|shared|both
|
||||
rem CONFIG: release|debug|both
|
||||
rem SAMPLES: yes|no
|
||||
rem
|
||||
rem VS_VERSION is required argument. Default is build all.
|
||||
|
||||
@ -188,7 +192,12 @@ goto :EOF
|
||||
:usage
|
||||
echo Usage:
|
||||
echo ------
|
||||
echo buildwin VS_VERSION [ACTION] [LINKMODE] [CONFIGURATION] [SAMPLES]
|
||||
echo "buildwin {71|80|90} [build|rebuild|clean] [static|shared|both] [release|debug|both] [yes|no]"
|
||||
|
||||
echo buildwin VS_VERSION [ACTION] [LINKMODE] [CONFIGURATION] [SAMPLES]
|
||||
echo VS_VERSION: "71|80|90"
|
||||
echo ACTION: "build|rebuild|clean"
|
||||
echo LINKMODE: "static|shared|both"
|
||||
echo CONFIG: "release|debug|both"
|
||||
echo SAMPLES: "yes|no"
|
||||
echo.
|
||||
echo Default is build all.
|
||||
endlocal
|
Loading…
x
Reference in New Issue
Block a user