package customer import ( "fmt" "net/http" "strings" "dev.tandem.ws/tandem/camper/pkg/auth" "dev.tandem.ws/tandem/camper/pkg/form" ) type filterForm struct { company *auth.Company perPage int pagination bool Name *form.Input Email *form.Input Cursor *form.Input } func newFilterForm(company *auth.Company) *filterForm { return &filterForm{ company: company, perPage: 25, Name: &form.Input{ Name: "name", }, Email: &form.Input{ Name: "email", }, Cursor: &form.Input{ Name: "cursor", }, } } func (f *filterForm) Parse(r *http.Request) error { if err := r.ParseForm(); err != nil { return err } f.Name.FillValue(r) f.Email.FillValue(r) f.Cursor.FillValue(r) f.pagination = f.Cursor.Val != "" 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)) } } } appendWhere("company_id = $%d", f.company.ID) maybeAppendWhere("name ILIKE $%d", f.Name.Val, func(v string) interface{} { return "%" + v + "%" }) maybeAppendWhere("email ILIKE $%d", f.Email.Val, func(v string) interface{} { return "%" + v + "%" }) if f.Cursor.Val != "" { params := strings.Split(f.Cursor.Val, ";") if len(params) == 2 { where = append(where, fmt.Sprintf("(name, contact_id) > ($%d, $%d)", len(args)+1, len(args)+2)) args = append(args, params[0]) args = append(args, params[1]) } } return strings.Join(where, ") AND ("), args } func (f *filterForm) buildCursor(customers []*customerEntry) []*customerEntry { if len(customers) <= f.perPage { f.Cursor.Val = "" return customers } customers = customers[:f.perPage] last := customers[f.perPage-1] f.Cursor.Val = fmt.Sprintf("%s;%d", last.Name, last.ID) return customers } func (f *filterForm) HasValue() bool { return f.Name.Val != "" || f.Email.Val != "" }