=MySQL connector

This commit is contained in:
Sergey Kholodilov
2008-06-25 10:42:16 +00:00
parent e4d212a9d3
commit 33efbefa71
32 changed files with 7420 additions and 0 deletions

623
Data/MySQL/src/Binder.cpp Normal file
View File

@@ -0,0 +1,623 @@
//
// MySQLException.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/Binder.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: Binder
//
// 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/Binder.h"
namespace Poco {
namespace Data {
namespace MySQL {
Binder::Binder()
{
}
Binder::~Binder()
{
}
void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_SHORT, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_SHORT, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0);
}
#ifndef POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const long& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0);
}
#endif
void Binder::bind(std::size_t pos, const bool& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const float& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_FLOAT, &val, 0);
}
void Binder::bind(std::size_t pos, const double& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_DOUBLE, &val, 0);
}
void Binder::bind(std::size_t pos, const char& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_STRING, val.c_str(), static_cast<int>(val.length()));
}
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_BLOB, val.rawContent(), static_cast<int>(val.size()));
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
mt.year = val.year();
mt.month = val.month();
mt.day = val.day();
mt.hour = val.hour();
mt.minute = val.minute();
mt.second = val.second();
mt.second_part = val.millisecond();
mt.time_type = MYSQL_TIMESTAMP_DATETIME;
_dates.push_back(mt);
realBind(pos, MYSQL_TYPE_DATETIME, &_dates.back(), sizeof(mt));
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
mt.year = val.year();
mt.month = val.month();
mt.day = val.day();
_dates.push_back(mt);
realBind(pos, MYSQL_TYPE_DATE, &_dates.back(), sizeof(mt));
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
mt.hour = val.hour();
mt.minute = val.minute();
mt.second = val.second();
mt.time_type = MYSQL_TIMESTAMP_TIME;
_dates.push_back(mt);
realBind(pos, MYSQL_TYPE_TIME, &_dates.back(), sizeof(mt));
}
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_NULL, 0, 0);
}
size_t Binder::size() const
{
return _bindArray.size();
}
MYSQL_BIND* Binder::getBindArray() const
{
if (_bindArray.size() == 0)
{
return 0;
}
return const_cast<MYSQL_BIND*>(&_bindArray[0]);
}
/*void Binder::updateDates()
{
for (size_t i = 0; i < _dates.size(); i++)
{
switch (_dates[i].mt.time_type)
{
case MYSQL_TIMESTAMP_DATE:
_dates[i].mt.year = _dates[i].link.date->year();
_dates[i].mt.month = _dates[i].link.date->month();
_dates[i].mt.day = _dates[i].link.date->day();
break;
case MYSQL_TIMESTAMP_DATETIME:
_dates[i].mt.year = _dates[i].link.dateTime->year();
_dates[i].mt.month = _dates[i].link.dateTime->month();
_dates[i].mt.day = _dates[i].link.dateTime->day();
_dates[i].mt.hour = _dates[i].link.dateTime->hour();
_dates[i].mt.minute = _dates[i].link.dateTime->minute();
_dates[i].mt.second = _dates[i].link.dateTime->second();
_dates[i].mt.second_part = _dates[i].link.dateTime->millisecond();
break;
case MYSQL_TIMESTAMP_TIME:
_dates[i].mt.hour = _dates[i].link.time->hour();
_dates[i].mt.minute = _dates[i].link.time->minute();
_dates[i].mt.second = _dates[i].link.time->second();
break;
}
}
}*/
///////////////////
//
// Private
//
////////////////////
void Binder::realBind(std::size_t pos, enum_field_types type, const void* buffer, int length)
{
if (pos > 1024)
{
throw StatementException("too many bind parameters");
}
if (pos >= _bindArray.size())
{
size_t s = _bindArray.size();
_bindArray.resize(pos + 1);
memset(&_bindArray[s], 0, sizeof(MYSQL_BIND) * (_bindArray.size() - s));
}
MYSQL_BIND b = {0};
b.buffer_type = type;
b.buffer = const_cast<void*>(buffer);
b.buffer_length = length;
_bindArray[pos] = b;
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<bool>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<bool>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<float>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<float>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<double>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<double>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<char>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<char>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::BLOB>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::BLOB>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Data::BLOB>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::DateTime>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::DateTime>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::DateTime>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::Date>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::Date>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Data::Date>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::Time>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::Time>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Data::Time>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::NullData>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::NullData>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Data::NullData>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<std::string>& val, Direction dir)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<std::string>& val, Direction dir)
{
throw NotImplementedException();
}
} } } // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,92 @@
//
// MySQLException.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/Connector.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: Connector
//
// 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/Connector.h"
#include "Poco/Data/MySQL/SessionImpl.h"
#include "Poco/Data/SessionFactory.h"
#include "Poco/Exception.h"
#include <mysql.h>
namespace Poco {
namespace Data {
namespace MySQL {
std::string Connector::KEY("MySQL");
Connector::Connector()
{
}
Connector::~Connector()
{
}
const std::string& Connector::name() const
{
return KEY;
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
}
void Connector::registerConnector()
{
if (mysql_library_init(0, 0, 0) != 0)
{
throw Exception("mysql_library_init error");
}
Poco::Data::SessionFactory::instance().add(new Connector());
}
void Connector::unregisterConnector()
{
Poco::Data::SessionFactory::instance().remove(KEY);
mysql_library_end();
}
} } } // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,622 @@
//
// MySQLException.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/Extractor.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: Extractor
//
// 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/Extractor.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
namespace Poco {
namespace Data {
namespace MySQL {
Extractor::Extractor(StatementExecutor& st, ResultMetadata& md): _stmt(st), _metadata(md)
{
}
Extractor::~Extractor()
{
}
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
{
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
}
bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
{
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
}
bool Extractor::extract(std::size_t pos, Poco::Int16& val)
{
return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val);
}
bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
{
return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val);
}
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
{
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
}
bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
{
return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
}
bool Extractor::extract(std::size_t pos, Poco::Int64& val)
{
return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val);
}
bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
{
return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val);
}
#ifndef POCO_LONG_IS_64_BIT
bool Extractor::extract(std::size_t pos, long& val)
/// Extracts a long. Returns false if null was received.
{
return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val);
}
#endif
bool Extractor::extract(std::size_t pos, bool& val)
{
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
}
bool Extractor::extract(std::size_t pos, float& val)
{
return realExtractFixed(pos, MYSQL_TYPE_FLOAT, &val);
}
bool Extractor::extract(std::size_t pos, double& val)
{
return realExtractFixed(pos, MYSQL_TYPE_DOUBLE, &val);
}
bool Extractor::extract(std::size_t pos, char& val)
{
return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
}
bool Extractor::extract(std::size_t pos, std::string& val)
{
if (_metadata.columnsReturned() <= pos)
throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain");
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
return false;
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_STRING)
throw MySQLException("Extractor: not a string");
val.assign(_metadata.rawData(pos), _metadata.length(pos));
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
{
if (_metadata.columnsReturned() <= pos)
throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain");
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
return false;
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a blob");
val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
return true;
}
bool Extractor::extract(std::size_t pos, DateTime& val)
{
MYSQL_TIME mt = {0};
if (!realExtractFixed(pos, MYSQL_TYPE_DATETIME, &mt))
return false;
val.assign(mt.year, mt.month, mt.day, mt.hour, mt.minute, mt.second, mt.second_part, 0);
return true;
}
bool Extractor::extract(std::size_t pos, Date& val)
{
MYSQL_TIME mt = {0};
if (!realExtractFixed(pos, MYSQL_TYPE_DATE, &mt))
return false;
val.assign(mt.year, mt.month, mt.day);
return true;
}
bool Extractor::extract(std::size_t pos, Time& val)
{
MYSQL_TIME mt = {0};
if (!realExtractFixed(pos, MYSQL_TYPE_TIME, &mt))
return false;
val.assign(mt.hour, mt.minute, mt.second);
return true;
}
bool Extractor::extract(std::size_t pos, Any& val)
{
return false;
}
bool Extractor::extract(std::size_t pos, DynamicAny& val)
{
return false;
}
bool Extractor::isNull(std::size_t col, std::size_t row)
{
poco_assert(row == POCO_DATA_INVALID_ROW);
if (_metadata.columnsReturned() <= col)
throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain");
if (_metadata.isNull(static_cast<Poco::UInt32>(col)))
return true;
return false;
}
void Extractor::reset()
{
AbstractExtractor::reset();
}
bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, size_t length)
{
MYSQL_BIND bind = {0};
my_bool isNull = 0;
bind.is_null = &isNull;
bind.buffer_type = type;
bind.buffer = buffer;
bind.buffer_length = static_cast<unsigned long>(length);
if (!_stmt.fetchColumn(pos, &bind))
return false;
return isNull == 0;
}
//////////////
// Not implemented
//////////////
bool Extractor::extract(std::size_t , std::vector<Poco::Int8>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::Int8>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::Int8>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::UInt8>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::UInt8>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::UInt8>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::Int16>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::Int16>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::Int16>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::UInt16>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::UInt16>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::UInt16>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::Int32>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::Int32>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::Int32>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::UInt32>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::UInt32>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::UInt32>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::Int64>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::Int64>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::Int64>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Poco::UInt64>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Poco::UInt64>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Poco::UInt64>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
#ifndef POCO_LONG_IS_64_BIT
bool Extractor::extract(std::size_t , std::vector<long>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<long>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<long>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
#endif
bool Extractor::extract(std::size_t , std::vector<bool>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<bool>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<bool>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<float>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<float>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<float>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<double>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<double>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<double>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<char>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<char>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<char>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<std::string>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<std::string>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<std::string>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<BLOB>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<BLOB>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<BLOB>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<DateTime>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<DateTime>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<DateTime>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Date>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Date>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Date>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Time>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Time>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Time>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<Any>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<Any>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<Any>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::vector<DynamicAny>& )
{
throw NotImplementedException("std::vector extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::deque<DynamicAny>& )
{
throw NotImplementedException("std::deque extractor must be implemented.");
}
bool Extractor::extract(std::size_t , std::list<DynamicAny>& )
{
throw NotImplementedException("std::list extractor must be implemented.");
}
} } } // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,160 @@
//
// MySQLException.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/MySQLException.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: MySQLException
//
// 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/MySQLException.h"
#include <mysql.h>
#include <stdio.h>
namespace Poco {
namespace Data {
namespace MySQL {
MySQLException::MySQLException(const std::string& msg) : Poco::Data::DataException(std::string("[MySQL]: ") + msg)
{
}
MySQLException::MySQLException(const MySQLException& exc) : Poco::Data::DataException(exc)
{
}
MySQLException::~MySQLException() throw()
{
}
/////
//
// ConnectionException
//
/////
ConnectionException::ConnectionException(const std::string& msg) : MySQLException(msg)
{
}
ConnectionException::ConnectionException(const std::string& text, MYSQL* h) : MySQLException(compose(text, h))
{
}
std::string ConnectionException::compose(const std::string& text, MYSQL* h)
{
std::string str;
str += "[Comment]: ";
str += text;
str += "\t[mysql_error]: ";
str += mysql_error(h);
str += "\t[mysql_errno]: ";
char buff[30];
sprintf(buff, "%d", mysql_errno(h));
str += buff;
str += "\t[mysql_sqlstate]: ";
str += mysql_sqlstate(h);
return str;
}
/////
//
// TransactionException
//
/////
TransactionException::TransactionException(const std::string& msg) : ConnectionException(msg)
{
}
TransactionException::TransactionException(const std::string& text, MYSQL* h) : ConnectionException(text, h)
{
}
/////
//
// StatementException
//
/////
StatementException::StatementException(const std::string& msg) : MySQLException(msg)
{
}
StatementException::StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt) : MySQLException(compose(text, h, stmt))
{
}
std::string StatementException::compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt)
{
std::string str;
str += "[Comment]: ";
str += text;
if (h != 0)
{
str += "\t[mysql_stmt_error]: ";
str += mysql_stmt_error(h);
str += "\t[mysql_stmt_errno]: ";
char buff[30];
sprintf(buff, "%d", mysql_stmt_errno(h));
str += buff;
str += "\t[mysql_stmt_sqlstate]: ";
str += mysql_stmt_sqlstate(h);
}
if (stmt.length() > 0)
{
str += "\t[statemnt]: ";
str += stmt;
}
return str;
}
} } } // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,200 @@
//
// MySQLException.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/MySQLStatementImpl.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: MySQLStatementImpl
//
// 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/MySQLStatementImpl.h"
namespace Poco {
namespace Data {
namespace MySQL {
MySQLStatementImpl::MySQLStatementImpl(SessionImpl& h)
: Poco::Data::StatementImpl(h),
_stmt(h.handle()),
_extractor(_stmt, _metadata),
_hasNext(NEXT_DONTKNOW)
{
}
MySQLStatementImpl::~MySQLStatementImpl()
{
}
Poco::UInt32 MySQLStatementImpl::columnsReturned() const
{
return _metadata.columnsReturned();
}
Poco::UInt32 MySQLStatementImpl::affectedRowCount() const
{
return 0;
}
const MetaColumn& MySQLStatementImpl::metaColumn(Poco::UInt32 pos) const
{
return _metadata.metaColumn(pos);
}
bool MySQLStatementImpl::hasNext()
{
if (_hasNext == NEXT_DONTKNOW)
{
if (_metadata.columnsReturned() == 0)
{
return false;
}
if (_stmt.fetch())
{
_hasNext = NEXT_TRUE;
return true;
}
_hasNext = NEXT_FALSE;
return false;
}
else if (_hasNext == NEXT_TRUE)
{
return true;
}
return false;
}
Poco::UInt32 MySQLStatementImpl::next()
{
if (!hasNext())
throw StatementException("No data received");
Poco::Data::AbstractExtractionVec::iterator it = extractions().begin();
Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end();
std::size_t pos = 0;
for (; it != itEnd; ++it)
{
(*it)->extract(pos);
pos += (*it)->numOfColumnsHandled();
}
_hasNext = NEXT_DONTKNOW;
return 1;
}
bool MySQLStatementImpl::canBind() const
{
bool ret = false;
if ((_stmt.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty())
ret = (*bindings().begin())->canBind();
return ret;
}
bool MySQLStatementImpl::canCompile() const
{
return (_stmt.state() < StatementExecutor::STMT_COMPILED);
}
void MySQLStatementImpl::compileImpl()
{
_metadata.reset();
_stmt.prepare(toString());
_metadata.init(_stmt);
if (_metadata.columnsReturned() > 0)
{
_stmt.bindResult(_metadata.row());
}
}
void MySQLStatementImpl::bindImpl()
{
//
// Bind all bindings
//
{
Poco::Data::AbstractBindingVec& binds = bindings();
size_t pos = 0;
Poco::Data::AbstractBindingVec::iterator it = binds.begin();
Poco::Data::AbstractBindingVec::iterator itEnd = binds.end();
for (; it != itEnd && (*it)->canBind(); ++it)
{
(*it)->bind(pos);
pos += (*it)->numOfColumnsHandled();
}
}
//
// And bind them to statement
//
_stmt.bindParams(_binder.getBindArray(), _binder.size());
//
// And execute
//
_stmt.execute();
_hasNext = NEXT_DONTKNOW;
}
AbstractExtractor& MySQLStatementImpl::extractor()
{
return _extractor;
}
AbstractBinder& MySQLStatementImpl::binder()
{
return _binder;
}
} } } // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,243 @@
//
// 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"
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;
};
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_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_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;
}
size_t count = mysql_num_fields(h);
MYSQL_FIELD* fields = mysql_fetch_fields(h);
size_t commonSize = 0;
_columns.reserve(count);
{for (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 (Now I dont know how to get it)
!IS_NOT_NULL(fields[i].flags) // nullable
));
commonSize += _columns[i].length();
}}
_buffer.resize(commonSize);
_row.resize(count);
_lengths.resize(count);
_isNull.resize(count);
size_t offset = 0;
{for (size_t i = 0; i < count; i++)
{
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;
}}
}
Poco::UInt32 ResultMetadata::columnsReturned() const
{
return static_cast<Poco::UInt32>(_columns.size());
}
const MetaColumn& ResultMetadata::metaColumn(Poco::UInt32 pos) const
{
return _columns[pos];
}
MYSQL_BIND* ResultMetadata::row()
{
return &_row[0];
}
size_t ResultMetadata::length(size_t pos) const
{
return _lengths[pos];
}
const char* ResultMetadata::rawData(size_t pos) const
{
return reinterpret_cast<const char*>(_row[pos].buffer);
}
bool ResultMetadata::isNull(size_t pos) const
{
return (_isNull[pos] != 0);
}
}}} // namespace Poco::Data::MySQL

