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:
Aleksandar Fabijanic 2008-10-07 18:58:47 +00:00
parent 9be2b5bd92
commit fa02d5aa5b
17 changed files with 316 additions and 46 deletions

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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.");

View File

@ -74,6 +74,8 @@ public:
virtual void testSimpleAccessVector();
virtual void testComplexTypeVector();
virtual void testSharedPtrComplexTypeVector();
virtual void testAutoPtrComplexTypeVector();
virtual void testInsertVector();
virtual void testInsertEmptyVector();

View File

@ -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); }

View File

@ -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)

View File

@ -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;

View File

@ -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
View File

@ -0,0 +1,2 @@
@echo off
buildwin 71 build shared both yes

2
build_vs80.cmd Normal file
View File

@ -0,0 +1,2 @@
@echo off
buildwin 80 build shared both yes

2
build_vs90.cmd Normal file
View File

@ -0,0 +1,2 @@
@echo off
buildwin 90 build shared both yes

View File

@ -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