1 #ifndef QTRESTCLIENT_PAGING_H
2 #define QTRESTCLIENT_PAGING_H
4 #include "QtRestClient/paging_fwd.h"
5 #include "QtRestClient/genericrestreply.h"
6 #include "QtRestClient/restclass.h"
8 #include <QtCore/qsharedpointer.h>
9 #include <QtCore/qpointer.h>
21 PagingData() =
default;
22 PagingData(
const PagingData &other) =
default;
33 d{
new __private::PagingData<T>{}}
50 d{
new __private::PagingData<T>{}}
52 d->iPaging.reset(iPaging);
66 return d->iPaging.data();
78 return d->iPaging->total();
84 return d->iPaging->offset();
90 return d->iPaging->hasNext();
97 if (d->iPaging->hasNext())
98 return d->client->rootClass()->template get<Paging<T>, EO>(d->iPaging->next());
106 return d->iPaging->next();
112 return d->iPaging->hasPrevious();
116 template<
typename EO>
119 if (d->iPaging->hasPrevious())
120 return d->client->rootClass()->template get<Paging<T>, EO>(d->iPaging->previous());
128 return d->iPaging->previous();
132 void Paging<T>::iterate(
const std::function<
bool (T, qint64)> &iterator, qint64 to, qint64 from)
const
134 Q_ASSERT(from >= d->iPaging->offset());
136 auto index = internalIterate(iterator, to ,from);
141 auto max = calcMax(to);
142 if (index < max && d->iPaging->hasNext()) {
143 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
144 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
145 next()->onSucceeded([iterator, to, index](
int,
const Paging<T> &paging) {
147 paging.
iterate(iterator, to, index);
155 Q_ASSERT(from >= d->iPaging->offset());
157 auto index = internalIterate(iterator, to ,from);
162 auto max = calcMax(to);
163 if (index < max && d->iPaging->hasNext()) {
164 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
165 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
166 next()->onSucceeded(scope, [scope, iterator, to, index](
int,
const Paging<T> &paging) {
168 paging.
iterate(scope, iterator, to, index);
174 template<
typename EO>
177 Q_ASSERT(from >= d->iPaging->offset());
179 auto index = internalIterate(iterator, to ,from);
184 auto max = calcMax(to);
185 if (index < max && d->iPaging->hasNext()) {
186 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
187 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
188 next<EO>()->onSucceeded([iterator, errorHandler, failureTransformer, to, index](
int,
const Paging<T> &paging) {
190 paging.
iterate(iterator, errorHandler, failureTransformer, to, index);
192 ->onAllErrors(errorHandler, failureTransformer);
197 template<
typename EO>
200 Q_ASSERT(from >= d->iPaging->offset());
202 auto index = internalIterate(iterator, to ,from);
207 auto max = calcMax(to);
208 if (index < max && d->iPaging->hasNext()) {
209 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
210 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
211 next<EO>()->onSucceeded(scope, [scope, iterator, errorHandler, failureTransformer, to, index](
int,
const Paging<T> &paging) {
213 paging.
iterate(scope, iterator, errorHandler, failureTransformer, to, index);
215 ->onAllErrors(scope, errorHandler, failureTransformer);
220 template<
typename EO>
223 Q_ASSERT(from >= d->iPaging->offset());
225 auto index = internalIterate(iterator, to ,from);
230 auto max = calcMax(to);
231 if (index < max && d->iPaging->hasNext()) {
232 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
233 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
234 next<EO>()->onSucceeded([iterator, failureHandler, errorHandler, exceptionHandler, to, index](
int,
const Paging<T> &paging) {
236 paging.
iterate(iterator, failureHandler, errorHandler, exceptionHandler, to, index);
238 ->onFailed(failureHandler)
239 ->onError(errorHandler)
240 ->onSerializeException(exceptionHandler);
245 template<
typename EO>
246 void Paging<T>::iterate(
QObject *scope,
const std::function<
bool(T, qint64)> &iterator,
const std::function<
void(
int, EO)> &failureHandler,
const std::function<
void(
QString,
int,
RestReply::Error)> &errorHandler,
const std::function<
void(
QtJsonSerializer::Exception &)> &exceptionHandler, qint64 to, qint64 from)
const
248 Q_ASSERT(from >= d->iPaging->offset());
250 auto index = internalIterate(iterator, to ,from);
255 auto max = calcMax(to);
256 if(index < max && d->iPaging->hasNext()) {
257 qCDebug(logPaging) <<
"Requesting next paging object with offset" << index
258 <<
"as" << d->iPaging->next().toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo);
259 next<EO>()->onSucceeded(scope, [scope, iterator, failureHandler, errorHandler, exceptionHandler, to, index](
int,
const Paging<T> &paging) {
261 paging.
iterate(scope, iterator, failureHandler, errorHandler, exceptionHandler, to, index);
263 ->onFailed(scope, failureHandler)
264 ->onError(scope, errorHandler)
265 ->onSerializeException(exceptionHandler);
272 return d->iPaging->properties();
278 __private::MetaComponent<T>::deleteAllLater(d->data);
286 auto count = d->data.size();
290 start = static_cast<int>(std::max(from, offset) - offset);
292 max = static_cast<int>(std::min(to, offset + count) - offset);
295 qCDebug(logPaging).nospace() <<
"iterating over available range ["
296 << offset + start <<
":"
297 << offset + max - 1 <<
"]";
300 for (
auto j = 0; j < start; ++j)
301 __private::MetaComponent<T>::deleteLater(d->data.value(j));
305 auto canceled =
false;
306 for (i = start; i < max; ++i) {
307 auto item = d->data.value(i);
308 auto index = offset >= 0 ? offset + i : -1ll;
309 if (!iterator(item, index)) {
310 qCDebug(logPaging) <<
"Iterator stopped paging iteration at index"
318 for (
auto j = i; j < count; ++j)
319 __private::MetaComponent<T>::deleteLater(d->data.value(j));
323 else if (offset >= 0)
330 qint64 Paging<T>::calcMax(qint64 to)
const
332 if (d->iPaging->offset() >= 0) {
334 return std::min(to, d->iPaging->total());
336 return d->iPaging->total();
338 return std::numeric_limits<qint64>::max();
343 #endif // QTRESTCLIENT_PAGING_H