View File

@@ -0,0 +1,135 @@
//
// SesssionHandle.cpp
//
// $Id: //poco/1.4/Data/MySQL/src/SessionHandle.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: SessionHandle
//
// 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/SessionHandle.h"
namespace Poco {
namespace Data {
namespace MySQL {
SessionHandle::SessionHandle(MYSQL* mysql)
{
h = mysql_init(mysql);
if (!h)
{
throw ConnectionException("mysql_init error");
}
}
SessionHandle::~SessionHandle()
{
close();
}
void SessionHandle::options(mysql_option opt)
{
int res = mysql_options(h, opt, 0);
if (res != 0)
{
throw ConnectionException("mysql_options error", h);
}
}
void SessionHandle::options(mysql_option opt, bool b)
{
my_bool tmp = b;
int res = mysql_options(h, opt, &tmp);
if (res != 0)
{
throw ConnectionException("mysql_options error", h);
}
}
void SessionHandle::connect(const char* host, const char* user, const char* password, const char* db, unsigned int port)
{
if (!mysql_real_connect(h, host, user, password, db, port, 0, 0))
{
throw ConnectionException("create session: mysql_real_connect error", h);
}
}
void SessionHandle::close()
{
if (h)
{
mysql_close(h);
h = 0;
}
}
void SessionHandle::startTransaction()
{
int res = mysql_autocommit(h, false);
if (res != 0)
{
throw TransactionException("Start transaction failed.", h);
}
}
void SessionHandle::commit()
{
int res = mysql_commit(h);
if (res != 0)
{
throw TransactionException("Commit failed.", h);
}
}
void SessionHandle::rollback()
{
int res = mysql_rollback(h);
if (res != 0)
{
throw TransactionException("Rollback failed.", h);
}
}
}}} // Poco::Data::MySQL

