/
pagination.go
119 lines (97 loc) 路 2.2 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
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 lib
import (
"math"
"gorm.io/gorm"
)
// PaginationPage is a sinlge, paginated page
type PaginationPage struct {
Count int64
Pages int
Records interface{}
Offset int
Range int
Limit int
Page int
PrevPage int
PrevPageRange []int
NextPage int
NextPageRange []int
Ordered bool
}
// Pagination has options for a Page
type Pagination struct {
DB *gorm.DB
CurrPage int
Limit int
OrderBy []string
}
// Page pages a dataset
func (p *Pagination) Page(data interface{}) (*PaginationPage, error) {
var pagination PaginationPage
var count int64
var offset int
db := p.DB
if p.CurrPage < 1 {
p.CurrPage = 1
}
if p.Limit == 0 {
p.Limit = 66
}
if len(p.OrderBy) > 0 {
for _, order := range p.OrderBy {
db = db.Order(order)
}
pagination.Ordered = true
} else {
pagination.Ordered = false
}
db.Model(data).Count(&count)
if p.CurrPage == 1 {
offset = 0
} else {
offset = (p.CurrPage - 1) * p.Limit
}
if err := db.Limit(p.Limit).Offset(offset).Preload("Technologies").Find(data).Error; err != nil {
return nil, err
}
pagination.Count = count
pagination.Records = data
pagination.Page = p.CurrPage
pagination.Offset = offset
pagination.Limit = p.Limit
pagination.Pages = int(math.Ceil(float64(count) / float64(p.Limit)))
pagination.Range = pagination.Offset + pagination.Limit
if p.CurrPage > 1 {
pagination.PrevPage = p.CurrPage - 1
} else {
pagination.PrevPage = p.CurrPage
}
if p.CurrPage >= pagination.Pages {
pagination.NextPage = p.CurrPage
} else {
pagination.NextPage = p.CurrPage + 1
}
pagination.PrevPageRange = makeSizedRange(1, pagination.PrevPage, 5)
// ceil if we are in front
if pagination.Page == 1 {
pagination.PrevPageRange = []int{}
}
// wrap if we reach the end
if pagination.Page == pagination.Pages {
pagination.NextPage = 1
pagination.NextPageRange = []int{}
} else {
pagination.NextPageRange = makeSizedRange(pagination.NextPage, pagination.Pages, 5)
}
return &pagination, nil
}
func makeSizedRange(min, max, l int) []int {
if min > max {
return []int{}
}
a := make([]int, max-min+1)
for i := range a {
a[i] = min + i
}
return a
}