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 | |
22 | namespace Poco { |
23 | namespace SQL { |
24 | |
25 | |
26 | const std::size_t RowIterator::POSITION_END = std::numeric_limits<std::size_t>::max(); |
27 | |
28 | |
29 | RowIterator::RowIterator(RecordSet* pRecordSet, bool positionEnd): |
30 | _pRecordSet(pRecordSet), |
31 | _position(positionEnd ? POSITION_END : 0) |
32 | { |
33 | } |
34 | |
35 | |
36 | RowIterator::RowIterator(RecordSet& recordSet, bool positionEnd): |
37 | _pRecordSet(&recordSet), |
38 | _position(positionEnd ? POSITION_END : 0) |
39 | { |
40 | } |
41 | |
42 | |
43 | RowIterator::RowIterator(const RowIterator& other): |
44 | _pRecordSet(other._pRecordSet), |
45 | _position(other._position) |
46 | { |
47 | } |
48 | |
49 | |
50 | RowIterator::~RowIterator() |
51 | { |
52 | } |
53 | |
54 | |
55 | RowIterator& RowIterator::operator = (const RowIterator& other) |
56 | { |
57 | RowIterator tmp(other); |
58 | swap(tmp); |
59 | return *this; |
60 | } |
61 | |
62 | |
63 | void RowIterator::swap(RowIterator& other) |
64 | { |
65 | using std::swap; |
66 | |
67 | swap(_pRecordSet, other._pRecordSet); |
68 | swap(_position, other._position); |
69 | } |
70 | |
71 | |
72 | void 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 | |
93 | void 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 | |
113 | void 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 | |
149 | Row& 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 | |
158 | Row* 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 | |
167 | const RowIterator& RowIterator::operator ++ () const |
168 | { |
169 | increment(); |
170 | return *this; |
171 | } |
172 | |
173 | |
174 | RowIterator RowIterator::operator ++ (int) const |
175 | { |
176 | RowIterator old(*this); |
177 | increment(); |
178 | return old; |
179 | } |
180 | |
181 | |
182 | const RowIterator& RowIterator::operator -- () const |
183 | { |
184 | decrement(); |
185 | return *this; |
186 | } |
187 | |
188 | |
189 | RowIterator RowIterator::operator -- (int) const |
190 | { |
191 | RowIterator old(*this); |
192 | decrement(); |
193 | return old; |
194 | } |
195 | |
196 | |
197 | RowIterator RowIterator::operator + (std::size_t diff) const |
198 | { |
199 | RowIterator ri(*this); |
200 | ri.setPosition(_position + diff); |
201 | return ri; |
202 | } |
203 | |
204 | |
205 | RowIterator 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 |