View File

@@ -0,0 +1,226 @@
//
// 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"
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 {
SessionImpl::SessionImpl(const std::string& connectionString) : _mysql(0), _connected(false), _inTransaction(0)
{
addProperty("insertId",
&SessionImpl::setInsertId,
&SessionImpl::getInsertId);
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"] = "";
//
// Parse string
//
for (std::string::const_iterator start = connectionString.begin();;)
{
// find next ';'
std::string::const_iterator finish = std::find(start, connectionString.end(), ';');
// find '='
std::string::const_iterator middle = std::find(start, finish, '=');
if (middle == finish)
{
throw MySQLException("create session: bad connection string format, can not find '='");
}
// Parse name and value, skip all spaces
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
if ((finish == connectionString.end()) || (finish + 1 == connectionString.end()))
{
// end of parse
break;
}
// move start position after ';'
start = finish + 1;
}
//
// Checking
//
if (options["user"] == "")
{
throw MySQLException("create session: specify user name");
}
if (options["db"] == "")
{
throw MySQLException("create session: specify database");
}
if (atoi(options["port"].c_str()) == 0)
{
throw MySQLException("create session: specify correct port (numeric in decimal notation)");
}
//
// Options
//
if (options["compress"] == "true")
{
_mysql.options(MYSQL_OPT_COMPRESS);
}
else if (options["compress"] == "false")
{
// do nothing
}
else if (options["compress"] != "")
{
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
}
if (options["auto-reconnect"] == "true")
{
_mysql.options(MYSQL_OPT_RECONNECT, true);
}
else if (options["auto-reconnect"] == "false")
{
_mysql.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
//
_mysql.connect(
options["host"].c_str(),
options["user"].c_str(),
options["password"].c_str(),
options["db"].c_str(),
atoi(options["port"].c_str()));
_connected = true;
}
SessionImpl::~SessionImpl()
{
close();
}
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
{
return new MySQLStatementImpl(*this);
}
void SessionImpl::begin()
{
_mysql.startTransaction();
_inTransaction++;
}
void SessionImpl::commit()
{
_mysql.commit();
_inTransaction--;
}
void SessionImpl::rollback()
{
_mysql.rollback();
_inTransaction--;
}
void SessionImpl::close()
{
if (_connected)
{
_mysql.close();
_connected = false;
}
}
bool SessionImpl::isConnected()
{
return _connected;
}
bool SessionImpl::isTransaction()
{
return (_inTransaction > 0);
}
}}}

