Search in sources :

Example 1 with QueryOptionFetchType

use of siena.core.options.QueryOptionFetchType 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)

Example 2 with QueryOptionFetchType

use of siena.core.options.QueryOptionFetchType 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);
                        }
                    }
            }
        }
    }
}
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) ArrayList(java.util.ArrayList) PreparedQuery(com.google.appengine.api.datastore.PreparedQuery) QueryOptionFetchType(siena.core.options.QueryOptionFetchType) Cursor(com.google.appengine.api.datastore.Cursor) QueryResultIterable(com.google.appengine.api.datastore.QueryResultIterable) QueryOptionPage(siena.core.options.QueryOptionPage) QueryOptionState(siena.core.options.QueryOptionState)

Example 3 with QueryOptionFetchType

use of siena.core.options.QueryOptionFetchType in project siena by mandubian.

the class GaePersistenceManager method doFetchList.

private <T> List<T> doFetchList(Query<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 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
                    List<Entity> entities = prepareKeysOnly(query).asList(fetchOptions);
                    // if paginating and 0 results then no more data else resets noMoreDataAfter
                    if (pag.isPaginating()) {
                        if (entities.size() == 0) {
                            gaeCtx.noMoreDataAfter = true;
                        } else {
                            gaeCtx.noMoreDataAfter = false;
                        }
                    }
                    return mapKeysOnly(query, entities);
                }
            case NORMAL:
            default:
                {
                    // uses iterable as it is the only async request for prepared query for the time being
                    List<Entity> entities = prepare(query).asList(fetchOptions);
                    // if paginating and 0 results then no more data else resets noMoreDataAfter
                    if (pag.isPaginating()) {
                        if (entities.size() == 0) {
                            gaeCtx.noMoreDataAfter = true;
                        } else {
                            gaeCtx.noMoreDataAfter = false;
                        }
                    }
                    return map(query, entities);
                }
        }
    } 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 with offsets
        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(gaeCtx.realOffset);
                            //}						
                            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());
                            }
                            // if paginating and 0 results then no more data else resets noMoreDataAfter
                            if (entities.size() == 0) {
                                gaeCtx.noMoreDataAfter = true;
                            } else {
                                gaeCtx.noMoreDataAfter = false;
                            }
                        } 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 mapKeysOnly(query, entities);
                    }
                case NORMAL:
                default:
                    {
                        PreparedQuery pq = prepare(query);
                        if (!gaeCtx.useCursor) {
                            // then uses offset (in case of IN or != operators)
                            //if(offset.isActive()){
                            //	fetchOptions.offset(gaeCtx.realOffset);
                            //}
                            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());
                            }
                            // if paginating and 0 results then no more data else resets noMoreDataAfter
                            if (entities.size() == 0) {
                                gaeCtx.noMoreDataAfter = true;
                            } else {
                                gaeCtx.noMoreDataAfter = false;
                            }
                        } 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 map(query, entities);
                    }
            }
        } 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(gaeCtx.realOffset);
                            //}
                            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);
                            }
                        }
                        // 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());
                            }
                            // if paginating and 0 results then no more data else resets noMoreDataAfter
                            if (entities.size() == 0) {
                                gaeCtx.noMoreDataAfter = true;
                            } else {
                                gaeCtx.noMoreDataAfter = false;
                            }
                        } 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 mapKeysOnly(query, entities);
                    }
                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(gaeCtx.realOffset);
                            //}
                            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);
                            }
                        }
                        // 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());
                            }
                            // if paginating and 0 results then no more data else resets noMoreDataAfter
                            if (entities.size() == 0) {
                                gaeCtx.noMoreDataAfter = true;
                            } else {
                                gaeCtx.noMoreDataAfter = false;
                            }
                        } else {
                            Cursor cursor = entities.getCursor();
                            if (cursor != null) {
                                gaeCtx.addAndMoveCursor(entities.getCursor().toWebSafeString());
                            }
                            // keeps track of the offset anyway
                            gaeCtx.realOffset += entities.size();
                        }
                        return map(query, entities);
                    }
            }
        }
    }
}
Also used : FetchOptions(com.google.appengine.api.datastore.FetchOptions) QueryOptionOffset(siena.core.options.QueryOptionOffset) QueryOptionPage(siena.core.options.QueryOptionPage) QueryResultList(com.google.appengine.api.datastore.QueryResultList) QueryOptionState(siena.core.options.QueryOptionState) ArrayList(java.util.ArrayList) PreparedQuery(com.google.appengine.api.datastore.PreparedQuery) QueryResultList(com.google.appengine.api.datastore.QueryResultList) ArrayList(java.util.ArrayList) List(java.util.List) QueryOptionFetchType(siena.core.options.QueryOptionFetchType) Cursor(com.google.appengine.api.datastore.Cursor)

Example 4 with QueryOptionFetchType

use of siena.core.options.QueryOptionFetchType in project siena by mandubian.

the class SdbPersistenceManager method doFetchList.

