-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsort.go
143 lines (127 loc) · 2.86 KB
/
sort.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
131
132
133
134
135
136
137
138
139
140
141
142
143
package pagination
import (
"fmt"
"strings"
)
type (
Sort struct {
// The sort value.
Sort string `query:"sort"`
// The order value.
Order string `query:"order"`
// List of allowed sort values.
// Can be []string{} or map[string]string.
// When it is a map, the key is the sort value, value is the
// sort expression in the ORDER BY clause. If value is empty,
// key is used. You can use {} in value to represent the order
// value (sort direction). For example:
// map[string]string{
// "created_at": "",
// "posts_count": "posts_count {} NULLS LAST",
// }
AllowedSorts interface{}
// DefaultSort is used if the sort value is empty or not in the
// AllowedSorts.
DefaultSort string
// DefaultOrder is used if the order value is empty.
// Must be "asc" or "desc". Default value is "desc".
DefaultOrder string
// Make "DefaultSort" as the "fallback" sort method.
AlwaysUseDefaultSort bool
}
SortResult struct {
// Effective sort value, null (nil) means no sort
Sort *string
// Effective order value, null (nil) means no sort
Order *string
}
)
func (s Sort) IsAllowed(sort string) bool {
switch sorts := s.AllowedSorts.(type) {
case []string:
for i := 0; i < len(sorts); i++ {
if sorts[i] == sort {
return true
}
}
return false
case map[string]string:
if _, ok := sorts[sort]; ok {
return true
}
return false
default:
return false
}
}
func (s Sort) GetSort() string {
if s.Sort != "" && s.IsAllowed(s.Sort) {
return s.Sort
}
if s.DefaultSort != "" {
return s.DefaultSort
}
return ""
}
func (s Sort) GetOrder() string {
order := s.Order
if order == "" {
order = s.DefaultOrder
}
if order == "asc" {
return "ASC"
} else {
return "DESC"
}
}
func (s Sort) OrderByValue() string {
if sort := s.GetSort(); sort != "" {
out := s.getSortExpression(sort, s.GetOrder())
if s.AlwaysUseDefaultSort && sort != s.DefaultSort {
defaultOrder := s.DefaultOrder
if defaultOrder == "asc" {
defaultOrder = "ASC"
} else {
defaultOrder = "DESC"
}
defaultSort := s.getSortExpression(s.DefaultSort, defaultOrder)
return out + ", " + defaultSort
}
return out
}
return ""
}
func (s Sort) OrderBy() string {
if value := s.OrderByValue(); value != "" {
return "ORDER BY " + value
}
return ""
}
func (s Sort) SortResult() (r SortResult) {
if sort := s.GetSort(); sort != "" {
order := strings.ToLower(s.GetOrder())
r.Sort = &sort
r.Order = &order
}
return
}
func (s Sort) getSortExpression(in, order string) string {
var sort string
switch sorts := s.AllowedSorts.(type) {
case []string:
sort = in
case map[string]string:
if out, ok := sorts[in]; ok && out != "" {
sort = out
} else {
sort = in
}
default:
sort = in
}
if strings.Contains(sort, "{}") {
return strings.Replace(sort, "{}", order, -1)
} else {
return fmt.Sprintf("%s %s", sort, order)
}
}