mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-16 18:56:52 +02:00
RowFormatter redesign, sample and some other minor changes
This commit is contained in:
@@ -1580,16 +1580,16 @@ void SQLiteTest::testInternalExtraction()
|
||||
|
||||
typedef std::deque<Int64> IntDeq;
|
||||
|
||||
const Column<Int64>& col = rset.column<Int64, IntDeq>(0);
|
||||
const Column<IntDeq>& col = rset.column<IntDeq>(0);
|
||||
assert (col[0] == 1);
|
||||
|
||||
try { rset.column<Int64, IntDeq>(100); fail ("must fail"); }
|
||||
try { rset.column<IntDeq>(100); fail ("must fail"); }
|
||||
catch (RangeException&) { }
|
||||
|
||||
const Column<Int64>& col1 = rset.column<Int64, IntDeq>(0);
|
||||
const Column<IntDeq>& col1 = rset.column<IntDeq>(0);
|
||||
assert ("int0" == col1.name());
|
||||
Column<Int64>::Iterator it = col1.begin();
|
||||
Column<Int64>::Iterator itEnd = col1.end();
|
||||
Column<IntDeq>::Iterator it = col1.begin();
|
||||
Column<IntDeq>::Iterator itEnd = col1.end();
|
||||
int counter = 1;
|
||||
for (; it != itEnd; ++it, ++counter)
|
||||
assert (counter == *it);
|
||||
@@ -1601,7 +1601,7 @@ void SQLiteTest::testInternalExtraction()
|
||||
stmt = (tmp << "DELETE FROM Vectors", now);
|
||||
rset = stmt;
|
||||
|
||||
try { rset.column<Int64, IntDeq>(0); fail ("must fail"); }
|
||||
try { rset.column<IntDeq>(0); fail ("must fail"); }
|
||||
catch (RangeException&) { }
|
||||
}
|
||||
|
||||
@@ -1723,8 +1723,8 @@ void SQLiteTest::testRowIterator()
|
||||
RecordSet rset(ses, "SELECT * FROM Vectors");
|
||||
|
||||
std::ostringstream osLoop;
|
||||
RecordSet::Iterator it = rset.begin();
|
||||
RecordSet::Iterator end = rset.end();
|
||||
RecordSet::ConstIterator it = rset.begin();
|
||||
RecordSet::ConstIterator end = rset.end();
|
||||
for (int i = 1; it != end; ++it, ++i)
|
||||
{
|
||||
assert (it->get(0) == i);
|
||||
|
@@ -55,25 +55,30 @@ namespace Data {
|
||||
template <class C>
|
||||
class Column
|
||||
/// Column class is column data container.
|
||||
/// Data (a pointer to container) is assigned to the class
|
||||
/// through either constructor or set() member function.
|
||||
/// Construction with null pointer is not allowed.
|
||||
/// Data (a pointer to underlying STL container) is assigned to the class
|
||||
/// at construction time. Construction with null pointer is not allowed.
|
||||
/// This class owns the data assigned to it and deletes the storage on destruction.
|
||||
{
|
||||
public:
|
||||
typedef C Container;
|
||||
typedef typename Container::const_iterator Iterator;
|
||||
typedef typename Container::const_reverse_iterator RIterator;
|
||||
typedef typename Container::size_type Size;
|
||||
typedef typename Container::value_type Type;
|
||||
typedef C Container;
|
||||
typedef Poco::SharedPtr<C> ContainerPtr;
|
||||
typedef typename C::const_iterator Iterator;
|
||||
typedef typename C::const_reverse_iterator RIterator;
|
||||
typedef typename C::size_type Size;
|
||||
typedef typename C::value_type Type;
|
||||
|
||||
Column(const MetaColumn& metaColumn, Container* pData): _metaColumn(metaColumn), _pData(pData)
|
||||
Column(const MetaColumn& metaColumn, Container* pData):
|
||||
_metaColumn(metaColumn),
|
||||
_pData(pData)
|
||||
/// Creates the Column.
|
||||
{
|
||||
poco_check_ptr (_pData);
|
||||
if (!_pData)
|
||||
throw NullPointerException("Container pointer must point to valid storage.");
|
||||
}
|
||||
|
||||
Column(const Column& col): _metaColumn(col._metaColumn), _pData(col._pData)
|
||||
Column(const Column& col):
|
||||
_metaColumn(col._metaColumn),
|
||||
_pData(col._pData)
|
||||
/// Creates the Column.
|
||||
{
|
||||
}
|
||||
@@ -182,8 +187,8 @@ public:
|
||||
private:
|
||||
Column();
|
||||
|
||||
MetaColumn _metaColumn;
|
||||
Poco::SharedPtr<Container> _pData;
|
||||
MetaColumn _metaColumn;
|
||||
ContainerPtr _pData;
|
||||
};
|
||||
|
||||
|
||||
@@ -202,10 +207,11 @@ class Column<std::vector<bool> >
|
||||
/// column data.
|
||||
{
|
||||
public:
|
||||
typedef std::vector<bool> Container;
|
||||
typedef Container::const_iterator Iterator;
|
||||
typedef std::vector<bool> Container;
|
||||
typedef Poco::SharedPtr<Container> ContainerPtr;
|
||||
typedef Container::const_iterator Iterator;
|
||||
typedef Container::const_reverse_iterator RIterator;
|
||||
typedef Container::size_type Size;
|
||||
typedef Container::size_type Size;
|
||||
|
||||
Column(const MetaColumn& metaColumn, Container* pData):
|
||||
_metaColumn(metaColumn),
|
||||
@@ -333,8 +339,8 @@ public:
|
||||
private:
|
||||
Column();
|
||||
|
||||
MetaColumn _metaColumn;
|
||||
Poco::SharedPtr<Container> _pData;
|
||||
MetaColumn _metaColumn;
|
||||
ContainerPtr _pData;
|
||||
mutable std::deque<bool> _deque;
|
||||
};
|
||||
|
||||
@@ -344,18 +350,23 @@ class Column<std::list<T> >
|
||||
/// Column specialization for std::list
|
||||
{
|
||||
public:
|
||||
typedef std::list<T> List;
|
||||
typedef typename List::const_iterator Iterator;
|
||||
typedef typename List::const_reverse_iterator RIterator;
|
||||
typedef typename List::size_type Size;
|
||||
typedef std::list<T> Container;
|
||||
typedef Poco::SharedPtr<Container> ContainerPtr;
|
||||
typedef typename Container::const_iterator Iterator;
|
||||
typedef typename Container::const_reverse_iterator RIterator;
|
||||
typedef typename Container::size_type Size;
|
||||
|
||||
Column(const MetaColumn& metaColumn, std::list<T>* pData): _metaColumn(metaColumn), _pData(pData)
|
||||
Column(const MetaColumn& metaColumn, std::list<T>* pData):
|
||||
_metaColumn(metaColumn),
|
||||
_pData(pData)
|
||||
/// Creates the Column.
|
||||
{
|
||||
poco_check_ptr (_pData);
|
||||
}
|
||||
|
||||
Column(const Column& col): _metaColumn(col._metaColumn), _pData(col._pData)
|
||||
Column(const Column& col):
|
||||
_metaColumn(col._metaColumn),
|
||||
_pData(col._pData)
|
||||
/// Creates the Column.
|
||||
{
|
||||
}
|
||||
@@ -381,7 +392,7 @@ public:
|
||||
swap(_pData, other._pData);
|
||||
}
|
||||
|
||||
List& data()
|
||||
Container& data()
|
||||
/// Returns reference to contained data.
|
||||
{
|
||||
return *_pData;
|
||||
@@ -481,8 +492,8 @@ public:
|
||||
private:
|
||||
Column();
|
||||
|
||||
MetaColumn _metaColumn;
|
||||
Poco::SharedPtr<List> _pData;
|
||||
MetaColumn _metaColumn;
|
||||
ContainerPtr _pData;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -45,10 +45,12 @@
|
||||
#include "Poco/Data/BulkExtraction.h"
|
||||
#include "Poco/Data/Statement.h"
|
||||
#include "Poco/Data/RowIterator.h"
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Data/BLOB.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -79,16 +81,22 @@ class Data_API RecordSet: private Statement
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::size_t, Row*> RowMap;
|
||||
typedef RowIterator Iterator;
|
||||
typedef const RowIterator ConstIterator;
|
||||
typedef RowIterator Iterator;
|
||||
|
||||
using Statement::isNull;
|
||||
|
||||
explicit RecordSet(const Statement& rStatement);
|
||||
/// Creates the RecordSet.
|
||||
|
||||
explicit RecordSet(Session& rSession, const std::string& query);
|
||||
explicit RecordSet(Session& rSession,
|
||||
const std::string& query,
|
||||
RowFormatter* pRowFormatter = 0);
|
||||
/// Creates the RecordSet.
|
||||
|
||||
RecordSet(const RecordSet& other);
|
||||
/// Copy-creates the recordset.
|
||||
|
||||
~RecordSet();
|
||||
/// Destroys the RecordSet.
|
||||
|
||||
@@ -101,37 +109,35 @@ public:
|
||||
std::size_t columnCount() const;
|
||||
/// Returns the number of rows in the recordset.
|
||||
|
||||
template <class C, class E>
|
||||
template <class C>
|
||||
const Column<C>& column(const std::string& name) const
|
||||
/// Returns the reference to the first Column with the specified name.
|
||||
{
|
||||
return column<C,E>(columnPosition<C,E>(name));
|
||||
}
|
||||
|
||||
template <class C, class E>
|
||||
const Column<C>& column(std::size_t pos) const
|
||||
/// Returns the reference to column at specified location.
|
||||
{
|
||||
typedef typename C::value_type T;
|
||||
typedef const E* ExtractionVecPtr;
|
||||
|
||||
const AbstractExtractionVec& rExtractions = extractions();
|
||||
|
||||
std::size_t s = rExtractions.size();
|
||||
if (0 == s || pos >= s)
|
||||
throw RangeException(format("Invalid column index: %z", pos));
|
||||
|
||||
ExtractionVecPtr pExtraction = dynamic_cast<ExtractionVecPtr>(rExtractions[pos].get());
|
||||
|
||||
if (pExtraction)
|
||||
if (isBulkExtraction())
|
||||
{
|
||||
return pExtraction->column();
|
||||
typedef InternalBulkExtraction<C> E;
|
||||
return columnImpl<C,E>(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Poco::BadCastException(format("Type cast failed!\nColumn: %z\nTarget type:\t%s",
|
||||
pos,
|
||||
std::string(typeid(T).name())));
|
||||
typedef InternalExtraction<C> E;
|
||||
return columnImpl<C,E>(name);
|
||||
}
|
||||
}
|
||||
|
||||
template <class C>
|
||||
const Column<C>& column(std::size_t pos) const
|
||||
/// Returns the reference to column at specified position.
|
||||
{
|
||||
if (isBulkExtraction())
|
||||
{
|
||||
typedef InternalBulkExtraction<C> E;
|
||||
return columnImpl<C,E>(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef InternalExtraction<C> E;
|
||||
return columnImpl<C,E>(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,27 +154,18 @@ public:
|
||||
case STORAGE_VECTOR:
|
||||
{
|
||||
typedef std::vector<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(col).value(row);
|
||||
return column<C>(col).value(row);
|
||||
}
|
||||
case STORAGE_LIST:
|
||||
{
|
||||
typedef std::list<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(col).value(row);
|
||||
return column<C>(col).value(row);
|
||||
}
|
||||
case STORAGE_DEQUE:
|
||||
case STORAGE_UNKNOWN:
|
||||
{
|
||||
typedef std::deque<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(col).value(row);
|
||||
return column<C>(col).value(row);
|
||||
}
|
||||
default:
|
||||
throw IllegalStateException("Invalid storage setting.");
|
||||
@@ -184,27 +181,18 @@ public:
|
||||
case STORAGE_VECTOR:
|
||||
{
|
||||
typedef std::vector<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(name).value(row);
|
||||
return column<C>(name).value(row);
|
||||
}
|
||||
case STORAGE_LIST:
|
||||
{
|
||||
typedef std::list<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(name).value(row);
|
||||
return column<C>(name).value(row);
|
||||
}
|
||||
case STORAGE_DEQUE:
|
||||
case STORAGE_UNKNOWN:
|
||||
{
|
||||
typedef std::deque<T> C;
|
||||
if (isBulkExtraction())
|
||||
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||
else
|
||||
return column<C, InternalExtraction<C> >(name).value(row);
|
||||
return column<C>(name).value(row);
|
||||
}
|
||||
default:
|
||||
throw IllegalStateException("Invalid storage setting.");
|
||||
@@ -225,8 +213,17 @@ public:
|
||||
/// Returns the value in the given column of the current row
|
||||
/// if the value is not NULL, or deflt otherwise.
|
||||
|
||||
const RowIterator& begin();
|
||||
/// Moves the row cursor to the first row and returns the pointer to row.
|
||||
ConstIterator& begin() const;
|
||||
/// Returns the const row iterator.
|
||||
|
||||
ConstIterator& end() const;
|
||||
/// Returns the const row iterator.
|
||||
|
||||
Iterator begin();
|
||||
/// Returns the row iterator.
|
||||
|
||||
Iterator end();
|
||||
/// Returns the row iterator.
|
||||
|
||||
bool moveFirst();
|
||||
/// Moves the row cursor to the first row.
|
||||
@@ -247,9 +244,6 @@ public:
|
||||
/// Returns true if the row is available, or false
|
||||
/// if there are no more rows available.
|
||||
|
||||
const RowIterator& end();
|
||||
/// Moves the row cursor to the last row and returns null pointer.
|
||||
|
||||
bool moveLast();
|
||||
/// Moves the row cursor to the last row.
|
||||
///
|
||||
@@ -294,6 +288,34 @@ public:
|
||||
bool isNull(const std::string& name) const;
|
||||
/// Returns true if column value of the current row is null.
|
||||
|
||||
void setFormatter(Row::FormatterPtr pRowFormatter);
|
||||
/// Sets the row formatter for this recordset.
|
||||
/// Row formatter is null pointer by default, indicating
|
||||
/// use of default formatter for output formatting.
|
||||
/// This function allows for custom formatters to be
|
||||
/// supplied by users. After setting a user supplied formatter,
|
||||
/// to revert back to the default one, call this function with
|
||||
/// zero argument.
|
||||
|
||||
std::ostream& copyNames(std::ostream& os) const;
|
||||
/// Copies the column names to the target output stream.
|
||||
/// Copied string is formatted by the current RowFormatter.
|
||||
|
||||
std::ostream& copyValues(std::ostream& os,
|
||||
std::size_t offset = 0,
|
||||
std::size_t length = RowIterator::POSITION_END) const;
|
||||
/// Copies the data values to the supplied output stream.
|
||||
/// The data set to be copied is starting at the specified offset
|
||||
/// from the recordset beginning. The number of rows to be copied
|
||||
/// is specified by length argument.
|
||||
/// An invalid combination of offset/length arguments shall
|
||||
/// cause RangeException to be thrown.
|
||||
/// Copied string is formatted by the current RowFormatter.
|
||||
|
||||
std::ostream& copy(std::ostream& os) const;
|
||||
/// Copies the column names and values to the target output stream.
|
||||
/// Copied strings are formatted by the current RowFormatter.
|
||||
|
||||
private:
|
||||
RecordSet();
|
||||
|
||||
@@ -329,16 +351,58 @@ private:
|
||||
throw NotFoundException(format("Column type: %s, name: %s", std::string(typeid(T).name()), name));
|
||||
}
|
||||
|
||||
std::size_t _currentRow;
|
||||
RowIterator* _pBegin;
|
||||
RowIterator* _pEnd;
|
||||
RowMap _rowMap;
|
||||
template <class C, class E>
|
||||
const Column<C>& columnImpl(const std::string& name) const
|
||||
/// Returns the reference to the first Column with the specified name.
|
||||
{
|
||||
return columnImpl<C,E>(columnPosition<C,E>(name));
|
||||
}
|
||||
|
||||
template <class C, class E>
|
||||
const Column<C>& columnImpl(std::size_t pos) const
|
||||
/// Returns the reference to column at specified position.
|
||||
{
|
||||
typedef typename C::value_type T;
|
||||
typedef const E* ExtractionVecPtr;
|
||||
|
||||
const AbstractExtractionVec& rExtractions = extractions();
|
||||
|
||||
std::size_t s = rExtractions.size();
|
||||
if (0 == s || pos >= s)
|
||||
throw RangeException(format("Invalid column index: %z", pos));
|
||||
|
||||
ExtractionVecPtr pExtraction = dynamic_cast<ExtractionVecPtr>(rExtractions[pos].get());
|
||||
|
||||
if (pExtraction)
|
||||
{
|
||||
return pExtraction->column();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Poco::BadCastException(format("Type cast failed!\nColumn: %z\nTarget type:\t%s",
|
||||
pos,
|
||||
std::string(typeid(T).name())));
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t _currentRow;
|
||||
RowIterator* _pBegin;
|
||||
RowIterator* _pEnd;
|
||||
RowMap _rowMap;
|
||||
Row::FormatterPtr _pRowFormatter;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
|
||||
inline Data_API std::ostream& operator << (std::ostream &os, const RecordSet& rs)
|
||||
{
|
||||
return rs.copy(os);
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t RecordSet::rowCount() const
|
||||
{
|
||||
poco_assert (extractions().size());
|
||||
@@ -431,15 +495,43 @@ inline bool RecordSet::isNull(const std::string& name) const
|
||||
}
|
||||
|
||||
|
||||
inline const RowIterator& RecordSet::end()
|
||||
inline RecordSet::ConstIterator& RecordSet::begin() const
|
||||
{
|
||||
if (!_pEnd)
|
||||
_pEnd = new RowIterator(*this, true);
|
||||
return *_pBegin;
|
||||
}
|
||||
|
||||
|
||||
inline RecordSet::ConstIterator& RecordSet::end() const
|
||||
{
|
||||
return *_pEnd;
|
||||
}
|
||||
|
||||
|
||||
inline RecordSet::Iterator RecordSet::begin()
|
||||
{
|
||||
return *_pBegin;
|
||||
}
|
||||
|
||||
|
||||
inline RecordSet::Iterator RecordSet::end()
|
||||
{
|
||||
return *_pEnd;
|
||||
}
|
||||
|
||||
|
||||
inline void RecordSet::setFormatter(Row::FormatterPtr pRowFormatter)
|
||||
{
|
||||
_pRowFormatter = pRowFormatter;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream& RecordSet::copyNames(std::ostream& os) const
|
||||
{
|
||||
os << (*_pBegin)->namesToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -47,7 +47,7 @@
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -79,9 +79,10 @@ class Data_API Row
|
||||
/// The stream operator is provided for Row data type as a free-standing function.
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::string> NameVec;
|
||||
typedef SharedPtr<std::vector<std::string> > NameVecPtr;
|
||||
typedef std::vector<DynamicAny> ValueVec;
|
||||
typedef RowFormatter::NameVec NameVec;
|
||||
typedef RowFormatter::NameVecPtr NameVecPtr;
|
||||
typedef RowFormatter::ValueVec ValueVec;
|
||||
typedef SharedPtr<RowFormatter> FormatterPtr;
|
||||
|
||||
enum ComparisonType
|
||||
{
|
||||
@@ -90,12 +91,10 @@ public:
|
||||
COMPARE_AS_STRING
|
||||
};
|
||||
|
||||
static const std::string EOL;
|
||||
|
||||
Row();
|
||||
/// Creates the Row.
|
||||
|
||||
explicit Row(NameVecPtr pNames, RowFormatter* pFormatter = 0);
|
||||
explicit Row(NameVecPtr pNames, FormatterPtr* pFormatter = 0);
|
||||
/// Creates the Row.
|
||||
|
||||
~Row();
|
||||
@@ -181,13 +180,11 @@ public:
|
||||
void resetSort();
|
||||
/// Resets the sorting criteria to field 0 only.
|
||||
|
||||
const std::string namesToString() const;
|
||||
/// Converts the row names to string, inserting separator
|
||||
/// string between fields and end-of-line at the end.
|
||||
const std::string& namesToString() const;
|
||||
/// Converts the row names to string.
|
||||
|
||||
const std::string valuesToString() const;
|
||||
/// Converts the row values to string, inserting separator
|
||||
/// string between fields and end-of-line at the end.
|
||||
const std::string& valuesToString() const;
|
||||
/// Converts the row values to string.
|
||||
|
||||
bool operator == (const Row& other) const;
|
||||
/// Equality operator.
|
||||
@@ -198,12 +195,19 @@ public:
|
||||
bool operator < (const Row& other) const;
|
||||
/// Less-then operator.
|
||||
|
||||
NameVecPtr names();
|
||||
const NameVecPtr names() const;
|
||||
/// Returns the shared pointer to names vector.
|
||||
|
||||
const ValueVec& values();
|
||||
const ValueVec& values() const;
|
||||
/// Returns the const reference to values vector.
|
||||
|
||||
void setFormatter(FormatterPtr* pFormatter);
|
||||
/// Sets the formatter for this row and takes the
|
||||
/// shared ownership of it.
|
||||
|
||||
const RowFormatter& getFormatter() const;
|
||||
/// Returns the reference to the formatter.
|
||||
|
||||
private:
|
||||
typedef Tuple<std::size_t, ComparisonType> SortTuple;
|
||||
typedef std::vector<SortTuple> SortMap;
|
||||
@@ -212,14 +216,19 @@ private:
|
||||
/// corresponds to adding order rather than field's position in the row.
|
||||
/// That requirement rules out use of std::map due to its sorted nature.
|
||||
|
||||
ValueVec& values();
|
||||
/// Returns the reference to values vector.
|
||||
|
||||
std::size_t getPosition(const std::string& name);
|
||||
bool isEqualSize(const Row& other) const;
|
||||
bool isEqualType(const Row& other) const;
|
||||
|
||||
NameVecPtr _pNames;
|
||||
ValueVec _values;
|
||||
SortMap _sortFields;
|
||||
mutable SharedPtr<RowFormatter> _pFormatter;
|
||||
NameVecPtr _pNames;
|
||||
ValueVec _values;
|
||||
SortMap _sortFields;
|
||||
FormatterPtr _pFormatter;
|
||||
mutable std::string _nameStr;
|
||||
mutable std::string _valueStr;
|
||||
};
|
||||
|
||||
|
||||
@@ -242,13 +251,19 @@ inline void Row::reset()
|
||||
}
|
||||
|
||||
|
||||
inline Row::NameVecPtr Row::names()
|
||||
inline const Row::NameVecPtr Row::names() const
|
||||
{
|
||||
return _pNames;
|
||||
}
|
||||
|
||||
|
||||
inline const Row::ValueVec& Row::values()
|
||||
inline const Row::ValueVec& Row::values() const
|
||||
{
|
||||
return _values;
|
||||
}
|
||||
|
||||
|
||||
inline Row::ValueVec& Row::values()
|
||||
{
|
||||
return _values;
|
||||
}
|
||||
@@ -266,6 +281,18 @@ inline DynamicAny& Row::operator [] (const std::string& name)
|
||||
}
|
||||
|
||||
|
||||
inline const RowFormatter& Row::getFormatter() const
|
||||
{
|
||||
return *_pFormatter;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& Row::valuesToString() const
|
||||
{
|
||||
return _pFormatter->formatValues(values(), _valueStr);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -41,47 +41,64 @@
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Row;
|
||||
|
||||
|
||||
class Data_API RowFormatter
|
||||
/// Row formatter is a rudimentary formatting class providing
|
||||
/// basic row formatting. This class will separate field names and
|
||||
/// filed values by a tab ('\t') and append the platform specific
|
||||
/// end of line at the end of each row. For custom formatting
|
||||
/// basic row formatting. For custom formatting
|
||||
/// strategies, inherit from this class and override formatNames()
|
||||
/// and formaValues() member functions.
|
||||
/// and formatValues() member functions.
|
||||
{
|
||||
public:
|
||||
static const std::string EOL;
|
||||
typedef std::vector<std::string> NameVec;
|
||||
typedef SharedPtr<std::vector<std::string> > NameVecPtr;
|
||||
typedef std::vector<DynamicAny> ValueVec;
|
||||
|
||||
RowFormatter(Row* pRow = 0);
|
||||
/// Creates the RowFormatter.
|
||||
static const int DEFAULT_COLUMN_WIDTH = 16;
|
||||
|
||||
RowFormatter(std::streamsize width);
|
||||
/// Creates the RowFormatter and sets the column width to specified value.
|
||||
|
||||
RowFormatter(const std::string& prefix = "", const std::string& postfix = "");
|
||||
/// Creates the RowFormatter and sets the prefix and postfix to specified values.
|
||||
|
||||
virtual ~RowFormatter();
|
||||
/// Destroys the RowFormatter.
|
||||
|
||||
void setRow(Row* pRow);
|
||||
/// Assigns the row to this formatter.
|
||||
const std::string& prefix() const;
|
||||
/// Returns prefix string;
|
||||
|
||||
virtual std::string& formatNames(std::string& names);
|
||||
virtual std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames) const;
|
||||
/// Formats the row field names.
|
||||
|
||||
virtual std::string& formatValues(std::string& values);
|
||||
virtual std::string& formatValues(const ValueVec& vals, std::string& formattedValues) const;
|
||||
/// Formats the row values.
|
||||
|
||||
private:
|
||||
RowFormatter(const RowFormatter&);
|
||||
RowFormatter& operator = (const RowFormatter&);
|
||||
const std::string& postfix() const;
|
||||
/// Returns postfix string;
|
||||
|
||||
Row* _pRow;
|
||||
std::string _separator;
|
||||
void setWidth(std::streamsize width);
|
||||
/// Sets the column width.
|
||||
|
||||
std::streamsize getWidth() const;
|
||||
/// Returns the column width.
|
||||
|
||||
protected:
|
||||
void setPrefix(const std::string& prefix);
|
||||
void setPostfix(const std::string& postfix);
|
||||
|
||||
private:
|
||||
std::streamsize _width;
|
||||
std::string _prefix;
|
||||
std::string _postfix;
|
||||
};
|
||||
|
||||
|
||||
@@ -89,11 +106,39 @@ private:
|
||||
/// inlines
|
||||
///
|
||||
|
||||
|
||||
inline void RowFormatter::setRow(Row* pRow)
|
||||
inline void RowFormatter::setWidth(std::streamsize width)
|
||||
{
|
||||
poco_check_ptr (pRow);
|
||||
_pRow = pRow;
|
||||
_width = width;
|
||||
}
|
||||
|
||||
|
||||
inline std::streamsize RowFormatter::getWidth() const
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
|
||||
inline void RowFormatter::setPrefix(const std::string& prefix)
|
||||
{
|
||||
_prefix = prefix;
|
||||
}
|
||||
|
||||
|
||||
inline void RowFormatter::setPostfix(const std::string& postfix)
|
||||
{
|
||||
_postfix = postfix;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& RowFormatter::prefix() const
|
||||
{
|
||||
return _prefix;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& RowFormatter::postfix() const
|
||||
{
|
||||
return _postfix;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -58,21 +58,30 @@ class Data_API RowIterator
|
||||
{
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef Row value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Row* pointer;
|
||||
typedef Row& reference;
|
||||
typedef Row value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Row* pointer;
|
||||
typedef Row& reference;
|
||||
|
||||
RowIterator(RecordSet& recordSet, bool positionEnd = false);
|
||||
static const int POSITION_END;
|
||||
/// End position indicator.
|
||||
|
||||
RowIterator(RecordSet* pRecordSet, bool positionEnd = false);
|
||||
/// Creates the RowIterator and positions it at the beginning.
|
||||
|
||||
RowIterator(const RowIterator& other);
|
||||
/// Creates a copy of other RowIterator.
|
||||
|
||||
~RowIterator();
|
||||
/// Destroys the RowIterator.
|
||||
|
||||
bool operator == (const RowIterator& other);
|
||||
RowIterator& operator = (const RowIterator& other);
|
||||
/// Assigns the other RowIterator.
|
||||
|
||||
bool operator == (const RowIterator& other) const;
|
||||
/// Equality operator.
|
||||
|
||||
bool operator != (const RowIterator& other);
|
||||
bool operator != (const RowIterator& other) const;
|
||||
/// Inequality operator.
|
||||
|
||||
Row& operator * () const;
|
||||
@@ -81,47 +90,80 @@ public:
|
||||
Row* operator -> () const;
|
||||
/// Returns pointer to the current row.
|
||||
|
||||
std::size_t operator ++ ();
|
||||
const RowIterator& operator ++ () const;
|
||||
/// Advances by one position and returns current position.
|
||||
|
||||
std::size_t operator ++ (int);
|
||||
/// Advances by one position and returns previous current position.
|
||||
RowIterator operator ++ (int) const;
|
||||
/// Advances by one position and returns copy of the iterator with
|
||||
/// previous current position.
|
||||
|
||||
std::size_t operator -- ();
|
||||
/// Goes back by one position and returns current position.
|
||||
const RowIterator& operator -- () const;
|
||||
/// Goes back by one position and returns copy of the iterator with
|
||||
/// previous current position.
|
||||
|
||||
std::size_t operator -- (int);
|
||||
/// Goes back by one position and returns previouscurrent position.
|
||||
RowIterator operator -- (int) const;
|
||||
/// Goes back by one position and returns previous current position.
|
||||
|
||||
RowIterator operator + (std::size_t diff) const;
|
||||
/// Returns a copy the RowIterator advanced by diff positions.
|
||||
|
||||
RowIterator operator - (std::size_t diff) const;
|
||||
/// Returns a copy the RowIterator backed by diff positions.
|
||||
/// Throws RangeException if diff is larger than current position.
|
||||
|
||||
void swap(RowIterator& other);
|
||||
/// Swaps the RowIterator with another one.
|
||||
|
||||
private:
|
||||
RowIterator();
|
||||
|
||||
void increment();
|
||||
void decrement();
|
||||
void increment() const;
|
||||
/// Increments the iterator position by one.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
static const int POSITION_END;
|
||||
void decrement() const;
|
||||
/// Decrements the iterator position by one.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
RecordSet& _recordSet;
|
||||
std::size_t _position;
|
||||
void setPosition(std::size_t pos) const;
|
||||
/// Sets the iterator position.
|
||||
/// Throws RangeException if position is out of range.
|
||||
|
||||
RecordSet* _pRecordSet;
|
||||
mutable std::size_t _position;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
inline bool RowIterator::operator == (const RowIterator& other)
|
||||
|
||||
|
||||
inline bool RowIterator::operator == (const RowIterator& other) const
|
||||
{
|
||||
return _position == other._position;
|
||||
return _pRecordSet == other._pRecordSet && _position == other._position;
|
||||
}
|
||||
|
||||
|
||||
inline bool RowIterator::operator != (const RowIterator& other)
|
||||
inline bool RowIterator::operator != (const RowIterator& other) const
|
||||
{
|
||||
return _position != other._position;
|
||||
return _pRecordSet != other._pRecordSet || _position != other._position;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator& s1,
|
||||
Poco::Data::RowIterator& s2)
|
||||
/// Full template specalization of std:::swap for RowIterator
|
||||
{
|
||||
s1.swap(s2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // Data_RowIterator_INCLUDED
|
||||
|
@@ -270,6 +270,8 @@ public:
|
||||
/// with the statement.
|
||||
|
||||
protected:
|
||||
typedef Poco::AutoPtr<StatementImpl> StatementImplPtr;
|
||||
|
||||
const AbstractExtractionVec& extractions() const;
|
||||
/// Returns the extractions vector.
|
||||
|
||||
@@ -285,9 +287,10 @@ protected:
|
||||
bool isBulkExtraction() const;
|
||||
/// Returns true if this statement extracts data in bulk.
|
||||
|
||||
private:
|
||||
typedef Poco::SharedPtr<StatementImpl> StatementImplPtr;
|
||||
StatementImplPtr impl() const;
|
||||
/// Returns pointer to statement implementation.
|
||||
|
||||
private:
|
||||
static const int WAIT_FOREVER = -1;
|
||||
|
||||
const Result& doAsyncExec();
|
||||
@@ -379,6 +382,12 @@ inline void Data_API reset(Statement& statement)
|
||||
//
|
||||
|
||||
|
||||
inline Statement::StatementImplPtr Statement::impl() const
|
||||
{
|
||||
return _pImpl;
|
||||
}
|
||||
|
||||
|
||||
inline std::string Statement::toString() const
|
||||
{
|
||||
return _pImpl->toString();
|
||||
|
@@ -12,4 +12,5 @@ projects:
|
||||
$(MAKE) -C Binding $(MAKECMDGOALS)
|
||||
$(MAKE) -C TypeHandler $(MAKECMDGOALS)
|
||||
$(MAKE) -C RecordSet $(MAKECMDGOALS)
|
||||
$(MAKE) -C RowFormatter $(MAKECMDGOALS)
|
||||
$(MAKE) -C Tuple $(MAKECMDGOALS)
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#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>
|
||||
|
||||
@@ -28,14 +27,6 @@
|
||||
using namespace Poco::Data;
|
||||
|
||||
|
||||
struct Person
|
||||
{
|
||||
std::string name;
|
||||
std::string address;
|
||||
int age;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// register SQLite connector
|
||||
@@ -51,30 +42,20 @@ int main(int argc, char** argv)
|
||||
session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;
|
||||
|
||||
// insert some rows
|
||||
session << "INSERT INTO Person VALUES('Homer Simpson', 'Springfield', 42)", now;
|
||||
session << "INSERT INTO Person VALUES('Marge Simpson', 'Springfield', 38)", now;
|
||||
session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12)", now;
|
||||
session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10)", now;
|
||||
|
||||
// a simple query
|
||||
Statement select(session);
|
||||
select << "SELECT * FROM Person";
|
||||
select.execute();
|
||||
// create a recordset and print the column names and data
|
||||
RecordSet rs(session, "SELECT * FROM Person");
|
||||
std::cout << rs;
|
||||
|
||||
// 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) << "\t\t";
|
||||
}
|
||||
// print just two middle rows
|
||||
std::cout << std::endl << "Middle rows :" << std::endl;
|
||||
rs.copyValues(std::cout, 1, 2);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "-----------------------------------" << std::endl;
|
||||
|
||||
// iterate over all rows and print the data
|
||||
RecordSet::Iterator it = rs.begin();
|
||||
RecordSet::Iterator end = rs.end();
|
||||
for (; it != end; ++it) std::cout << *it;
|
||||
std::cout << "---" << std::endl << "Thats all, folks!" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
17
Data/samples/RowFormatter/Makefile
Normal file
17
Data/samples/RowFormatter/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Makefile
|
||||
#
|
||||
# $Id: //poco/Main/Data/samples/RowFormatter/Makefile#1 $
|
||||
#
|
||||
# Makefile for Poco Data RowFormatter sample
|
||||
#
|
||||
|
||||
include $(POCO_BASE)/build/rules/global
|
||||
|
||||
objects = RowFormatter
|
||||
|
||||
target = RowFormatter
|
||||
target_version = 1
|
||||
target_libs = PocoFoundation PocoData PocoSQLite
|
||||
|
||||
include $(POCO_BASE)/build/rules/exec
|
147
Data/samples/RowFormatter/RowFormatter_vs71.vcproj
Normal file
147
Data/samples/RowFormatter/RowFormatter_vs71.vcproj
Normal file
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="RowFormatter"
|
||||
ProjectGUID="{56F66D36-F11E-4AA1-AD37-4518A253059D}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug_shared|Win32"
|
||||
OutputDirectory="obj\debug_shared"
|
||||
IntermediateDirectory="obj\debug_shared"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLite\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="TRUE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="bin/RowFormatterd.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\..\lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="bin/RowFormatterd.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release_shared|Win32"
|
||||
OutputDirectory="obj\release_shared"
|
||||
IntermediateDirectory="obj\release_shared"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="4"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLite\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="FALSE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="bin/RowFormatter.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\lib"
|
||||
GenerateDebugInformation="FALSE"
|
||||
ProgramDatabaseFile=""
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\src\RowFormatter.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
209
Data/samples/RowFormatter/RowFormatter_vs80.vcproj
Normal file
209
Data/samples/RowFormatter/RowFormatter_vs80.vcproj
Normal file
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="RowFormatter"
|
||||
ProjectGUID="{2613C7FF-A9A1-4376-9CD7-07F694501498}"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug_shared|Win32"
|
||||
OutputDirectory="obj\debug_shared"
|
||||
IntermediateDirectory="obj\debug_shared"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLite\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="true"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="bin/RowFormatterd.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\..\lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="bin/RowFormatterd.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release_shared|Win32"
|
||||
OutputDirectory="obj\release_shared"
|
||||
IntermediateDirectory="obj\release_shared"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="4"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLite\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="bin/Rowformatter.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\lib"
|
||||
GenerateDebugInformation="false"
|
||||
ProgramDatabaseFile=""
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\RowFormatter.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
106
Data/samples/RowFormatter/src/RowFormatter.cpp
Normal file
106
Data/samples/RowFormatter/src/RowFormatter.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// RecordSet.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/samples/RecordSet/src/RowFormatter.cpp#2 $
|
||||
//
|
||||
// This sample demonstrates the Data library recordset formatting
|
||||
// capabilities.
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This is unpublished proprietary source code of Applied Informatics
|
||||
// Software Engineering GmbH.
|
||||
// The contents of this file may not be disclosed to third parties,
|
||||
// copied or duplicated in any form, in whole or in part, without
|
||||
// prior written permission from Applied Informatics.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Poco::Data;
|
||||
|
||||
|
||||
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) const
|
||||
{
|
||||
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) const
|
||||
{
|
||||
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 Person", now;
|
||||
|
||||
// (re)create table
|
||||
session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;
|
||||
|
||||
// insert some rows
|
||||
session << "INSERT INTO Person VALUES('Homer Simpson', 'Springfield', 42)", now;
|
||||
session << "INSERT INTO Person VALUES('Marge Simpson', 'Springfield', 38)", now;
|
||||
session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12)", now;
|
||||
session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10)", now;
|
||||
|
||||
// create a recordset and print the column names and data as HTML table
|
||||
std::cout << RecordSet(session, "SELECT * FROM Person", new HTMLTableFormatter);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -65,7 +65,7 @@ public:
|
||||
TypeHandler<int>::extract(pos++, person.age, deflt.age, pExtr);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const Person& person, AbstractPreparation* pPrep)
|
||||
static void prepare(std::size_t pos, Person& person, AbstractPreparation* pPrep)
|
||||
{
|
||||
TypeHandler<std::string>::prepare(pos++, person.name, pPrep);
|
||||
TypeHandler<std::string>::prepare(pos++, person.address, pPrep);
|
||||
|
@@ -15,11 +15,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tuple", "Tuple\Tuple_vs71.v
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RowFormatter", "RowFormatter\RowFormatter_vs71.vcproj", "{56F66D36-F11E-4AA1-AD37-4518A253059D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
debug_shared = debug_shared
|
||||
release_shared = release_shared
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectDependencies) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{54BCEDA8-C241-4DCF-AEAD-6177F115B0D0}.debug_shared.ActiveCfg = debug_shared|Win32
|
||||
{54BCEDA8-C241-4DCF-AEAD-6177F115B0D0}.debug_shared.Build.0 = debug_shared|Win32
|
||||
@@ -37,6 +43,10 @@ Global
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.debug_shared.Build.0 = debug_shared|Win32
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared.ActiveCfg = release_shared|Win32
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared.Build.0 = release_shared|Win32
|
||||
{56F66D36-F11E-4AA1-AD37-4518A253059D}.debug_shared.ActiveCfg = debug_shared|Win32
|
||||
{56F66D36-F11E-4AA1-AD37-4518A253059D}.debug_shared.Build.0 = debug_shared|Win32
|
||||
{56F66D36-F11E-4AA1-AD37-4518A253059D}.release_shared.ActiveCfg = release_shared|Win32
|
||||
{56F66D36-F11E-4AA1-AD37-4518A253059D}.release_shared.Build.0 = release_shared|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RecordSet", "RecordSet\Reco
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tuple", "Tuple\Tuple_vs80.vcproj", "{08C81227-3322-4DBD-A83F-55CCC933A5F7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RowFormatter", "RowFormatter\RowFormatter_vs80.vcproj", "{2613C7FF-A9A1-4376-9CD7-07F694501498}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug_shared|Win32 = debug_shared|Win32
|
||||
@@ -31,6 +33,10 @@ Global
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.debug_shared|Win32.Build.0 = debug_shared|Win32
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared|Win32.ActiveCfg = release_shared|Win32
|
||||
{08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared|Win32.Build.0 = release_shared|Win32
|
||||
{2613C7FF-A9A1-4376-9CD7-07F694501498}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
|
||||
{2613C7FF-A9A1-4376-9CD7-07F694501498}.debug_shared|Win32.Build.0 = debug_shared|Win32
|
||||
{2613C7FF-A9A1-4376-9CD7-07F694501498}.release_shared|Win32.ActiveCfg = release_shared|Win32
|
||||
{2613C7FF-A9A1-4376-9CD7-07F694501498}.release_shared|Win32.Build.0 = release_shared|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@@ -52,17 +52,30 @@ namespace Data {
|
||||
RecordSet::RecordSet(const Statement& rStatement):
|
||||
Statement(rStatement),
|
||||
_currentRow(0),
|
||||
_pBegin(0),
|
||||
_pEnd(0)
|
||||
_pBegin(new RowIterator(this)),
|
||||
_pEnd(new RowIterator(this, true))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RecordSet::RecordSet(Session& rSession, const std::string& query):
|
||||
RecordSet::RecordSet(Session& rSession,
|
||||
const std::string& query,
|
||||
RowFormatter* pRowFormatter):
|
||||
Statement((rSession << query, now)),
|
||||
_currentRow(0),
|
||||
_pBegin(0),
|
||||
_pEnd(0)
|
||||
_pBegin(new RowIterator(this)),
|
||||
_pEnd(new RowIterator(this, true)),
|
||||
_pRowFormatter(pRowFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RecordSet::RecordSet(const RecordSet& other):
|
||||
Statement(other.impl().duplicate()),
|
||||
_currentRow(other._currentRow),
|
||||
_pBegin(new RowIterator(this)),
|
||||
_pEnd(new RowIterator(this, true)),
|
||||
_pRowFormatter(other._pRowFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -74,8 +87,7 @@ RecordSet::~RecordSet()
|
||||
|
||||
RowMap::iterator it = _rowMap.begin();
|
||||
RowMap::iterator end = _rowMap.end();
|
||||
for (; it != end; ++it)
|
||||
delete it->second;
|
||||
for (; it != end; ++it) delete it->second;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,15 +143,6 @@ DynamicAny RecordSet::value(const std::string& name, std::size_t row) const
|
||||
}
|
||||
|
||||
|
||||
const RowIterator& RecordSet::begin()
|
||||
{
|
||||
if (!_pBegin)
|
||||
_pBegin = new RowIterator(*this);
|
||||
|
||||
return *_pBegin;
|
||||
}
|
||||
|
||||
|
||||
Row& RecordSet::row(std::size_t pos)
|
||||
{
|
||||
if (pos > rowCount() - 1)
|
||||
@@ -147,27 +150,31 @@ Row& RecordSet::row(std::size_t pos)
|
||||
|
||||
RowMap::iterator it = _rowMap.find(pos);
|
||||
Row* pRow = 0;
|
||||
std::size_t columns = columnCount();
|
||||
if (it == _rowMap.end())
|
||||
{
|
||||
if (_rowMap.size())//reuse first row column names to save some memory
|
||||
{
|
||||
pRow = new Row(_rowMap.begin()->second->names());
|
||||
for (std::size_t i = 0; i < columnCount(); ++i)
|
||||
pRow->set(i, value(i, pos));
|
||||
pRow = new Row(_rowMap.begin()->second->names(), &_pRowFormatter);
|
||||
for (std::size_t col = 0; col < columns; ++col)
|
||||
pRow->set(col, value(col, pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
pRow = new Row;
|
||||
for (std::size_t i = 0; i < columnCount(); ++i)
|
||||
pRow->append(metaColumn(static_cast<UInt32>(pos)).name(), value(i, pos));
|
||||
if (_pRowFormatter) pRow->setFormatter(&_pRowFormatter);
|
||||
for (std::size_t col = 0; col < columns; ++col)
|
||||
pRow->append(metaColumn(static_cast<UInt32>(col)).name(), value(col, pos));
|
||||
}
|
||||
|
||||
_rowMap.insert(RowMap::value_type(pos, pRow));
|
||||
}
|
||||
else
|
||||
{
|
||||
pRow = it->second;
|
||||
poco_check_ptr (pRow);
|
||||
}
|
||||
|
||||
poco_check_ptr (pRow);
|
||||
return *pRow;
|
||||
}
|
||||
|
||||
@@ -228,4 +235,30 @@ DynamicAny RecordSet::nvl(std::size_t index, const DynamicAny& deflt) const
|
||||
}
|
||||
|
||||
|
||||
std::ostream& RecordSet::copyValues(std::ostream& os, std::size_t offset, std::size_t length) const
|
||||
{
|
||||
if (length == RowIterator::POSITION_END)
|
||||
{
|
||||
if (0 != offset) throw RangeException("Invalid range.");
|
||||
length = rowCount();
|
||||
}
|
||||
|
||||
RowIterator itBegin = *_pBegin + offset;
|
||||
RowIterator itEnd = itBegin + length;
|
||||
std::copy(itBegin, itEnd, std::ostream_iterator<Row>(os));
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& RecordSet::copy(std::ostream& os) const
|
||||
{
|
||||
const RowFormatter& ri = (*_pBegin)->getFormatter();
|
||||
os << ri.prefix();
|
||||
copyNames(os);
|
||||
copyValues(os);
|
||||
os << ri.postfix();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
|
||||
#include "Poco/Data/Row.h"
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
@@ -51,20 +52,18 @@ std::ostream& operator << (std::ostream &os, const Row& row)
|
||||
|
||||
Row::Row():
|
||||
_pNames(0),
|
||||
_pFormatter(new RowFormatter(this))
|
||||
_pFormatter(new RowFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Row::Row(NameVecPtr pNames, RowFormatter* pFormatter):
|
||||
_pNames(pNames),
|
||||
_pFormatter(pFormatter)
|
||||
Row::Row(NameVecPtr pNames, FormatterPtr* pFormatter):
|
||||
_pNames(pNames)
|
||||
{
|
||||
if (!_pNames)
|
||||
throw NullPointerException();
|
||||
if (!_pNames) throw NullPointerException();
|
||||
|
||||
if (!_pFormatter) _pFormatter = new RowFormatter(this);
|
||||
else _pFormatter->setRow(this);
|
||||
if (pFormatter && *pFormatter) _pFormatter = *pFormatter;
|
||||
else _pFormatter = new RowFormatter;
|
||||
|
||||
_values.resize(_pNames->size());
|
||||
addSortField(0);
|
||||
@@ -316,20 +315,21 @@ bool Row::operator < (const Row& other) const
|
||||
}
|
||||
|
||||
|
||||
const std::string Row::valuesToString() const
|
||||
void Row::setFormatter(FormatterPtr* pFormatter)
|
||||
{
|
||||
std::string values;
|
||||
return _pFormatter->formatValues(values);
|
||||
if (pFormatter && *pFormatter)
|
||||
_pFormatter = *pFormatter;
|
||||
else
|
||||
_pFormatter = new RowFormatter;
|
||||
}
|
||||
|
||||
|
||||
const std::string Row::namesToString() const
|
||||
const std::string& Row::namesToString() const
|
||||
{
|
||||
if (!_pNames)
|
||||
throw NullPointerException();
|
||||
|
||||
std::string names;
|
||||
return _pFormatter->formatNames(names);
|
||||
return _pFormatter->formatNames(names(), _nameStr);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -35,26 +35,24 @@
|
||||
|
||||
|
||||
#include "Poco/Data/RowFormatter.h"
|
||||
#include "Poco/Data/Row.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
const std::string RowFormatter::EOL = "\r\n";
|
||||
#elif (POCO_OS == POCO_OS_MAC_OS_X)
|
||||
const std::string RowFormatter::EOL = "\r";
|
||||
#else
|
||||
const std::string RowFormatter::EOL = "\n";
|
||||
#endif
|
||||
RowFormatter::RowFormatter(std::streamsize width):
|
||||
_width(width)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RowFormatter::RowFormatter(Row* pRow):
|
||||
_pRow(pRow),
|
||||
_separator("\t")
|
||||
RowFormatter::RowFormatter(const std::string& prefix, const std::string& postfix):
|
||||
_width(DEFAULT_COLUMN_WIDTH),
|
||||
_prefix(prefix),
|
||||
_postfix(postfix)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -64,40 +62,44 @@ RowFormatter::~RowFormatter()
|
||||
}
|
||||
|
||||
|
||||
std::string& RowFormatter::formatNames(std::string& names)
|
||||
std::string& RowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames) const
|
||||
{
|
||||
if (!_pRow)
|
||||
throw NullPointerException("Null row.");
|
||||
std::ostringstream str;
|
||||
std::string line(_width * pNames->size(), '-');
|
||||
|
||||
Row::NameVec::const_iterator it = _pRow->names()->begin();
|
||||
Row::NameVec::const_iterator end = _pRow->names()->end();
|
||||
NameVec::const_iterator it = pNames->begin();
|
||||
NameVec::const_iterator end = pNames->end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
names.append(*it);
|
||||
names.append(_separator);
|
||||
str << std::left << std::setw(_width) << *it;
|
||||
}
|
||||
names.replace(names.find_last_of(_separator), _separator.length(), EOL);
|
||||
str << std::endl << line << std::endl;
|
||||
|
||||
return names;
|
||||
return formattedNames = str.str();
|
||||
}
|
||||
|
||||
|
||||
std::string& RowFormatter::formatValues(std::string& values)
|
||||
std::string& RowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues) const
|
||||
{
|
||||
if (!_pRow)
|
||||
throw NullPointerException("Null row.");
|
||||
std::ostringstream str;
|
||||
|
||||
Row::ValueVec::const_iterator it = _pRow->values().begin();
|
||||
Row::ValueVec::const_iterator end = _pRow->values().end();
|
||||
ValueVec::const_iterator it = vals.begin();
|
||||
ValueVec::const_iterator end = vals.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
values.append(it->convert<std::string>());
|
||||
values.append(_separator);
|
||||
if (it->isNumeric())
|
||||
{
|
||||
str << std::right
|
||||
<< std::fixed
|
||||
<< std::setprecision(2);
|
||||
}
|
||||
else str << std::left;
|
||||
|
||||
str << std::setw(_width) << it->convert<std::string>();
|
||||
}
|
||||
values.replace(values.find_last_of(_separator), _separator.length(), EOL);
|
||||
str << std::endl;
|
||||
|
||||
return values;
|
||||
return formattedValues = str.str();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
@@ -48,9 +48,16 @@ namespace Data {
|
||||
const int RowIterator::POSITION_END = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
|
||||
RowIterator::RowIterator(RecordSet& recordSet, bool positionEnd):
|
||||
_recordSet(recordSet),
|
||||
_position((0 == recordSet.rowCount()) || positionEnd ? POSITION_END : 0)
|
||||
RowIterator::RowIterator(RecordSet* pRecordSet, bool positionEnd):
|
||||
_pRecordSet(pRecordSet),
|
||||
_position((0 == pRecordSet->rowCount()) || positionEnd ? POSITION_END : 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RowIterator::RowIterator(const RowIterator& other):
|
||||
_pRecordSet(other._pRecordSet),
|
||||
_position(other._position)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,35 +67,63 @@ RowIterator::~RowIterator()
|
||||
}
|
||||
|
||||
|
||||
void RowIterator::increment()
|
||||
RowIterator& RowIterator::operator = (const RowIterator& other)
|
||||
{
|
||||
RowIterator tmp(other);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void RowIterator::swap(RowIterator& other)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(_pRecordSet, other._pRecordSet);
|
||||
swap(_position, other._position);
|
||||
}
|
||||
|
||||
|
||||
void RowIterator::increment() const
|
||||
{
|
||||
if (POSITION_END == _position)
|
||||
throw RangeException("End of iterator reached.");
|
||||
|
||||
if (_position < _recordSet.rowCount() - 1)
|
||||
if (_position < _pRecordSet->rowCount() - 1)
|
||||
++_position;
|
||||
else
|
||||
_position = POSITION_END;
|
||||
}
|
||||
|
||||
|
||||
void RowIterator::decrement()
|
||||
void RowIterator::decrement() const
|
||||
{
|
||||
if (0 == _position)
|
||||
throw RangeException("Beginning of iterator reached.");
|
||||
else if (POSITION_END == _position)
|
||||
_position = _recordSet.rowCount() - 1;
|
||||
_position = _pRecordSet->rowCount() - 1;
|
||||
else
|
||||
--_position;
|
||||
}
|
||||
|
||||
|
||||
void RowIterator::setPosition(std::size_t pos) const
|
||||
{
|
||||
if (pos < _pRecordSet->rowCount())
|
||||
_position = pos;
|
||||
else if (pos == _pRecordSet->rowCount())
|
||||
_position = POSITION_END;
|
||||
else
|
||||
throw RangeException("Invalid position argument.");
|
||||
}
|
||||
|
||||
|
||||
Row& RowIterator::operator * () const
|
||||
{
|
||||
if (POSITION_END == _position)
|
||||
throw InvalidAccessException("End of iterator reached.");
|
||||
|
||||
return _recordSet.row(_position);
|
||||
return _pRecordSet->row(_position);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,37 +132,54 @@ Row* RowIterator::operator -> () const
|
||||
if (POSITION_END == _position)
|
||||
throw InvalidAccessException("End of iterator reached.");
|
||||
|
||||
return &_recordSet.row(_position);
|
||||
return &_pRecordSet->row(_position);
|
||||
}
|
||||
|
||||
|
||||
std::size_t RowIterator::operator ++ ()
|
||||
const RowIterator& RowIterator::operator ++ () const
|
||||
{
|
||||
increment();
|
||||
return _position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
std::size_t RowIterator::operator ++ (int)
|
||||
RowIterator RowIterator::operator ++ (int) const
|
||||
{
|
||||
std::size_t oldPos = _position;
|
||||
RowIterator old(*this);
|
||||
increment();
|
||||
return oldPos;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
std::size_t RowIterator::operator -- ()
|
||||
const RowIterator& RowIterator::operator -- () const
|
||||
{
|
||||
decrement();
|
||||
return _position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
std::size_t RowIterator::operator -- (int)
|
||||
RowIterator RowIterator::operator -- (int) const
|
||||
{
|
||||
std::size_t oldPos = _position;
|
||||
RowIterator old(*this);
|
||||
decrement();
|
||||
return oldPos;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
RowIterator RowIterator::operator + (std::size_t diff) const
|
||||
{
|
||||
RowIterator ri(*this);
|
||||
ri.setPosition(_position + diff);
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
RowIterator RowIterator::operator - (std::size_t diff) const
|
||||
{
|
||||
if (diff > _position) throw RangeException("Invalid position argument.");
|
||||
RowIterator ri(*this);
|
||||
ri.setPosition(_position - diff);
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
|
||||
|
||||
@@ -1000,12 +1001,25 @@ void DataTest::testRowFormat()
|
||||
row1.append("field3", 3);
|
||||
row1.append("field4", 4);
|
||||
|
||||
RowFormatter rf;
|
||||
std::streamsize sz = rf.getWidth();
|
||||
|
||||
std::string line(sz * 5, '-');
|
||||
std::ostringstream os;
|
||||
os << "field0\tfield1\tfield2\tfield3\tfield4" << RowFormatter::EOL;
|
||||
os << std::left << std::setw(sz) << "field0"
|
||||
<< std::setw(sz) << "field1"
|
||||
<< std::setw(sz) << "field2"
|
||||
<< std::setw(sz) << "field3"
|
||||
<< std::setw(sz) << "field4" << std::endl
|
||||
<< line << std::endl;
|
||||
assert (row1.namesToString() == os.str());
|
||||
|
||||
os.str("");
|
||||
os << "0\t1\t2\t3\t4" << RowFormatter::EOL;
|
||||
os << std::right << std::setw(sz) << "0"
|
||||
<< std::setw(sz) << "1"
|
||||
<< std::setw(sz) << "2"
|
||||
<< std::setw(sz) << "3"
|
||||
<< std::setw(sz) << "4" << std::endl;
|
||||
assert (row1.valuesToString() == os.str());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user