forked from gobuffalo/pop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
paginator.go
130 lines (110 loc) · 3.35 KB
/
paginator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package pop
import (
"encoding/json"
"strconv"
"github.com/gobuffalo/pop/v5/internal/defaults"
)
// PaginatorPerPageDefault is the amount of results per page
var PaginatorPerPageDefault = 20
// PaginatorPageKey is the query parameter holding the current page index
var PaginatorPageKey = "page"
// PaginatorPerPageKey is the query parameter holding the amount of results per page
// to override the default one
var PaginatorPerPageKey = "per_page"
type paginable interface {
Paginate() string
}
var _ paginable = Paginator{}
// Paginator is a type used to represent the pagination of records
// from the database.
type Paginator struct {
// Current page you're on
Page int `json:"page"`
// Number of results you want per page
PerPage int `json:"per_page"`
// Page * PerPage (ex: 2 * 20, Offset == 40)
Offset int `json:"offset"`
// Total potential records matching the query
TotalEntriesSize int `json:"total_entries_size"`
// Total records returns, will be <= PerPage
CurrentEntriesSize int `json:"current_entries_size"`
// Total pages
TotalPages int `json:"total_pages"`
}
// Paginate implements the paginable interface.
func (p Paginator) Paginate() string {
b, _ := json.Marshal(p)
return string(b)
}
func (p Paginator) String() string {
return p.Paginate()
}
// NewPaginator returns a new `Paginator` value with the appropriate
// defaults set.
func NewPaginator(page int, perPage int) *Paginator {
if page < 1 {
page = 1
}
if perPage < 1 {
perPage = 20
}
p := &Paginator{Page: page, PerPage: perPage}
p.Offset = (page - 1) * p.PerPage
return p
}
// PaginationParams is a parameters provider interface to get the pagination params from
type PaginationParams interface {
Get(key string) string
}
// NewPaginatorFromParams takes an interface of type `PaginationParams`,
// the `url.Values` type works great with this interface, and returns
// a new `Paginator` based on the params or `PaginatorPageKey` and
// `PaginatorPerPageKey`. Defaults are `1` for the page and
// PaginatorPerPageDefault for the per page value.
func NewPaginatorFromParams(params PaginationParams) *Paginator {
page := defaults.String(params.Get("page"), "1")
perPage := defaults.String(params.Get("per_page"), strconv.Itoa(PaginatorPerPageDefault))
p, err := strconv.Atoi(page)
if err != nil {
p = 1
}
pp, err := strconv.Atoi(perPage)
if err != nil {
pp = PaginatorPerPageDefault
}
return NewPaginator(p, pp)
}
// Paginate records returned from the database.
//
// q := c.Paginate(2, 15)
// q.All(&[]User{})
// q.Paginator
func (c *Connection) Paginate(page int, perPage int) *Query {
return Q(c).Paginate(page, perPage)
}
// Paginate records returned from the database.
//
// q = q.Paginate(2, 15)
// q.All(&[]User{})
// q.Paginator
func (q *Query) Paginate(page int, perPage int) *Query {
q.Paginator = NewPaginator(page, perPage)
return q
}
// PaginateFromParams paginates records returned from the database.
//
// q := c.PaginateFromParams(req.URL.Query())
// q.All(&[]User{})
// q.Paginator
func (c *Connection) PaginateFromParams(params PaginationParams) *Query {
return Q(c).PaginateFromParams(params)
}
// PaginateFromParams paginates records returned from the database.
//
// q = q.PaginateFromParams(req.URL.Query())
// q.All(&[]User{})
// q.Paginator
func (q *Query) PaginateFromParams(params PaginationParams) *Query {
q.Paginator = NewPaginatorFromParams(params)
return q
}