Browse Source

RowFormatter strategy

Aleksandar Fabijanic 18 years ago
parent
commit
1d774be07b

+ 12 - 6
Data/Data_VS71.vcproj

@@ -187,6 +187,9 @@
 				<File
 					RelativePath=".\include\Poco\Data\Common.h">
 				</File>
+				<File
+					RelativePath=".\include\Poco\Data\Connector.h">
+				</File>
 				<File
 					RelativePath=".\include\Poco\Data\Data.h">
 				</File>
@@ -214,6 +217,9 @@
 				<File
 					RelativePath=".\include\Poco\Data\Row.h">
 				</File>
+				<File
+					RelativePath=".\include\Poco\Data\RowFormatter.h">
+				</File>
 				<File
 					RelativePath=".\include\Poco\Data\RowIterator.h">
 				</File>
@@ -226,9 +232,6 @@
 				<File
 					RelativePath=".\include\Poco\Data\SessionImpl.h">
 				</File>
-				<File
-					RelativePath=".\include\Poco\Data\Connector.h">
-				</File>
 				<File
 					RelativePath=".\include\Poco\Data\Statement.h">
 				</File>
@@ -269,6 +272,9 @@
 				<File
 					RelativePath=".\include\Poco\Data\BLOBStream.h">
 				</File>
+				<File
+					RelativePath=".\src\Connector.cpp">
+				</File>
 				<File
 					RelativePath=".\src\DataException.cpp">
 				</File>
@@ -287,6 +293,9 @@
 				<File
 					RelativePath=".\src\Row.cpp">
 				</File>
+				<File
+					RelativePath=".\src\RowFormatter.cpp">
+				</File>
 				<File
 					RelativePath=".\src\RowIterator.cpp">
 				</File>
@@ -299,9 +308,6 @@
 				<File
 					RelativePath=".\src\SessionImpl.cpp">
 				</File>
-				<File
-					RelativePath=".\src\Connector.cpp">
-				</File>
 				<File
 					RelativePath=".\src\Statement.cpp">
 				</File>

+ 8 - 0
Data/Data_VS80.vcproj

@@ -297,6 +297,10 @@
 					RelativePath=".\include\Poco\Data\Row.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\Poco\Data\RowFormatter.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\Poco\Data\RowIterator.h"
 					>
@@ -393,6 +397,10 @@
 					RelativePath=".\src\Row.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\RowFormatter.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\RowIterator.cpp"
 					>

+ 2 - 1
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

+ 14 - 10
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<std::string> NameVec;
 	typedef SharedPtr<std::vector<std::string> > NameVecPtr;
+	typedef std::vector<DynamicAny> 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<DynamicAny> ValueVec;
 	typedef Tuple<std::size_t, ComparisonType> SortTuple;
 	typedef std::vector<SortTuple> 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<RowFormatter> _pFormatter;
 };
 
 
@@ -238,15 +242,15 @@ inline void Row::reset()
 }
 
 
-inline void Row::separator(const std::string& sep)
+inline Row::NameVecPtr Row::names()
 {
-	_separator = sep;
+	return _pNames;
 }
 
 
-inline Row::NameVecPtr Row::names()
+inline const Row::ValueVec& Row::values()
 {
-	return _pNames;
+	return _values;
 }
 
 

+ 103 - 0
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

+ 13 - 32
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<std::string>());
-		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);
 }
 
 

+ 103 - 0
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<std::string>());
+		values.append(_separator);
+	}
+	values.replace(values.find_last_of(_separator), _separator.length(), EOL);
+
+	return values;
+}
+
+
+} } // namespace Poco::Data

+ 20 - 10
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;
 }

+ 1 - 0
Data/testsuite/src/DataTest.h

@@ -60,6 +60,7 @@ public:
 	void testColumnList();
 	void testRow();
 	void testRowSort();
+	void testRowFormat();
 
 	void setUp();
 	void tearDown();