aboutsummaryrefslogtreecommitdiff
path: root/cmd/monfront/filter.go
blob: 968cb36eebd7ea5fd1039be0ba60e2906b165ae5 (plain) (blame)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main

import (
	"fmt"
	"strings"
)

type (
	filter struct {
		idx    int
		where  []string
		params []interface{}
		Vals   map[string]string
	}
)

func newFilter() *filter {
	return &filter{
		idx:    0,
		where:  []string{},
		params: []interface{}{},
		Vals:   map[string]string{},
	}
}

func (f *filter) filterChecks(c *Context) {
	args := c.r.URL.Query()
	for name, val := range args {
		if !strings.HasPrefix(name, "filter-") {
			continue
		}
		arg := strings.TrimPrefix(name, "filter-")
		switch arg {
		case "command":
			if val[0] == "" {
				continue
			}
			f.Add("co.id", "=", val[0], "int")
			f.Vals[arg] = val[0]
		case "search":
			if val[0] == "" {
				continue
			}
			f.Add(`n.name`, `like`, strings.ReplaceAll(val[0], "*", "%"), "text")
			f.Vals[arg] = val[0]
		case "state":
			if val[0] == "" {
				continue
			}
			f.Add("states[1]", ">=", val[0], "int")
			f.Vals[arg] = val[0]
		case "ack":
			if val[0] == "" {
				continue
			}
			if val[0] != "true" && val[0] != "false" {
				continue
			}
			f.Add("acknowledged", "=", val[0], "boolean")
			f.Vals[arg] = val[0]
		case "mapping":
			if val[0] == "" {
				continue
			}
			f.Add("ac.mapping_id", "=", val[0], "int")
			f.Vals[arg] = val[0]
		case "mute":
			if val[0] == "" {
				continue
			}
			isNull := false
			if val[0] == "true" {
				isNull = true
				f.Vals[arg] = "true"
			} else if val[0] == "false" {
				f.Vals[arg] = "false"
			}
			f.AddNull("cn.check_id", isNull)
		}
	}
}

// Add a new where clause element which will be joined at the end.
func (f *filter) Add(field, op string, arg interface{}, castTo string) {
	f.idx += 1
	f.where = append(f.where, fmt.Sprintf("%s %s $%d::%s", field, op, f.idx, castTo))
	f.params = append(f.params, arg)
}

func (f *filter) AddNull(field string, isNull bool) {
	check := "is not null"
	if isNull {
		check = "is null"
	}
	f.where = append(f.where, fmt.Sprintf("%s %s", field, check))
}

// AddSpecial lets you add a special where clause comparison where you can
// wrap the argument in whatevery you like.
//
// Your string has to contain %d. This will place the index of the variable
// in the query string.
//
// Example:
//
//	AddSpecial("foo", "=", "to_tsvector('english', $%d), search)
func (f *filter) AddSpecial(field, op, special string, arg interface{}) {
	f.idx += 1
	f.where = append(f.where, fmt.Sprintf("%s %s "+special, field, op, f.idx))
	f.params = append(f.params, arg)
}

// Join takes all where clauses and joins them together with the AND operator.
// The result and all collected parameters are then returned.
func (f *filter) Join() (string, []interface{}) {
	return strings.Join(f.where, " and "), f.params
}