#215 - Remove findPagingList() ... it has been deprecated for a while, please migrate to findPagedList()

This commit is contained in:
rbygrave
2014-12-01 21:52:40 +13:00
parent e3bf3629ee
commit 09f8967459
14 changed files with 5 additions and 873 deletions
@@ -578,13 +578,6 @@ public interface EbeanServer {
*/
public SqlFutureList findFutureList(SqlQuery query, Transaction transaction);
/**
* Find using a PagingList with explicit transaction and pageSize.
* Deprecated in favour of findPagedList().
* @deprecated
*/
public <T> PagingList<T> findPagingList(Query<T> query, Transaction transaction, int pageSize);
/**
* Return a PagedList for this query.
* <p>
@@ -208,25 +208,6 @@ public interface ExpressionList<T> extends Serializable {
*/
public FutureList<T> findFutureList();
/**
* Return a PagingList for this query.
* <p>
* This can be used to break up a query into multiple queries to fetch the
* data a page at a time.
* </p>
* <p>
* This typically works by using a query per page and setting
* {@link Query#setFirstRow(int)} and and {@link Query#setMaxRows(int)} on the
* query. This usually would translate into SQL that uses limit offset, rownum
* or row_number function to limit the result set.
* </p>
*
* @param pageSize
* the number of beans fetched per Page
* @deprecated
*/
public PagingList<T> findPagingList(int pageSize);
/**
* Return a PagedList for this query.
* <p>
@@ -1,127 +0,0 @@
package com.avaje.ebean;
import java.util.List;
import java.util.concurrent.Future;
/**
* Used to page through a query result rather than fetching all the results in a
* single query.
* <p>
* Has the ability to use background threads to 'fetch ahead' the next page and
* get the total row count.
* </p>
* <p>
* If you are building a stateless web application and not keeping the
* PagingList over multiple requests then there is not much to be gained in
* using PagingList. Instead you can just use {@link Query#setFirstRow(int)} and
* {@link Query#setMaxRows(int)}.
* </p>
*
* <p>
* If you are using PagingList is a stateful web application where the
* PagingList is held over multiple requests then PagingList provides the extra
* benefits of
* <ul>
* <li>Fetch ahead - automatically fetching the next page via background query
* execution</li>
* <li>Automatic propagation of the persistence context</li>
* </ul>
* </p>
* <p>
* So with PagingList when you use Page 2 it can automatically fetch Page 3 data
* in the background (using a findFutureList() query). It also automatically
* propagates the persistence context so that all the queries executed by the
* PagingList all use the same persistence context.
* </p>
*
* <pre>
* PagingList&lt;TOne&gt; pagingList =
* Ebean.find(TOne.class)
* .where().gt(&quot;name&quot;, &quot;2&quot;)
* .findPagingList(10);
*
* // get the row count in the background...
* // ... otherwise it is fetched on demand
* // ... when getRowCount() or getPageCount()
* // ... is called
* pagingList.getFutureRowCount();
*
* // get the first page
* Page&lt;TOne&gt; page = pagingList.getPage(0);
*
* // get the beans from the page as a list
* List&lt;TOne&gt; list = page.getList();
* </pre>
*
* @author rbygrave
*
* @param <T>
* the entity bean type
*/
public interface PagingList<T> {
/**
* Refresh will clear all the pages and row count forcing them to be
* re-fetched when next required.
*/
public void refresh();
// public void fetchAll();
// public String? getOrderBy();
// public void setOrderBy(String?);
/**
* By default fetchAhead is true so use this to turn off fetchAhead.
* <p>
* Set this to false if you don't want to fetch ahead using background
* fetching.
* <p>
* If set to true (or left as to default) then the next page is fetched in the
* background as soon as the list is accessed.
* </p>
*/
public PagingList<T> setFetchAhead(boolean fetchAhead);
/**
* Return the Future for getting the total row count.
*/
public Future<Integer> getFutureRowCount();
/**
* Return the data for all the pages in the form of a single List.
* <p>
* Iterating through this list will automatically fire the paging queries as
* required.
* </p>
*/
public List<T> getAsList();
/**
* Return the page size. This is the number of rows per page.
*/
public int getPageSize();
/**
* Return the total row count.
* <p>
* This gets the result from getFutureRowCount and will wait until that query
* has completed.
* </p>
*/
public int getTotalRowCount();
/**
* Return the total page count.
* <p>
* This is based on the total row count. This will wait until the row count
* has returned if it has not already.
* </p>
*/
public int getTotalPageCount();
/**
* Return the page for a given page position (starting at 0).
*/
public Page<T> getPage(int i);
}
-7
View File
@@ -684,13 +684,6 @@ public interface Query<T> extends Serializable {
*/
public FutureList<T> findFutureList();
/**
* This is being deprecated in favour of the simplier {@link Query#findPagedList(int, int)}.
*
* @deprecated
*/
public PagingList<T> findPagingList(int pageSize);
/**
* Return a PagedList for this query.
* <p>
@@ -1338,28 +1338,6 @@ public final class DefaultServer implements SpiEbeanServer {
return queryFuture;
}
public <T> PagingList<T> findPagingList(Query<T> query, Transaction t, int pageSize) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
// we want to use a single PersistenceContext to be used
// for all the paging queries so we make sure there is a
// PersistenceContext on the query
PersistenceContext pc = spiQuery.getPersistenceContext();
if (pc == null) {
SpiTransaction currentTransaction = getCurrentServerTransaction();
if (currentTransaction != null) {
pc = currentTransaction.getPersistenceContext();
}
if (pc == null) {
pc = new DefaultPersistenceContext();
}
spiQuery.setPersistenceContext(pc);
}
return new LimitOffsetPagingQuery<T>(this, spiQuery, pageSize);
}
@Override
public <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction, int pageIndex, int pageSize) {
@@ -247,10 +247,6 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
public <K> Map<K, T> findMap(String keyProperty, Class<K> keyType) {
return exprList.findMap(keyProperty, keyType);
}
public PagingList<T> findPagingList(int pageSize) {
return exprList.findPagingList(pageSize);
}
@Override
public PagedList<T> findPagedList(int pageIndex, int pageSize) {
@@ -1,225 +0,0 @@
package com.avaje.ebeaninternal.server.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import com.avaje.ebean.Page;
public class LimitOffsetList<T> implements List<T> {
private final LimitOffsetPagingQuery<T> owner;
private List<T> localCopy;
public LimitOffsetList(LimitOffsetPagingQuery<T> owner) {
this.owner = owner;
}
private void ensureLocalCopy() {
if (localCopy == null){
localCopy = new ArrayList<T>();
int pgIndex = 0;
while(true){
Page<T> page = owner.getPage(pgIndex++);
List<T> list = page.getList();
localCopy.addAll(list);
if (!page.hasNext()){
break;
}
}
}
}
private boolean hasNext(int position){
return owner.hasNext(position);
}
public void clear() {
localCopy = new ArrayList<T>();
}
public T get(int index) {
if (localCopy != null){
return localCopy.get(index);
} else {
return owner.get(index);
}
}
public boolean isEmpty() {
if (localCopy != null){
return localCopy.isEmpty();
} else {
return owner.getTotalRowCount() == 0;
}
}
public int size() {
if (localCopy != null){
return localCopy.size();
} else {
return owner.getTotalRowCount();
}
}
public Iterator<T> iterator() {
if (localCopy != null){
return localCopy.iterator();
} else {
return new ListItr(this, 0);
}
}
public ListIterator<T> listIterator() {
if (localCopy != null){
return localCopy.listIterator();
} else {
return new ListItr(this, 0);
}
}
public ListIterator<T> listIterator(int index) {
if (localCopy != null){
return localCopy.listIterator(index);
} else {
return new ListItr(this, index);
}
}
public List<T> subList(int fromIndex, int toIndex) {
if (localCopy != null){
return localCopy.subList(fromIndex, toIndex);
} else {
//FIXME: subList not implemented ...
throw new RuntimeException("Not implemented at this point");
}
}
public int lastIndexOf(Object o) {
ensureLocalCopy();
return localCopy.lastIndexOf(o);
}
public void add(int index, T element) {
ensureLocalCopy();
localCopy.add(index, element);
}
public boolean add(T o) {
ensureLocalCopy();
return localCopy.add(o);
}
public boolean addAll(Collection<? extends T> c) {
ensureLocalCopy();
return localCopy.addAll(c);
}
public boolean addAll(int index, Collection<? extends T> c) {
ensureLocalCopy();
return localCopy.addAll(index, c);
}
public boolean contains(Object o) {
ensureLocalCopy();
return localCopy.contains(o);
}
public boolean containsAll(Collection<?> c) {
ensureLocalCopy();
return localCopy.containsAll(c);
}
public int indexOf(Object o) {
ensureLocalCopy();
return localCopy.indexOf(o);
}
public T remove(int index) {
ensureLocalCopy();
return localCopy.remove(index);
}
public boolean remove(Object o) {
ensureLocalCopy();
return localCopy.remove(o);
}
public boolean removeAll(Collection<?> c) {
ensureLocalCopy();
return localCopy.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
ensureLocalCopy();
return localCopy.retainAll(c);
}
public T set(int index, T element) {
ensureLocalCopy();
return localCopy.set(index, element);
}
public Object[] toArray() {
ensureLocalCopy();
return localCopy.toArray();
}
public <K> K[] toArray(K[] a) {
ensureLocalCopy();
return localCopy.toArray(a);
}
private class ListItr implements ListIterator<T> {
private LimitOffsetList<T> ownerList;
private int position;
ListItr(LimitOffsetList<T> ownerList, int position) {
this.ownerList = ownerList;
this.position = position;
}
public void add(T o) {
ownerList.add(position++, o);
}
public boolean hasNext() {
return ownerList.hasNext(position);
}
public boolean hasPrevious() {
return position > 0;
}
public T next() {
return ownerList.get(position++);
}
public int nextIndex() {
return position;
}
public T previous() {
return get(--position);
}
public int previousIndex() {
return position - 1;
}
public void remove() {
throw new RuntimeException("Not supported yet");
}
public void set(T o) {
throw new RuntimeException("Not supported yet");
}
}
}
@@ -1,107 +0,0 @@
package com.avaje.ebeaninternal.server.query;
import java.util.List;
import javax.persistence.PersistenceException;
import com.avaje.ebean.FutureList;
import com.avaje.ebean.Page;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionTouched;
import com.avaje.ebeaninternal.api.SpiQuery;
/**
* Page implementation based on limit offset types of queries.
*
* @author rbygrave
*
* @param <T>
* the entity bean type
*/
public class LimitOffsetPage<T> implements Page<T>, BeanCollectionTouched {
private final int pageIndex;
private final LimitOffsetPagingQuery<T> owner;
private FutureList<T> futureList;
public LimitOffsetPage(int pageIndex, LimitOffsetPagingQuery<T> owner) {
this.pageIndex = pageIndex;
this.owner = owner;
}
public FutureList<T> getFutureList() {
if (futureList == null) {
SpiQuery<T> originalQuery = owner.getSpiQuery();
SpiQuery<T> copy = originalQuery.copy();
copy.setPersistenceContext(originalQuery.getPersistenceContext());
int pageSize = owner.getPageSize();
copy.setFirstRow(pageIndex * pageSize);
copy.setMaxRows(pageSize);
copy.setBeanCollectionTouched(this);
futureList = owner.getServer().findFutureList(copy, null);
}
return futureList;
}
/**
* Perform fetch ahead when the list is first accessed.
*/
public void notifyTouched(BeanCollection<?> c) {
if (hasNext()) {
owner.fetchAheadIfRequired(pageIndex);
}
}
public List<T> getList() {
try {
return getFutureList().get();
} catch (Exception e) {
throw new PersistenceException(e);
}
}
public boolean hasNext() {
return pageIndex < getTotalPageCount() - 1;
}
public boolean hasPrev() {
return pageIndex > 0;
}
public Page<T> next() {
return owner.getPage(pageIndex + 1);
}
public Page<T> prev() {
return owner.getPage(pageIndex - 1);
}
public int getPageIndex() {
return pageIndex;
}
public int getTotalPageCount() {
return owner.getTotalPageCount();
}
public int getTotalRowCount() {
return owner.getTotalRowCount();
}
public String getDisplayXtoYofZ(String to, String of) {
int first = pageIndex * owner.getPageSize() + 1;
int last = first + getList().size() - 1;
int total = getTotalRowCount();
return first+to+last+of+total;
}
}
@@ -1,137 +0,0 @@
package com.avaje.ebeaninternal.server.query;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import javax.persistence.PersistenceException;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.Page;
import com.avaje.ebean.PagingList;
import com.avaje.ebeaninternal.api.Monitor;
import com.avaje.ebeaninternal.api.SpiQuery;
public class LimitOffsetPagingQuery<T> implements PagingList<T> {
private transient EbeanServer server;
private final SpiQuery<T> query;
private final List<LimitOffsetPage<T>> pages = new ArrayList<LimitOffsetPage<T>>();
private final Monitor monitor = new Monitor();
private final int pageSize;
private boolean fetchAhead = true;
private Future<Integer> futureRowCount;
public LimitOffsetPagingQuery(EbeanServer server, SpiQuery<T> query, int pageSize) {
this.query = query;
this.pageSize = pageSize;
this.server = server;
}
public EbeanServer getServer() {
return server;
}
public void setServer(EbeanServer server) {
this.server = server;
}
public SpiQuery<T> getSpiQuery() {
return query;
}
public PagingList<T> setFetchAhead(boolean fetchAhead) {
this.fetchAhead = fetchAhead;
return this;
}
public List<T> getAsList() {
return new LimitOffsetList<T>(this);
}
public Future<Integer> getFutureRowCount() {
synchronized (monitor) {
if (futureRowCount == null){
futureRowCount = server.findFutureRowCount(query, null);
}
return futureRowCount;
}
}
private LimitOffsetPage<T> internalGetPage(int i){
synchronized (monitor) {
int ps = pages.size();
if (ps <= i){
for (int j = ps; j <= i; j++) {
LimitOffsetPage<T> p = new LimitOffsetPage<T>(j, this);
pages.add(p);
}
}
return pages.get(i);
}
}
protected void fetchAheadIfRequired(int pageIndex){
synchronized (monitor) {
// Already checked in LimitOffsetPage that there is another page
if (fetchAhead){
// fetchAhead is turned on so get the next page and trigger query
LimitOffsetPage<T> nextPage = internalGetPage(pageIndex + 1);
nextPage.getFutureList();
}
}
}
public void refresh() {
synchronized (monitor) {
futureRowCount = null;
pages.clear();
}
}
public Page<T> getPage(int i) {
return internalGetPage(i);
}
protected boolean hasNext(int position){
return position < getTotalRowCount();
}
protected T get(int rowIndex){
int pg = rowIndex / pageSize;
int offset = rowIndex % pageSize;
Page<T> page = getPage(pg);
return page.getList().get(offset);
}
public int getTotalPageCount() {
int rowCount = getTotalRowCount();
if (rowCount == 0){
return 0;
} else {
return ((rowCount-1) / pageSize) + 1;
}
}
public int getPageSize() {
return pageSize;
}
public int getTotalRowCount() {
try {
return getFutureRowCount().get();
} catch (Exception e) {
throw new PersistenceException(e);
}
}
}
@@ -963,10 +963,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return server.findFutureRowCount(this, null);
}
public PagingList<T> findPagingList(int pageSize) {
return server.findPagingList(this, null, pageSize);
}
@Override
public PagedList<T> findPagedList(int pageIndex, int pageSize) {
return server.findPagedList(this, null, pageIndex, pageSize);
@@ -143,10 +143,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.findFutureList();
}
public PagingList<T> findPagingList(int pageSize) {
return query.findPagingList(pageSize);
}
@Override
public PagedList<T> findPagedList(int pageIndex, int pageSize) {
return query.findPagedList(pageIndex, pageSize);
@@ -1,22 +1,14 @@
package com.avaje.ebeaninternal.util;
import com.avaje.ebean.*;
import com.avaje.ebeaninternal.api.SpiExpressionList;
import com.avaje.ebeaninternal.server.expression.FilterExprPath;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.PersistenceException;
import com.avaje.ebean.ExpressionFactory;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.FutureIds;
import com.avaje.ebean.FutureList;
import com.avaje.ebean.FutureRowCount;
import com.avaje.ebean.OrderBy;
import com.avaje.ebean.PagingList;
import com.avaje.ebean.Query;
import com.avaje.ebeaninternal.api.SpiExpressionList;
import com.avaje.ebeaninternal.server.expression.FilterExprPath;
public class FilterExpressionList<T> extends DefaultExpressionList<T> {
private static final long serialVersionUID = 2226895827150099020L;
@@ -71,10 +63,6 @@ public class FilterExpressionList<T> extends DefaultExpressionList<T> {
return rootQuery.findMap();
}
public PagingList<T> findPagingList(int pageSize) {
return rootQuery.findPagingList(pageSize);
}
public int findRowCount() {
return rootQuery.findRowCount();
}
@@ -438,11 +438,6 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public <T> PagingList<T> findPagingList(Query<T> query, Transaction transaction, int pageSize) {
return null;
}
@Override
public <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction, int pageIndex, int pageSize) {
return null;
@@ -1,188 +0,0 @@
package com.avaje.tests.basic;
import java.util.List;
import java.util.Random;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.Page;
import com.avaje.ebean.PagingList;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.TOne;
public class TestPaging extends BaseTestCase {
private void loadData() {
int rowCount = Ebean.find(TOne.class).findRowCount();
if (rowCount > 500){
return;
}
Random r = new Random();
Ebean.beginTransaction();
try {
for (int i = 0; i < 1000; i++) {
TOne o = new TOne();
int rvalue = r.nextInt(100000);
o.setName(rvalue+"name");
o.setDescription(rvalue+"");
Ebean.save(o);
}
Ebean.commitTransaction();
} finally {
Ebean.endTransaction();
}
}
@Test
public void test() throws Exception {
loadData();
//checkLastPage();
//bgFetchOne();
pagingOne();
}
// private void checkLastPage() {
//
//
// PagingList<TOne> pagingList =
// Ebean.find(TOne.class)
// .where().gt("name", "2")
// .findPagingList(10);
//
//
// pagingList.setFetchAhead(false);
//
// Page<TOne> lastPage = pagingList.getPage(pagingList.getTotalPageCount() - 1);
// String displayLastPage = lastPage.getDisplayXtoYofZ(" to "," of ");
// System.out.println("LASTPAGE: "+displayLastPage);
//
// List<TOne> list = lastPage.getList();
// list.get(0);
//
// Assert.assertFalse(lastPage.hasNext());
//
// }
// @SuppressWarnings("unchecked")
// private void bgFetchOne() {
//
//
// Query<TOne> query = Ebean.find(TOne.class)
// .setAutofetch(false)
// .select("id")
// .where().gt("name", "2")
// .setBackgroundFetchAfter(10)
// //.setMaxRows(20)
// .orderBy("id");
//
// //query.findList();
// //query.findIds();
//
//// long t1 = System.currentTimeMillis();
//
// List<TOne> ids = query.findList();
// //List<Object> ids = query.findIds();
//
//// long t0 = System.currentTimeMillis();
//// System.out.println("Got: "+ids.size());
// BeanCollection<TOne> bc = (BeanCollection<TOne>)ids;
// bc.backgroundFetchWait();
//
//// long ex0 = System.currentTimeMillis() - t0;
//// long ex1 = System.currentTimeMillis() - t1;
//// System.out.println("Got: "+ids.size());
//// System.out.println("exetime t0:"+ex0+" t1:"+ex1);
// //System.out.println("done "+bc.size());
// }
private void pagingOne() throws InterruptedException {
loadData();
int pageSize = 10;
PagingList<TOne> pagingList =
Ebean.find(TOne.class)
.select("id")
//.where().gt("name", "2")
.findPagingList(10);
// get the row count in the background...
// ... otherwise it is fetched on demand
// ... when getRowCount() or getPageCount()
// ... is called
pagingList.getFutureRowCount();
// get the first page
Page<TOne> page = pagingList.getPage(0);
//String display0 = page.getDisplayXtoYofZ(" to "," of ");
//System.out.println("PAGE0: "+display0);
// get the beans from the page as a list
List<TOne> list = page.getList();
Assert.assertTrue("page size ",list.size() == pageSize);
int totalRows = pagingList.getTotalRowCount();
Assert.assertTrue("page size ",totalRows >= list.size());
Thread.sleep(300);
Page<TOne> next = page.next();
//String display1 = next.getDisplayXtoYofZ(" to "," of ");
//System.out.println("PAGE1: "+display1);
List<TOne> list2 = next.getList();
Assert.assertTrue("page size ",list2.size() == pageSize);
if (page.hasNext()){
Page<TOne> next3 = page.next();
List<TOne> list3 = next3.getList();
Assert.assertTrue("page size ",list3.size() == pageSize);
}
Page<TOne> lastPage = pagingList.getPage(pagingList.getTotalPageCount() - 1);
//String displayLastPage = lastPage.getDisplayXtoYofZ(" to "," of ");
//System.out.println("LASTPAGE: "+displayLastPage);
Assert.assertFalse(lastPage.hasNext());
checkForLoop();
}
private void checkForLoop() {
EbeanServer server = Ebean.getServer(null);
Query<TOne> query = server.find(TOne.class)
.where().gt("name", "2")
.query();
int pageSize = 10;
PagingList<TOne> pagingList = server.findPagingList(query, null, pageSize);
List<TOne> asList = pagingList.getAsList();
for (int i = 0; i < asList.size(); i++) {
if (i % 10 == 0){
//System.out.println("here");
}
TOne tOne = asList.get(i);
tOne.hashCode();
//System.out.print(".");
}
}
}