This is a gem that will help you to get pagination working on the Google AppEngine. It uses the AppEngine Cursor so currently you can only get the next cursor, you cannot go in reverse and get previous records. In order to do that you would need to have two queries.
gem install appengine-paginator
Simply create a paginate object by passing it an AppEngine::Datastore::Query object, the limit, then an optional model and option cursor.
i.e. p = Paginator::Paginate.new(query, 10, :model => Post, :cursor => c)
The query and the limit are pretty self explanitory. The :model is an optional datamapper model that is used if you want the paginate object to return active record models. The cursor is what tells the query where to start, thus giving it pagination.
Once the paginate object is created you can access the results by either calling result or datamapper_result. The result method returns the raw entities returned by the query. The datastore_result method returns an array of Datamapper models that are instiances of the the model class (the class you passed in at creating time). If a cursor is passed in then the result set will start with the record indicated by the cursor (i.e. if you passed in a limit of 10 and then created the cursor it would point to the 11th search result).
In order to get the cursor simply call cursor on the paginate object. This will return an instance of Paginator::Cursor (a wrapper for com.google.appengine.api.datastore.Cursor) which points to the first row after the given limit. Simple call to_s on the cursor object to get a string representation that can be stored in a session, the datastore, or on the rendered HTML page. Calling Paginator::Cursor.parse <string_representation_of_cursor> will convert the cursor string back into a cursor object that can be passed into a new Paginator::Paginate object.
As long as DataMapper is loaded before appengine-paginator then it will integrate into DataMapper. With datamapper integration you can pass the cursor into the query like this: p = Post.all(:limit => 10, :cursor => c, :updated_at.gt => Date.today) (where c is a Paginator::Cursor). Also all the result sets of datamapper queries now have a cursor method that will return the Paginator::Cursor that is the start of the next query. Here is a complete example:
posts = Post.all :updated_at.gt => Date.today, :limit => 10 c = posts.cursor
next_page_posts = Post.all :updated_at.gt => Date.today, :limit => 10, :cursor => c
Note on Patches/Pull Requests
Fork the project.
Make your feature addition or bug fix.
Add tests for it. This is important so I don't break it in a future version unintentionally.
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
Send me a pull request. Bonus points for topic branches.
Copyright © 2010 Josh Moore. See LICENSE for details.