Row and RowIterator done and tested (windows and linux)

This commit is contained in:
Aleksandar Fabijanic
2007-06-23 01:22:55 +00:00
parent 08f8448478
commit b2977d3df2
26 changed files with 745 additions and 155 deletions

View File

@@ -121,13 +121,13 @@ 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());
_pBegin = new RowIterator(*this);
return *_pBegin;
}
const Row& RecordSet::row(std::size_t pos) const
Row& RecordSet::row(std::size_t pos)
{
if (pos > rowCount() - 1)
throw RangeException("Invalid recordset row requested.");
@@ -136,12 +136,23 @@ const Row& RecordSet::row(std::size_t pos) const
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));
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));
}
else
{
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));
}
else
pRow = it->second;
poco_check_ptr (pRow);
return *pRow;

View File

@@ -1,7 +1,7 @@
//
// Row.cpp
//
// $Id: //poco/Main/Data/src/Row.cpp#2 $
// $Id: //poco/Main/Data/src/Row.cpp#1 $
//
// Library: Data
// Package: DataCore
@@ -52,60 +52,74 @@ const std::string Row::EOL = "\n";
std::ostream& operator << (std::ostream &os, const Row& row)
{
os << row.toStringV();
os << row.valuesToString();
return os;
}
Row::Row():
_separator("\t"),
_sortField(0),
_comparison(COMPARE_AS_STRING)
Row::Row(): _separator("\t"), _pNames(0)
{
}
Row::Row(NameVecPtr pNames): _separator("\t"), _pNames(pNames)
{
if (!_pNames)
throw NullPointerException();
_values.resize(_pNames->size());
addSortField(0);
}
Row::~Row()
{
}
DynamicAny& Row::operator [] (std::size_t col)
DynamicAny& Row::get(std::size_t col)
{
try
{
return _values.at(col);
}catch (std::range_error& re)
}catch (std::out_of_range& 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();
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::sortField(std::size_t pos)
void Row::addSortField(std::size_t pos)
{
poco_assert (pos <= _values.size());
_sortField = pos;
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)) ||
@@ -116,24 +130,103 @@ void Row::sortField(std::size_t pos)
(_values[pos].type() == typeid(Poco::UInt64)) ||
(_values[pos].type() == typeid(bool)))
{
comparison(COMPARE_AS_INTEGER);
ct = COMPARE_AS_INTEGER;
}
else if ((_values[pos].type() == typeid(float)) ||
(_values[pos].type() == typeid(double)))
{
comparison(COMPARE_AS_FLOAT);
ct = COMPARE_AS_FLOAT;
}
else
{
comparison(COMPARE_AS_STRING);
ct = COMPARE_AS_STRING;
}
_sortFields.push_back(SortTuple(pos, ct));
}
void Row::sortField(const std::string& name)
void Row::addSortField(const std::string& name)
{
sortField(getPosition(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);
}
@@ -157,12 +250,6 @@ bool Row::isEqualType(const Row& other) const
}
void Row::comparison(Comparison comp)
{
_comparison = comp;
}
bool Row::operator == (const Row& other) const
{
if (!isEqualSize(other)) return false;
@@ -188,57 +275,80 @@ bool Row::operator != (const Row& other) const
bool Row::operator < (const Row& other) const
{
if (_sortField != other._sortField)
if (_sortFields != other._sortFields)
throw InvalidAccessException("Rows compared have different sorting criteria.");
switch (_comparison)
SortMap::const_iterator it = _sortFields.begin();
SortMap::const_iterator end = _sortFields.end();
for (; it != end; ++it)
{
case COMPARE_AS_INTEGER:
return (_values[_sortField].convert<Poco::Int64>() <
other._values[other._sortField].convert<Poco::Int64>());
switch (it->get<1>())
{
case COMPARE_AS_INTEGER:
if (_values[it->get<0>()].convert<Poco::Int64>() <
other._values[it->get<0>()].convert<Poco::Int64>())
return true;
else if (_values[it->get<0>()].convert<Poco::Int64>() !=
other._values[it->get<0>()].convert<Poco::Int64>())
return false;
break;
case COMPARE_AS_FLOAT:
return (_values[_sortField].convert<double>() <
other._values[other._sortField].convert<double>());
case COMPARE_AS_FLOAT:
if (_values[it->get<0>()].convert<double>() <
other._values[it->get<0>()].convert<double>())
return true;
else if (_values[it->get<0>()].convert<double>() <
other._values[it->get<0>()].convert<double>())
return false;
break;
case COMPARE_AS_STRING:
return (_values[_sortField].convert<std::string>() <
other._values[other._sortField].convert<std::string>());
case COMPARE_AS_STRING:
if (_values[it->get<0>()].convert<std::string>() <
other._values[it->get<0>()].convert<std::string>())
return true;
else if (_values[it->get<0>()].convert<std::string>() <
other._values[it->get<0>()].convert<std::string>())
return false;
break;
}
}
throw IllegalStateException("Unknown comparison mode.");
return false;
}
const std::string& Row::toStringV() const
const std::string Row::valuesToString() const
{
_strValues.clear();
std::vector<DynamicAny>::const_iterator it = _values.begin();
std::vector<DynamicAny>::const_iterator end = _values.end();
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.append(it->convert<std::string>());
strValues.append(_separator);
}
_strValues.replace(_strValues.find_last_of(_separator), _separator.length(), EOL);
strValues.replace(strValues.find_last_of(_separator), _separator.length(), EOL);
return _strValues;
return strValues;
}
const std::string& Row::toStringN() const
const std::string Row::namesToString() const
{
_strNames.clear();
std::vector<std::string>::const_iterator it = _names.begin();
std::vector<std::string>::const_iterator end = _names.end();
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.append(*it);
strNames.append(_separator);
}
_strNames.replace(_strNames.find_last_of(_separator), _separator.length(), EOL);
strNames.replace(strNames.find_last_of(_separator), _separator.length(), EOL);
return _strNames;
return strNames;
}

