Commit d06571d28037e08857feb04282620204542ad0a8

Authored by Marko Tikvić
1 parent dcfc404979
Exists in master

filter.ValueAt()

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