mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-25 18:22:59 +02:00 
			
		
		
		
	ODBC generic nulls, added Row and RowIterator
This commit is contained in:
		| @@ -293,6 +293,14 @@ | |||||||
| 					RelativePath=".\include\Poco\Data\RecordSet.h" | 					RelativePath=".\include\Poco\Data\RecordSet.h" | ||||||
| 					> | 					> | ||||||
| 				</File> | 				</File> | ||||||
|  | 				<File | ||||||
|  | 					RelativePath=".\include\Poco\Data\Row.h" | ||||||
|  | 					> | ||||||
|  | 				</File> | ||||||
|  | 				<File | ||||||
|  | 					RelativePath=".\include\Poco\Data\RowIterator.h" | ||||||
|  | 					> | ||||||
|  | 				</File> | ||||||
| 				<File | 				<File | ||||||
| 					RelativePath=".\include\Poco\Data\Session.h" | 					RelativePath=".\include\Poco\Data\Session.h" | ||||||
| 					> | 					> | ||||||
| @@ -381,6 +389,14 @@ | |||||||
| 					RelativePath=".\src\RecordSet.cpp" | 					RelativePath=".\src\RecordSet.cpp" | ||||||
| 					> | 					> | ||||||
| 				</File> | 				</File> | ||||||
|  | 				<File | ||||||
|  | 					RelativePath=".\src\Row.cpp" | ||||||
|  | 					> | ||||||
|  | 				</File> | ||||||
|  | 				<File | ||||||
|  | 					RelativePath=".\src\RowIterator.cpp" | ||||||
|  | 					> | ||||||
|  | 				</File> | ||||||
| 				<File | 				<File | ||||||
| 					RelativePath=".\src\Session.cpp" | 					RelativePath=".\src\Session.cpp" | ||||||
| 					> | 					> | ||||||
|   | |||||||
| @@ -215,6 +215,7 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir) | |||||||
|  |  | ||||||
| 	switch (val) | 	switch (val) | ||||||
| 	{ | 	{ | ||||||
|  | 	case NULL_GENERIC: | ||||||
| 	case NULL_INT8:	     bindNull(pos, SQL_C_STINYINT); break; | 	case NULL_INT8:	     bindNull(pos, SQL_C_STINYINT); break; | ||||||
| 	case NULL_UINT8:     bindNull(pos, SQL_C_UTINYINT); break; | 	case NULL_UINT8:     bindNull(pos, SQL_C_UTINYINT); break; | ||||||
| 	case NULL_INT16:     bindNull(pos, SQL_C_SSHORT); break; | 	case NULL_INT16:     bindNull(pos, SQL_C_SSHORT); break; | ||||||
|   | |||||||
| @@ -2068,7 +2068,7 @@ void SQLExecutor::notNulls(const std::string& sqlState) | |||||||
| { | { | ||||||
| 	try | 	try | ||||||
| 	{ | 	{ | ||||||
| 		*_pSession << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(NULL_INT8), use(NULL_FLOAT), use(NULL_STRING), now; | 		*_pSession << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now; | ||||||
| 		fail ("must fail"); | 		fail ("must fail"); | ||||||
| 	}catch (StatementException& se)  | 	}catch (StatementException& se)  | ||||||
| 	{  | 	{  | ||||||
| @@ -2083,7 +2083,7 @@ void SQLExecutor::nulls() | |||||||
| { | { | ||||||
| 	std::string funct = "nulls()"; | 	std::string funct = "nulls()"; | ||||||
|  |  | ||||||
| 	try { *_pSession << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(NULL_INT32), use(NULL_FLOAT), use(NULL_STRING), now; } | 	try { *_pSession << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now; } | ||||||
| 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | ||||||
| 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | ||||||
|  |  | ||||||
| @@ -2115,12 +2115,12 @@ void SQLExecutor::nulls() | |||||||
| 	assert (!rs.isNull("r")); | 	assert (!rs.isNull("r")); | ||||||
| 	assert (rs["v"] == "123"); | 	assert (rs["v"] == "123"); | ||||||
| 	 | 	 | ||||||
| 	try { *_pSession << "UPDATE NullTest SET v = ? WHERE i = ?", use(NULL_STRING), use(i), now; } | 	try { *_pSession << "UPDATE NullTest SET v = ? WHERE i = ?", use(null), use(i), now; } | ||||||
| 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | ||||||
| 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | ||||||
| 	i = 2; | 	i = 2; | ||||||
| 	f = 3.4; | 	f = 3.4; | ||||||
| 	try { *_pSession << "INSERT INTO NullTest (i, r, v) VALUES (?,?,?)", use(i), use(NULL_FLOAT), use(NULL_STRING), now; } | 	try { *_pSession << "INSERT INTO NullTest (i, r, v) VALUES (?,?,?)", use(i), use(null), use(null), now; } | ||||||
| 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } | ||||||
| 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } | ||||||
| 	rs = (*_pSession << "SELECT i, r, v FROM NullTest ORDER BY i ASC", now); | 	rs = (*_pSession << "SELECT i, r, v FROM NullTest ORDER BY i ASC", now); | ||||||
|   | |||||||
| @@ -43,6 +43,7 @@ | |||||||
| #include "Poco/Data/Data.h" | #include "Poco/Data/Data.h" | ||||||
| #include "Poco/Data/Extraction.h" | #include "Poco/Data/Extraction.h" | ||||||
| #include "Poco/Data/Statement.h" | #include "Poco/Data/Statement.h" | ||||||
|  | #include "Poco/Data/RowIterator.h" | ||||||
| #include "Poco/Data/BLOB.h" | #include "Poco/Data/BLOB.h" | ||||||
| #include "Poco/String.h" | #include "Poco/String.h" | ||||||
| #include "Poco/DynamicAny.h" | #include "Poco/DynamicAny.h" | ||||||
| @@ -58,7 +59,7 @@ class Session; | |||||||
|  |  | ||||||
| class Data_API RecordSet: private Statement | class Data_API RecordSet: private Statement | ||||||
| 	/// RecordSet provides access to data returned from a query. | 	/// RecordSet provides access to data returned from a query. | ||||||
| 	/// Data access indexes (row and column) are 0-based, as usual in C++. | 	/// Data access indices (row and column) are 0-based, as usual in C++. | ||||||
| 	///  | 	///  | ||||||
| 	/// Recordset provides navigation methods to iterate through the | 	/// Recordset provides navigation methods to iterate through the | ||||||
| 	/// recordset, retrieval methods to extract data, and methods | 	/// recordset, retrieval methods to extract data, and methods | ||||||
| @@ -76,6 +77,8 @@ class Data_API RecordSet: private Statement | |||||||
| 	/// a limit for the Statement. | 	/// a limit for the Statement. | ||||||
| { | { | ||||||
| public: | public: | ||||||
|  | 	typedef std::map<std::size_t, Row*> RowMap; | ||||||
|  |  | ||||||
| 	using Statement::isNull; | 	using Statement::isNull; | ||||||
|  |  | ||||||
| 	explicit RecordSet(const Statement& rStatement); | 	explicit RecordSet(const Statement& rStatement); | ||||||
| @@ -129,6 +132,10 @@ public: | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	const Row& row(std::size_t pos) const; | ||||||
|  | 		/// Returns row at position pos. | ||||||
|  | 		/// Rows are lazy-created and cached. | ||||||
|  |  | ||||||
| 	template <class T> | 	template <class T> | ||||||
| 	const T& value(std::size_t col, std::size_t row) const | 	const T& value(std::size_t col, std::size_t row) const | ||||||
| 		/// Returns the reference to data value at [col, row] location. | 		/// Returns the reference to data value at [col, row] location. | ||||||
| @@ -166,10 +173,13 @@ public: | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	DynamicAny value(std::size_t col, std::size_t row) const; | 	DynamicAny value(std::size_t col, std::size_t row) const; | ||||||
| 		/// Returns the reference to data value at column, row location. | 		/// Returns the data value at column, row location. | ||||||
|  |  | ||||||
| 	DynamicAny value(const std::string& name, std::size_t row) const; | 	DynamicAny value(const std::string& name, std::size_t row) const; | ||||||
| 		/// Returns the reference to data value at named column, row location. | 		/// Returns the data value at named column, row location. | ||||||
|  |  | ||||||
|  | 	const RowIterator& begin(); | ||||||
|  | 		/// Moves the row cursor to the first row and returns the pointer to row. | ||||||
|  |  | ||||||
| 	bool moveFirst(); | 	bool moveFirst(); | ||||||
| 		/// Moves the row cursor to the first row. | 		/// Moves the row cursor to the first row. | ||||||
| @@ -190,6 +200,9 @@ public: | |||||||
| 		/// Returns true if the row is available, or false | 		/// Returns true if the row is available, or false | ||||||
| 		/// if there are no more rows available. | 		/// if there are no more rows available. | ||||||
|  |  | ||||||
|  | 	const RowIterator& end(); | ||||||
|  | 		/// Moves the row cursor to the last row and returns null pointer. | ||||||
|  |  | ||||||
| 	bool moveLast(); | 	bool moveLast(); | ||||||
| 		/// Moves the row cursor to the last row. | 		/// Moves the row cursor to the last row. | ||||||
| 		/// | 		/// | ||||||
| @@ -263,6 +276,9 @@ private: | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	std::size_t    _currentRow; | 	std::size_t    _currentRow; | ||||||
|  | 	RowIterator*   _pBegin; | ||||||
|  | 	RowIterator*   _pEnd; | ||||||
|  | 	mutable RowMap _rowMap; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -361,6 +377,15 @@ inline bool RecordSet::isNull(const std::string& name) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline const RowIterator& RecordSet::end() | ||||||
|  | { | ||||||
|  | 	if (!_pEnd) | ||||||
|  | 		_pEnd = new RowIterator(*this); | ||||||
|  |  | ||||||
|  | 	return *_pEnd; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| } } // namespace Poco::Data | } } // namespace Poco::Data | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										169
									
								
								Data/include/Poco/Data/Row.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								Data/include/Poco/Data/Row.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | |||||||
|  | // | ||||||
|  | // Row.h | ||||||
|  | // | ||||||
|  | // $Id: //poco/Main/Data/include/Poco/Data/Row.h#7 $ | ||||||
|  | // | ||||||
|  | // Library: Data | ||||||
|  | // Package: DataCore | ||||||
|  | // Module:  Row | ||||||
|  | // | ||||||
|  | // Definition of the Row 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_Row_INCLUDED | ||||||
|  | #define Data_Row_INCLUDED | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "Poco/Data/Data.h" | ||||||
|  | #include "Poco/DynamicAny.h" | ||||||
|  | #include <vector> | ||||||
|  | #include <string> | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace Poco { | ||||||
|  | namespace Data { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class RecordSet; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Data_API Row | ||||||
|  | 	/// Row class. | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	enum Comparison | ||||||
|  | 	{ | ||||||
|  | 		COMPARE_AS_INTEGER, | ||||||
|  | 		COMPARE_AS_FLOAT, | ||||||
|  | 		COMPARE_AS_STRING | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static const std::string EOL; | ||||||
|  |  | ||||||
|  | 	Row(); | ||||||
|  | 		/// Creates the Row. | ||||||
|  |  | ||||||
|  | 	~Row(); | ||||||
|  | 		/// Destroys the Row. | ||||||
|  |  | ||||||
|  | 	DynamicAny& operator [] (std::size_t col); | ||||||
|  | 		/// Returns the reference to data value at column location. | ||||||
|  |  | ||||||
|  | 	DynamicAny& operator [] (const std::string& name); | ||||||
|  | 		/// Returns the reference to data value at named column location. | ||||||
|  |  | ||||||
|  | 	template <typename T> | ||||||
|  | 	void append(const std::string& name, const T& val) | ||||||
|  | 		/// Appends the value to the row. | ||||||
|  | 	{ | ||||||
|  | 		DynamicAny da = val; | ||||||
|  | 		_values.push_back(da); | ||||||
|  | 		_names.push_back(name); | ||||||
|  | 	} | ||||||
|  | 		 | ||||||
|  | 	std::size_t fieldCount() const; | ||||||
|  | 		/// Returns the number of fields in this row. | ||||||
|  |  | ||||||
|  | 	void reset(); | ||||||
|  | 		/// Resets the row. | ||||||
|  |  | ||||||
|  | 	void separator(const std::string& sep); | ||||||
|  | 		/// Sets the separator. | ||||||
|  |  | ||||||
|  | 	void sortField(std::size_t pos); | ||||||
|  | 		/// Sets the field used for sorting. | ||||||
|  |  | ||||||
|  | 	void sortField(const std::string& name); | ||||||
|  | 		/// Sets the field used for sorting. | ||||||
|  |  | ||||||
|  | 	const std::string& toStringN() const; | ||||||
|  | 		/// Converts the row names to string, inserting separator | ||||||
|  | 		/// string between fields and end-of-line at the end. | ||||||
|  |  | ||||||
|  | 	const std::string& toStringV() const; | ||||||
|  | 		/// Converts the row values to string, inserting separator | ||||||
|  | 		/// string between fields and end-of-line at the end. | ||||||
|  |  | ||||||
|  | 	bool operator == (const Row& other) const; | ||||||
|  | 		/// Equality operator. | ||||||
|  |  | ||||||
|  | 	bool operator != (const Row& other) const; | ||||||
|  | 		/// Inequality operator. | ||||||
|  |  | ||||||
|  | 	bool operator < (const Row& other) const; | ||||||
|  | 		/// Less-then operator. | ||||||
|  |  | ||||||
|  | 	void comparison(Comparison comp); | ||||||
|  | 		/// Sets the type of comparison. | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	std::size_t getPosition(const std::string& name); | ||||||
|  | 	bool isEqualSize(const Row& other) const; | ||||||
|  | 	bool isEqualType(const Row& other) const; | ||||||
|  |  | ||||||
|  | 	std::vector<std::string> _names; | ||||||
|  | 	std::vector<DynamicAny>  _values; | ||||||
|  | 	mutable std::string      _strValues; | ||||||
|  | 	mutable std::string      _strNames; | ||||||
|  | 	std::string              _separator; | ||||||
|  | 	std::size_t              _sortField; | ||||||
|  | 	Comparison               _comparison; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Data_API std::ostream& operator << (std::ostream &os, const Row& row); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | /// inlines | ||||||
|  | /// | ||||||
|  | inline std::size_t Row::fieldCount() const | ||||||
|  | { | ||||||
|  | 	return _values.size(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void Row::reset() | ||||||
|  | { | ||||||
|  | 	_names.clear(); | ||||||
|  | 	_values.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline void Row::separator(const std::string& sep) | ||||||
|  | { | ||||||
|  | 	_separator = sep; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } } // namespace Poco::Data | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif // Data_Row_INCLUDED | ||||||
							
								
								
									
										121
									
								
								Data/include/Poco/Data/RowIterator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								Data/include/Poco/Data/RowIterator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | // | ||||||
|  | // RowIterator.h | ||||||
|  | // | ||||||
|  | // $Id: //poco/Main/Data/include/Poco/Data/RowIterator.h#7 $ | ||||||
|  | // | ||||||
|  | // Library: Data | ||||||
|  | // Package: DataCore | ||||||
|  | // Module:  RowIterator | ||||||
|  | // | ||||||
|  | // Definition of the RowIterator 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_RowIterator_INCLUDED | ||||||
|  | #define Data_RowIterator_INCLUDED | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "Poco/Data/Data.h" | ||||||
|  | #include "Poco/Data/Row.h" | ||||||
|  | #include "Poco/DynamicAny.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace Poco { | ||||||
|  | namespace Data { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class RecordSet; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Data_API RowIterator | ||||||
|  | 	/// RowIterator class is an interface to a row of RecordSet data. | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	RowIterator(const RecordSet& recordSet, bool isEmpty = true); | ||||||
|  | 		/// Creates the RowIterator and positions it at the beginning. | ||||||
|  |  | ||||||
|  | 	~RowIterator(); | ||||||
|  | 		/// Destroys the RowIterator. | ||||||
|  |  | ||||||
|  | 	bool operator == (const RowIterator& other); | ||||||
|  | 		/// Equality operator. | ||||||
|  |  | ||||||
|  | 	bool operator != (const RowIterator& other); | ||||||
|  | 		/// Inequality operator. | ||||||
|  |  | ||||||
|  | 	const Row& operator * () const; | ||||||
|  | 		/// Returns const reference to the current row. | ||||||
|  |  | ||||||
|  | 	const Row& operator ++ (); | ||||||
|  | 		/// Advances by one position and returns const reference  | ||||||
|  | 		/// to the current row. | ||||||
|  |  | ||||||
|  | 	const Row& operator ++ (int); | ||||||
|  | 		/// Advances by one position and returns const reference  | ||||||
|  | 		/// to the previous current row. | ||||||
|  |  | ||||||
|  | 	const Row& operator -- (); | ||||||
|  | 		/// Goes back by one position and returns const reference  | ||||||
|  | 		/// to the current row. | ||||||
|  |  | ||||||
|  | 	const Row& operator -- (int); | ||||||
|  | 		/// Goes back by one position and returns const reference  | ||||||
|  | 		/// to the previous current row. | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	RowIterator(); | ||||||
|  |  | ||||||
|  | 	void increment(); | ||||||
|  | 	void decrement(); | ||||||
|  |  | ||||||
|  | 	static const int POSITION_END; | ||||||
|  |  | ||||||
|  | 	std::size_t _position; | ||||||
|  | 	const RecordSet& _recordSet; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | /// inlines | ||||||
|  | /// | ||||||
|  | inline bool RowIterator::operator == (const RowIterator& other) | ||||||
|  | { | ||||||
|  | 	return _position == other._position; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | inline bool RowIterator::operator != (const RowIterator& other) | ||||||
|  | { | ||||||
|  | 	return _position != other._position; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } } // namespace Poco::Data | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif // Data_RowIterator_INCLUDED | ||||||
| @@ -44,20 +44,31 @@ namespace Data { | |||||||
|  |  | ||||||
| RecordSet::RecordSet(const Statement& rStatement):  | RecordSet::RecordSet(const Statement& rStatement):  | ||||||
| 	Statement(rStatement), | 	Statement(rStatement), | ||||||
| 	_currentRow(0) | 	_currentRow(0), | ||||||
|  | 	_pBegin(0), | ||||||
|  | 	_pEnd(0) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| RecordSet::RecordSet(Session& rSession, const std::string& query):  | RecordSet::RecordSet(Session& rSession, const std::string& query):  | ||||||
| 	Statement((rSession << query, now)), | 	Statement((rSession << query, now)), | ||||||
| 	_currentRow(0) | 	_currentRow(0), | ||||||
|  | 	_pBegin(0), | ||||||
|  | 	_pEnd(0) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| RecordSet::~RecordSet() | RecordSet::~RecordSet() | ||||||
| { | { | ||||||
|  | 	delete _pBegin; | ||||||
|  | 	delete _pEnd; | ||||||
|  |  | ||||||
|  | 	RowMap::iterator it = _rowMap.begin(); | ||||||
|  | 	RowMap::iterator end = _rowMap.end(); | ||||||
|  | 	for (; it != end; ++it) | ||||||
|  | 		delete it->second; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -107,6 +118,36 @@ DynamicAny RecordSet::value(const std::string& name, std::size_t row) const | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const RowIterator& RecordSet::begin() | ||||||
|  | { | ||||||
|  | 	if (!_pBegin) | ||||||
|  | 		_pBegin = new RowIterator(*this, 0 == extractions().size()); | ||||||
|  |  | ||||||
|  | 	return *_pBegin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RecordSet::row(std::size_t pos) const | ||||||
|  | { | ||||||
|  | 	if (pos > rowCount() - 1) | ||||||
|  | 		throw RangeException("Invalid recordset row requested."); | ||||||
|  |  | ||||||
|  | 	RowMap::iterator it = _rowMap.find(pos); | ||||||
|  | 	Row* pRow = 0; | ||||||
|  | 	if (it == _rowMap.end()) | ||||||
|  | 	{ | ||||||
|  | 		pRow = new Row; | ||||||
|  | 		for (std::size_t i = 0; i < columnCount(); ++i) | ||||||
|  | 			pRow->append(metaColumn(static_cast<UInt32>(pos)).name(), value(i, pos)); | ||||||
|  |  | ||||||
|  | 		_rowMap.insert(RowMap::value_type(pos, pRow)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	poco_check_ptr (pRow); | ||||||
|  | 	return *pRow; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| bool RecordSet::moveFirst() | bool RecordSet::moveFirst() | ||||||
| { | { | ||||||
| 	if (rowCount() > 0) | 	if (rowCount() > 0) | ||||||
|   | |||||||
							
								
								
									
										245
									
								
								Data/src/Row.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								Data/src/Row.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | |||||||
|  | // | ||||||
|  | // Row.cpp | ||||||
|  | // | ||||||
|  | // $Id: //poco/Main/Data/src/Row.cpp#2 $ | ||||||
|  | // | ||||||
|  | // Library: Data | ||||||
|  | // Package: DataCore | ||||||
|  | // Module:  Row | ||||||
|  | // | ||||||
|  | // 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/Row.h" | ||||||
|  | #include "Poco/Exception.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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.toStringV(); | ||||||
|  |       return os; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Row::Row():  | ||||||
|  | 	_separator("\t"),  | ||||||
|  | 	_sortField(0), | ||||||
|  | 	_comparison(COMPARE_AS_STRING) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Row::~Row() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DynamicAny& Row::operator [] (std::size_t col) | ||||||
|  | { | ||||||
|  | 	try | ||||||
|  | 	{ | ||||||
|  | 		return _values.at(col); | ||||||
|  | 	}catch (std::range_error& re) | ||||||
|  | 	{ | ||||||
|  | 		throw RangeException(re.what()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DynamicAny& Row::operator [] (const std::string& name) | ||||||
|  | { | ||||||
|  | 	std::size_t col = getPosition(name); | ||||||
|  | 	return (*this)[col]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | std::size_t Row::getPosition(const std::string& name) | ||||||
|  | { | ||||||
|  | 	std::vector<std::string>::const_iterator it = _names.begin(); | ||||||
|  | 	std::vector<std::string>::const_iterator end = _names.end(); | ||||||
|  | 	std::size_t col = 0; | ||||||
|  | 	for (; it != end; ++it, ++col) | ||||||
|  | 		if (name == *it) break; | ||||||
|  | 	 | ||||||
|  | 	return col; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Row::sortField(std::size_t pos) | ||||||
|  | { | ||||||
|  | 	poco_assert (pos <= _values.size()); | ||||||
|  | 	_sortField = pos; | ||||||
|  |  | ||||||
|  | 	if ((_values[pos].type() == typeid(Poco::Int8))   || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::UInt8))  || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::Int16))  || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::UInt16)) || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::Int32))  || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::UInt32)) || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::Int64))  || | ||||||
|  | 		(_values[pos].type() == typeid(Poco::UInt64)) || | ||||||
|  | 		(_values[pos].type() == typeid(bool))) | ||||||
|  | 	{ | ||||||
|  | 		comparison(COMPARE_AS_INTEGER); | ||||||
|  | 	} | ||||||
|  | 	else if ((_values[pos].type() == typeid(float)) || | ||||||
|  | 		(_values[pos].type() == typeid(double))) | ||||||
|  | 	{ | ||||||
|  | 		comparison(COMPARE_AS_FLOAT); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		comparison(COMPARE_AS_STRING); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Row::sortField(const std::string& name) | ||||||
|  | { | ||||||
|  | 	sortField(getPosition(name)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Row::isEqualSize(const Row& other) const | ||||||
|  | { | ||||||
|  | 	return (other._values.size() == _values.size()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Row::isEqualType(const Row& other) const | ||||||
|  | { | ||||||
|  | 	std::vector<DynamicAny>::const_iterator it = _values.begin(); | ||||||
|  | 	std::vector<DynamicAny>::const_iterator end = _values.end(); | ||||||
|  | 	for (int i = 0; it != end; ++it, ++i) | ||||||
|  | 	{ | ||||||
|  | 		if (it->type() != other._values[i].type()) | ||||||
|  | 			return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Row::comparison(Comparison comp) | ||||||
|  | { | ||||||
|  | 	_comparison = comp; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Row::operator == (const Row& other) const | ||||||
|  | { | ||||||
|  | 	if (!isEqualSize(other)) return false; | ||||||
|  | 	if (!isEqualType(other)) return false; | ||||||
|  |  | ||||||
|  | 	std::vector<DynamicAny>::const_iterator it = _values.begin(); | ||||||
|  | 	std::vector<DynamicAny>::const_iterator end = _values.end(); | ||||||
|  | 	for (int i = 0; it != end; ++it, ++i) | ||||||
|  | 	{ | ||||||
|  | 		if ((*it).convert<std::string>() != other._values[i].convert<std::string>()) | ||||||
|  | 			return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Row::operator != (const Row& other) const | ||||||
|  | { | ||||||
|  | 	return !(*this == other); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Row::operator < (const Row& other) const | ||||||
|  | { | ||||||
|  | 	if (_sortField != other._sortField) | ||||||
|  | 		throw InvalidAccessException("Rows compared have different sorting criteria."); | ||||||
|  |  | ||||||
|  | 	switch (_comparison) | ||||||
|  | 	{ | ||||||
|  | 	case COMPARE_AS_INTEGER: | ||||||
|  | 		return (_values[_sortField].convert<Poco::Int64>() <  | ||||||
|  | 			other._values[other._sortField].convert<Poco::Int64>()); | ||||||
|  |  | ||||||
|  | 	case COMPARE_AS_FLOAT: | ||||||
|  | 		return (_values[_sortField].convert<double>() <  | ||||||
|  | 			other._values[other._sortField].convert<double>()); | ||||||
|  |  | ||||||
|  | 	case COMPARE_AS_STRING: | ||||||
|  | 		return (_values[_sortField].convert<std::string>() <  | ||||||
|  | 			other._values[other._sortField].convert<std::string>()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	throw IllegalStateException("Unknown comparison mode."); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const std::string& Row::toStringV() const | ||||||
|  | { | ||||||
|  | 	_strValues.clear(); | ||||||
|  | 	std::vector<DynamicAny>::const_iterator it = _values.begin(); | ||||||
|  | 	std::vector<DynamicAny>::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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const std::string& Row::toStringN() const | ||||||
|  | { | ||||||
|  | 	_strNames.clear(); | ||||||
|  | 	std::vector<std::string>::const_iterator it = _names.begin(); | ||||||
|  | 	std::vector<std::string>::const_iterator end = _names.end(); | ||||||
|  | 	for (; it != end; ++it) | ||||||
|  | 	{ | ||||||
|  | 		_strNames.append(*it); | ||||||
|  | 		_strNames.append(_separator); | ||||||
|  | 	} | ||||||
|  | 	_strNames.replace(_strNames.find_last_of(_separator), _separator.length(), EOL); | ||||||
|  |  | ||||||
|  | 	return _strNames; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } } // namespace Poco::Data | ||||||
							
								
								
									
										118
									
								
								Data/src/RowIterator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								Data/src/RowIterator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | |||||||
|  | // | ||||||
|  | // RowIterator.cpp | ||||||
|  | // | ||||||
|  | // $Id: //poco/Main/Data/src/RowIterator.cpp#2 $ | ||||||
|  | // | ||||||
|  | // Library: Data | ||||||
|  | // Package: DataCore | ||||||
|  | // Module:  RowIterator | ||||||
|  | // | ||||||
|  | // 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/RowIterator.h" | ||||||
|  | #include "Poco/Data/RecordSet.h" | ||||||
|  | #undef min | ||||||
|  | #undef max | ||||||
|  | #include <limits> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace Poco { | ||||||
|  | namespace Data { | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const int RowIterator::POSITION_END = std::numeric_limits<std::size_t>::max(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RowIterator::RowIterator(const RecordSet& recordSet, bool isEmpty):  | ||||||
|  | 	_position(isEmpty ? POSITION_END : 0), | ||||||
|  | 	_recordSet(recordSet) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RowIterator::~RowIterator() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void RowIterator::increment() | ||||||
|  | { | ||||||
|  | 	if (POSITION_END == _position) | ||||||
|  | 		throw RangeException("End of iterator reached."); | ||||||
|  |  | ||||||
|  | 	if (_position < _recordSet.rowCount() - 1) | ||||||
|  | 		++_position; | ||||||
|  | 	else | ||||||
|  | 		_position = POSITION_END; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void RowIterator::decrement() | ||||||
|  | { | ||||||
|  | 	if (0 == _position) | ||||||
|  | 		throw RangeException("End of iterator reached."); | ||||||
|  |  | ||||||
|  | 	--_position; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RowIterator::operator * () const | ||||||
|  | { | ||||||
|  | 	return _recordSet.row(_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RowIterator::operator ++ () | ||||||
|  | { | ||||||
|  | 	increment(); | ||||||
|  | 	return _recordSet.row(_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RowIterator::operator ++ (int) | ||||||
|  | { | ||||||
|  | 	increment(); | ||||||
|  | 	return _recordSet.row(_position - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RowIterator::operator -- () | ||||||
|  | { | ||||||
|  | 	decrement(); | ||||||
|  | 	return _recordSet.row(_position); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const Row& RowIterator::operator -- (int) | ||||||
|  | { | ||||||
|  | 	decrement(); | ||||||
|  | 	return _recordSet.row(_position + 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } } // namespace Poco::Data | ||||||
| @@ -38,12 +38,15 @@ | |||||||
| #include "Poco/Data/BLOBStream.h" | #include "Poco/Data/BLOBStream.h" | ||||||
| #include "Poco/Data/MetaColumn.h" | #include "Poco/Data/MetaColumn.h" | ||||||
| #include "Poco/Data/Column.h" | #include "Poco/Data/Column.h" | ||||||
|  | #include "Poco/Data/Row.h" | ||||||
| #include "Connector.h" | #include "Connector.h" | ||||||
| #include "Poco/BinaryReader.h" | #include "Poco/BinaryReader.h" | ||||||
| #include "Poco/BinaryWriter.h" | #include "Poco/BinaryWriter.h" | ||||||
| #include "Poco/Types.h" | #include "Poco/Types.h" | ||||||
| #include "Poco/Exception.h" | #include "Poco/Exception.h" | ||||||
| #include <cstring> | #include <cstring> | ||||||
|  | #include <sstream> | ||||||
|  | #include <map> | ||||||
|  |  | ||||||
|  |  | ||||||
| using namespace Poco::Data; | using namespace Poco::Data; | ||||||
| @@ -570,6 +573,84 @@ void DataTest::testColumnList() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void DataTest::testRow() | ||||||
|  | { | ||||||
|  | 	Row row; | ||||||
|  |  | ||||||
|  | 	row.append("field0", 0); | ||||||
|  | 	row.append("field1", 1); | ||||||
|  | 	row.append("field2", 2); | ||||||
|  | 	row.append("field3", 3); | ||||||
|  | 	row.append("field4", 4); | ||||||
|  |  | ||||||
|  | 	assert (5 == row.fieldCount()); | ||||||
|  | 	assert (row[0] == 0); | ||||||
|  | 	assert (row["field0"] == 0); | ||||||
|  | 	assert (row[1] == 1); | ||||||
|  | 	assert (row["field1"] == 1); | ||||||
|  | 	assert (row[2] == 2); | ||||||
|  | 	assert (row["field2"] == 2); | ||||||
|  | 	assert (row[3] == 3); | ||||||
|  | 	assert (row["field3"] == 3); | ||||||
|  | 	assert (row[4] == 4); | ||||||
|  | 	assert (row["field4"] == 4); | ||||||
|  |  | ||||||
|  | 	assert (row.toStringN() == 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.toStringN() == 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); | ||||||
|  | 	row2.append("field1", 4); | ||||||
|  | 	row2.append("field2", 3); | ||||||
|  | 	row2.append("field3", 2); | ||||||
|  | 	row2.append("field4", 1); | ||||||
|  |  | ||||||
|  | 	assert (row != row2); | ||||||
|  |  | ||||||
|  | 	std::map<Row, int> rowMap; | ||||||
|  | 	rowMap.insert(std::map<Row, int>::value_type(row2, 0)); | ||||||
|  | 	rowMap.insert(std::map<Row, int>::value_type(row, 1)); | ||||||
|  | 	std::map<Row, int>::iterator it = rowMap.begin(); | ||||||
|  | 	assert (row == it->first); | ||||||
|  | 	++it; | ||||||
|  | 	assert (row2 == it->first); | ||||||
|  |  | ||||||
|  | 	rowMap.clear(); | ||||||
|  | 	row.sortField("field4"); | ||||||
|  | 	rowMap.insert(std::map<Row, int>::value_type(row, 0)); | ||||||
|  | 	try | ||||||
|  | 	{ | ||||||
|  | 		rowMap.insert(std::map<Row, int>::value_type(row2, 1)); | ||||||
|  | 		fail ("must fail"); | ||||||
|  | 	}catch (InvalidAccessException&) {} | ||||||
|  |  | ||||||
|  | 	row2.sortField("field4"); | ||||||
|  | 	rowMap.insert(std::map<Row, int>::value_type(row2, 1)); | ||||||
|  | 	it = rowMap.begin(); | ||||||
|  | 	assert (row2 == it->first); | ||||||
|  | 	++it; | ||||||
|  | 	assert (row == it->first); | ||||||
|  |  | ||||||
|  | 	Row row3; | ||||||
|  |  | ||||||
|  | 	row3.append("field0", 0); | ||||||
|  | 	row3.append("field1", 1); | ||||||
|  | 	row3.append("field2", 2); | ||||||
|  | 	row3.append("field3", 3); | ||||||
|  | 	row3.append("field4", 4); | ||||||
|  |  | ||||||
|  | 	assert (row3 == row); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void DataTest::setUp() | void DataTest::setUp() | ||||||
| { | { | ||||||
| } | } | ||||||
| @@ -592,6 +673,7 @@ CppUnit::Test* DataTest::suite() | |||||||
| 	CppUnit_addTest(pSuite, DataTest, testColumnVector); | 	CppUnit_addTest(pSuite, DataTest, testColumnVector); | ||||||
| 	CppUnit_addTest(pSuite, DataTest, testColumnDeque); | 	CppUnit_addTest(pSuite, DataTest, testColumnDeque); | ||||||
| 	CppUnit_addTest(pSuite, DataTest, testColumnList); | 	CppUnit_addTest(pSuite, DataTest, testColumnList); | ||||||
|  | 	CppUnit_addTest(pSuite, DataTest, testRow); | ||||||
|  |  | ||||||
| 	return pSuite; | 	return pSuite; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -56,6 +56,7 @@ public: | |||||||
| 	void testColumnVector(); | 	void testColumnVector(); | ||||||
| 	void testColumnDeque(); | 	void testColumnDeque(); | ||||||
| 	void testColumnList(); | 	void testColumnList(); | ||||||
|  | 	void testRow(); | ||||||
|  |  | ||||||
| 	void setUp(); | 	void setUp(); | ||||||
| 	void tearDown(); | 	void tearDown(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Aleksandar Fabijanic
					Aleksandar Fabijanic