View File

@@ -0,0 +1,197 @@
//
// StatementExecutor.cpp
//
// $Id: //poco/1.3/Data/MySQL/src/StatementExecutor.cpp#1 $
//
// Library: Data
// Package: MySQL
// Module: StatementExecutor
//
// 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 <mysql.h>
#include "Poco/Data/MySQL/StatementExecutor.h"
namespace Poco {
namespace Data {
namespace MySQL {
StatementExecutor::StatementExecutor(MYSQL* mysql)
{
h = mysql_stmt_init(mysql);
if (!h)
{
throw StatementException("mysql_stmt_init error");
}
_state = STMT_INITED;
}
StatementExecutor::~StatementExecutor()
{
mysql_stmt_close(h);
}
int StatementExecutor::state() const
{
return _state;
}
void StatementExecutor::prepare(const std::string& query)
{
if (_state >= STMT_COMPILED)
{
_state = STMT_COMPILED;
return;
//throw StatementException("Satement is already compiled");
}
// compile
int res = mysql_stmt_prepare(h, query.c_str(), static_cast<unsigned int>(query.length()));
if (res != 0)
{
throw StatementException("mysql_stmt_prepare error", h, query);
}
_query = query;
_state = STMT_COMPILED;
}
void StatementExecutor::bindParams(MYSQL_BIND* params, size_t count)
{
if (_state < STMT_COMPILED)
{
throw StatementException("Satement is not compiled yet");
}
if (count != mysql_stmt_param_count(h))
{
throw StatementException("wrong bind parameters count", 0, _query);
}
if (count == 0)
{
return;
}
int res = mysql_stmt_bind_param(h, params);
if (res != 0)
{
throw StatementException("mysql_stmt_bind_param() error ", h, _query);
}
}
void StatementExecutor::bindResult(MYSQL_BIND* result)
{
if (_state < STMT_COMPILED)
{
throw StatementException("Satement is not compiled yet");
}
int res = mysql_stmt_bind_result(h, result);
if (res != 0)
{
throw StatementException("mysql_stmt_bind_result error ", h, _query);
}
}
void StatementExecutor::execute()
{
if (_state < STMT_COMPILED)
{
throw StatementException("Satement is not compiled yet");
}
int res = mysql_stmt_execute(h);
if (res != 0)
{
throw StatementException("mysql_stmt_execute error", h, _query);
}
_state = STMT_EXECUTED;
}
bool StatementExecutor::fetch()
{
if (_state < STMT_EXECUTED)
{
throw StatementException("Satement is not executed yet");
}
int res = mysql_stmt_fetch(h);
if ((res != 0) && (res != MYSQL_NO_DATA))
{
throw StatementException("mysql_stmt_fetch error", h, _query);
}
return (res == 0);
}
bool StatementExecutor::fetchColumn(size_t n, MYSQL_BIND *bind)
{
if (_state < STMT_EXECUTED)
{
throw StatementException("Satement is not executed yet");
}
int res = mysql_stmt_fetch_column(h, bind, static_cast<unsigned int>(n), 0);
if ((res != 0) && (res != MYSQL_NO_DATA))
{
std::string msg;
msg += "mysql_stmt_fetch_column(";
char buff[30];
sprintf(buff, "%d", n);
msg += buff;
msg += ") error";
throw StatementException(msg, h, _query);
}
return (res == 0);
}
}}}