-
Notifications
You must be signed in to change notification settings - Fork 1
/
pagination.go
68 lines (59 loc) · 1.31 KB
/
pagination.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
package util
import (
"encoding/json"
"io"
"math"
)
type PaginationSource interface {
Count() (int64, error)
Data(limit, p int64, format func(i interface{}) map[string]interface{}) ([]map[string]interface{}, error)
}
type Pagination interface {
Output(w io.Writer) error
}
type paginationImpl struct {
Rows interface{} `json:"rows,omitempty"`
Total int64 `json:"total,omitempty"`
AllPages int64 `json:"allPages,omitempty"`
Page int64 `json:"page,omitempty"`
Limit int64 `json:"limit,omitempty"`
}
const (
MaxLimit = 300
)
func (pi *paginationImpl) Output(w io.Writer) error {
return json.NewEncoder(w).Encode(pi)
}
func NewPagination(
source PaginationSource,
limit, page int64,
format func(i interface{}) map[string]interface{},
) (Pagination, error) {
total, err := source.Count()
if err != nil {
return nil, err
}
if total == 0 {
return nil, nil
}
if limit < 1 || limit > MaxLimit {
limit = 100
}
totalPage := int64(math.Ceil(float64(total) / float64(limit)))
if page > totalPage {
page = totalPage
} else if page < 1 {
page = 1
}
result, err := source.Data(limit, page, format)
if err != nil {
return nil, err
}
return &paginationImpl{
Rows: result,
Total: total,
AllPages: totalPage,
Page: page,
Limit: limit,
}, nil
}