diff --git a/Data/Data_VS71.vcproj b/Data/Data_VS71.vcproj index 39a1ac68e..6d6823991 100644 --- a/Data/Data_VS71.vcproj +++ b/Data/Data_VS71.vcproj @@ -187,6 +187,9 @@ + + @@ -214,6 +217,9 @@ + + @@ -226,9 +232,6 @@ - - @@ -269,6 +272,9 @@ + + @@ -287,6 +293,9 @@ + + @@ -299,9 +308,6 @@ - - diff --git a/Data/Data_VS80.vcproj b/Data/Data_VS80.vcproj index 8d34c37af..6ed99a04b 100644 --- a/Data/Data_VS80.vcproj +++ b/Data/Data_VS80.vcproj @@ -297,6 +297,10 @@ RelativePath=".\include\Poco\Data\Row.h" > + + @@ -393,6 +397,10 @@ RelativePath=".\src\Row.cpp" > + + diff --git a/Data/Makefile b/Data/Makefile index 3c54670f0..b633fd35d 100644 --- a/Data/Makefile +++ b/Data/Makefile @@ -12,7 +12,8 @@ objects = AbstractBinder AbstractBinding AbstractExtraction \ AbstractExtractor AbstractPreparation AbstractPrepare \ BLOB BLOBStream DataException Limit MetaColumn \ PooledSessionHolder PooledSessionImpl \ - Range RecordSet Row RowIterator Session SessionFactory SessionImpl \ + Range RecordSet Row RowFormatter RowIterator \ + Session SessionFactory SessionImpl \ Connector SessionPool Statement StatementCreator StatementImpl target = PocoData diff --git a/Data/include/Poco/Data/Row.h b/Data/include/Poco/Data/Row.h index ac8b93da2..377080e9c 100644 --- a/Data/include/Poco/Data/Row.h +++ b/Data/include/Poco/Data/Row.h @@ -41,6 +41,7 @@ #include "Poco/Data/Data.h" +#include "Poco/Data/RowFormatter.h" #include "Poco/DynamicAny.h" #include "Poco/Tuple.h" #include "Poco/SharedPtr.h" @@ -80,6 +81,7 @@ class Data_API Row public: typedef std::vector NameVec; typedef SharedPtr > NameVecPtr; + typedef std::vector ValueVec; enum ComparisonType { @@ -93,7 +95,7 @@ public: Row(); /// Creates the Row. - explicit Row(NameVecPtr pNames); + explicit Row(NameVecPtr pNames, RowFormatter* pFormatter = 0); /// Creates the Row. ~Row(); @@ -199,8 +201,10 @@ public: NameVecPtr names(); /// Returns the shared pointer to names vector. + const ValueVec& values(); + /// Returns the const reference to values vector. + private: - typedef std::vector ValueVec; typedef Tuple SortTuple; typedef std::vector SortMap; /// The type for map holding fields used for sorting criteria. @@ -212,10 +216,10 @@ private: bool isEqualSize(const Row& other) const; bool isEqualType(const Row& other) const; - std::string _separator; - NameVecPtr _pNames; - ValueVec _values; - SortMap _sortFields; + NameVecPtr _pNames; + ValueVec _values; + SortMap _sortFields; + mutable SharedPtr _pFormatter; }; @@ -238,18 +242,18 @@ inline void Row::reset() } -inline void Row::separator(const std::string& sep) -{ - _separator = sep; -} - - inline Row::NameVecPtr Row::names() { return _pNames; } +inline const Row::ValueVec& Row::values() +{ + return _values; +} + + inline DynamicAny& Row::operator [] (std::size_t col) { return get(col); diff --git a/Data/include/Poco/Data/RowFormatter.h b/Data/include/Poco/Data/RowFormatter.h new file mode 100644 index 000000000..889d82928 --- /dev/null +++ b/Data/include/Poco/Data/RowFormatter.h @@ -0,0 +1,103 @@ +// +// RowFormatter.h +// +// $Id: //poco/Main/Data/include/Poco/Data/RowFormatter.h#1 $ +// +// Library: Data +// Package: DataCore +// Module: RowFormatter +// +// Definition of the RowFormatter class. +// +// 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. +// + + +#ifndef Data_RowFormatter_INCLUDED +#define Data_RowFormatter_INCLUDED + + +#include "Poco/Data/Data.h" + + +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 + /// strategies, inherit from this class and override formatNames() + /// and formaValues() member functions. +{ +public: + static const std::string EOL; + + RowFormatter(Row* pRow = 0); + /// Creates the RowFormatter. + + virtual ~RowFormatter(); + /// Destroys the RowFormatter. + + void setRow(Row* pRow); + /// Assigns the row to this formatter. + + virtual std::string& formatNames(std::string& names); + /// Formats the row field names. + + virtual std::string& formatValues(std::string& values); + /// Formats the row values. + +private: + RowFormatter(const RowFormatter&); + RowFormatter& operator = (const RowFormatter&); + + Row* _pRow; + std::string _separator; +}; + + +/// +/// inlines +/// + + +inline void RowFormatter::setRow(Row* pRow) +{ + poco_check_ptr (pRow); + _pRow = pRow; +} + + +} } // namespace Poco::Data + + +#endif // Data_RowFormatter_INCLUDED diff --git a/Data/src/Row.cpp b/Data/src/Row.cpp index 8c3f83589..016be6ad9 100644 --- a/Data/src/Row.cpp +++ b/Data/src/Row.cpp @@ -42,14 +42,6 @@ namespace Poco { namespace Data { -#if defined(POCO_OS_FAMILY_WINDOWS) -const std::string Row::EOL = "\r\n"; -#else -const std::string Row::EOL = "\n"; -#endif - - - std::ostream& operator << (std::ostream &os, const Row& row) { os << row.valuesToString(); @@ -57,16 +49,23 @@ std::ostream& operator << (std::ostream &os, const Row& row) } -Row::Row(): _separator("\t"), _pNames(0) +Row::Row(): + _pNames(0), + _pFormatter(new RowFormatter(this)) { } -Row::Row(NameVecPtr pNames): _separator("\t"), _pNames(pNames) +Row::Row(NameVecPtr pNames, RowFormatter* pFormatter): + _pNames(pNames), + _pFormatter(pFormatter) { if (!_pNames) throw NullPointerException(); + if (!_pFormatter) _pFormatter = new RowFormatter(this); + else _pFormatter->setRow(this); + _values.resize(_pNames->size()); addSortField(0); } @@ -319,17 +318,8 @@ bool Row::operator < (const Row& other) const const std::string Row::valuesToString() const { - std::string strValues; - ValueVec::const_iterator it = _values.begin(); - ValueVec::const_iterator end = _values.end(); - for (; it != end; ++it) - { - strValues.append(it->convert()); - strValues.append(_separator); - } - strValues.replace(strValues.find_last_of(_separator), _separator.length(), EOL); - - return strValues; + std::string values; + return _pFormatter->formatValues(values); } @@ -338,17 +328,8 @@ const std::string Row::namesToString() const if (!_pNames) throw NullPointerException(); - std::string strNames; - NameVec::const_iterator it = _pNames->begin(); - NameVec::const_iterator end = _pNames->end(); - for (; it != end; ++it) - { - strNames.append(*it); - strNames.append(_separator); - } - strNames.replace(strNames.find_last_of(_separator), _separator.length(), EOL); - - return strNames; + std::string names; + return _pFormatter->formatNames(names); } diff --git a/Data/src/RowFormatter.cpp b/Data/src/RowFormatter.cpp new file mode 100644 index 000000000..9a873a009 --- /dev/null +++ b/Data/src/RowFormatter.cpp @@ -0,0 +1,103 @@ +// +// 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/RowFormatter.h" +#include "Poco/Data/Row.h" +#include "Poco/Exception.h" + + +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(Row* pRow): + _pRow(pRow), + _separator("\t") +{ +} + + +RowFormatter::~RowFormatter() +{ +} + + +std::string& RowFormatter::formatNames(std::string& names) +{ + if (!_pRow) + throw NullPointerException("Null row."); + + Row::NameVec::const_iterator it = _pRow->names()->begin(); + Row::NameVec::const_iterator end = _pRow->names()->end(); + for (; it != end; ++it) + { + names.append(*it); + names.append(_separator); + } + names.replace(names.find_last_of(_separator), _separator.length(), EOL); + + return names; +} + + +std::string& RowFormatter::formatValues(std::string& values) +{ + if (!_pRow) + throw NullPointerException("Null row."); + + Row::ValueVec::const_iterator it = _pRow->values().begin(); + Row::ValueVec::const_iterator end = _pRow->values().end(); + for (; it != end; ++it) + { + values.append(it->convert()); + values.append(_separator); + } + values.replace(values.find_last_of(_separator), _separator.length(), EOL); + + return values; +} + + +} } // namespace Poco::Data diff --git a/Data/testsuite/src/DataTest.cpp b/Data/testsuite/src/DataTest.cpp index ec0daaaf7..79fb3a957 100644 --- a/Data/testsuite/src/DataTest.cpp +++ b/Data/testsuite/src/DataTest.cpp @@ -680,16 +680,6 @@ void DataTest::testRow() assert (row[4] == 4); assert (row["field4"] == 4); - assert (row.namesToString() == std::string("field0\tfield1\tfield2\tfield3\tfield4") + Row::EOL); - std::ostringstream os; - os << row; - assert (os.str() == std::string("0\t1\t2\t3\t4") + Row::EOL); - row.separator(","); - assert (row.namesToString() == std::string("field0,field1,field2,field3,field4") + Row::EOL); - os.str(""); - os << row; - assert (os.str() == std::string("0,1,2,3,4") + Row::EOL); - Row row2; row2.append("field0", 5); @@ -866,6 +856,25 @@ void DataTest::testRowStrictWeak(const Row& row1, const Row& row2, const Row& ro } +void DataTest::testRowFormat() +{ + Row row1; + row1.append("field0", 0); + row1.append("field1", 1); + row1.append("field2", 2); + row1.append("field3", 3); + row1.append("field4", 4); + + std::ostringstream os; + os << "field0\tfield1\tfield2\tfield3\tfield4" << RowFormatter::EOL; + assert (row1.namesToString() == os.str()); + + os.str(""); + os << "0\t1\t2\t3\t4" << RowFormatter::EOL; + assert (row1.valuesToString() == os.str()); +} + + void DataTest::setUp() { } @@ -891,6 +900,7 @@ CppUnit::Test* DataTest::suite() CppUnit_addTest(pSuite, DataTest, testColumnList); CppUnit_addTest(pSuite, DataTest, testRow); CppUnit_addTest(pSuite, DataTest, testRowSort); + CppUnit_addTest(pSuite, DataTest, testRowFormat); return pSuite; } diff --git a/Data/testsuite/src/DataTest.h b/Data/testsuite/src/DataTest.h index 9057b67c6..dc2ed5d64 100644 --- a/Data/testsuite/src/DataTest.h +++ b/Data/testsuite/src/DataTest.h @@ -60,6 +60,7 @@ public: void testColumnList(); void testRow(); void testRowSort(); + void testRowFormat(); void setUp(); void tearDown();