Commit d7e8e0a94e5116e22f5afb860489c01302d4e67d

Authored by Marko Tikvić
1 parent ad6d508b94
Exists in master

count; add

Showing 1 changed file with 4 additions and 4 deletions   Show diff stats
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "net/http" 5 "net/http"
6 "net/url" 6 "net/url"
7 "strings" 7 "strings"
8 ) 8 )
9 9
10 type Filter map[string][]string 10 type Filter map[string][]string
11 11
12 func (f Filter) Get(key string) (values []string, ok bool) { 12 func (f Filter) Get(key string) (values []string, ok bool) {
13 values, ok = f[key] 13 values, ok = f[key]
14 return values, ok 14 return values, ok
15 } 15 }
16 16
17 func (f Filter) Size() int { 17 func (f Filter) Count() int {
18 return len(f) 18 return len(f)
19 } 19 }
20 20
21 func (f Filter) IsNotEmpty() bool { 21 func (f Filter) Add(key, val string) {
22 return len(f) > 0 22 f[key] = append(f[key], val)
23 } 23 }
24 24
25 func (f Filter) ValueAt(val string, index int) string { 25 func (f Filter) ValueAt(val string, index int) string {
26 if filter, ok := f[val]; ok { 26 if filter, ok := f[val]; ok {
27 if len(filter) > index { 27 if len(filter) > index {
28 return filter[index] 28 return filter[index]
29 } 29 }
30 } 30 }
31 31
32 return "" 32 return ""
33 } 33 }
34 34
35 func (fs Filter) validate(validFilters []string) (Filter, bool) { 35 func (fs Filter) validate(validFilters []string) (Filter, bool) {
36 goodFilters := make(Filter) 36 goodFilters := make(Filter)
37 cnt, len := 0, 0 37 cnt, len := 0, 0
38 for f, _ := range fs { 38 for f, _ := range fs {
39 len++ 39 len++
40 for _, v := range validFilters { 40 for _, v := range validFilters {
41 if f == v { 41 if f == v {
42 cnt++ 42 cnt++
43 goodFilters[f] = fs[f] 43 goodFilters[f] = fs[f]
44 } 44 }
45 } 45 }
46 } 46 }
47 47
48 result := true 48 result := true
49 if len > 0 && cnt == 0 { 49 if len > 0 && cnt == 0 {
50 // if no valid filters are found declare filtering request as invalid 50 // if no valid filters are found declare filtering request as invalid
51 result = false 51 result = false
52 } 52 }
53 53
54 return goodFilters, result 54 return goodFilters, result
55 } 55 }
56 56
57 // requires input in format: "param1::value1|param2::value2..." 57 // requires input in format: "param1::value1|param2::value2..."
58 func ParseFilters(req *http.Request, header string) (filters Filter) { 58 func ParseFilters(req *http.Request, header string) (filters Filter) {
59 q := req.FormValue(header) 59 q := req.FormValue(header)
60 q = strings.Trim(q, "\"") 60 q = strings.Trim(q, "\"")
61 kvp := strings.Split(q, "|") 61 kvp := strings.Split(q, "|")
62 filters = make(Filter, len(kvp)) 62 filters = make(Filter, len(kvp))
63 63
64 for i, _ := range kvp { 64 for i, _ := range kvp {
65 kv := strings.Split(kvp[i], "::") 65 kv := strings.Split(kvp[i], "::")
66 if len(kv) == 2 { 66 if len(kv) == 2 {
67 key, _ := url.QueryUnescape(kv[0]) 67 key, _ := url.QueryUnescape(kv[0])
68 68
69 // get values (if more than 1) 69 // get values (if more than 1)
70 vals := strings.Split(kv[1], ",") 70 vals := strings.Split(kv[1], ",")
71 for _, v := range vals { 71 for _, v := range vals {
72 u, _ := url.QueryUnescape(v) 72 u, _ := url.QueryUnescape(v)
73 filters[key] = append(filters[key], u) 73 filters[key] = append(filters[key], u)
74 } 74 }
75 } 75 }
76 } 76 }
77 77
78 return filters 78 return filters
79 } 79 }
80 80
81 // TODO(marko): very dodgy, needs more robustness 81 // TODO(marko): very dodgy, needs more robustness
82 func MakeFilterString(prefix string, filters Filter, validFilters []string) (res string, ok bool) { 82 func MakeFilterString(prefix string, filters Filter, validFilters []string) (res string, ok bool) {
83 if prefix != "" { 83 if prefix != "" {
84 prefix += "." 84 prefix += "."
85 } 85 }
86 86
87 if !filters.IsNotEmpty() { 87 if filters.Count() == 0 {
88 return "", true 88 return "", true
89 } 89 }
90 90
91 filters, ok = filters.validate(validFilters) 91 filters, ok = filters.validate(validFilters)
92 if !ok { 92 if !ok {
93 return "", false 93 return "", false
94 } 94 }
95 95
96 first := true 96 first := true
97 for k, filter := range filters { 97 for k, filter := range filters {
98 symbol := "=" 98 symbol := "="
99 99
100 if first { 100 if first {
101 res += " where " 101 res += " where "
102 first = false 102 first = false
103 } else { 103 } else {
104 res += " and " 104 res += " and "
105 } 105 }
106 106
107 res += "(" 107 res += "("
108 for i, f := range filter { 108 for i, f := range filter {
109 if strings.HasPrefix(f, "<") || strings.HasPrefix(f, ">") || strings.HasPrefix(f, "!") { 109 if strings.HasPrefix(f, "<") || strings.HasPrefix(f, ">") || strings.HasPrefix(f, "!") {
110 symbol = string(f[0]) 110 symbol = string(f[0])
111 f = strings.TrimLeft(f, "<>!") 111 f = strings.TrimLeft(f, "<>!")
112 if strings.HasPrefix(f, "=") { 112 if strings.HasPrefix(f, "=") {
113 f = strings.TrimLeft(f, "=") 113 f = strings.TrimLeft(f, "=")
114 symbol += "=" 114 symbol += "="
115 } 115 }
116 } 116 }
117 117
118 res += fmt.Sprintf("%s%s %s '%s'", prefix, k, symbol, f) 118 res += fmt.Sprintf("%s%s %s '%s'", prefix, k, symbol, f)
119 119
120 if i < len(filter)-1 { 120 if i < len(filter)-1 {
121 res += " or " 121 res += " or "
122 } 122 }
123 } 123 }
124 res += ")" 124 res += ")"
125 } 125 }
126 126
127 return res, ok 127 return res, ok
128 } 128 }
129 129