Search in sources :

Example 1 with QueryOptionState

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...");
    }
}
Also used : QueryOptionOffset(siena.core.options.QueryOptionOffset) QueryOptionPage(siena.core.options.QueryOptionPage) QueryOptionState(siena.core.options.QueryOptionState) SienaException(siena.SienaException)

Example 2 with QueryOptionState

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();
            }
        }
    }
}
Also used : QueryOptionOffset(siena.core.options.QueryOptionOffset) QueryOptionPage(siena.core.options.QueryOptionPage) QueryOptionState(siena.core.options.QueryOptionState)

Example 3 with QueryOptionState

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;
    }
}
Also used : QueryOptionOffset(siena.core.options.QueryOptionOffset) QueryOptionPage(siena.core.options.QueryOptionPage) QueryOptionState(siena.core.options.QueryOptionState)

Example 4 with QueryOptionState

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;
}
Also used : QueryOptionState(siena.core.options.QueryOptionState)

Example 5 with QueryOptionState

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);
                    }
            }
        }
    }
}
Also used : FetchOptions(com.google.appengine.api.datastore.FetchOptions) QueryOptionOffset(siena.core.options.QueryOptionOffset) QueryResultIterable(com.google.appengine.api.datastore.QueryResultIterable) QueryResultList(com.google.appengine.api.datastore.QueryResultList) PreparedQuery(com.google.appengine.api.datastore.PreparedQuery) QueryOptionFetchType(siena.core.options.QueryOptionFetchType) Cursor(com.google.appengine.api.datastore.Cursor) SienaFutureMock(siena.core.async.SienaFutureMock) QueryOptionPage(siena.core.options.QueryOptionPage) QueryOptionState(siena.core.options.QueryOptionState)

Aggregations

QueryOptionState (siena.core.options.QueryOptionState)20 QueryOptionOffset (siena.core.options.QueryOptionOffset)16 QueryOptionPage (siena.core.options.QueryOptionPage)15 SienaException (siena.SienaException)6 ArrayList (java.util.ArrayList)5 QueryOptionFetchType (siena.core.options.QueryOptionFetchType)5 Cursor (com.google.appengine.api.datastore.Cursor)4 FetchOptions (com.google.appengine.api.datastore.FetchOptions)4 PreparedQuery (com.google.appengine.api.datastore.PreparedQuery)4 QueryResultList (com.google.appengine.api.datastore.QueryResultList)4 QueryResultIterable (com.google.appengine.api.datastore.QueryResultIterable)3 PreparedStatement (java.sql.PreparedStatement)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 SienaFutureMock (siena.core.async.SienaFutureMock)2 HashMap (java.util.HashMap)1 List (java.util.List)1