View File

@@ -1,7 +1,7 @@
//
// RowIterator.cpp
//
// $Id: //poco/Main/Data/src/RowIterator.cpp#2 $
// $Id: //poco/Main/Data/src/RowIterator.cpp#1 $
//
// Library: Data
// Package: DataCore
@@ -48,9 +48,9 @@ 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(RecordSet& recordSet, bool positionEnd):
_recordSet(recordSet),
_position((0 == recordSet.rowCount()) || positionEnd ? POSITION_END : 0)
{
}
@@ -75,43 +75,59 @@ void RowIterator::increment()
void RowIterator::decrement()
{
if (0 == _position)
throw RangeException("End of iterator reached.");
--_position;
throw RangeException("Beginning of iterator reached.");
else if (POSITION_END == _position)
_position = _recordSet.rowCount() - 1;
else
--_position;
}
const Row& RowIterator::operator * () const
Row& RowIterator::operator * () const
{
if (POSITION_END == _position)
throw InvalidAccessException("End of iterator reached.");
return _recordSet.row(_position);
}
const Row& RowIterator::operator ++ ()
Row* RowIterator::operator -> () const
{
if (POSITION_END == _position)
throw InvalidAccessException("End of iterator reached.");
return &_recordSet.row(_position);
}
std::size_t RowIterator::operator ++ ()
{
increment();
return _recordSet.row(_position);
return _position;
}
const Row& RowIterator::operator ++ (int)
std::size_t RowIterator::operator ++ (int)
{
std::size_t oldPos = _position;
increment();
return _recordSet.row(_position - 1);
return oldPos;
}
const Row& RowIterator::operator -- ()
std::size_t RowIterator::operator -- ()
{
decrement();
return _recordSet.row(_position);
return _position;
}
const Row& RowIterator::operator -- (int)
std::size_t RowIterator::operator -- (int)
{
std::size_t oldPos = _position;
decrement();
return _recordSet.row(_position + 1);
return oldPos;
}