Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objectify return List & Cursor

I am trying to use a cursor with Objectify and Google App Engine to return a subset of data and a cursor so that I can retrieve more data when the user is ready. I found an example here that looks exactly like what I need but I don't know how to return the final list plus the cursor. Here is the code I have:

@ApiMethod(name = "listIconThemeCursor") //https://code.google.com/p/objectify-appengine/wiki/Queries#Cursors
public CollectionResponse<IconTheme> listIconThemeCursor(@Named("cursor") String cursorStr) {
    Query<IconTheme> query = ofy().load().type(IconTheme.class).limit(10);
    if (cursorStr != null ) {
        query.startAt(Cursor.fromWebSafeString(cursorStr));
    }
    List<IconTheme> result = new ArrayList<IconTheme>();
    int count = 0;
    QueryResultIterator<IconTheme> iterator = query.iterator();
    while (iterator.hasNext()) {
        IconTheme theme = iterator.next();
        result.add(theme);
        count++;
    }
    Cursor cursor = iterator.getCursor();
    String encodeCursor = cursor.toWebSafeString();
    return serial(tClass, result, encodeCursor);
}

Note that this was modified from a previous endpoint in which I returned the CollectionResponse of ALL the data. My dataset is large enough that this is no longer practical. Basically, I don't know what was in the user's function of 'serial(tClass, result, encodeCursor) that let it get returned to the user.

There is another example here but it doesn't appear to answer my question either.

like image 599
easycheese Avatar asked Aug 15 '14 02:08

easycheese


2 Answers

I don't quite understand what you are asking, but I see one immediate bug in your code:

query.startAt(Cursor.fromWebSafeString(cursorStr));

...should be:

query = query.startAt(Cursor.fromWebSafeString(cursorStr));

Objectify command objects are immutable, functional objects.

like image 93
stickfigure Avatar answered Nov 15 '22 07:11

stickfigure


After a long slog, I figured out that CollectionResponse has the cursor in it :(

Here is the complete code I used incorporating the comment from stickfigure above:

   @ApiMethod(name = "listIconThemeCursor", path="get_cursor") 
    public CollectionResponse<IconTheme> listIconThemeCursor(@Named("cursor") String cursorStr) {
        Query<IconTheme> query = ofy().load().type(IconTheme.class)
                .filter("errors <", 10)
                .limit(10);
        if (cursorStr != null ) {
            query = query.startAt(Cursor.fromWebSafeString(cursorStr));
        }
        List<IconTheme> result = new ArrayList<IconTheme>();
        QueryResultIterator<IconTheme> iterator = query.iterator();
        while (iterator.hasNext()) {
            IconTheme theme = iterator.next();
            result.add(theme);
        }
        Cursor cursor = iterator.getCursor();
        CollectionResponse<IconTheme> response = CollectionResponse.<IconTheme> builder()
                .setItems(result)
                .setNextPageToken(cursor.toWebSafeString())
                .build();

        return response;
    }
like image 25
easycheese Avatar answered Nov 15 '22 09:11

easycheese