use of com.google.appengine.api.datastore.FetchOptions in project siena by mandubian.
the class GaePersistenceManager method doFetchIterable.
private <T> Iterable<T> doFetchIterable(Query<T> query, int limit, int offset) {
QueryOptionGaeContext gaeCtx = (QueryOptionGaeContext) query.option(QueryOptionGaeContext.ID);
QueryOptionState state = (QueryOptionState) query.option(QueryOptionState.ID);
QueryOptionFetchType fetchType = (QueryOptionFetchType) query.option(QueryOptionFetchType.ID);
if (gaeCtx == null) {
gaeCtx = new QueryOptionGaeContext();
query.customize(gaeCtx);
}
FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
QueryOptionPage pag = (QueryOptionPage) query.option(QueryOptionPage.ID);
if (!pag.isPaginating()) {
// no pagination but pageOption active
if (pag.isActive()) {
// if local limit is set, it overrides the pageOption.pageSize
if (limit != Integer.MAX_VALUE) {
gaeCtx.realPageSize = limit;
fetchOptions.limit(gaeCtx.realPageSize);
// pageOption is passivated to be sure it is not reused
pag.passivate();
} else // using pageOption.pageSize
{
gaeCtx.realPageSize = pag.pageSize;
fetchOptions.limit(gaeCtx.realPageSize);
// passivates the pageOption in stateless mode not to keep anything between 2 requests
if (state.isStateless()) {
pag.passivate();
}
}
} else {
if (limit != Integer.MAX_VALUE) {
gaeCtx.realPageSize = limit;
fetchOptions.limit(gaeCtx.realPageSize);
}
}
} else {
// paginating so use the pagesize and don't passivate pageOption
// local limit is not taken into account
gaeCtx.realPageSize = pag.pageSize;
fetchOptions.limit(gaeCtx.realPageSize);
}
QueryOptionOffset off = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
// if local offset has been set, uses it
if (offset != 0) {
off.activate();
off.offset = offset;
}
// if previousPage has detected there is no more data, simply returns an empty list
if (gaeCtx.noMoreDataBefore) {
return new ArrayList<T>();
}
if (state.isStateless()) {
if (pag.isPaginating()) {
if (off.isActive()) {
gaeCtx.realOffset += off.offset;
fetchOptions.offset(gaeCtx.realOffset);
off.passivate();
} else {
fetchOptions.offset(gaeCtx.realOffset);
}
} else {
// if stateless and not paginating, resets the realoffset to 0
gaeCtx.realOffset = off.offset;
if (off.isActive()) {
fetchOptions.offset(gaeCtx.realOffset);
off.passivate();
}
}
switch(fetchType.fetchType) {
case ITER:
default:
{
// uses iterable as it is the only async request for prepared query for the time being
Iterable<Entity> entities = prepare(query).asIterable(fetchOptions);
return new GaeSienaIterable<T>(this, entities, query);
}
}
} else {
if (off.isActive()) {
// by default, we add the offset but it can be added with the realoffset
// in case of cursor desactivated
fetchOptions.offset(off.offset);
gaeCtx.realOffset += off.offset;
off.passivate();
}
// manages cursor limitations for IN and != operators
if (!gaeCtx.isActive()) {
// cursor not yet created
switch(fetchType.fetchType) {
case ITER:
default:
{
PreparedQuery pq = prepare(query);
if (pag.isPaginating()) {
// in case of pagination, we need to allow asynchronous calls such as:
// QueryAsync<MyClass> query = pm.createQuery(MyClass).paginate(5).stateful().order("name");
// SienaFuture<Iterable<MyClass>> future1 = query.iter();
// SienaFuture<Iterable<MyClass>> future2 = query.nextPage().iter();
// Iterable<MyClass> it = future1.get().iterator();
// while(it.hasNext()) { // do it }
// it = future2.get().iterator();
// while(it.hasNext()) { // do it }
// so we can't use the asQueryResultIterable as the cursor is not moved to the end of the current page
// but moved at each call of iterable.iterator().next()
// thus we use the List in this case to be able to move directly to the next page with cursors
QueryResultList<Entity> entities = pq.asQueryResultList(fetchOptions);
// activates the GaeCtx now that it is initialised
gaeCtx.activate();
// sets the current cursor (in stateful mode, cursor is always kept for further use)
// if(gaeCtx.useCursor){
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addCursor(cursor.toWebSafeString());
}
// }
return new GaeSienaIterable<T>(this, entities, query);
} else {
// if not paginating, we simply use the queryresultiterable and moves the current cursor
// while iterating
QueryResultIterable<Entity> entities = pq.asQueryResultIterable(fetchOptions);
// activates the GaeCtx now that it is initialised
gaeCtx.activate();
return new GaeSienaIterableWithCursor<T>(this, entities, query);
}
}
}
} else {
switch(fetchType.fetchType) {
case ITER:
default:
{
PreparedQuery pq = prepare(query);
if (pag.isPaginating()) {
// in case of pagination, we need to allow asynchronous calls such as:
// QueryAsync<MyClass> query = pm.createQuery(MyClass).paginate(5).stateful().order("name");
// SienaFuture<Iterable<MyClass>> future1 = query.iter();
// SienaFuture<Iterable<MyClass>> future2 = query.nextPage().iter();
// Iterable<MyClass> it = future1.get().iterator();
// while(it.hasNext()) { // do it }
// it = future2.get().iterator();
// while(it.hasNext()) { // do it }
// so we can't use the asQueryResultIterable as the cursor is not moved to the end of the current page
// but moved at each call of iterable.iterator().next()
// thus we use the List in this case to be able to move directly to the next page with cursors
QueryResultList<Entity> entities;
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(gaeCtx.realOffset);
// }
fetchOptions.offset(gaeCtx.realOffset);
entities = pq.asQueryResultList(fetchOptions);
} else {
String cursor = gaeCtx.currentCursor();
if (cursor != null) {
entities = pq.asQueryResultList(fetchOptions.startCursor(Cursor.fromWebSafeString(cursor)));
} else {
entities = pq.asQueryResultList(fetchOptions);
}
// sets the current cursor (in stateful mode, cursor is always kept for further use)
// if(gaeCtx.useCursor){
gaeCtx.addCursor(entities.getCursor().toWebSafeString());
// }
}
return new GaeSienaIterable<T>(this, entities, query);
} else {
// if not paginating, we simply use the queryresultiterable and moves the current cursor
// while iterating
QueryResultIterable<Entity> entities;
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(gaeCtx.realOffset);
// }
fetchOptions.offset(gaeCtx.realOffset);
entities = pq.asQueryResultIterable(fetchOptions);
} else {
String cursor = gaeCtx.currentCursor();
if (cursor != null) {
entities = pq.asQueryResultIterable(fetchOptions.startCursor(Cursor.fromWebSafeString(gaeCtx.currentCursor())));
} else {
entities = pq.asQueryResultIterable(fetchOptions);
}
}
return new GaeSienaIterableWithCursor<T>(this, entities, query);
}
}
}
}
}
}
use of com.google.appengine.api.datastore.FetchOptions in project siena by mandubian.
the class GaePersistenceManagerAsync method doFetchList.
private <T> SienaFuture<List<T>> doFetchList(QueryAsync<T> query, int limit, int offset) {
QueryOptionGaeContext gaeCtx = (QueryOptionGaeContext) query.option(QueryOptionGaeContext.ID);
if (gaeCtx == null) {
gaeCtx = new QueryOptionGaeContext();
query.customize(gaeCtx);
}
QueryOptionState state = (QueryOptionState) query.option(QueryOptionState.ID);
QueryOptionFetchType fetchType = (QueryOptionFetchType) query.option(QueryOptionFetchType.ID);
FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
QueryOptionPage pag = (QueryOptionPage) query.option(QueryOptionPage.ID);
if (!pag.isPaginating()) {
// no pagination but pageOption active
if (pag.isActive()) {
// if local limit is set, it overrides the pageOption.pageSize
if (limit != Integer.MAX_VALUE) {
gaeCtx.realPageSize = limit;
fetchOptions.limit(gaeCtx.realPageSize);
// pageOption is passivated to be sure it is not reused
pag.passivate();
} else // using pageOption.pageSize
{
gaeCtx.realPageSize = pag.pageSize;
fetchOptions.limit(gaeCtx.realPageSize);
// passivates the pageOption in stateless mode not to keep anything between 2 requests
if (state.isStateless()) {
pag.passivate();
}
}
} else {
if (limit != Integer.MAX_VALUE) {
gaeCtx.realPageSize = limit;
fetchOptions.limit(gaeCtx.realPageSize);
}
}
} else {
// paginating so use the pagesize and don't passivate pageOption
// local limit is not taken into account
gaeCtx.realPageSize = pag.pageSize;
fetchOptions.limit(gaeCtx.realPageSize);
}
QueryOptionOffset off = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
// if local offset has been set, uses it
if (offset != 0) {
off.activate();
off.offset = offset;
}
// if previousPage has detected there is no more data, simply returns an empty list
if (gaeCtx.noMoreDataBefore) {
return new SienaFutureMock<List<T>>(new ArrayList<T>());
}
if (state.isStateless()) {
if (pag.isPaginating()) {
if (off.isActive()) {
gaeCtx.realOffset += off.offset;
fetchOptions.offset(gaeCtx.realOffset);
off.passivate();
} else {
fetchOptions.offset(gaeCtx.realOffset);
}
} else {
// if stateless and not paginating, resets the realoffset to 0
gaeCtx.realOffset = 0;
if (off.isActive()) {
gaeCtx.realOffset = off.offset;
fetchOptions.offset(gaeCtx.realOffset);
off.passivate();
}
}
switch(fetchType.fetchType) {
case KEYS_ONLY:
{
// uses iterable as it is the only async request for prepared query for the time being
Iterable<Entity> entities = prepareKeysOnly(query).asIterable(fetchOptions);
return new GaeSienaFutureListMapper<T>(this, entities, query, GaeSienaFutureListMapper.MapType.KEYS_ONLY);
}
case NORMAL:
default:
{
// uses iterable as it is the only async request for prepared query for the time being
Iterable<Entity> entities = prepare(query).asIterable(fetchOptions);
return new GaeSienaFutureListMapper<T>(this, entities, query);
}
}
} else {
if (off.isActive()) {
// by default, we add the offset but it can be added with the realoffset
// in case of cursor desactivated
fetchOptions.offset(off.offset);
gaeCtx.realOffset += off.offset;
off.passivate();
}
// manages cursor limitations for IN and != operators by using offset
if (!gaeCtx.isActive()) {
// cursor not yet created
switch(fetchType.fetchType) {
case KEYS_ONLY:
{
PreparedQuery pq = prepareKeysOnly(query);
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(offset.offset);
// }
fetchOptions.offset(gaeCtx.realOffset);
}
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
QueryResultList<Entity> entities = pq.asQueryResultList(fetchOptions);
// activates the GaeCtx now that it is initialised
gaeCtx.activate();
// sets the current cursor (in stateful mode, cursor is always kept for further use)
if (pag.isPaginating()) {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addCursor(cursor.toWebSafeString());
}
} else {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addAndMoveCursor(entities.getCursor().toWebSafeString());
}
// keeps track of the offset anyway if not paginating
gaeCtx.realOffset += entities.size();
}
return new GaeSienaFutureListMapper<T>(this, entities, query, GaeSienaFutureListMapper.MapType.KEYS_ONLY);
}
case NORMAL:
default:
{
PreparedQuery pq = prepare(query);
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(offset.offset);
// }
fetchOptions.offset(gaeCtx.realOffset);
}
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
QueryResultList<Entity> entities = pq.asQueryResultList(fetchOptions);
// activates the GaeCtx now that it is initialised
gaeCtx.activate();
// if(gaeCtx.useCursor){
if (pag.isPaginating()) {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addCursor(cursor.toWebSafeString());
}
} else {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addAndMoveCursor(entities.getCursor().toWebSafeString());
}
// keeps track of the offset anyway if not paginating
gaeCtx.realOffset += entities.size();
}
return new GaeSienaFutureListMapper<T>(this, entities, query);
}
}
} else {
switch(fetchType.fetchType) {
case KEYS_ONLY:
{
// we prepare the query each time
PreparedQuery pq = prepareKeysOnly(query);
QueryResultList<Entity> entities;
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(offset.offset);
// }
fetchOptions.offset(gaeCtx.realOffset);
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
entities = pq.asQueryResultList(fetchOptions);
} else {
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
String cursor = gaeCtx.currentCursor();
if (cursor != null) {
entities = pq.asQueryResultList(fetchOptions.startCursor(Cursor.fromWebSafeString(cursor)));
} else {
entities = pq.asQueryResultList(fetchOptions);
}
}
// if(gaeCtx.useCursor){
if (pag.isPaginating()) {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addCursor(cursor.toWebSafeString());
}
} else {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addAndMoveCursor(entities.getCursor().toWebSafeString());
}
// keeps track of the offset anyway if not paginating
gaeCtx.realOffset += entities.size();
}
return new GaeSienaFutureListMapper<T>(this, entities, query, GaeSienaFutureListMapper.MapType.KEYS_ONLY);
}
case NORMAL:
default:
{
PreparedQuery pq = prepare(query);
QueryResultList<Entity> entities;
if (!gaeCtx.useCursor) {
// then uses offset (in case of IN or != operators)
// if(offset.isActive()){
// fetchOptions.offset(offset.offset);
// }
fetchOptions.offset(gaeCtx.realOffset);
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
entities = pq.asQueryResultList(fetchOptions);
} else {
// we can't use real asynchronous function with cursors
// so the page is extracted at once and wrapped into a SienaFuture
String cursor = gaeCtx.currentCursor();
if (cursor != null) {
entities = pq.asQueryResultList(fetchOptions.startCursor(Cursor.fromWebSafeString(gaeCtx.currentCursor())));
} else {
entities = pq.asQueryResultList(fetchOptions);
}
}
// if(gaeCtx.useCursor){
if (pag.isPaginating()) {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addCursor(cursor.toWebSafeString());
}
} else {
Cursor cursor = entities.getCursor();
if (cursor != null) {
gaeCtx.addAndMoveCursor(entities.getCursor().toWebSafeString());
}
// keeps track of the offset anyway
gaeCtx.realOffset += entities.size();
}
return new GaeSienaFutureListMapper<T>(this, entities, query);
}
}
}
}
}
use of com.google.appengine.api.datastore.FetchOptions in project getting-started-java by GoogleCloudPlatform.
the class DatastoreDao method listBooks.
// [END entitiesToBooks]
// [START listbooks]
@Override
public Result<Book> listBooks(String startCursorString) {
// Only show 10 at a time
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(10);
if (startCursorString != null && !startCursorString.equals("")) {
// Where we left off
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursorString));
}
Query query = // We only care about Books
new Query(BOOK_KIND).addSort(Book.TITLE, // Use default Index "title"
SortDirection.ASCENDING);
PreparedQuery preparedQuery = datastore.prepare(query);
QueryResultIterator<Entity> results = preparedQuery.asQueryResultIterator(fetchOptions);
// Retrieve and convert Entities
List<Book> resultBooks = entitiesToBooks(results);
// Where to start next time
Cursor cursor = results.getCursor();
if (cursor != null && resultBooks.size() == 10) {
// Are we paging? Save Cursor
// Cursors are WebSafe
String cursorString = cursor.toWebSafeString();
return new Result<>(resultBooks, cursorString);
} else {
return new Result<>(resultBooks);
}
}
use of com.google.appengine.api.datastore.FetchOptions in project Cached-Datastore by Emperorlou.
the class CachedDatastoreService method fetchKeys.
private List<Key> fetchKeys(Query q, int limit) {
q.setKeysOnly();
prepareQuery(q);
int chunkSize = limit;
FetchOptions fo = FetchOptions.Builder.withLimit(limit).chunkSize(chunkSize).prefetchSize(limit);
List<Key> keys = new ArrayList<>();
List<Entity> entities = pq.asList(fo);
int count = entities.size();
if (count > limit)
count = limit;
for (int i = 0; i < count; i++) {
Entity e = entities.get(i);
keys.add(e.getKey());
}
lastQuery_endCursor = null;
if (statsTracking)
incrementStat(QUERYKEYCACHE_QUERIES);
return keys;
}
use of com.google.appengine.api.datastore.FetchOptions in project getting-started-java by GoogleCloudPlatform.
the class DatastoreDao method listBooksByUser.
// [END listbooks]
// [START listbyuser]
@Override
public Result<Book> listBooksByUser(String userId, String startCursorString) {
// Only show 10 at a time
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(10);
if (startCursorString != null && !startCursorString.equals("")) {
// Where we left off
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursorString));
}
Query query = // We only care about Books
new Query(BOOK_KIND).setFilter(new Query.FilterPredicate(Book.CREATED_BY_ID, Query.FilterOperator.EQUAL, userId)).addSort(Book.TITLE, SortDirection.ASCENDING);
PreparedQuery preparedQuery = datastore.prepare(query);
QueryResultIterator<Entity> results = preparedQuery.asQueryResultIterator(fetchOptions);
// Retrieve and convert Entities
List<Book> resultBooks = entitiesToBooks(results);
// Where to start next time
Cursor cursor = results.getCursor();
if (cursor != null && resultBooks.size() == 10) {
// Are we paging? Save Cursor
// Cursors are WebSafe
String cursorString = cursor.toWebSafeString();
return new Result<>(resultBooks, cursorString);
} else {
return new Result<>(resultBooks);
}
}
Aggregations