Skip to content

Instantly share code, notes, and snippets.

@lqd
Created March 6, 2012 14:25
Show Gist options
  • Save lqd/1986550 to your computer and use it in GitHub Desktop.
Save lqd/1986550 to your computer and use it in GitHub Desktop.
Paginated view iterator for jcouchdb
import java.util.Iterator;
import java.util.List;
import lombok.var;
import org.jcouchdb.db.Database;
import org.jcouchdb.db.Options;
import org.jcouchdb.document.ValueAndDocumentRow;
import org.jcouchdb.document.ValueRow;
import org.jcouchdb.document.ViewAndDocumentsResult;
import org.jcouchdb.document.ViewResult;
// Fast view pagination method described at http://guide.couchdb.org/draft/recipes.html#fast
public abstract class PaginatedViewIterator<T, U extends List<? extends ValueRow<?>>>
{
protected Database database;
protected String view;
protected Class<T> valueClass;
protected int rowsPerPage;
private Object nextStartKey;
private String nextStartKeyDocId;
private boolean hasNext = true;
/** PaginatedViewIterator with key/value mapping */
public static <T> WithValue <T> of (Database database, String view, Class<T> valueClass, int rowsPerPage)
{
return new WithValue <T> (database, view, valueClass, rowsPerPage);
}
/** PaginatedViewIterator with key/value mapping + document */
public static <T, U> WithValueAndDocument <T, U> of (Database database, String view, Class<T> valueClass, Class<U> documentClass, int rowsPerPage)
{
return new WithValueAndDocument <T, U> (database, view, valueClass, documentClass, rowsPerPage);
}
public static class WithValue <T> extends PaginatedViewIterator <T, List<ValueRow<T>>>
implements Iterator<List<ValueRow<T>>>
{
public WithValue (Database database, String view, Class<T> valueClass, int rowsPerPage)
{
super (database, view, valueClass, rowsPerPage);
}
@Override
protected List<ValueRow<T>> query (Options options)
{
ViewResult<T> result = database.queryView (view, valueClass, options, null);
return result.getRows ();
}
}
public static class WithValueAndDocument <T, U> extends PaginatedViewIterator <T, List<ValueAndDocumentRow<T, U>>>
implements Iterator<List<ValueAndDocumentRow<T, U>>>
{
private Class<U> documentClass;
public WithValueAndDocument (Database database, String view, Class<T> valueClass, Class<U> documentClass, int rowsPerPage)
{
super (database, view, valueClass, rowsPerPage);
this.documentClass = documentClass;
}
@Override
protected List<ValueAndDocumentRow<T, U>> query (Options options)
{
ViewAndDocumentsResult<T, U> result = database.queryViewAndDocuments (view, valueClass, documentClass, options, null);
return result.getRows ();
}
}
public PaginatedViewIterator (Database database, String view, Class<T> valueClass, int rowsPerPage)
{
this.database = database;
this.view = view;
this.valueClass = valueClass;
this.rowsPerPage = rowsPerPage;
}
public boolean hasNext ()
{
return hasNext;
}
protected abstract U query (Options options);
@SuppressWarnings("unchecked")
public U next()
{
Options options = new Options().limit (rowsPerPage + 1);
if (nextStartKey != null && nextStartKeyDocId != null)
options.startKey (nextStartKey)
.startKeyDocId (nextStartKeyDocId);
U allRows = query (options);
var count = allRows.size ();
if (count <= rowsPerPage)
{
hasNext = false;
return allRows;
}
var rows = allRows.subList (0, rowsPerPage);
var lastRow = allRows.get (count - 1);
nextStartKey = lastRow.getKey ();
nextStartKeyDocId = lastRow.getId ();
return (U) rows;
}
public void remove ()
{
throw new IllegalStateException ("not supported");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment