mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-24 22:29:47 +01:00
- SQL logging channel and archiving strategy
- row formatting refactored - affected row count for insert, delete and update returned from Statement::execute() - internal SQL string formatting capability using Poco::format()
This commit is contained in:
166
Data/src/ArchiveStrategy.cpp
Normal file
166
Data/src/ArchiveStrategy.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// ArchiveStrategy.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/ArchiveStrategy.cpp#8 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: Logging
|
||||
// Module: ArchiveStrategy
|
||||
//
|
||||
// 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 "Poco/Data/ArchiveStrategy.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
//
|
||||
// ArchiveStrategy
|
||||
//
|
||||
|
||||
|
||||
const std::string ArchiveStrategy::DEFAULT_ARCHIVE_DESTINATION = "T_POCO_LOG_ARCHIVE";
|
||||
|
||||
|
||||
ArchiveStrategy::ArchiveStrategy(const std::string& connector,
|
||||
const std::string& connect,
|
||||
const std::string& source,
|
||||
const std::string& destination):
|
||||
_connector(connector),
|
||||
_connect(connect),
|
||||
_source(source),
|
||||
_destination(destination)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
ArchiveStrategy::~ArchiveStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ArchiveStrategy::open()
|
||||
{
|
||||
if (_connector.empty() || _connect.empty())
|
||||
throw IllegalStateException("Connector and connect string must be non-empty.");
|
||||
|
||||
_pSession = new Session(_connector, _connect);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ArchiveByAgeStrategy
|
||||
//
|
||||
|
||||
|
||||
ArchiveByAgeStrategy::ArchiveByAgeStrategy(const std::string& connector,
|
||||
const std::string& connect,
|
||||
const std::string& sourceTable,
|
||||
const std::string& destinationTable):
|
||||
ArchiveStrategy(connector, connect, sourceTable, destinationTable)
|
||||
{
|
||||
initStatements();
|
||||
}
|
||||
|
||||
|
||||
ArchiveByAgeStrategy::~ArchiveByAgeStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ArchiveByAgeStrategy::archive()
|
||||
{
|
||||
if (!session().isConnected()) open();
|
||||
|
||||
DateTime now;
|
||||
_archiveDateTime = now - _maxAge;
|
||||
getCountStatement().execute();
|
||||
if (_archiveCount > 0)
|
||||
{
|
||||
getCopyStatement().execute();
|
||||
getDeleteStatement().execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArchiveByAgeStrategy::initStatements()
|
||||
{
|
||||
std::string src = getSource();
|
||||
std::string dest = getDestination();
|
||||
|
||||
setCountStatement();
|
||||
_archiveCount = 0;
|
||||
std::string sql;
|
||||
Poco::format(sql, "SELECT COUNT(*) FROM %s WHERE DateTime < ?", src);
|
||||
getCountStatement() << sql, into(_archiveCount), use(_archiveDateTime);
|
||||
|
||||
setCopyStatement();
|
||||
sql.clear();
|
||||
Poco::format(sql, "INSERT INTO %s SELECT * FROM %s WHERE DateTime < ?", dest, src);
|
||||
getCopyStatement() << sql, use(_archiveDateTime);
|
||||
|
||||
setDeleteStatement();
|
||||
sql.clear();
|
||||
Poco::format(sql, "DELETE FROM %s WHERE DateTime < ?", src);
|
||||
getDeleteStatement() << sql, use(_archiveDateTime);
|
||||
}
|
||||
|
||||
|
||||
void ArchiveByAgeStrategy::setThreshold(const std::string& age)
|
||||
{
|
||||
std::string::const_iterator it = age.begin();
|
||||
std::string::const_iterator end = age.end();
|
||||
int n = 0;
|
||||
while (it != end && std::isspace(*it)) ++it;
|
||||
while (it != end && std::isdigit(*it)) { n *= 10; n += *it++ - '0'; }
|
||||
while (it != end && std::isspace(*it)) ++it;
|
||||
std::string unit;
|
||||
while (it != end && std::isalpha(*it)) unit += *it++;
|
||||
|
||||
Timespan::TimeDiff factor = Timespan::SECONDS;
|
||||
if (unit == "minutes")
|
||||
factor = Timespan::MINUTES;
|
||||
else if (unit == "hours")
|
||||
factor = Timespan::HOURS;
|
||||
else if (unit == "days")
|
||||
factor = Timespan::DAYS;
|
||||
else if (unit == "weeks")
|
||||
factor = 7*Timespan::DAYS;
|
||||
else if (unit == "months")
|
||||
factor = 30*Timespan::DAYS;
|
||||
else if (unit != "seconds")
|
||||
throw InvalidArgumentException("setMaxAge", age);
|
||||
|
||||
_maxAge = factor * n;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
@@ -64,9 +64,9 @@ RecordSet::RecordSet(Session& rSession,
|
||||
Statement((rSession << query, now)),
|
||||
_currentRow(0),
|
||||
_pBegin(new RowIterator(this)),
|
||||
_pEnd(new RowIterator(this, true)),
|
||||
_pRowFormatter(pRowFormatter)
|
||||
_pEnd(new RowIterator(this, true))
|
||||
{
|
||||
if (pRowFormatter) setRowFormatter(pRowFormatter);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,7 @@ RecordSet::RecordSet(const RecordSet& other):
|
||||
Statement(other.impl().duplicate()),
|
||||
_currentRow(other._currentRow),
|
||||
_pBegin(new RowIterator(this)),
|
||||
_pEnd(new RowIterator(this, true)),
|
||||
_pRowFormatter(other._pRowFormatter)
|
||||
_pEnd(new RowIterator(this, true))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -155,14 +154,14 @@ Row& RecordSet::row(std::size_t pos)
|
||||
{
|
||||
if (_rowMap.size())//reuse first row column names to save some memory
|
||||
{
|
||||
pRow = new Row(_rowMap.begin()->second->names(), &_pRowFormatter);
|
||||
pRow = new Row(_rowMap.begin()->second->names(), getRowFormatter());
|
||||
for (std::size_t col = 0; col < columns; ++col)
|
||||
pRow->set(col, value(col, pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
pRow = new Row;
|
||||
if (_pRowFormatter) pRow->setFormatter(&_pRowFormatter);
|
||||
pRow->setFormatter(getRowFormatter());
|
||||
for (std::size_t col = 0; col < columns; ++col)
|
||||
pRow->append(metaColumn(static_cast<UInt32>(col)).name(), value(col, pos));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
#include "Poco/Data/Row.h"
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Data/SimpleRowFormatter.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
@@ -52,18 +52,17 @@ std::ostream& operator << (std::ostream &os, const Row& row)
|
||||
|
||||
Row::Row():
|
||||
_pNames(0),
|
||||
_pFormatter(new RowFormatter)
|
||||
_pFormatter(new SimpleRowFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Row::Row(NameVecPtr pNames, FormatterPtr* pFormatter):
|
||||
Row::Row(NameVecPtr pNames, const RowFormatterPtr& pFormatter):
|
||||
_pNames(pNames)
|
||||
{
|
||||
if (!_pNames) throw NullPointerException();
|
||||
|
||||
if (pFormatter && *pFormatter) _pFormatter = *pFormatter;
|
||||
else _pFormatter = new RowFormatter;
|
||||
setFormatter(pFormatter);
|
||||
|
||||
_values.resize(_pNames->size());
|
||||
addSortField(0);
|
||||
@@ -315,12 +314,12 @@ bool Row::operator < (const Row& other) const
|
||||
}
|
||||
|
||||
|
||||
void Row::setFormatter(FormatterPtr* pFormatter)
|
||||
void Row::setFormatter(const RowFormatterPtr& pFormatter)
|
||||
{
|
||||
if (pFormatter && *pFormatter)
|
||||
_pFormatter = *pFormatter;
|
||||
if (pFormatter)
|
||||
_pFormatter = pFormatter;
|
||||
else
|
||||
_pFormatter = new RowFormatter;
|
||||
_pFormatter = new SimpleRowFormatter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,14 +43,7 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
RowFormatter::RowFormatter(std::streamsize width):
|
||||
_width(width)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RowFormatter::RowFormatter(const std::string& prefix, const std::string& postfix):
|
||||
_width(DEFAULT_COLUMN_WIDTH),
|
||||
_prefix(prefix),
|
||||
_postfix(postfix)
|
||||
{
|
||||
@@ -62,44 +55,4 @@ RowFormatter::~RowFormatter()
|
||||
}
|
||||
|
||||
|
||||
std::string& RowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
std::string line(_width * pNames->size(), '-');
|
||||
|
||||
NameVec::const_iterator it = pNames->begin();
|
||||
NameVec::const_iterator end = pNames->end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
str << std::left << std::setw(_width) << *it;
|
||||
}
|
||||
str << std::endl << line << std::endl;
|
||||
|
||||
return formattedNames = str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string& RowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->isNumeric())
|
||||
{
|
||||
str << std::right
|
||||
<< std::fixed
|
||||
<< std::setprecision(2);
|
||||
}
|
||||
else str << std::left;
|
||||
|
||||
str << std::setw(_width) << it->convert<std::string>();
|
||||
}
|
||||
str << std::endl;
|
||||
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
296
Data/src/SQLChannel.cpp
Normal file
296
Data/src/SQLChannel.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
//
|
||||
// SQLChannel.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/SQLChannel.cpp#3 $
|
||||
//
|
||||
// Library: Net
|
||||
// Package: Logging
|
||||
// Module: SQLChannel
|
||||
//
|
||||
// Copyright (c) 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 "Poco/Data/SQLChannel.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/LoggingFactory.h"
|
||||
#include "Poco/Instantiator.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/Format.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
const std::string SQLChannel::PROP_CONNECTOR("connector");
|
||||
const std::string SQLChannel::PROP_CONNECT("connect");
|
||||
const std::string SQLChannel::PROP_NAME("name");
|
||||
const std::string SQLChannel::PROP_TABLE("table");
|
||||
const std::string SQLChannel::PROP_ARCHIVE_TABLE("archive");
|
||||
const std::string SQLChannel::PROP_MAX_AGE("keep");
|
||||
const std::string SQLChannel::PROP_ASYNC("async");
|
||||
const std::string SQLChannel::PROP_TIMEOUT("timeout");
|
||||
const std::string SQLChannel::PROP_THROW("throw");
|
||||
|
||||
|
||||
SQLChannel::SQLChannel():
|
||||
_name("-"),
|
||||
_table("T_POCO_LOG"),
|
||||
_timeout(1000),
|
||||
_throw(true),
|
||||
_async(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SQLChannel::SQLChannel(const std::string& connector,
|
||||
const std::string& connect,
|
||||
const std::string& name):
|
||||
_connector(connector),
|
||||
_connect(connect),
|
||||
_name(name),
|
||||
_table("T_POCO_LOG"),
|
||||
_timeout(1000),
|
||||
_throw(true),
|
||||
_async(true)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
SQLChannel::~SQLChannel()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::open()
|
||||
{
|
||||
if (_connector.empty() || _connect.empty())
|
||||
throw IllegalStateException("Connector and connect string must be non-empty.");
|
||||
|
||||
_pSession = new Session(_connector, _connect);
|
||||
initLogStatement();
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::close()
|
||||
{
|
||||
wait();
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::log(const Message& msg)
|
||||
{
|
||||
if (_async) logAsync(msg);
|
||||
else logSync(msg);
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::logAsync(const Message& msg)
|
||||
{
|
||||
if (!_pSession || !_pSession->isConnected()) open();
|
||||
|
||||
Statement::ResultType ret = wait();
|
||||
if (0 == ret && !_pLogStatement->done() && !_pLogStatement->initialized())
|
||||
{
|
||||
if (_throw)
|
||||
throw TimeoutException("Timed out waiting for previous statement completion");
|
||||
else return;
|
||||
}
|
||||
|
||||
logSync(msg);
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::logSync(const Message& msg)
|
||||
{
|
||||
//if (isArchiving()) archive();
|
||||
if (_pArchiveStrategy) _pArchiveStrategy->archive();
|
||||
|
||||
_source = msg.getSource();
|
||||
_pid = msg.getPid();
|
||||
_thread = msg.getThread();
|
||||
_tid = msg.getTid();
|
||||
_priority = msg.getPriority();
|
||||
_text = msg.getText();
|
||||
_dateTime = msg.getTime();
|
||||
if (_source.empty()) _source = _name;
|
||||
|
||||
_pLogStatement->execute();
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::setProperty(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == PROP_NAME)
|
||||
{
|
||||
_name = value;
|
||||
if (_name.empty()) _name = "-";
|
||||
}
|
||||
else if (name == PROP_CONNECTOR)
|
||||
{
|
||||
_connector = value;
|
||||
close(); open();
|
||||
}
|
||||
else if (name == PROP_CONNECT)
|
||||
{
|
||||
_connect = value;
|
||||
close(); open();
|
||||
}
|
||||
else if (name == PROP_TABLE)
|
||||
{
|
||||
_table = value;
|
||||
initLogStatement();
|
||||
}
|
||||
else if (name == PROP_ARCHIVE_TABLE)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
_pArchiveStrategy = 0;
|
||||
}
|
||||
else if (_pArchiveStrategy)
|
||||
{
|
||||
_pArchiveStrategy->setDestination(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pArchiveStrategy = new ArchiveByAgeStrategy(_connector, _connect, _table, value);
|
||||
}
|
||||
}
|
||||
else if (name == PROP_MAX_AGE)
|
||||
{
|
||||
if (value.empty() || "forever" == value)
|
||||
{
|
||||
_pArchiveStrategy = 0;
|
||||
}
|
||||
else if (_pArchiveStrategy)
|
||||
{
|
||||
_pArchiveStrategy->setThreshold(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArchiveByAgeStrategy* p = new ArchiveByAgeStrategy(_connector, _connect, _table);
|
||||
p->setThreshold(value);
|
||||
_pArchiveStrategy = p;
|
||||
}
|
||||
}
|
||||
else if (name == PROP_ASYNC)
|
||||
{
|
||||
_async = isTrue(value);
|
||||
initLogStatement();
|
||||
}
|
||||
else if (name == PROP_TIMEOUT)
|
||||
{
|
||||
if (value.empty() || '0' == value[0])
|
||||
_timeout = Statement::WAIT_FOREVER;
|
||||
else
|
||||
_timeout = NumberParser::parse(value);
|
||||
}
|
||||
else if (name == PROP_THROW)
|
||||
{
|
||||
_throw = isTrue(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Channel::setProperty(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string SQLChannel::getProperty(const std::string& name) const
|
||||
{
|
||||
if (name == PROP_NAME)
|
||||
{
|
||||
if (_name != "-") return _name;
|
||||
else return "";
|
||||
}
|
||||
else if (name == PROP_CONNECTOR)
|
||||
{
|
||||
return _connector;
|
||||
}
|
||||
else if (name == PROP_CONNECT)
|
||||
{
|
||||
return _connect;
|
||||
}
|
||||
else if (name == PROP_TABLE)
|
||||
{
|
||||
return _table;
|
||||
}
|
||||
else if (name == PROP_ARCHIVE_TABLE)
|
||||
{
|
||||
return _pArchiveStrategy ? _pArchiveStrategy->getDestination() : "" ;
|
||||
}
|
||||
else if (name == PROP_MAX_AGE)
|
||||
{
|
||||
return _pArchiveStrategy ? _pArchiveStrategy->getThreshold() : "forever";
|
||||
}
|
||||
else if (name == PROP_TIMEOUT)
|
||||
{
|
||||
return NumberFormatter::format(_timeout);
|
||||
}
|
||||
else if (name == PROP_THROW)
|
||||
{
|
||||
if (_throw) return "true";
|
||||
else return "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
return Channel::getProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::initLogStatement()
|
||||
{
|
||||
_pLogStatement = new Statement(*_pSession);
|
||||
|
||||
std::string sql;
|
||||
Poco::format(sql, "INSERT INTO %s VALUES (?,?,?,?,?,?,?,?)", _table);
|
||||
*_pLogStatement << sql,
|
||||
use(_source),
|
||||
use(_name),
|
||||
use(_pid),
|
||||
use(_thread),
|
||||
use(_tid),
|
||||
use(_priority),
|
||||
use(_text),
|
||||
use(_dateTime);
|
||||
|
||||
if (_async) _pLogStatement->setAsync();
|
||||
}
|
||||
|
||||
|
||||
void SQLChannel::registerChannel()
|
||||
{
|
||||
Poco::LoggingFactory::defaultFactory().registerChannelClass("SQLChannel", new Poco::Instantiator<SQLChannel, Poco::Channel>);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
@@ -58,11 +58,11 @@ SessionFactory& SessionFactory::instance()
|
||||
}
|
||||
|
||||
|
||||
void SessionFactory::add(const std::string& key, Connector* pIn)
|
||||
void SessionFactory::add(Connector* pIn)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||
SessionInfo info(pIn);
|
||||
std::pair<Connectors::iterator, bool> res = _connectors.insert(std::make_pair(key, info));
|
||||
std::pair<Connectors::iterator, bool> res = _connectors.insert(std::make_pair(pIn->name(), info));
|
||||
if (!res.second)
|
||||
{
|
||||
res.first->second.cnt++;
|
||||
|
||||
123
Data/src/SimpleRowFormatter.cpp
Normal file
123
Data/src/SimpleRowFormatter.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// RowFormatter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/RowFormatter.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: RowFormatter
|
||||
//
|
||||
// Copyright (c) 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 "Poco/Data/SimpleRowFormatter.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
SimpleRowFormatter::SimpleRowFormatter(std::streamsize columnWidth):
|
||||
_colWidth(columnWidth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SimpleRowFormatter::SimpleRowFormatter(const SimpleRowFormatter& other):
|
||||
RowFormatter(other.prefix(), other.postfix()),
|
||||
_colWidth(other._colWidth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SimpleRowFormatter::~SimpleRowFormatter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SimpleRowFormatter& SimpleRowFormatter::operator = (const SimpleRowFormatter& row)
|
||||
{
|
||||
SimpleRowFormatter tmp(row);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void SimpleRowFormatter::swap(SimpleRowFormatter& other)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
setPrefix(other.prefix());
|
||||
setPostfix(other.postfix());
|
||||
swap(_colWidth, other._colWidth);
|
||||
}
|
||||
|
||||
|
||||
std::string& SimpleRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
std::string line(_colWidth * pNames->size(), '-');
|
||||
|
||||
NameVec::const_iterator it = pNames->begin();
|
||||
NameVec::const_iterator end = pNames->end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
str << std::left << std::setw(_colWidth) << *it;
|
||||
}
|
||||
str << std::endl << line << std::endl;
|
||||
|
||||
return formattedNames = str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string& SimpleRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->isNumeric())
|
||||
{
|
||||
str << std::right
|
||||
<< std::fixed
|
||||
<< std::setprecision(2);
|
||||
}
|
||||
else str << std::left;
|
||||
|
||||
str << std::setw(_colWidth) << it->convert<std::string>();
|
||||
}
|
||||
str << std::endl;
|
||||
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
@@ -68,7 +68,9 @@ Statement::Statement(const Statement& stmt):
|
||||
_pImpl(stmt._pImpl),
|
||||
_async(stmt._async),
|
||||
_pResult(stmt._pResult),
|
||||
_pAsyncExec(stmt._pAsyncExec)
|
||||
_pAsyncExec(stmt._pAsyncExec),
|
||||
_arguments(stmt._arguments),
|
||||
_pRowFormatter(stmt._pRowFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,6 +96,8 @@ void Statement::swap(Statement& other)
|
||||
swap(_async, other._async);
|
||||
swap(_pAsyncExec, other._pAsyncExec);
|
||||
swap(_pResult, other._pResult);
|
||||
_arguments.swap(other._arguments);
|
||||
swap(_pRowFormatter, other._pRowFormatter);
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +115,12 @@ Statement::ResultType Statement::execute()
|
||||
bool isDone = done();
|
||||
if (initialized() || paused() || isDone)
|
||||
{
|
||||
if (_arguments.size())
|
||||
{
|
||||
_pImpl->formatSQL(_arguments);
|
||||
_arguments.clear();
|
||||
}
|
||||
|
||||
if (!isAsync())
|
||||
{
|
||||
if (isDone) _pImpl->reset();
|
||||
@@ -141,9 +151,7 @@ const Statement::Result& Statement::doAsyncExec()
|
||||
if (done()) _pImpl->reset();
|
||||
if (!_pAsyncExec)
|
||||
_pAsyncExec = new AsyncExecMethod(_pImpl, &StatementImpl::execute);
|
||||
poco_check_ptr (_pAsyncExec);
|
||||
_pResult = new Result((*_pAsyncExec)());
|
||||
poco_check_ptr (_pResult);
|
||||
return *_pResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Poco::UInt32 StatementImpl::execute()
|
||||
if (lim < _lowerLimit)
|
||||
throw LimitException("Did not receive enough data.");
|
||||
|
||||
if (0 == lim) lim = affectedRowCount();
|
||||
|
||||
return lim;
|
||||
}
|
||||
|
||||
@@ -361,4 +363,12 @@ void StatementImpl::addExtract(AbstractExtraction* pExtraction)
|
||||
}
|
||||
|
||||
|
||||
void StatementImpl::formatSQL(std::vector<Any>& arguments)
|
||||
{
|
||||
std::string sql;
|
||||
Poco::format(sql, _ostr.str(), arguments);
|
||||
_ostr.str(""); _ostr << sql;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
Reference in New Issue
Block a user