TurnThePage - very small, fast and lightweight pagination app


I had this code waiting to published few months. I used all the time scrivener_ecto, but I realised it takes some time to count all the pages within, which is useless for me.

I created one simple module that uses Stream & Enum functions for paging lists and Ecto.Query for queries.


|> TurnThePage.paginate(page: 2, limit: 15) # it returns Ecto.Query
|> Repo.all()

Link to hex: turn_the_page

I hope it will help you :slight_smile:


Hey there. As a minor note you probably don’t want to be pattern matching on keyword lists https://github.com/PatNowak/turn_the_page/blob/master/lib/turn_the_page.ex#L33

Keyword lists are order dependent, so if someone calls it like: |> TurnThePage.paginate(limit: 15, page: 3) it will explode.


Thanks, I’m gonna enhance it :slight_smile:
Edit: Already fixed.

@benwilson512, thanks again! :slight_smile: You did turn this page into good direction :slight_smile:


What happens if someone is paging through when a new record is added to the front, doesn’t it keep it’s place or is everything shifted? What if something is deleted?

1 Like

Imagine the situation:

You have a list Enum.to_list(1..100) and if you use TurnThePage.paginate(list, page: 3, limit: 8) you would get Enum.to_list(17..24).

If you would like to insert somewhere new element, it depends whether you would like to do before or after the paginate call.

I guess your question is more related to the DB situation - I paginate the entries, but in the same time someone just inserted new one. It depends now which call to DB was faster - mine with select or another person’s with insert. If mine - I see “old” requests, if his, I will see this new one as well.

This library is really simple. I wrote it few months ago on personal purpose, because I saw that scrivener_ecto returns more metadata, but they slow down the request (eg. total_item_count etc.).

TL;DR: You paginate the collection as it is. What you see, is what you will paginate (WYSIWYWP) :slight_smile:

I’m thinking more concurrently, like, oh, a messaging forum, where users can keep posting new things thus.

Yeah that is a big problem most paginate libraries have. You should not paginate based on the order but rather you should paginate based on some ordered unique ID. For example I paginate an ‘amount’ after a unique ID, there-for it always stays in sync (since my unique ID is linearly added, I often just use inserted_at with the id as a tie-breaker in the query).