camper/pkg/user/filter.go

99 lines
2.1 KiB
Go

package user
import (
"fmt"
"net/http"
"strconv"
"strings"
"dev.tandem.ws/tandem/camper/pkg/auth"
"dev.tandem.ws/tandem/camper/pkg/database"
"dev.tandem.ws/tandem/camper/pkg/form"
)
type filterForm struct {
company *auth.Company
FromDate *form.Input
ToDate *form.Input
Cursor *form.Cursor
}
func newFilterForm() *filterForm {
return &filterForm{
FromDate: &form.Input{
Name: "from_date",
},
ToDate: &form.Input{
Name: "to_date",
},
Cursor: &form.Cursor{
Name: "cursor",
PerPage: 5,
},
}
}
func (f *filterForm) Parse(r *http.Request) error {
if err := r.ParseForm(); err != nil {
return err
}
f.FromDate.FillValue(r)
f.ToDate.FillValue(r)
f.Cursor.FillValue(r)
return nil
}
func (f *filterForm) BuildQuery(args []interface{}) (string, []interface{}) {
var where []string
appendWhere := func(expression string, value interface{}) {
args = append(args, value)
where = append(where, fmt.Sprintf(expression, len(args)))
}
maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) {
if value != "" {
if conv == nil {
appendWhere(expression, value)
} else {
appendWhere(expression, conv(value))
}
}
}
maybeAppendWhere("attempted_at >= $%d", f.FromDate.Val, nil)
maybeAppendWhere("attempted_at <= $%d", f.ToDate.Val, nil)
if f.Paginated() {
params := f.Cursor.Params()
if len(params) == 2 {
where = append(where, fmt.Sprintf("(attempted_at, attempt_id) < ($%d, $%d)", len(args)+1, len(args)+2))
args = append(args, params[0])
args = append(args, params[1])
}
}
if len(where) == 0 {
return "1=1", args
}
return strings.Join(where, ") AND ("), args
}
func (f *filterForm) buildCursor(customers []*loginAttemptEntry) []*loginAttemptEntry {
return form.BuildCursor(f.Cursor, customers, func(entry *loginAttemptEntry) []string {
return []string{entry.Date.Format(database.ISODateTimeFormat), strconv.Itoa(entry.ID)}
})
}
func (f *filterForm) HasValue() bool {
return f.FromDate.Val != "" ||
f.ToDate.Val != ""
}
func (f *filterForm) PerPage() int {
return f.Cursor.PerPage
}
func (f *filterForm) Paginated() bool {
return f.Cursor.Pagination
}