-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathvalueFilterArguments.go
145 lines (124 loc) · 4.07 KB
/
valueFilterArguments.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
144
145
package filterparams
import (
"fmt"
"regexp"
"strings"
"github.com/cbrand/go-filterparams/binding"
"github.com/cbrand/go-filterparams/definition"
)
// orderMatcher is used to verify
var orderMatcher = regexp.MustCompile("(?:(asc|desc)\\(([a-zA-Z0-9_\\-]*)\\)|([a-zA-Z0-9_\\-]*))")
// ParamNotFoundError represents a parameter which is specified
// in the query.
type ParamNotFoundError struct {
ParamName string
}
// Error returns the string representation of the given error.
func (f *ParamNotFoundError) Error() string {
return fmt.Sprintf("Parameter \"%s\" missing", f.ParamName)
}
// NewFilterParamNotFoundError creates a new error with the given parameter name.
func NewFilterParamNotFoundError(paramName string) *ParamNotFoundError {
return &ParamNotFoundError{
ParamName: paramName,
}
}
// ValueFilterArguments is an internal used struct to adjust the filter arguments
// entry.
type ValueFilterArguments struct {
arguments map[string]*definition.Parameter
queryBinding string
orders []string
}
// GetArgument returns the value of the arugment with the given name. Returns an empty
// string if the argument is not present
func (v *ValueFilterArguments) GetArgument(key string) *definition.Parameter {
return v.arguments[key]
}
// SetArgument sets the argument with the passed data.
func (v *ValueFilterArguments) SetArgument(key string, value *definition.Parameter) {
v.arguments[key] = value
}
// DelArgument removes the argument with the given entry.
func (v *ValueFilterArguments) DelArgument(key string) {
delete(v.arguments, key)
}
// SetQueryBinding sets the string representation of the binding
// for the given query.
func (v *ValueFilterArguments) SetQueryBinding(binding string) {
v.queryBinding = binding
}
// GetQueryBinding returns the set queryBinding of this configuartion or an
// empty string if none has been set.
func (v *ValueFilterArguments) GetQueryBinding() string {
return v.queryBinding
}
// HasQueryBinding returns if an query binding has been set.
func (v *ValueFilterArguments) HasQueryBinding() bool {
return len(v.GetQueryBinding()) > 0
}
// AddOrder adds an order entry to the system.
func (v *ValueFilterArguments) AddOrder(order string) {
v.orders = append(v.orders, order)
}
// GetOrders returns the configured ordered parameters.
func (v *ValueFilterArguments) GetOrders() []string {
return v.orders
}
// ParsedBinding parses the order string and returns the parsed result.
func (v *ValueFilterArguments) ParsedBinding() (interface{}, error) {
data, err := binding.ParseString(v.queryBinding)
if err != nil {
return nil, err
}
parameters := data.(definition.ParameterHaver).GetParameters()
for _, parameter := range parameters {
argument := v.GetArgument(parameter.Identification)
if argument == nil {
return nil, NewFilterParamNotFoundError(parameter.Identification)
}
parameter.Name = argument.Name
parameter.Value = argument.Value
parameter.Filter = argument.Filter
}
return data, nil
}
// ApplyOrders takes the configured orders and returns the configured
// order objects.
func (v *ValueFilterArguments) ApplyOrders() []*definition.Order {
orders := []*definition.Order{}
for _, orderString := range v.GetOrders() {
matches := orderMatcher.FindStringSubmatch(orderString)
if len(matches) == 0 {
continue
}
ascDesc := "asc"
name := matches[3]
if len(matches[3]) == 0 {
ascDesc = matches[1]
name = matches[2]
}
orders = append(orders, definition.NewOrder(name, ascDesc))
}
return orders
}
// ConstructDefaultQueryBinding creates a query binding where all parameters
// are connected with an AND-Statement.
func (v *ValueFilterArguments) ConstructDefaultQueryBinding() string {
args := v.arguments
data := make([]string, len(args))
index := 0
for key := range args {
data[index] = key
index++
}
return strings.Join(data, "&")
}
// NewValueFilterArgument initializes the ValueFilterArguments struct
// which is then used to store the parsed data.
func NewValueFilterArgument() *ValueFilterArguments {
return &ValueFilterArguments{
arguments: map[string]*definition.Parameter{},
orders: []string{},
}
}