func BuildFilters()

in lib/storage/storage.go [160:210]


func BuildFilters(str string, fields map[string]func(p proto.Message) string) ([][]Filter, error) {
	if len(str) == 0 {
		return nil, nil
	}
	var out [][]Filter
	ands := strutil.QuoteSplit(str, " and ", false)
	for _, a := range ands {
		var ors []Filter
		a = strings.Trim(a, " ")
		brackets := false
		if strings.HasPrefix(a, "(") && strings.HasSuffix(a, ")") {
			brackets = true
			// Strip off the brackets
			a = a[1 : len(a)-1]
		}
		// Perform additional checks to improve error handling.
		parts := strutil.QuoteSplit(a, " ", false)
		for _, p := range parts {
			if strings.HasPrefix(p, `"`) {
				continue
			}
			if strings.Contains(p, "(") || strings.Contains(p, ")") {
				return nil, fmt.Errorf("mismatched or nested brackets on filter %q", str)
			}
			if strings.ToLower(p) == "or" && !brackets && len(ands) > 1 {
				return nil, fmt.Errorf("brackets around OR clauses are required in filter %q", str)
			}
		}
		// Use regexp to parse the OR clause or simple expression.
		if !orCheckRE.MatchString(a) {
			return nil, fmt.Errorf("invalid filter %q", str)
		}
		match := orFilterRE.FindAllStringSubmatch(a, -1)
		if len(match) == 0 {
			return nil, fmt.Errorf("invalid filter %q", str)
		}
		for _, m := range match {
			fn, ok := fields[strings.ToLower(m[1])]
			if !ok {
				return nil, fmt.Errorf("field %q not defined", m[1])
			}
			val := strings.ToLower(m[3])
			if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) {
				val = val[1 : len(val)-1]
			}
			ors = append(ors, Filter{extract: fn, compare: strings.ToLower(m[2]), value: val})
		}
		out = append(out, ors)
	}
	return out, nil
}