protected <T> void doFetchList(Query<T> query, int limit, int offset, List<T> resList, int depth) {
    if (depth >= MAX_DEPTH) {
        throw new SienaException("Reached maximum depth of recursion when retrieving more data (" + MAX_DEPTH + ")");
    }
    preFetch(query, limit, offset, !resList.isEmpty());
    QueryOptionSdbContext sdbCtx = (QueryOptionSdbContext) query.option(QueryOptionSdbContext.ID);
    QueryOptionFetchType fetchType = (QueryOptionFetchType) query.option(QueryOptionFetchType.ID);
    QueryOptionOffset off = (QueryOptionOffset) query.option(QueryOptionOffset.ID);
    // if previousPage has detected there is no more data, simply returns an empty list
    if (sdbCtx.noMoreDataBefore || sdbCtx.noMoreDataAfter) {
        return;
    }
    // manages cursor limitations for IN and != operators with offsets
    if (!sdbCtx.isActive()) {
        StringBuffer domainBuf = new StringBuffer();
        SelectRequest req = SdbMappingUtils.buildQuery(query, prefix, domainBuf);
        req.setConsistentRead(isReadConsistent());
        checkDomain(domainBuf.toString());
        SelectResult res = sdb.select(req);
        // activates the SdbCtx now that it is really initialised
        sdbCtx.activate();
        postFetch(query, res);
        // cursor not yet created
        switch(fetchType.fetchType) {
            case KEYS_ONLY:
                if (off.isActive()) {
                    SdbMappingUtils.mapSelectResultToListKeysOnly(res, resList, query.getQueriedClass(), off.offset);
                } else {
                    SdbMappingUtils.mapSelectResultToListKeysOnly(res, resList, query.getQueriedClass());
                }
                break;
            case NORMAL:
            default:
                if (off.isActive()) {
                    SdbMappingUtils.mapSelectResultToList(res, resList, query.getQueriedClass(), off.offset);
                } else {
                    SdbMappingUtils.mapSelectResultToList(res, resList, query.getQueriedClass());
                }
                // join management
                if (!query.getJoins().isEmpty() || !ClassInfo.getClassInfo(query.getQueriedClass()).joinFields.isEmpty())
                    mapJoins(query, resList);
        }
        continueFetchNextToken(query, resList, depth);
        postMapping(query);
    } else {
        // we prepare the query each time
        StringBuffer domainBuf = new StringBuffer();
        SelectRequest req = SdbMappingUtils.buildQuery(query, prefix, domainBuf);
        req.setConsistentRead(isReadConsistent());
        checkDomain(domainBuf.toString());
        // we can't use real asynchronous function with cursors
        // so the page is extracted at once and wrapped into a SienaFuture			
        String token = sdbCtx.currentToken();
        if (token != null) {
            req.setNextToken(token);
        }
        SelectResult res = sdb.select(req);
        postFetch(query, res);
        switch(fetchType.fetchType) {
            case KEYS_ONLY:
                if (off.isActive()) {
                    SdbMappingUtils.mapSelectResultToListKeysOnly(res, resList, query.getQueriedClass(), off.offset);
                } else {
                    SdbMappingUtils.mapSelectResultToListKeysOnly(res, resList, query.getQueriedClass());
                }
                break;
            case NORMAL:
            default:
                if (off.isActive()) {
                    SdbMappingUtils.mapSelectResultToList(res, resList, query.getQueriedClass(), off.offset);
                } else {
                    SdbMappingUtils.mapSelectResultToList(res, resList, query.getQueriedClass());
                }
                // join management
                if (!query.getJoins().isEmpty() || !ClassInfo.getClassInfo(query.getQueriedClass()).joinFields.isEmpty())
                    mapJoins(query, resList);
        }
        continueFetchNextToken(query, resList, depth);
        postMapping(query);
    }
}
Also used : QueryOptionOffset(siena.core.options.QueryOptionOffset) SelectResult(com.amazonaws.services.simpledb.model.SelectResult) SienaException(siena.SienaException) QueryOptionFetchType(siena.core.options.QueryOptionFetchType) SelectRequest(com.amazonaws.services.simpledb.model.SelectRequest)

Example 5 with QueryOptionFetchType

use of siena.core.options.QueryOptionFetchType in project siena by mandubian.

the class SdbMappingUtils method buildQuery.

public static <T> SelectRequest buildQuery(Query<T> query, String prefix, StringBuffer domainBuf) {
    Class<?> clazz = query.getQueriedClass();
    String domain = getDomainName(clazz, prefix);
    domainBuf.append(domain);
    QueryOptionFetchType fetchType = (QueryOptionFetchType) query.option(QueryOptionFetchType.ID);
    StringBuilder q = new StringBuilder();
    switch(fetchType.fetchType) {
        case KEYS_ONLY:
            q.append(SELECT + ITEM_NAME + FROM + domain);
            break;
        case NORMAL:
        default:
            q.append(SELECT + ALL_COLS + FROM + domain);
            break;
    }
    return new SelectRequest(buildFilterOrder(query, q).toString());
}
Also used : QueryOptionFetchType(siena.core.options.QueryOptionFetchType) SelectRequest(com.amazonaws.services.simpledb.model.SelectRequest)

Aggregations

QueryOptionFetchType (siena.core.options.QueryOptionFetchType)7 QueryOptionOffset (siena.core.options.QueryOptionOffset)6 QueryOptionPage (siena.core.options.QueryOptionPage)5 QueryOptionState (siena.core.options.QueryOptionState)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 SelectRequest (com.amazonaws.services.simpledb.model.SelectRequest)2 ArrayList (java.util.ArrayList)2 SienaFutureMock (siena.core.async.SienaFutureMock)2 SelectResult (com.amazonaws.services.simpledb.model.SelectResult)1 HashMap (java.util.HashMap)1 List (java.util.List)1 SienaException (siena.SienaException)1