Blame view

filtering.go 2.34 KB
564ef6971   Marko Tikvić   added simple sql ...
1
2
3
4
5
  package webutility
  
  import (
  	"fmt"
  	"net/http"
d869bd3f2   Marko Tikvić   filtering fix
6
  	"net/url"
564ef6971   Marko Tikvić   added simple sql ...
7
8
  	"strings"
  )
dcfc40497   Marko Tikvić   improved filtering
9
  type Filter map[string][]string
564ef6971   Marko Tikvić   added simple sql ...
10

dcfc40497   Marko Tikvić   improved filtering
11
12
13
  func (f Filter) Get(key string) (values []string, ok bool) {
  	values, ok = f[key]
  	return values, ok
ab548c502   Marko Tikvić   added Valid() to ...
14
  }
d7e8e0a94   Marko Tikvić   count; add
15
  func (f Filter) Count() int {
dcfc40497   Marko Tikvić   improved filtering
16
17
  	return len(f)
  }
d7e8e0a94   Marko Tikvić   count; add
18
19
  func (f Filter) Add(key, val string) {
  	f[key] = append(f[key], val)
ab548c502   Marko Tikvić   added Valid() to ...
20
  }
d06571d28   Marko Tikvić   filter.ValueAt()
21
22
23
24
25
26
27
28
29
  func (f Filter) ValueAt(val string, index int) string {
  	if filter, ok := f[val]; ok {
  		if len(filter) > index {
  			return filter[index]
  		}
  	}
  
  	return ""
  }
564ef6971   Marko Tikvić   added simple sql ...
30
  func (fs Filter) validate(validFilters []string) (Filter, bool) {
dcfc40497   Marko Tikvić   improved filtering
31
32
  	goodFilters := make(Filter)
  	cnt, len := 0, 0
564ef6971   Marko Tikvić   added simple sql ...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  	for f, _ := range fs {
  		len++
  		for _, v := range validFilters {
  			if f == v {
  				cnt++
  				goodFilters[f] = fs[f]
  			}
  		}
  	}
  
  	result := true
  	if len > 0 && cnt == 0 {
  		// if no valid filters are found declare filtering request as invalid
  		result = false
  	}
  
  	return goodFilters, result
  }
  
  // requires input in format: "param1::value1|param2::value2..."
  func ParseFilters(req *http.Request, header string) (filters Filter) {
  	q := req.FormValue(header)
  	q = strings.Trim(q, "\"")
  	kvp := strings.Split(q, "|")
dcfc40497   Marko Tikvić   improved filtering
57
  	filters = make(Filter, len(kvp))
564ef6971   Marko Tikvić   added simple sql ...
58
59
60
61
  
  	for i, _ := range kvp {
  		kv := strings.Split(kvp[i], "::")
  		if len(kv) == 2 {
d869bd3f2   Marko Tikvić   filtering fix
62
  			key, _ := url.QueryUnescape(kv[0])
dcfc40497   Marko Tikvić   improved filtering
63
64
65
66
67
68
69
  
  			// get values (if more than 1)
  			vals := strings.Split(kv[1], ",")
  			for _, v := range vals {
  				u, _ := url.QueryUnescape(v)
  				filters[key] = append(filters[key], u)
  			}
564ef6971   Marko Tikvić   added simple sql ...
70
71
72
73
74
  		}
  	}
  
  	return filters
  }
d3cc6a289   Marko Tikvić   < > filtering
75
  // TODO(marko): very dodgy, needs more robustness
564ef6971   Marko Tikvić   added simple sql ...
76
77
78
79
  func MakeFilterString(prefix string, filters Filter, validFilters []string) (res string, ok bool) {
  	if prefix != "" {
  		prefix += "."
  	}
dcfc40497   Marko Tikvić   improved filtering
80

d7e8e0a94   Marko Tikvić   count; add
81
  	if filters.Count() == 0 {
564ef6971   Marko Tikvić   added simple sql ...
82
83
84
85
86
  		return "", true
  	}
  
  	filters, ok = filters.validate(validFilters)
  	if !ok {
dcfc40497   Marko Tikvić   improved filtering
87
  		return "", false
564ef6971   Marko Tikvić   added simple sql ...
88
  	}
ad6d508b9   Marko Tikvić   minor fix
89
  	first := true
dcfc40497   Marko Tikvić   improved filtering
90
  	for k, filter := range filters {
dcfc40497   Marko Tikvić   improved filtering
91
92
93
  		symbol := "="
  
  		if first {
4f226ef30   Marko Tikvić   fixed filterd ord...
94
  			res += " where "
dcfc40497   Marko Tikvić   improved filtering
95
  			first = false
564ef6971   Marko Tikvić   added simple sql ...
96
  		} else {
4f226ef30   Marko Tikvić   fixed filterd ord...
97
  			res += " and "
564ef6971   Marko Tikvić   added simple sql ...
98
  		}
d3cc6a289   Marko Tikvić   < > filtering
99

dcfc40497   Marko Tikvić   improved filtering
100
101
  		res += "("
  		for i, f := range filter {
66643e090   Marko Tikvić   added support for !=
102
  			if strings.HasPrefix(f, "<") || strings.HasPrefix(f, ">") || strings.HasPrefix(f, "!") {
dcfc40497   Marko Tikvić   improved filtering
103
  				symbol = string(f[0])
66643e090   Marko Tikvić   added support for !=
104
  				f = strings.TrimLeft(f, "<>!")
dcfc40497   Marko Tikvić   improved filtering
105
106
107
108
109
110
111
112
113
114
115
116
117
  				if strings.HasPrefix(f, "=") {
  					f = strings.TrimLeft(f, "=")
  					symbol += "="
  				}
  			}
  
  			res += fmt.Sprintf("%s%s %s '%s'", prefix, k, symbol, f)
  
  			if i < len(filter)-1 {
  				res += " or "
  			}
  		}
  		res += ")"
564ef6971   Marko Tikvić   added simple sql ...
118
119
120
121
  	}
  
  	return res, ok
  }