diff --git a/filtering.go b/filtering.go index 82f5e4c..a56a4f9 100644 --- a/filtering.go +++ b/filtering.go @@ -7,20 +7,24 @@ import ( "strings" ) -type Filter map[string]string +type Filter map[string][]string -func (f *Filter) Size() int { - return len(*f) +func (f Filter) Get(key string) (values []string, ok bool) { + values, ok = f[key] + return values, ok } -func (f *Filter) Valid() bool { - return len(*f) > 0 +func (f Filter) Size() int { + return len(f) +} + +func (f Filter) IsNotEmpty() bool { + return len(f) > 0 } func (fs Filter) validate(validFilters []string) (Filter, bool) { - goodFilters := make(map[string]string) - cnt := 0 - len := 0 + goodFilters := make(Filter) + cnt, len := 0, 0 for f, _ := range fs { len++ for _, v := range validFilters { @@ -45,14 +49,19 @@ func ParseFilters(req *http.Request, header string) (filters Filter) { q := req.FormValue(header) q = strings.Trim(q, "\"") kvp := strings.Split(q, "|") - filters = make(map[string]string, len(kvp)) + filters = make(Filter, len(kvp)) for i, _ := range kvp { kv := strings.Split(kvp[i], "::") if len(kv) == 2 { key, _ := url.QueryUnescape(kv[0]) - val, _ := url.QueryUnescape(kv[1]) - filters[key] = val + + // 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) + } } } @@ -64,30 +73,45 @@ func MakeFilterString(prefix string, filters Filter, validFilters []string) (res if prefix != "" { prefix += "." } - if len(filters) == 0 { + + if !filters.IsNotEmpty() { return "", true } filters, ok = filters.validate(validFilters) if !ok { - return "", ok + return "", false } - symbol := "=" - for k, v := range filters { - if res != "" { + for k, filter := range filters { + first := true + symbol := "=" + + if first { res += " and " + first = false } else { res += " where " } - c := string(v[0]) - if c == "<" || c == ">" { - symbol = "" // examples: >3, >=3 - } else { - symbol = "=" - } - res += fmt.Sprintf("%s%s %s '%s'", prefix, k, symbol, v) + 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 += ")" } return res, ok