1//
2// RowIterator.cpp
3//
4// Library: SQL
5// Package: SQLCore
6// Module: RowIterator
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/SQL/RowIterator.h"
16#include "Poco/SQL/RecordSet.h"
17#undef min
18#undef max
19#include <limits>
20
21
22namespace Poco {
23namespace SQL {
24
25
26const std::size_t RowIterator::POSITION_END = std::numeric_limits<std::size_t>::max();
27
28
29RowIterator::RowIterator(RecordSet* pRecordSet, bool positionEnd):
30 _pRecordSet(pRecordSet),
31 _position(positionEnd ? POSITION_END : 0)
32{
33}
34
35
36RowIterator::RowIterator(RecordSet& recordSet, bool positionEnd):
37 _pRecordSet(&recordSet),
38 _position(positionEnd ? POSITION_END : 0)
39{
40}
41
42
43RowIterator::RowIterator(const RowIterator& other):
44 _pRecordSet(other._pRecordSet),
45 _position(other._position)
46{
47}
48
49
50RowIterator::~RowIterator()
51{
52}
53
54
55RowIterator& RowIterator::operator = (const RowIterator& other)
56{
57 RowIterator tmp(other);
58 swap(tmp);
59 return *this;
60}
61
62
63void RowIterator::swap(RowIterator& other)
64{
65 using std::swap;
66
67 swap(_pRecordSet, other._pRecordSet);
68 swap(_position, other._position);
69}
70
71
72void RowIterator::increment() const
73{
74 if (POSITION_END == _position)
75 throw RangeException("End of iterator reached.");
76
77 if (_position < _pRecordSet->storageRowCount() - 1)
78 ++_position;
79 else
80 _position = POSITION_END;
81
82 if (_pRecordSet->getFilter() && POSITION_END != _position)
83 {
84 while (!_pRecordSet->isAllowed(_position))
85 {
86 increment();
87 if (POSITION_END == _position) break;
88 }
89 }
90}
91
92
93void RowIterator::decrement() const
94{
95 if (0 == _position)
96 throw RangeException("Beginning of iterator reached.");
97 else if (POSITION_END == _position)
98 _position = _pRecordSet->storageRowCount() - 1;
99 else
100 --_position;
101
102 if (_pRecordSet->getFilter() && 0 != _position)
103 {
104 while (!_pRecordSet->isAllowed(_position))
105 {
106 decrement();
107 if (0 == _position) break;
108 }
109 }
110}
111
112
113void RowIterator::setPosition(std::size_t pos) const
114{
115 if (_position == pos) return;
116
117 if (_pRecordSet->getFilter())
118 {
119 std::size_t start = _position;
120 if (_position > pos)
121 {
122 std::size_t end = _position - pos;
123 for (; start > end; --start)
124 {
125 if (pos) --pos;
126 else throw RangeException("Invalid position argument.");
127 }
128 }
129 else
130 {
131 std::size_t end = pos - _position;
132 for (; start < end; ++start)
133 {
134 if (_pRecordSet->storageRowCount() != pos) ++pos;
135 else throw RangeException("Invalid position argument.");
136 }
137 }
138 }
139
140 if (pos < _pRecordSet->storageRowCount())
141 _position = pos;
142 else if (pos == _pRecordSet->storageRowCount())
143 _position = POSITION_END;
144 else
145 throw RangeException("Invalid position argument.");
146}
147
148
149Row& RowIterator::operator * () const
150{
151 if (POSITION_END == _position)
152 throw InvalidAccessException("End of iterator reached.");
153
154 return _pRecordSet->row(_position);
155}
156
157
158Row* RowIterator::operator -> () const
159{
160 if (POSITION_END == _position)
161 throw InvalidAccessException("End of iterator reached.");
162
163 return &_pRecordSet->row(_position);
164}
165
166
167const RowIterator& RowIterator::operator ++ () const
168{
169 increment();
170 return *this;
171}
172
173
174RowIterator RowIterator::operator ++ (int) const
175{
176 RowIterator old(*this);
177 increment();
178 return old;
179}
180
181
182const RowIterator& RowIterator::operator -- () const
183{
184 decrement();
185 return *this;
186}
187
188
189RowIterator RowIterator::operator -- (int) const
190{
191 RowIterator old(*this);
192 decrement();
193 return old;
194}
195
196
197RowIterator RowIterator::operator + (std::size_t diff) const
198{
199 RowIterator ri(*this);
200 ri.setPosition(_position + diff);
201 return ri;
202}
203
204
205RowIterator RowIterator::operator - (std::size_t diff) const
206{
207 if (diff > _position) throw RangeException("Invalid position argument.");
208 RowIterator ri(*this);
209 ri.setPosition(_position - diff);
210 return ri;
211}
212
213
214} } // namespace Poco::SQL
215