11defimpl Scrivener.Paginater , for: Ecto.Query do
22 import Ecto.Query
33
4- alias Scrivener . { Config , Page }
4+ alias Scrivener . { Config , Page , SimplePage }
55
66 @ moduledoc false
77
8- @ spec paginate ( Ecto.Query . t ( ) , Scrivener.Config . t ( ) ) :: Scrivener.Page . t ( )
8+ @ spec paginate ( Ecto.Query . t ( ) , Scrivener.Config . t ( ) ) ::
9+ Scrivener.Page . t ( ) | Scrivener.SimplePage . t ( )
910 def paginate ( query , % Config {
10- page_size: page_size ,
11- page_number: page_number ,
11+ page_type: :normal ,
1212 module: repo ,
1313 caller: caller ,
14+ page_number: page_number ,
15+ page_size: page_size ,
1416 options: options
1517 } ) do
1618 total_entries =
@@ -26,25 +28,59 @@ defimpl Scrivener.Paginater, for: Ecto.Query do
2628 page_number =
2729 if allow_overflow_page_number , do: page_number , else: min ( total_pages , page_number )
2830
31+ entries =
32+ if page_number > total_pages ,
33+ do: [ ] ,
34+ else: entries ( query , repo , page_number , page_size , options )
35+
2936 % Page {
3037 page_size: page_size ,
3138 page_number: page_number ,
32- entries: entries ( query , repo , page_number , total_pages , page_size , options ) ,
39+ entries: entries ,
3340 total_entries: total_entries ,
3441 total_pages: total_pages
3542 }
3643 end
3744
38- defp entries ( _query , _repo , page_number , total_pages , _page_size , _options )
39- when page_number > total_pages ,
40- do: [ ]
45+ def paginate ( query , % Config {
46+ page_type: :simple ,
47+ module: repo ,
48+ page_number: page_number ,
49+ page_size: page_size ,
50+ options: options
51+ } ) do
52+ entries_with_maybe_one_extra =
53+ entries ( query , repo , page_number , page_size , options , extra_entry_size: 1 )
54+
55+ { entries , has_more } =
56+ if length ( entries_with_maybe_one_extra ) > page_size do
57+ entries =
58+ entries_with_maybe_one_extra
59+ |> Enum . reverse ( )
60+ |> tl ( )
61+ |> Enum . reverse ( )
62+
63+ { entries , true }
64+ else
65+ { entries_with_maybe_one_extra , false }
66+ end
67+
68+ % SimplePage {
69+ page_size: page_size ,
70+ page_number: page_number ,
71+ entries: entries ,
72+ has_more: has_more
73+ }
74+ end
4175
42- defp entries ( query , repo , page_number , _total_pages , page_size , options ) do
76+ defp entries ( query , repo , page_number , page_size , options , opts \\ [ ] ) do
77+ extra_entry_size = Keyword . get ( opts , :extra_entry_size , 0 )
4378 offset = Keyword . get_lazy ( options , :offset , fn -> page_size * ( page_number - 1 ) end )
79+ limit = page_size + extra_entry_size
4480
4581 query
4682 |> offset ( ^ offset )
47- |> limit ( ^ page_size )
83+ |> limit ( ^ limit )
4884 |> repo . all ( options )
4985 end
5086
0 commit comments