de.gesellix.couchdb.PagedViewIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of couchdb-client Show documentation
Show all versions of couchdb-client Show documentation
A CouchDB client written in Groovy
The newest version!
package de.gesellix.couchdb;
import de.gesellix.couchdb.model.NonReducedViewQueryResponse;
import de.gesellix.couchdb.model.RowReference;
import de.gesellix.couchdb.model.ViewQueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.BiFunction;
public class PagedViewIterator>
implements Iterator> {
private static final Logger log = LoggerFactory.getLogger(PagedViewIterator.class);
private final int pageSize;
private final BiFunction, Integer, ViewQueryResponse> pageProvider;
RowReference nextPage;
ViewQueryResponse lastResult;
public PagedViewIterator(int pageSize, BiFunction, Integer, ViewQueryResponse> pageProvider) {
this.pageSize = pageSize;
this.pageProvider = pageProvider;
this.nextPage = null;
this.lastResult = null;
}
@Override
public boolean hasNext() {
if (lastResult == null) {
// we didn't even try, yet
return true;
}
return nextPage != null;
}
@Override
public ViewQueryResponse next() {
if (!hasNext()) {
throw new NoSuchElementException("no more pages available");
}
ViewQueryResponse fetched = fetch();
return fetched;
}
private ViewQueryResponse fetch() {
lastResult = pageProvider.apply(nextPage, pageSize + 1);
if (lastResult == null || lastResult.getRows() == null) {
throw new IllegalStateException("failed to fetch more rows. nextPage(" + RowReference.toString(nextPage) + ")");
}
if (lastResult instanceof NonReducedViewQueryResponse) {
NonReducedViewQueryResponse, ?> nonReducedLastResult = (NonReducedViewQueryResponse, ?>) lastResult;
log.info("got result, totalRows({}), offset({}), rows({}), nextPage({})",
nonReducedLastResult.getTotalRows(), nonReducedLastResult.getOffset(), lastResult.getRows().size(), RowReference.toString(nextPage));
} else {
log.info("got result, rows({}), nextPage({})",
lastResult.getRows().size(), RowReference.toString(nextPage));
}
if (lastResult.getRows().size() <= pageSize) {
// finished
updateNextPage(null);
} else {
// safe for the next iteration
Row trailingRow = lastResult.getRows().remove(lastResult.getRows().size() - 1);
updateNextPage(trailingRow);
}
return lastResult;
}
private void updateNextPage(RowReference nextPage) {
if (Objects.equals(this.nextPage, nextPage)) {
if (lastResult instanceof NonReducedViewQueryResponse) {
NonReducedViewQueryResponse, ?> nonReducedLastResult = (NonReducedViewQueryResponse, ?>) lastResult;
int offset = nonReducedLastResult.getOffset() == null ? -1 : nonReducedLastResult.getOffset();
log.info("nextPage hasn't changed: previous({}) == next({}), lastResult.offset({})",
RowReference.toString(this.nextPage),
RowReference.toString(nextPage),
offset);
} else {
log.info("nextPage hasn't changed: previous({}) == next({})",
RowReference.toString(this.nextPage),
RowReference.toString(nextPage));
}
// throw exception?
nextPage = null;
}
this.nextPage = nextPage;
}
}