forked from gobuffalo/pop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
paginator.go
119 lines (102 loc) · 3.16 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
package pop
import (
"encoding/json"
"strconv"
"github.com/markbates/going/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"
// 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"`
}
func (p Paginator) String() string {
b, _ := json.Marshal(p)
return string(b)
}
// 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
}