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.
Example:
User
|> TurnThePage.paginate(page: 2, limit: 15) # it returns Ecto.Query
|> Repo.all()
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?
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)
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).