use of siena.core.options.QueryOptionState in project siena by mandubian.
the class SdbMappingUtils method previousPage.
public static <T> void previousPage(QueryData<T> query) {
QueryOptionPage pag = (QueryOptionPage) query.option(QueryOptionPage.ID);
QueryOptionState state = (QueryOptionState) query.option(QueryOptionState.ID);
QueryOptionSdbContext sdbCtx = (QueryOptionSdbContext) query.option(QueryOptionSdbContext.ID);
if (sdbCtx == null) {
sdbCtx = new QueryOptionSdbContext();
query.options().put(sdbCtx.type, sdbCtx);
}
// if no more data before, doesn't try to go before
if (sdbCtx.noMoreDataBefore) {
return;
}
// if no more data after, removes flag to be able to go before
if (sdbCtx.noMoreDataAfter) {
// here the realoffset is not at the end of current pages
// but at the beginning of the last page
// so need to fake that we are at the end of the last page
sdbCtx.realOffset += pag.pageSize;
sdbCtx.noMoreDataAfter = false;
}
if (pag.isPaginating()) {
if (sdbCtx.hasToken()) {
// if tokenIdx is 0, it means at first page after beginning
if (sdbCtx.tokenIdx == 0) {
sdbCtx.previousToken();
// follows the real offset
sdbCtx.realOffset -= pag.pageSize;
// uses offset
if (sdbCtx.currentTokenOffset() <= sdbCtx.realOffset) {
QueryOptionOffset offset = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
offset.activate();
offset.offset = sdbCtx.realOffset - sdbCtx.currentTokenOffset();
} else // if currentokenoffset is greater than previous page realoffset
// go to previous page again
{
previousPage(query);
}
} else {
if (sdbCtx.previousToken() == null) {
sdbCtx.realOffset -= pag.pageSize;
// so now uses realOffset
if (sdbCtx.realOffset >= 0) {
QueryOptionOffset offset = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
offset.activate();
offset.offset = sdbCtx.realOffset;
} else {
// resets realOffset to 0 because it was negative
sdbCtx.realOffset = 0;
sdbCtx.noMoreDataBefore = true;
}
} else {
// follows the real offset
sdbCtx.realOffset -= pag.pageSize;
// uses offset
if (sdbCtx.currentTokenOffset() <= sdbCtx.realOffset) {
QueryOptionOffset offset = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
offset.activate();
offset.offset = sdbCtx.realOffset - sdbCtx.currentTokenOffset();
} else // if currentokenoffset is greater than previous page realoffset
// go to previous page again
{
previousPage(query);
}
}
}
} else {
QueryOptionOffset offset = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
// to simulate the nextPage as there was no token yet
if (sdbCtx.realOffset != 0) {
// follows the real offset
sdbCtx.realOffset -= pag.pageSize;
offset.activate();
offset.offset = sdbCtx.realOffset;
} else {
sdbCtx.noMoreDataBefore = true;
}
/*if(offset.offset != 0){
offset.offset -= pag.pageSize;
offset.activate();
// follows the real offset
sdbCtx.realOffset -= pag.pageSize;
}else {
// if the realOffset is not null, it means we are not at the index 0 of the table
// so now uses realOffset
if(sdbCtx.realOffset != 0){
offset.activate();
offset.offset = sdbCtx.realOffset;
}
sdbCtx.noMoreDataBefore = true;
}*/
}
} else {
// throws exception because it's impossible to reuse nextPage when paginating has been interrupted, the cases are too many
throw new SienaException("Can't use nextPage after pagination has been interrupted...");
}
}
use of siena.core.options.QueryOptionState in project siena by mandubian.
the class SdbPersistenceManager method continueFetchNextToken.
protected <T> void continueFetchNextToken(Query<T> query, List<T> results, int depth) {
QueryOptionPage pag = (QueryOptionPage) query.option(QueryOptionPage.ID);
QueryOptionSdbContext sdbCtx = (QueryOptionSdbContext) query.option(QueryOptionSdbContext.ID);
QueryOptionState state = (QueryOptionState) query.option(QueryOptionState.ID);
QueryOptionOffset off = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
// desactivates offset not to use if fetching more items from next token
if (state.isStateless()) {
off.passivate();
}
if (!pag.isActive()) {
if (state.isStateless()) {
// retrieves next token
if (sdbCtx.nextToken() != null) {
doFetchList(query, Integer.MAX_VALUE, 0, results, depth + 1);
}
} else {
if (sdbCtx.currentToken() != null) {
// desactivates offset because we don't to go on using offset while going to next tokens
boolean b = off.isActive();
off.passivate();
doFetchList(query, Integer.MAX_VALUE, 0, results, depth + 1);
// reactivate it if it was activated
if (b)
off.activate();
}
}
}
}
use of siena.core.options.QueryOptionState in project siena by mandubian.
the class SdbPersistenceManager method preFetch.
protected <T> void preFetch(Query<T> query, int limit, int offset, boolean recursing) {
QueryOptionSdbContext sdbCtx = (QueryOptionSdbContext) query.option(QueryOptionSdbContext.ID);
QueryOptionState state = (QueryOptionState) query.option(QueryOptionState.ID);
QueryOptionPage pag = (QueryOptionPage) query.option(QueryOptionPage.ID);
QueryOptionOffset off = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
if (sdbCtx == null) {
sdbCtx = new QueryOptionSdbContext();
query.customize(sdbCtx);
}
if (!pag.isPaginating()) {
if (state.isStateless()) {
// if not empty, it means we are recursing on tokens
sdbCtx.reset(recursing);
}
// no pagination but pageOption active
if (pag.isActive()) {
// if local limit is set, it overrides the pageOption.pageSize
if (limit != Integer.MAX_VALUE) {
sdbCtx.realPageSize = limit;
// DONT DO THAT BECAUSE IT PREVENTS GOING TO NEXT TOKENS USING PAGE SIZE
// pageOption is passivated to be sure it is not reused
//pag.passivate();
} else // using pageOption.pageSize
{
sdbCtx.realPageSize = pag.pageSize;
// DONT DO THAT BECAUSE IT PREVENTS GOING TO NEXT TOKENS USING PAGE SIZE
// passivates the pageOption in stateless mode not to keep anything between 2 requests
//if(state.isStateless()){
// pag.passivate();
//}
}
} else {
if (limit != Integer.MAX_VALUE) {
sdbCtx.realPageSize = limit;
// activates paging (but not pagination)
pag.activate();
} else {
sdbCtx.realPageSize = 0;
}
}
} else {
// paginating so use the pagesize and don't passivate pageOption
// local limit is not taken into account
sdbCtx.realPageSize = pag.pageSize;
}
// if local offset has been set, uses it
if (offset != 0) {
off.activate();
off.offset = offset;
}
}
use of siena.core.options.QueryOptionState in project siena by mandubian.
the class BaseQueryData method optionStateless.
protected void optionStateless() {
QueryOptionState opt = (QueryOptionState) (options.get(QueryOptionState.ID)).activate();
opt.lifeCycle = QueryOptionState.LifeCycle.STATELESS;
}
use of siena.core.options.QueryOptionState 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);
}
}
}
}
}
Aggregations