// // Row.cpp // // $Id: //poco/Main/Data/src/Row.cpp#1 $ // // 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/Data/SimpleRowFormatter.h" #include "Poco/Exception.h" namespace Poco { namespace Data { std::ostream& operator << (std::ostream &os, const Row& row) { os << row.valuesToString(); return os; } Row::Row(): _pNames(0), _pFormatter(new SimpleRowFormatter) { } Row::Row(NameVecPtr pNames, const RowFormatterPtr& pFormatter): _pNames(pNames) { if (!_pNames) throw NullPointerException(); setFormatter(pFormatter); _values.resize(_pNames->size()); addSortField(0); } Row::~Row() { } DynamicAny& Row::get(std::size_t col) { try { return _values.at(col); }catch (std::out_of_range& re) { throw RangeException(re.what()); } } std::size_t Row::getPosition(const std::string& name) { if (!_pNames) throw NullPointerException(); NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator end = _pNames->end(); std::size_t col = 0; for (; it != end; ++it, ++col) if (name == *it) break; if (it == end) throw NotFoundException(name); return col; } void Row::addSortField(std::size_t pos) { poco_assert (pos <= _values.size()); SortMap::iterator it = _sortFields.begin(); SortMap::iterator end = _sortFields.end(); for (; it != end; ++it) { if (it->get<0>() == pos) throw InvalidAccessException("Field already in comparison set."); } ComparisonType ct; 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))) { ct = COMPARE_AS_INTEGER; } else if ((_values[pos].type() == typeid(float)) || (_values[pos].type() == typeid(double))) { ct = COMPARE_AS_FLOAT; } else { ct = COMPARE_AS_STRING; } _sortFields.push_back(SortTuple(pos, ct)); } void Row::addSortField(const std::string& name) { addSortField(getPosition(name)); } void Row::removeSortField(std::size_t pos) { SortMap::iterator it = _sortFields.begin(); SortMap::iterator end = _sortFields.end(); for (; it != end; ++it) { if (it->get<0>() == pos) { _sortFields.erase(it); return; } } } void Row::removeSortField(const std::string& name) { removeSortField(getPosition(name)); } void Row::replaceSortField(std::size_t oldPos, std::size_t newPos) { poco_assert (oldPos <= _values.size()); poco_assert (newPos <= _values.size()); ComparisonType ct; if ((_values[newPos].type() == typeid(Poco::Int8)) || (_values[newPos].type() == typeid(Poco::UInt8)) || (_values[newPos].type() == typeid(Poco::Int16)) || (_values[newPos].type() == typeid(Poco::UInt16)) || (_values[newPos].type() == typeid(Poco::Int32)) || (_values[newPos].type() == typeid(Poco::UInt32)) || (_values[newPos].type() == typeid(Poco::Int64)) || (_values[newPos].type() == typeid(Poco::UInt64)) || (_values[newPos].type() == typeid(bool))) { ct = COMPARE_AS_INTEGER; } else if ((_values[newPos].type() == typeid(float)) || (_values[newPos].type() == typeid(double))) { ct = COMPARE_AS_FLOAT; } else { ct = COMPARE_AS_STRING; } SortMap::iterator it = _sortFields.begin(); SortMap::iterator end = _sortFields.end(); for (; it != end; ++it) { if (it->get<0>() == oldPos) { *it = SortTuple(newPos, ct); return; } } throw NotFoundException("Field not found"); } void Row::replaceSortField(const std::string& oldName, const std::string& newName) { replaceSortField(getPosition(oldName), getPosition(newName)); } void Row::resetSort() { _sortFields.clear(); if (_values.size()) addSortField(0); } bool Row::isEqualSize(const Row& other) const { return (other._values.size() == _values.size()); } bool Row::isEqualType(const Row& other) const { std::vector::const_iterator it = _values.begin(); std::vector::const_iterator end = _values.end(); for (int i = 0; it != end; ++it, ++i) { if (it->type() != other._values[i].type()) return false; } return true; } bool Row::operator == (const Row& other) const { if (!isEqualSize(other)) return false; if (!isEqualType(other)) return false; std::vector::const_iterator it = _values.begin(); std::vector::const_iterator end = _values.end(); for (int i = 0; it != end; ++it, ++i) { if ((*it).convert() != other._values[i].convert()) return false; } return true; } bool Row::operator != (const Row& other) const { return !(*this == other); } bool Row::operator < (const Row& other) const { if (_sortFields != other._sortFields) throw InvalidAccessException("Rows compared have different sorting criteria."); SortMap::const_iterator it = _sortFields.begin(); SortMap::const_iterator end = _sortFields.end(); for (; it != end; ++it) { switch (it->get<1>()) { case COMPARE_AS_INTEGER: if (_values[it->get<0>()].convert() < other._values[it->get<0>()].convert()) return true; else if (_values[it->get<0>()].convert() != other._values[it->get<0>()].convert()) return false; break; case COMPARE_AS_FLOAT: if (_values[it->get<0>()].convert() < other._values[it->get<0>()].convert()) return true; else if (_values[it->get<0>()].convert() < other._values[it->get<0>()].convert()) return false; break; case COMPARE_AS_STRING: if (_values[it->get<0>()].convert() < other._values[it->get<0>()].convert()) return true; else if (_values[it->get<0>()].convert() < other._values[it->get<0>()].convert()) return false; break; } } return false; } void Row::setFormatter(const RowFormatterPtr& pFormatter) { if (pFormatter) _pFormatter = pFormatter; else _pFormatter = new SimpleRowFormatter; } const std::string& Row::namesToString() const { if (!_pNames) throw NullPointerException(); return _pFormatter->formatNames(names(), _nameStr); } } } // namespace Poco::Data