/
filters.go
64 lines (57 loc) · 1.53 KB
/
filters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package jargo
import (
"fmt"
"github.com/crushedpixel/jargo/internal"
"github.com/go-pg/pg/orm"
)
type Filters struct {
resource *Resource
filters map[internal.SchemaField]*Filter
}
// A Filter contains values to be filtered by,
// each of the filter operators being connected
// via a logical OR, and all of the values for
// an operator being connected via a logical AND.
type Filter struct {
Eq []string
Not []string
Like []string
Lt []string
Lte []string
Gt []string
Gte []string
}
func newFilters(r *Resource, filters map[internal.SchemaField]*Filter) *Filters {
return &Filters{
resource: r,
filters: filters,
}
}
func (f *Filters) applyToQuery(q *orm.Query) {
for field, filter := range f.filters {
filter.applyToQuery(q, field)
}
}
func (f *Filter) applyToQuery(q *orm.Query, field internal.SchemaField) {
andWhereOr(q, field, "=", f.Eq)
andWhereOr(q, field, "<>", f.Not)
andWhereOr(q, field, "LIKE", f.Like)
andWhereOr(q, field, "<", f.Lt)
andWhereOr(q, field, "<=", f.Lte)
andWhereOr(q, field, ">", f.Gt)
andWhereOr(q, field, ">=", f.Gte)
}
// generates an AND WHERE (xxx OR xxx) clause
func andWhereOr(q *orm.Query, field internal.SchemaField, op string, values []string) {
if len(values) > 0 {
q.WhereGroup(func(q *orm.Query) (*orm.Query, error) {
for _, val := range values {
// go-pg does not escape the fields in where clauses,
// so we need to do it ourselves
f := escapePGColumn(field.PGFilterColumn())
q = q.WhereOr(fmt.Sprintf("%s %s ?", f, op), val)
}
return q, nil
})
}
}