mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-19 00:46:03 +01:00
clean temp file garbage
This commit is contained in:
parent
2a81e59e8c
commit
413db6d246
@ -1,246 +0,0 @@
|
||||
//
|
||||
// MySQLException.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/src/ResultMetadata.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: ResultMetadata
|
||||
//
|
||||
// Copyright (c) 2008, 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 "Poco/Data/MySQL/ResultMetadata.h"
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
class ResultMetadataHandle
|
||||
/// Simple exception-safe wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit ResultMetadataHandle(MYSQL_STMT* stmt)
|
||||
{
|
||||
h = mysql_stmt_result_metadata(stmt);
|
||||
}
|
||||
|
||||
~ResultMetadataHandle()
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
mysql_free_result(h);
|
||||
}
|
||||
}
|
||||
|
||||
operator MYSQL_RES* ()
|
||||
{
|
||||
return h;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MYSQL_RES* h;
|
||||
};
|
||||
|
||||
std::size_t fieldSize(const MYSQL_FIELD& field)
|
||||
/// Convert field MySQL-type and field MySQL-length to actual field length
|
||||
{
|
||||
switch (field.type)
|
||||
{
|
||||
case MYSQL_TYPE_TINY: return sizeof(char);
|
||||
case MYSQL_TYPE_SHORT: return sizeof(short);
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG: return sizeof(Poco::Int32);
|
||||
case MYSQL_TYPE_FLOAT: return sizeof(float);
|
||||
case MYSQL_TYPE_DOUBLE: return sizeof(double);
|
||||
case MYSQL_TYPE_LONGLONG: return sizeof(Poco::Int64);
|
||||
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
return sizeof(MYSQL_TIME);
|
||||
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_STRING:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
return field.length;
|
||||
|
||||
default:
|
||||
throw Poco::Data::MySQL::StatementException("unknown field type");
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Data::MetaColumn::ColumnDataType fieldType(const MYSQL_FIELD& field)
|
||||
/// Convert field MySQL-type to Poco-type
|
||||
{
|
||||
bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG);
|
||||
|
||||
switch (field.type)
|
||||
{
|
||||
case MYSQL_TYPE_TINY:
|
||||
if (unsig) return Poco::Data::MetaColumn::FDT_UINT8;
|
||||
return Poco::Data::MetaColumn::FDT_INT8;
|
||||
|
||||
case MYSQL_TYPE_SHORT:
|
||||
if (unsig) return Poco::Data::MetaColumn::FDT_UINT16;
|
||||
return Poco::Data::MetaColumn::FDT_INT16;
|
||||
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
if (unsig) return Poco::Data::MetaColumn::FDT_UINT32;
|
||||
return Poco::Data::MetaColumn::FDT_INT32;
|
||||
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
return Poco::Data::MetaColumn::FDT_FLOAT;
|
||||
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
return Poco::Data::MetaColumn::FDT_DOUBLE;
|
||||
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
if (unsig) return Poco::Data::MetaColumn::FDT_UINT64;
|
||||
return Poco::Data::MetaColumn::FDT_INT64;
|
||||
|
||||
case MYSQL_TYPE_STRING:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
return Poco::Data::MetaColumn::FDT_STRING;
|
||||
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
return Poco::Data::MetaColumn::FDT_BLOB;
|
||||
default:
|
||||
return Poco::Data::MetaColumn::FDT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
void ResultMetadata::reset()
|
||||
{
|
||||
_columns.resize(0);
|
||||
_row.resize(0);
|
||||
_buffer.resize(0);
|
||||
_lengths.resize(0);
|
||||
_isNull.resize(0);
|
||||
}
|
||||
|
||||
void ResultMetadata::init(MYSQL_STMT* stmt)
|
||||
{
|
||||
ResultMetadataHandle h(stmt);
|
||||
|
||||
if (!h)
|
||||
{
|
||||
// all right, it is normal
|
||||
// querys such an "INSERT INTO" just does not have result at all
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t count = mysql_num_fields(h);
|
||||
MYSQL_FIELD* fields = mysql_fetch_fields(h);
|
||||
|
||||
std::size_t commonSize = 0;
|
||||
_columns.reserve(count);
|
||||
|
||||
{for (std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
_columns.push_back(MetaColumn(
|
||||
i, // position
|
||||
fields[i].name, // name
|
||||
fieldType(fields[i]), // type
|
||||
fieldSize(fields[i]), // length
|
||||
0, // TODO: precision
|
||||
!IS_NOT_NULL(fields[i].flags) // nullable
|
||||
));
|
||||
|
||||
commonSize += _columns[i].length();
|
||||
}}
|
||||
|
||||
_buffer.resize(commonSize);
|
||||
_row.resize(count);
|
||||
_lengths.resize(count);
|
||||
_isNull.resize(count);
|
||||
|
||||
std::size_t offset = 0;
|
||||
|
||||
{for (std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
std::memset(&_row[i], 0, sizeof(MYSQL_BIND));
|
||||
|
||||
_row[i].buffer_type = fields[i].type;
|
||||
_row[i].buffer_length = static_cast<unsigned int>(_columns[i].length());
|
||||
_row[i].buffer = &_buffer[0] + offset;
|
||||
_row[i].length = &_lengths[i];
|
||||
_row[i].is_null = &_isNull[i];
|
||||
|
||||
offset += _row[i].buffer_length;
|
||||
}}
|
||||
}
|
||||
|
||||
std::size_t ResultMetadata::columnsReturned() const
|
||||
{
|
||||
return static_cast<std::size_t>(_columns.size());
|
||||
}
|
||||
|
||||
const MetaColumn& ResultMetadata::metaColumn(std::size_t pos) const
|
||||
{
|
||||
return _columns[pos];
|
||||
}
|
||||
|
||||
MYSQL_BIND* ResultMetadata::row()
|
||||
{
|
||||
return &_row[0];
|
||||
}
|
||||
|
||||
std::size_t ResultMetadata::length(std::size_t pos) const
|
||||
{
|
||||
return _lengths[pos];
|
||||
}
|
||||
|
||||
const unsigned char* ResultMetadata::rawData(std::size_t pos) const
|
||||
{
|
||||
return reinterpret_cast<const unsigned char*>(_row[pos].buffer);
|
||||
}
|
||||
|
||||
bool ResultMetadata::isNull(std::size_t pos) const
|
||||
{
|
||||
return (_isNull[pos] != 0);
|
||||
}
|
||||
|
||||
}}} // namespace Poco::Data::MySQL
|
@ -1,290 +0,0 @@
|
||||
//
|
||||
// MySQLException.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/src/SessionImpl.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Copyright (c) 2008, 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 "Poco/Data/MySQL/SessionImpl.h"
|
||||
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to)
|
||||
{
|
||||
// skip leading spaces
|
||||
while ((from != to) && isspace(*from)) from++;
|
||||
// skip trailing spaces
|
||||
while ((from != to) && isspace(*(to - 1))) to--;
|
||||
|
||||
return std::string(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
|
||||
const std::string SessionImpl::MYSQL_READ_UNCOMMITTED = "READ UNCOMMITTED";
|
||||
const std::string SessionImpl::MYSQL_READ_COMMITTED = "READ COMMITTED";
|
||||
const std::string SessionImpl::MYSQL_REPEATABLE_READ = "REPEATABLE READ";
|
||||
const std::string SessionImpl::MYSQL_SERIALIZABLE = "SERIALIZABLE";
|
||||
|
||||
|
||||
SessionImpl::SessionImpl(const std::string& connectionString, std::size_t loginTimeout) :
|
||||
Poco::Data::AbstractSessionImpl<SessionImpl>(toLower(connectionString), loginTimeout),
|
||||
_handle(0),
|
||||
_connected(false),
|
||||
_inTransaction(false)
|
||||
{
|
||||
addProperty("insertId",
|
||||
&SessionImpl::setInsertId,
|
||||
&SessionImpl::getInsertId);
|
||||
|
||||
open();
|
||||
setConnectionTimeout(CONNECTION_TIMEOUT_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::open(const std::string& connect)
|
||||
{
|
||||
if (connect != connectionString())
|
||||
{
|
||||
if (isConnected())
|
||||
throw InvalidAccessException("Session already connected");
|
||||
|
||||
if (!connect.empty())
|
||||
setConnectionString(connect);
|
||||
}
|
||||
|
||||
poco_assert_dbg (!connectionString().empty());
|
||||
|
||||
_handle.init();
|
||||
|
||||
unsigned int timeout = static_cast<unsigned int>(getLoginTimeout());
|
||||
_handle.options(MYSQL_OPT_CONNECT_TIMEOUT, timeout);
|
||||
|
||||
std::map<std::string, std::string> options;
|
||||
|
||||
// Default values
|
||||
options["host"] = "localhost";
|
||||
options["port"] = "3306";
|
||||
options["user"] = "";
|
||||
options["password"] = "";
|
||||
options["db"] = "";
|
||||
options["compress"] = "";
|
||||
options["auto-reconnect"] = "";
|
||||
|
||||
const std::string& connString = connectionString();
|
||||
for (std::string::const_iterator start = connString.begin();;)
|
||||
{
|
||||
std::string::const_iterator finish = std::find(start, connString.end(), ';');
|
||||
std::string::const_iterator middle = std::find(start, finish, '=');
|
||||
|
||||
if (middle == finish)
|
||||
throw MySQLException("create session: bad connection string format, can not find '='");
|
||||
|
||||
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
|
||||
|
||||
if ((finish == connString.end()) || (finish + 1 == connString.end())) break;
|
||||
|
||||
start = finish + 1;
|
||||
}
|
||||
|
||||
if (options["user"] == "")
|
||||
throw MySQLException("create session: specify user name");
|
||||
|
||||
const char * db = NULL;
|
||||
if (!options["db"].empty())
|
||||
db = options["db"].c_str();
|
||||
|
||||
unsigned int port = 0;
|
||||
if (!NumberParser::tryParseUnsigned(options["port"], port) || 0 == port || port > 65535)
|
||||
throw MySQLException("create session: specify correct port (numeric in decimal notation)");
|
||||
|
||||
if (options["compress"] == "true")
|
||||
_handle.options(MYSQL_OPT_COMPRESS);
|
||||
else if (options["compress"] == "false")
|
||||
;
|
||||
else if (options["compress"] != "")
|
||||
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
|
||||
|
||||
if (options["auto-reconnect"] == "true")
|
||||
_handle.options(MYSQL_OPT_RECONNECT, true);
|
||||
else if (options["auto-reconnect"] == "false")
|
||||
_handle.options(MYSQL_OPT_RECONNECT, false);
|
||||
else if (options["auto-reconnect"] != "")
|
||||
throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
|
||||
|
||||
// Real connect
|
||||
_handle.connect(options["host"].c_str(),
|
||||
options["user"].c_str(),
|
||||
options["password"].c_str(),
|
||||
db,
|
||||
port);
|
||||
|
||||
addFeature("autoCommit",
|
||||
&SessionImpl::autoCommit,
|
||||
&SessionImpl::isAutoCommit);
|
||||
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
|
||||
SessionImpl::~SessionImpl()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
|
||||
{
|
||||
return new MySQLStatementImpl(*this);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::begin()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock l(_mutex);
|
||||
|
||||
if (_inTransaction)
|
||||
throw Poco::InvalidAccessException("Already in transaction.");
|
||||
|
||||
_handle.startTransaction();
|
||||
_inTransaction = true;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::commit()
|
||||
{
|
||||
_handle.commit();
|
||||
_inTransaction = false;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::rollback()
|
||||
{
|
||||
_handle.rollback();
|
||||
_inTransaction = false;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::autoCommit(const std::string&, bool val)
|
||||
{
|
||||
StatementExecutor ex(_handle);
|
||||
ex.prepare(Poco::format("SET autocommit=%d", val ? 1 : 0));
|
||||
ex.execute();
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isAutoCommit(const std::string&)
|
||||
{
|
||||
int ac = 0;
|
||||
return 1 == getSetting("autocommit", ac);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
|
||||
{
|
||||
std::string isolation;
|
||||
switch (ti)
|
||||
{
|
||||
case Session::TRANSACTION_READ_UNCOMMITTED:
|
||||
isolation = MYSQL_READ_UNCOMMITTED; break;
|
||||
case Session::TRANSACTION_READ_COMMITTED:
|
||||
isolation = MYSQL_READ_COMMITTED; break;
|
||||
case Session::TRANSACTION_REPEATABLE_READ:
|
||||
isolation = MYSQL_REPEATABLE_READ; break;
|
||||
case Session::TRANSACTION_SERIALIZABLE:
|
||||
isolation = MYSQL_SERIALIZABLE; break;
|
||||
default:
|
||||
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||
}
|
||||
|
||||
StatementExecutor ex(_handle);
|
||||
ex.prepare(Poco::format("SET SESSION TRANSACTION ISOLATION LEVEL %s", isolation));
|
||||
ex.execute();
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 SessionImpl::getTransactionIsolation()
|
||||
{
|
||||
std::string isolation;
|
||||
getSetting("tx_isolation", isolation);
|
||||
Poco::replaceInPlace(isolation, "-", " ");
|
||||
if (MYSQL_READ_UNCOMMITTED == isolation)
|
||||
return Session::TRANSACTION_READ_UNCOMMITTED;
|
||||
else if (MYSQL_READ_COMMITTED == isolation)
|
||||
return Session::TRANSACTION_READ_COMMITTED;
|
||||
else if (MYSQL_REPEATABLE_READ == isolation)
|
||||
return Session::TRANSACTION_REPEATABLE_READ;
|
||||
else if (MYSQL_SERIALIZABLE == isolation)
|
||||
return Session::TRANSACTION_SERIALIZABLE;
|
||||
|
||||
throw InvalidArgumentException("getTransactionIsolation()");
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
|
||||
{
|
||||
return Session::TRANSACTION_READ_UNCOMMITTED == ti ||
|
||||
Session::TRANSACTION_READ_COMMITTED == ti ||
|
||||
Session::TRANSACTION_REPEATABLE_READ == ti ||
|
||||
Session::TRANSACTION_SERIALIZABLE == ti;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::close()
|
||||
{
|
||||
if (_connected)
|
||||
{
|
||||
_handle.close();
|
||||
_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setConnectionTimeout(std::size_t timeout)
|
||||
{
|
||||
_handle.options(MYSQL_OPT_READ_TIMEOUT, static_cast<unsigned int>(timeout));
|
||||
_handle.options(MYSQL_OPT_WRITE_TIMEOUT, static_cast<unsigned int>(timeout));
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
@ -1,861 +0,0 @@
|
||||
//
|
||||
// MySQLTest.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/testsuite/src/MySQLTest.cpp#1 $
|
||||
//
|
||||
// Copyright (c) 2008, 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 "MySQLTest.h"
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/Tuple.h"
|
||||
#include "Poco/NamedTuple.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/StatementImpl.h"
|
||||
#include "Poco/Data/MySQL/Connector.h"
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include "Poco/Nullable.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Poco::Data;
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::Data::MySQL::ConnectionException;
|
||||
using Poco::Data::MySQL::StatementException;
|
||||
using Poco::format;
|
||||
using Poco::NotFoundException;
|
||||
using Poco::Int32;
|
||||
using Poco::Nullable;
|
||||
using Poco::Tuple;
|
||||
using Poco::NamedTuple;
|
||||
|
||||
Poco::SharedPtr<Poco::Data::Session> MySQLTest::_pSession = 0;
|
||||
Poco::SharedPtr<SQLExecutor> MySQLTest::_pExecutor = 0;
|
||||
|
||||
//
|
||||
// Parameters for barebone-test
|
||||
#define MYSQL_USER "root"
|
||||
#define MYSQL_PWD "poco"
|
||||
#define MYSQL_HOST "192.168.1.33"
|
||||
#define MYSQL_PORT 3306
|
||||
#define MYSQL_DB "test"
|
||||
|
||||
//
|
||||
// Connection string
|
||||
std::string MySQLTest::_dbConnString = "host=" MYSQL_HOST
|
||||
";user=" MYSQL_USER
|
||||
";password=" MYSQL_PWD
|
||||
";db=" MYSQL_DB
|
||||
";compress=true;auto-reconnect=true";
|
||||
|
||||
|
||||
MySQLTest::MySQLTest(const std::string& name):
|
||||
CppUnit::TestCase(name)
|
||||
{
|
||||
MySQL::Connector::registerConnector();
|
||||
}
|
||||
|
||||
|
||||
MySQLTest::~MySQLTest()
|
||||
{
|
||||
MySQL::Connector::unregisterConnector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testConnectNoDB()
|
||||
{
|
||||
std::string dbConnString = "host=" MYSQL_HOST
|
||||
";user=" MYSQL_USER
|
||||
";password=" MYSQL_PWD
|
||||
";compress=true;auto-reconnect=true";
|
||||
|
||||
try
|
||||
{
|
||||
Session session(MySQL::Connector::KEY, dbConnString);
|
||||
std::cout << "Connected to [" << "MySQL" << "] without database. Disconnecting ..." << std::endl;
|
||||
session.close();
|
||||
std::cout << "Disconnected." << std::endl;
|
||||
}
|
||||
catch (ConnectionFailedException& ex)
|
||||
{
|
||||
std::cout << ex.displayText() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testBareboneMySQL()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
std::string tableCreateString = "CREATE TABLE Test "
|
||||
"(First VARCHAR(30),"
|
||||
"Second VARCHAR(30),"
|
||||
"Third VARBINARY(30),"
|
||||
"Fourth INTEGER,"
|
||||
"Fifth FLOAT)";
|
||||
|
||||
_pExecutor->bareboneMySQLTest(MYSQL_HOST, MYSQL_USER, MYSQL_PWD, MYSQL_DB, MYSQL_PORT, tableCreateString.c_str());
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSimpleAccess()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->simpleAccess();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testComplexType()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->complexType();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSimpleAccessVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->simpleAccessVector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testComplexTypeVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->complexTypeVector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testInsertVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateStringsTable();
|
||||
_pExecutor->insertVector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testInsertEmptyVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateStringsTable();
|
||||
_pExecutor->insertEmptyVector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testInsertSingleBulk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->insertSingleBulk();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testInsertSingleBulkVec()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->insertSingleBulkVec();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLimit()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->limits();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLimitZero()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->limitZero();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLimitOnce()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->limitOnce();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLimitPrepare()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->limitPrepare();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MySQLTest::testPrepare()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateIntsTable();
|
||||
_pExecutor->prepare();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSetSimple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->setSimple();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSetComplex()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->setComplex();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSetComplexUnique()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->setComplexUnique();
|
||||
}
|
||||
|
||||
void MySQLTest::testMultiSetSimple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->multiSetSimple();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testMultiSetComplex()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->multiSetComplex();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testMapComplex()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->mapComplex();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testMapComplexUnique()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->mapComplexUnique();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testMultiMapComplex()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->multiMapComplex();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSelectIntoSingle()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->selectIntoSingle();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSelectIntoSingleStep()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->selectIntoSingleStep();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSelectIntoSingleFail()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->selectIntoSingleFail();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLowerLimitOk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->lowerLimitOk();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSingleSelect()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->singleSelect();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testLowerLimitFail()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->lowerLimitFail();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testCombinedLimits()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->combinedLimits();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MySQLTest::testRange()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->ranges();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testCombinedIllegalLimits()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->combinedIllegalLimits();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MySQLTest::testIllegalRange()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->illegalRange();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testEmptyDB()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->emptyDB();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testBLOB()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
const std::size_t maxFldSize = 65534;
|
||||
_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
|
||||
recreatePersonBLOBTable();
|
||||
|
||||
try
|
||||
{
|
||||
_pExecutor->blob(maxFldSize);
|
||||
fail ("must fail");
|
||||
}
|
||||
catch (DataException&)
|
||||
{
|
||||
_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize));
|
||||
}
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
_pExecutor->blob(maxFldSize);
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
|
||||
try
|
||||
{
|
||||
_pExecutor->blob(maxFldSize+1);
|
||||
fail ("must fail");
|
||||
}
|
||||
catch (DataException&) { }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testBLOBStmt()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
_pExecutor->blobStmt();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testFloat()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateFloatsTable();
|
||||
_pExecutor->floats();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testDouble()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateFloatsTable();
|
||||
_pExecutor->doubles();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTuple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateTuplesTable();
|
||||
_pExecutor->tuples();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTupleVector()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateTuplesTable();
|
||||
_pExecutor->tupleVector();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testInternalExtraction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateVectorsTable();
|
||||
_pExecutor->internalExtraction();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testNull()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateVectorsTable();
|
||||
_pExecutor->doNull();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSessionTransaction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->sessionTransaction(_dbConnString);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTransaction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->transaction(_dbConnString);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testReconnect()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonTable();
|
||||
_pExecutor->reconnect();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testNullableInt()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateNullableIntTable();
|
||||
|
||||
Nullable<Int32> i1(1);
|
||||
Nullable<Int32> i2;
|
||||
|
||||
int id = 1;
|
||||
*_pSession << "INSERT INTO NullableIntTest VALUES(?, ?)", use(id), use(i1), now;
|
||||
id = 2;
|
||||
*_pSession << "INSERT INTO NullableIntTest VALUES(?, ?)", use(id), use(i2), now;
|
||||
id = 3;
|
||||
i2 = 3;
|
||||
*_pSession << "INSERT INTO NullableIntTest VALUES(?, ?)", use(id), use(i2), now;
|
||||
|
||||
int count = 0;
|
||||
*_pSession << "SELECT COUNT(*) FROM NullableIntTest", into(count), now;
|
||||
assert (count == 3);
|
||||
|
||||
Nullable<Int32> ci1;
|
||||
Nullable<Int32> ci2;
|
||||
Nullable<Int32> ci3;
|
||||
id = 1;
|
||||
*_pSession << "SELECT Value FROM NullableIntTest WHERE Id = ?", into(ci1), use(id), now;
|
||||
assert (ci1 == i1);
|
||||
id = 2;
|
||||
*_pSession << "SELECT Value FROM NullableIntTest WHERE Id = ?", into(ci2), use(id), now;
|
||||
assert (ci2.isNull());
|
||||
assert (!(0 == ci2));
|
||||
assert (0 != ci2);
|
||||
assert (!(ci2 == 0));
|
||||
assert (ci2 != 0);
|
||||
ci2 = 10;
|
||||
assert (10 == ci2);
|
||||
assert (ci2 == 10);
|
||||
assert (!ci2.isNull());
|
||||
id = 3;
|
||||
*_pSession << "SELECT Value FROM NullableIntTest WHERE Id = ?", into(ci3), use(id), now;
|
||||
assert (!ci3.isNull());
|
||||
assert (ci3 == 3);
|
||||
assert (3 == ci3);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testNullableString()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateNullableStringTable();
|
||||
|
||||
Int32 id = 0;
|
||||
Nullable<std::string> address("Address");
|
||||
Nullable<Int32> age = 10;
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(id), use(address), use(age), now;
|
||||
id++;
|
||||
address = null;
|
||||
age = null;
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(id), use(address), use(age), now;
|
||||
|
||||
Nullable<std::string> resAddress;
|
||||
Nullable<Int32> resAge;
|
||||
*_pSession << "SELECT Address, Age FROM NullableStringTest WHERE Id = ?", into(resAddress), into(resAge), use(id), now;
|
||||
assert(resAddress == address);
|
||||
assert(resAge == age);
|
||||
assert(resAddress.isNull());
|
||||
assert(null == resAddress);
|
||||
assert(resAddress == null);
|
||||
|
||||
resAddress = std::string("Test");
|
||||
assert(!resAddress.isNull());
|
||||
assert(resAddress == std::string("Test"));
|
||||
assert(std::string("Test") == resAddress);
|
||||
assert(null != resAddress);
|
||||
assert(resAddress != null);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTupleWithNullable()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateNullableStringTable();
|
||||
|
||||
typedef Poco::Tuple<Int32, Nullable<std::string>, Nullable<Int32> > Info;
|
||||
|
||||
Info info(0, std::string("Address"), 10);
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(info), now;
|
||||
|
||||
info.set<0>(info.get<0>()++);
|
||||
info.set<1>(null);
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(info), now;
|
||||
|
||||
info.set<0>(info.get<0>()++);
|
||||
info.set<1>(std::string("Address!"));
|
||||
info.set<2>(null);
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(info), now;
|
||||
|
||||
std::vector<Info> infos;
|
||||
infos.push_back(Info(10, std::string("A"), 0));
|
||||
infos.push_back(Info(11, null, 12));
|
||||
infos.push_back(Info(12, std::string("B"), null));
|
||||
|
||||
*_pSession << "INSERT INTO NullableStringTest VALUES(?, ?, ?)", use(infos), now;
|
||||
|
||||
std::vector<Info> result;
|
||||
|
||||
*_pSession << "SELECT Id, Address, Age FROM NullableStringTest", into(result), now;
|
||||
|
||||
assert(result[0].get<1>() == std::string("Address"));
|
||||
assert(result[0].get<2>() == 10);
|
||||
|
||||
assert(result[1].get<1>() == null);
|
||||
assert(result[1].get<2>() == 10);
|
||||
|
||||
assert(result[2].get<1>() == std::string("Address!"));
|
||||
assert(result[2].get<2>() == null);
|
||||
|
||||
assert(result[3].get<1>() == std::string("A"));
|
||||
assert(result[3].get<2>() == 0);
|
||||
|
||||
assert(result[4].get<1>() == null);
|
||||
assert(result[4].get<2>() == 12);
|
||||
|
||||
assert(result[5].get<1>() == std::string("B"));
|
||||
assert(result[5].get<2>() == null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::dropTable(const std::string& tableName)
|
||||
{
|
||||
|
||||
try { *_pSession << format("DROP TABLE IF EXISTS %s", tableName), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("dropTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("dropTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreatePersonTable()
|
||||
{
|
||||
dropTable("Person");
|
||||
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreatePersonBLOBTable()
|
||||
{
|
||||
dropTable("Person");
|
||||
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreatePersonDateTimeTable()
|
||||
{
|
||||
dropTable("Person");
|
||||
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Birthday DATETIME)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonDateTimeTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonDateTimeTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateIntsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateStringsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateStringsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateStringsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateFloatsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateFloatsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateFloatsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateTuplesTable()
|
||||
{
|
||||
dropTable("Tuples");
|
||||
try { *_pSession << "CREATE TABLE Tuples "
|
||||
"(i0 INTEGER, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, i5 INTEGER, i6 INTEGER, "
|
||||
"i7 INTEGER, i8 INTEGER, i9 INTEGER, i10 INTEGER, i11 INTEGER, i12 INTEGER, i13 INTEGER,"
|
||||
"i14 INTEGER, i15 INTEGER, i16 INTEGER, i17 INTEGER, i18 INTEGER, i19 INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateTuplesTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateTuplesTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateNullableIntTable()
|
||||
{
|
||||
dropTable("NullableIntTest");
|
||||
try {
|
||||
*_pSession << "CREATE TABLE NullableIntTest (Id INTEGER(10), Value INTEGER(10))", now;
|
||||
}
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateNullableIntTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateNullableIntTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateNullableStringTable()
|
||||
{
|
||||
dropTable("NullableStringTest");
|
||||
try {
|
||||
*_pSession << "CREATE TABLE NullableStringTest (Id INTEGER(10), Address VARCHAR(30), Age INTEGER(10))", now;
|
||||
}
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateNullableStringTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateNullableStringTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateVectorsTable()
|
||||
{
|
||||
dropTable("Vectors");
|
||||
try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateVectorsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateVectorsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::tearDown()
|
||||
{
|
||||
dropTable("Person");
|
||||
dropTable("Strings");
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* MySQLTest::suite()
|
||||
{
|
||||
MySQL::Connector::registerConnector();
|
||||
|
||||
try
|
||||
{
|
||||
_pSession = new Session(MySQL::Connector::KEY, _dbConnString);
|
||||
}
|
||||
catch (ConnectionFailedException& ex)
|
||||
{
|
||||
std::cout << ex.displayText() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "*** Connected to [" << "MySQL" << "] test database." << std::endl;
|
||||
|
||||
_pExecutor = new SQLExecutor("MySQL SQL Executor", _pSession);
|
||||
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTest");
|
||||
|
||||
CppUnit_addTest(pSuite, MySQLTest, testConnectNoDB);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testBareboneMySQL);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSimpleAccess);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testComplexType);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSimpleAccessVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testComplexTypeVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInsertVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInsertEmptyVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulk);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulkVec);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLimit);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLimitOnce);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLimitPrepare);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLimitZero);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testPrepare);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSetComplexUnique);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testMultiSetSimple);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testMultiSetComplex);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testMapComplex);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testMapComplexUnique);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testMultiMapComplex);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingle);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleStep);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleFail);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLowerLimitOk);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testLowerLimitFail);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testCombinedLimits);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testCombinedIllegalLimits);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testRange);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testIllegalRange);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSingleSelect);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testEmptyDB);
|
||||
//CppUnit_addTest(pSuite, MySQLTest, testBLOB);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testBLOBStmt);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testFloat);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testDouble);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testNull);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testNullableInt);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testNullableString);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTupleWithNullable);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSessionTransaction);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTransaction);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testReconnect);
|
||||
|
||||
return pSuite;
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
//
|
||||
// ODBCMySQLTest.h
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/testsuite/src/ODBCMySQLTest.h#1 $
|
||||
//
|
||||
// Definition of the MySQLTest class.
|
||||
//
|
||||
// Copyright (c) 2008, 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef MySQLTest_INCLUDED
|
||||
#define MySQLTest_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "CppUnit/TestCase.h"
|
||||
#include "SQLExecutor.h"
|
||||
|
||||
|
||||
class MySQLTest: public CppUnit::TestCase
|
||||
/// MySQL test class
|
||||
/// Tested:
|
||||
///
|
||||
/// Driver | DB | OS
|
||||
/// ----------------+---------------------------+------------------------------------------
|
||||
/// 03.51.12.00 | MySQL 5.0.27-community-nt | MS Windows XP Professional x64 v.2003/SP1
|
||||
///
|
||||
|
||||
{
|
||||
public:
|
||||
MySQLTest(const std::string& name);
|
||||
~MySQLTest();
|
||||
|
||||
void testConnectNoDB();
|
||||
void testBareboneMySQL();
|
||||
|
||||
void testSimpleAccess();
|
||||
void testComplexType();
|
||||
void testSimpleAccessVector();
|
||||
void testComplexTypeVector();
|
||||
void testInsertVector();
|
||||
void testInsertEmptyVector();
|
||||
|
||||
void testInsertSingleBulk();
|
||||
void testInsertSingleBulkVec();
|
||||
|
||||
void testLimit();
|
||||
void testLimitOnce();
|
||||
void testLimitPrepare();
|
||||
void testLimitZero();
|
||||
void testPrepare();
|
||||
|
||||
void testSetSimple();
|
||||
void testSetComplex();
|
||||
void testSetComplexUnique();
|
||||
void testMultiSetSimple();
|
||||
void testMultiSetComplex();
|
||||
void testMapComplex();
|
||||
void testMapComplexUnique();
|
||||
void testMultiMapComplex();
|
||||
void testSelectIntoSingle();
|
||||
void testSelectIntoSingleStep();
|
||||
void testSelectIntoSingleFail();
|
||||
void testLowerLimitOk();
|
||||
void testLowerLimitFail();
|
||||
void testCombinedLimits();
|
||||
void testCombinedIllegalLimits();
|
||||
void testRange();
|
||||
void testIllegalRange();
|
||||
void testSingleSelect();
|
||||
void testEmptyDB();
|
||||
|
||||
void testBLOB();
|
||||
void testBLOBStmt();
|
||||
|
||||
void testFloat();
|
||||
void testDouble();
|
||||
|
||||
void testTuple();
|
||||
void testTupleVector();
|
||||
|
||||
void testInternalExtraction();
|
||||
|
||||
void testNull();
|
||||
void testNullVector();
|
||||
|
||||
void testNullableInt();
|
||||
void testNullableString();
|
||||
void testTupleWithNullable();
|
||||
|
||||
void testSessionTransaction();
|
||||
void testTransaction();
|
||||
|
||||
void testReconnect();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
private:
|
||||
|
||||
void dropTable(const std::string& tableName);
|
||||
void recreatePersonTable();
|
||||
void recreatePersonBLOBTable();
|
||||
void recreatePersonDateTimeTable();
|
||||
void recreateStringsTable();
|
||||
void recreateIntsTable();
|
||||
void recreateFloatsTable();
|
||||
void recreateTuplesTable();
|
||||
void recreateVectorsTable();
|
||||
void recreateNullableIntTable();
|
||||
void recreateNullableStringTable();
|
||||
|
||||
static std::string _dbConnString;
|
||||
static Poco::SharedPtr<Poco::Data::Session> _pSession;
|
||||
static Poco::SharedPtr<SQLExecutor> _pExecutor;
|
||||
static const bool bindValues[8];
|
||||
};
|
||||
|
||||
|
||||
#endif // MySQLTest_INCLUDED
|
File diff suppressed because it is too large
Load Diff
@ -1,126 +0,0 @@
|
||||
//
|
||||
// SQLExecutor.h
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/testsuite/src/SQLExecutor.h#1 $
|
||||
//
|
||||
// Definition of the SQLExecutor class.
|
||||
//
|
||||
// Copyright (c) 2008, 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef SQLExecutor_INCLUDED
|
||||
#define SQLExecutor_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
|
||||
|
||||
class SQLExecutor: public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
enum DataBinding
|
||||
{
|
||||
PB_IMMEDIATE,
|
||||
PB_AT_EXEC
|
||||
};
|
||||
|
||||
enum DataExtraction
|
||||
{
|
||||
DE_MANUAL,
|
||||
DE_BOUND
|
||||
};
|
||||
|
||||
SQLExecutor(const std::string& name, Poco::Data::Session* _pSession);
|
||||
~SQLExecutor();
|
||||
|
||||
void bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString);
|
||||
/// This function uses "bare bone" MySQL API calls (i.e. calls are not
|
||||
/// "wrapped" in PocoData framework structures).
|
||||
/// The purpose of the function is to verify that driver behaves
|
||||
/// correctly. If this test passes, subsequent tests failures are likely ours.
|
||||
|
||||
void simpleAccess();
|
||||
void complexType();
|
||||
void simpleAccessVector();
|
||||
void complexTypeVector();
|
||||
void insertVector();
|
||||
void insertEmptyVector();
|
||||
|
||||
void insertSingleBulk();
|
||||
void insertSingleBulkVec();
|
||||
|
||||
void limits();
|
||||
void limitOnce();
|
||||
void limitPrepare();
|
||||
void limitZero();
|
||||
void prepare();
|
||||
|
||||
void setSimple();
|
||||
void setComplex();
|
||||
void setComplexUnique();
|
||||
void multiSetSimple();
|
||||
void multiSetComplex();
|
||||
void mapComplex();
|
||||
void mapComplexUnique();
|
||||
void multiMapComplex();
|
||||
void selectIntoSingle();
|
||||
void selectIntoSingleStep();
|
||||
void selectIntoSingleFail();
|
||||
void lowerLimitOk();
|
||||
void lowerLimitFail();
|
||||
void combinedLimits();
|
||||
void combinedIllegalLimits();
|
||||
void ranges();
|
||||
void illegalRange();
|
||||
void singleSelect();
|
||||
void emptyDB();
|
||||
|
||||
void blob(int bigSize = 1024);
|
||||
void blobStmt();
|
||||
void dateTime();
|
||||
void floats();
|
||||
void doubles();
|
||||
void tuples();
|
||||
void tupleVector();
|
||||
|
||||
void internalExtraction();
|
||||
void doNull();
|
||||
|
||||
void sessionTransaction(const std::string& connect);
|
||||
void transaction(const std::string& connect);
|
||||
|
||||
void reconnect();
|
||||
|
||||
private:
|
||||
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
|
||||
|
||||
Poco::Data::Session* _pSession;
|
||||
};
|
||||
|
||||
|
||||
#endif // SQLExecutor_INCLUDED
|
File diff suppressed because it is too large
Load Diff
@ -1,103 +0,0 @@
|
||||
//
|
||||
// RecordSet.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/samples/RecordSet/src/RecordSet.cpp#2 $
|
||||
//
|
||||
// This sample demonstrates the Data library.
|
||||
//
|
||||
/// Copyright (c) 2008, 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 "Poco/SharedPtr.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/Column.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::DateTime;
|
||||
using Poco::Data::Session;
|
||||
using Poco::Data::Statement;
|
||||
using Poco::Data::RecordSet;
|
||||
|
||||
|
||||
struct Person
|
||||
{
|
||||
std::string name;
|
||||
std::string address;
|
||||
int age;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// register SQLite connector
|
||||
Poco::Data::SQLite::Connector::registerConnector();
|
||||
|
||||
// create a session
|
||||
Session session("SQLite", "sample.db");
|
||||
|
||||
// drop sample table, if it exists
|
||||
session << "DROP TABLE IF EXISTS Person", now;
|
||||
|
||||
// (re)create table
|
||||
session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3), Birthday DATE)", now;
|
||||
|
||||
// insert some rows
|
||||
session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12, ?)", use(DateTime(1980, 4, 1)), now;
|
||||
session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10, ?)", use(DateTime(1982, 5, 9)), now;
|
||||
|
||||
// a simple query
|
||||
Statement select(session);
|
||||
select << "SELECT * FROM Person";
|
||||
select.execute();
|
||||
|
||||
// create a RecordSet
|
||||
RecordSet rs(select);
|
||||
std::size_t cols = rs.columnCount();
|
||||
// print all column names
|
||||
for (std::size_t col = 0; col < cols; ++col)
|
||||
{
|
||||
std::cout << rs.columnName(col) << std::endl;
|
||||
}
|
||||
// iterate over all rows and columns
|
||||
bool more = rs.moveFirst();
|
||||
while (more)
|
||||
{
|
||||
for (std::size_t col = 0; col < cols; ++col)
|
||||
{
|
||||
std::cout << rs[col].convert<std::string>() << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
more = rs.moveNext();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
//
|
||||
// RowFormatter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/samples/RecordSet/src/RowFormatter.cpp#2 $
|
||||
//
|
||||
// This sample demonstrates the Data library recordset row formatting
|
||||
// and streaming capabilities.
|
||||
//
|
||||
// Copyright (c) 2008, 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 "Poco/SharedPtr.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/Statement.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::DateTime;
|
||||
using Poco::Data::Session;
|
||||
using Poco::Data::Statement;
|
||||
using Poco::Data::RecordSet;
|
||||
using Poco::Data::RowFormatter;
|
||||
|
||||
|
||||
class HTMLTableFormatter : public RowFormatter
|
||||
{
|
||||
public:
|
||||
HTMLTableFormatter()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "<TABLE border=\"1\" cellspacing=\"0\">" << std::endl;
|
||||
setPrefix(os.str());
|
||||
|
||||
os.str("");
|
||||
os << "</TABLE>" << std::endl;
|
||||
setPostfix(os.str());
|
||||
}
|
||||
|
||||
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
str << "\t<TR>" << std::endl;
|
||||
NameVec::const_iterator it = pNames->begin();
|
||||
NameVec::const_iterator end = pNames->end();
|
||||
for (; it != end; ++it) str << "\t\t<TH align=\"center\">" << *it << "</TH>" << std::endl;
|
||||
str << "\t</TR>" << std::endl;
|
||||
|
||||
return formattedNames = str.str();
|
||||
}
|
||||
|
||||
std::string& formatValues(const ValueVec& vals, std::string& formattedValues)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
str << "\t<TR>" << std::endl;
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->isNumeric())
|
||||
str << "\t\t<TD align=\"right\">";
|
||||
else
|
||||
str << "\t\t<TD align=\"left\">";
|
||||
|
||||
str << it->convert<std::string>() << "</TD>" << std::endl;
|
||||
}
|
||||
str << "\t</TR>" << std::endl;
|
||||
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// register SQLite connector
|
||||
Poco::Data::SQLite::Connector::registerConnector();
|
||||
|
||||
// create a session
|
||||
Session session("SQLite", "sample.db");
|
||||
|
||||
// drop sample table, if it exists
|
||||
session << "DROP TABLE IF EXISTS Simpsons", now;
|
||||
|
||||
// (re)create table
|
||||
session << "CREATE TABLE Simpsons (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3), Birthday DATE)", now;
|
||||
|
||||
// insert some rows
|
||||
DateTime hd(1956, 3, 1), md(1954, 10, 1), bd(1980, 4, 1), ld(1982, 5, 9);
|
||||
session << "INSERT INTO Simpsons VALUES('Homer Simpson', 'Springfield', 42, ?)", use(hd), now;
|
||||
session << "INSERT INTO Simpsons VALUES('Marge Simpson', 'Springfield', 38, ?)", use(md), now;
|
||||
session << "INSERT INTO Simpsons VALUES('Bart Simpson', 'Springfield', 12, ?)", use(bd), now;
|
||||
session << "INSERT INTO Simpsons VALUES('Lisa Simpson', 'Springfield', 10, ?)", use(ld), now;
|
||||
|
||||
// create a statement and print the column names and data as HTML table
|
||||
HTMLTableFormatter tf;
|
||||
Statement stmt = (session << "SELECT * FROM Simpsons", format(tf), now);
|
||||
RecordSet rs(stmt);
|
||||
std::cout << rs << std::endl;
|
||||
|
||||
// Note: The code above is divided into individual steps for clarity purpose.
|
||||
// The four lines can be reduced to the following single line of code:
|
||||
std::cout << RecordSet(session, "SELECT * FROM Simpsons", new HTMLTableFormatter);
|
||||
|
||||
// simple formatting example (uses the default SimpleRowFormatter provided by framework)
|
||||
std::cout << std::endl << "Simple formatting:" << std::endl << std::endl;
|
||||
std::cout << RecordSet(session, "SELECT * FROM Simpsons");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,923 +0,0 @@
|
||||
//
|
||||
// JSONTest.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/XML/testsuite/src/JSONTest.cpp#1 $
|
||||
//
|
||||
// Copyright (c) 2004-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 "JSONTest.h"
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Query.h"
|
||||
#include "Poco/JSON/JSONException.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "Poco/JSON/DefaultHandler.h"
|
||||
#include "Poco/JSON/Template.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/Glob.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
using namespace Poco::JSON;
|
||||
using namespace Poco::Dynamic;
|
||||
|
||||
|
||||
JSONTest::JSONTest(const std::string& name): CppUnit::TestCase("JSON")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
JSONTest::~JSONTest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testStringifier()
|
||||
{
|
||||
Object obj;
|
||||
|
||||
Array arr;
|
||||
Object obj2;
|
||||
|
||||
obj.set("array", arr);
|
||||
obj.set("obj2", obj2);
|
||||
|
||||
std::ostringstream ostr;
|
||||
obj.stringify(ostr);
|
||||
assert (ostr.str() == "{\"array\":[],\"obj2\":{}}");
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testNullProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : null }";
|
||||
Parser parser;
|
||||
|
||||
Var result;
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->isNull("test"));
|
||||
Var test = object->get("test");
|
||||
assert(test.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testTrueProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : true }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(value);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testFalseProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : false }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(!value);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testNumberProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : 1969 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isInteger());
|
||||
int value = test;
|
||||
assert(value == 1969);
|
||||
}
|
||||
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
|
||||
|
||||
void JSONTest::testNumber64Property()
|
||||
{
|
||||
std::string json = "{ \"test\" : 5000000000000000 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isInteger());
|
||||
Int64 value = test;
|
||||
assert(value == 5000000000000000);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void JSONTest::testStringProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : \"value\" }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testEmptyObject()
|
||||
{
|
||||
std::string json = "{}";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->size() == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDoubleProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : 123.45 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value == 123.45);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDouble2Property()
|
||||
{
|
||||
std::string json = "{ \"test\" : 12e34 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value >= 1.99e34 && value <= 12.01e34);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDouble3Property()
|
||||
{
|
||||
std::string json = "{ \"test\" : 12e-34 }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
Var test = object->get("test");
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value == 12e-34);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testObjectProperty()
|
||||
{
|
||||
std::string json = "{ \"test\" : { \"property\" : \"value\" } }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert (object->isObject("test"));
|
||||
assert (!object->isArray("test"));
|
||||
|
||||
Var test = object->get("test");
|
||||
assert(test.type() == typeid(Object::Ptr));
|
||||
object = test.extract<Object::Ptr>();
|
||||
|
||||
test = object->get("property");
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testObjectArray()
|
||||
{
|
||||
std::string json = "{ \"test\" : { \"test1\" : [1, 2, 3], \"test2\" : 4 } }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
assert(object->isObject("test"));
|
||||
object = object->getObject("test");
|
||||
assert(!object->isObject("test1"));
|
||||
assert(object->isArray("test1"));
|
||||
assert(!object->isObject("test2"));
|
||||
assert(!object->isArray("test2"));
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testEmptyArray()
|
||||
{
|
||||
std::string json = "[]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
assert(array->size() == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testNestedArray()
|
||||
{
|
||||
std::string json = "[[[[]]]]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
assert(array->size() == 1);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testNullElement()
|
||||
{
|
||||
std::string json = "[ null ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
assert(array->isNull(0));
|
||||
Var test = array->get(0);
|
||||
assert(test.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testTrueElement()
|
||||
{
|
||||
std::string json = "[ true ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(value);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testFalseElement()
|
||||
{
|
||||
std::string json = "[ false ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.type() == typeid(bool));
|
||||
bool value = test;
|
||||
assert(!value);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testNumberElement()
|
||||
{
|
||||
std::string json = "[ 1969 ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isInteger());
|
||||
int value = test;
|
||||
assert(value == 1969);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testStringElement()
|
||||
{
|
||||
std::string json = "[ \"value\" ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isString());
|
||||
std::string value = test.convert<std::string>();
|
||||
assert(value.compare("value") == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testEmptyObjectElement()
|
||||
{
|
||||
std::string json = "[{}]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Object::Ptr object = array->getObject(0);
|
||||
assert(object->size() == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testDoubleElement()
|
||||
{
|
||||
std::string json = "[ 123.45 ]";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Array::Ptr));
|
||||
|
||||
Array::Ptr array = result.extract<Array::Ptr>();
|
||||
Var test = array->get(0);
|
||||
assert(test.isNumeric());
|
||||
double value = test;
|
||||
assert(value == 123.45);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testOptValue()
|
||||
{
|
||||
std::string json = "{ }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Object::Ptr object = result.extract<Object::Ptr>();
|
||||
int n = object->optValue("test", 123);
|
||||
assert(n == 123);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testQuery()
|
||||
{
|
||||
std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(json);
|
||||
result = handler.result();
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::cout << jsone.message() << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
assert(result.type() == typeid(Object::Ptr));
|
||||
|
||||
Query query(result);
|
||||
|
||||
std::string firstChild = query.findValue("children[0]", "");
|
||||
assert(firstChild.compare("Jonas") == 0);
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testValidJanssonFiles()
|
||||
{
|
||||
Poco::Path pathPattern(getTestFilesPath("valid"));
|
||||
|
||||
std::set<std::string> paths;
|
||||
Poco::Glob::glob(pathPattern, paths);
|
||||
|
||||
for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
|
||||
{
|
||||
Poco::Path filePath(*it, "input");
|
||||
|
||||
if ( filePath.isFile() )
|
||||
{
|
||||
Poco::File inputFile(filePath);
|
||||
if ( inputFile.exists() )
|
||||
{
|
||||
Poco::FileInputStream fis(filePath.toString());
|
||||
std::cout << filePath.toString() << std::endl;
|
||||
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(fis);
|
||||
result = handler.result();
|
||||
std::cout << "Ok!" << std::endl;
|
||||
}
|
||||
catch(JSONException& jsone)
|
||||
{
|
||||
std::string err = jsone.displayText();
|
||||
std::cout << "Failed:" << err << std::endl;
|
||||
fail (err);
|
||||
}
|
||||
catch(Poco::Exception& e)
|
||||
{
|
||||
std::string err = e.displayText();
|
||||
std::cout << "Failed:" << err << std::endl;
|
||||
fail (err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testInvalidJanssonFiles()
|
||||
{
|
||||
Poco::Path pathPattern(getTestFilesPath("invalid"));
|
||||
|
||||
std::set<std::string> paths;
|
||||
Poco::Glob::glob(pathPattern, paths);
|
||||
|
||||
for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
|
||||
{
|
||||
Poco::Path filePath(*it, "input");
|
||||
|
||||
if ( filePath.isFile() )
|
||||
{
|
||||
Poco::File inputFile(filePath);
|
||||
if ( inputFile.exists() )
|
||||
{
|
||||
Poco::FileInputStream fis(filePath.toString());
|
||||
std::cout << filePath.toString() << std::endl;
|
||||
|
||||
Parser parser;
|
||||
Var result;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultHandler handler;
|
||||
parser.setHandler(&handler);
|
||||
parser.parse(fis);
|
||||
result = handler.result();
|
||||
// We shouldn't get here.
|
||||
std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
|
||||
fail(result.convert<std::string>());
|
||||
}
|
||||
catch(JSONException&)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
catch(Poco::SyntaxException&)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JSONTest::testTemplate()
|
||||
{
|
||||
Template tpl;
|
||||
tpl.parse("Hello world! From <?= person.name ?>\n<?if person.toOld ?>You're too old<?endif?>\n");
|
||||
|
||||
Object::Ptr data = new Object();
|
||||
Object::Ptr person = new Object();
|
||||
data->set("person", person);
|
||||
person->set("name", "Franky");
|
||||
person->set("toOld", true);
|
||||
tpl.render(data, std::cout);
|
||||
}
|
||||
|
||||
|
||||
std::string JSONTest::getTestFilesPath(const std::string& type)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "data/" << type << '/';
|
||||
std::string validDir(ostr.str());
|
||||
Poco::Path pathPattern(validDir);
|
||||
if (Poco::File(pathPattern).exists())
|
||||
{
|
||||
validDir += '*';
|
||||
return validDir;
|
||||
}
|
||||
|
||||
ostr.str("");
|
||||
ostr << "/JSON/testsuite/data/" << type << '/';
|
||||
validDir = Poco::Environment::get("POCO_BASE") + ostr.str();
|
||||
pathPattern = validDir;
|
||||
|
||||
if (Poco::File(pathPattern).exists())
|
||||
validDir += '*';
|
||||
else
|
||||
throw Poco::NotFoundException("cannot locate directory containing valid JSON test files");
|
||||
|
||||
return validDir;
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* JSONTest::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("JSONTest");
|
||||
|
||||
CppUnit_addTest(pSuite, JSONTest, testStringifier);
|
||||
CppUnit_addTest(pSuite, JSONTest, testNullProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testTrueProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testFalseProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testNumberProperty);
|
||||
#if defined(POCO_HAVE_INT64)
|
||||
CppUnit_addTest(pSuite, JSONTest, testNumber64Property);
|
||||
#endif
|
||||
CppUnit_addTest(pSuite, JSONTest, testStringProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testEmptyObject);
|
||||
CppUnit_addTest(pSuite, JSONTest, testDoubleProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testDouble2Property);
|
||||
CppUnit_addTest(pSuite, JSONTest, testDouble3Property);
|
||||
CppUnit_addTest(pSuite, JSONTest, testObjectProperty);
|
||||
CppUnit_addTest(pSuite, JSONTest, testObjectArray);
|
||||
CppUnit_addTest(pSuite, JSONTest, testEmptyArray);
|
||||
CppUnit_addTest(pSuite, JSONTest, testNestedArray);
|
||||
CppUnit_addTest(pSuite, JSONTest, testNullElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testTrueElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testFalseElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testNumberElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testStringElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testEmptyObjectElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testDoubleElement);
|
||||
CppUnit_addTest(pSuite, JSONTest, testOptValue);
|
||||
CppUnit_addTest(pSuite, JSONTest, testQuery);
|
||||
CppUnit_addTest(pSuite, JSONTest, testValidJanssonFiles);
|
||||
CppUnit_addTest(pSuite, JSONTest, testInvalidJanssonFiles);
|
||||
CppUnit_addTest(pSuite, JSONTest, testTemplate);
|
||||
|
||||
return pSuite;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user