Blame view

filtering.go 2.14 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
  }
dcfc40497   Marko Tikvić   improved filtering
15
16
17
18
19
20
  func (f Filter) Size() int {
  	return len(f)
  }
  
  func (f Filter) IsNotEmpty() bool {
  	return len(f) > 0
ab548c502   Marko Tikvić   added Valid() to ...
21
  }
564ef6971   Marko Tikvić   added simple sql ...
22
  func (fs Filter) validate(validFilters []string) (Filter, bool) {
dcfc40497   Marko Tikvić   improved filtering
23
24
  	goodFilters := make(Filter)
  	cnt, len := 0, 0
564ef6971   Marko Tikvić   added simple sql ...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  	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
49
  	filters = make(Filter, len(kvp))
564ef6971   Marko Tikvić   added simple sql ...
50
51
52
53
  
  	for i, _ := range kvp {
  		kv := strings.Split(kvp[i], "::")
  		if len(kv) == 2 {
d869bd3f2   Marko Tikvić   filtering fix
54
  			key, _ := url.QueryUnescape(kv[0])
dcfc40497   Marko Tikvić   improved filtering
55
56
57
58
59
60
61
  
  			// 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 ...
62
63
64
65
66
  		}
  	}
  
  	return filters
  }
d3cc6a289   Marko Tikvić   < > filtering
67
  // TODO(marko): very dodgy, needs more robustness
564ef6971   Marko Tikvić   added simple sql ...
68
69
70
71
  func MakeFilterString(prefix string, filters Filter, validFilters []string) (res string, ok bool) {
  	if prefix != "" {
  		prefix += "."
  	}
dcfc40497   Marko Tikvić   improved filtering
72
73
  
  	if !filters.IsNotEmpty() {
564ef6971   Marko Tikvić   added simple sql ...
74
75
76
77
78
  		return "", true
  	}
  
  	filters, ok = filters.validate(validFilters)
  	if !ok {
dcfc40497   Marko Tikvić   improved filtering
79
  		return "", false
564ef6971   Marko Tikvić   added simple sql ...
80
  	}
dcfc40497   Marko Tikvić   improved filtering
81
82
83
84
85
  	for k, filter := range filters {
  		first := true
  		symbol := "="
  
  		if first {
564ef6971   Marko Tikvić   added simple sql ...
86
  			res += " and "
dcfc40497   Marko Tikvić   improved filtering
87
  			first = false
564ef6971   Marko Tikvić   added simple sql ...
88
89
90
  		} else {
  			res += " where "
  		}
d3cc6a289   Marko Tikvić   < > filtering
91

dcfc40497   Marko Tikvić   improved filtering
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  		res += "("
  		for i, f := range filter {
  			if strings.HasPrefix(f, "<") || strings.HasPrefix(f, ">") {
  				symbol = string(f[0])
  				f = strings.TrimLeft(f, "<>")
  				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 ...
110
111
112
113
  	}
  
  	return res, ok
  }