diff --git a/app/repository/smartfilter/filters.go b/app/repository/smartfilter/filters.go new file mode 100644 index 0000000..39a6acd --- /dev/null +++ b/app/repository/smartfilter/filters.go @@ -0,0 +1,51 @@ +package smartfilter + +import ( + "fmt" + + "gorm.io/gorm" +) + +func applyFilterEQ[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s = ?", tableName, filterField.Name), value) +} + +func applyFilterNE[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s != ?", tableName, filterField.Name), value) +} + +func applyFilterLIKE(query *gorm.DB, tableName string, filterField *FilterField, value string) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s LIKE ?", tableName, filterField.Name), fmt.Sprintf("%%%s%%", value)) +} + +func applyFilterILIKE(query *gorm.DB, tableName string, filterField *FilterField, value string) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s ILIKE ?", tableName, filterField.Name), fmt.Sprintf("%%%s%%", value)) +} + +func applyFilterGT[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s > ?", tableName, filterField.Name), value) +} + +func applyFilterGE[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s >= ?", tableName, filterField.Name), value) +} + +func applyFilterLT[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s < ?", tableName, filterField.Name), value) +} + +func applyFilterLE[T bool | int64 | uint64 | float64 | string]( + query *gorm.DB, tableName string, filterField *FilterField, value T, +) *gorm.DB { + return query.Where(fmt.Sprintf("%s.%s <= ?", tableName, filterField.Name), value) +} diff --git a/app/repository/smartfilter/smartfilter.go b/app/repository/smartfilter/smartfilter.go index 04f4b05..cf87c7d 100644 --- a/app/repository/smartfilter/smartfilter.go +++ b/app/repository/smartfilter/smartfilter.go @@ -14,7 +14,7 @@ import ( const TAG_NAME = "filterfield" const TAG_VALUE_SEPARATOR = "," -type handlerFunc func(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) +type handlerFunc func(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB var operatorHandlers = map[Operator]handlerFunc{ OperatorEQ: handleOperatorEQ, @@ -80,179 +80,15 @@ func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) { return nil, fmt.Errorf("no handler for operator %s", filterField.Operator) } - query, err = operatorHandler(query, tableName, filterField) - if err != nil { - return nil, err + query = operatorHandler(query, tableName, filterField) + if query == nil { + return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) } } return query, nil } -func handleOperatorEQ(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Bool: - query = applyFilterEQ(query, tableName, filterField, *filterField.boolValue) - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterEQ(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterEQ(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterEQ(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterEQ(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterEQ[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s = ?", tableName, filterField.Name), value) -} - -func handleOperatorNE(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Bool: - query = applyFilterNE(query, tableName, filterField, *filterField.boolValue) - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterNE(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterNE(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterNE(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterNE(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterNE[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s != ?", tableName, filterField.Name), value) -} - -func handleOperatorLIKE(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.String: - query = applyFilterLIKE(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterLIKE(query *gorm.DB, tableName string, filterField *FilterField, value string) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s LIKE ?", tableName, filterField.Name), fmt.Sprintf("%%%s%%", value)) -} - -func handleOperatorILIKE(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.String: - query = applyFilterILIKE(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterILIKE(query *gorm.DB, tableName string, filterField *FilterField, value string) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s ILIKE ?", tableName, filterField.Name), fmt.Sprintf("%%%s%%", value)) -} - -func handleOperatorGT(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterGT(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterGT(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterGT(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterGT(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterGT[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s > ?", tableName, filterField.Name), value) -} - -func handleOperatorGE(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterGE(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterGE(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterGE(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterGE(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterGE[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s >= ?", tableName, filterField.Name), value) -} - -func handleOperatorLT(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterLT(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterLT(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterLT(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterLT(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterLT[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s < ?", tableName, filterField.Name), value) -} - -func handleOperatorLE(query *gorm.DB, tableName string, filterField *FilterField) (*gorm.DB, error) { - switch filterField.valueKind { - case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: - query = applyFilterLE(query, tableName, filterField, *filterField.intValue) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - query = applyFilterLE(query, tableName, filterField, *filterField.uintValue) - case reflect.Float32, reflect.Float64: - query = applyFilterLE(query, tableName, filterField, *filterField.floatValue) - case reflect.String: - query = applyFilterLE(query, tableName, filterField, *filterField.strValue) - default: - return nil, fmt.Errorf("invalid field type for operator %s", filterField.Operator) - } - return query, nil -} - -func applyFilterLE[T bool | int64 | uint64 | float64 | string]( - query *gorm.DB, tableName string, filterField *FilterField, value T, -) *gorm.DB { - return query.Where(fmt.Sprintf("%s.%s <= ?", tableName, filterField.Name), value) -} - func newFilterField(tagValue string) (*FilterField, error) { values := strings.Split(tagValue, TAG_VALUE_SEPARATOR) if len(values) != 2 { @@ -270,3 +106,107 @@ func newFilterField(tagValue string) (*FilterField, error) { } return &f, nil } + +func handleOperatorEQ(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Bool: + return applyFilterEQ(query, tableName, filterField, *filterField.boolValue) + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterEQ(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterEQ(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterEQ(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterEQ(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorNE(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Bool: + return applyFilterNE(query, tableName, filterField, *filterField.boolValue) + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterNE(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterNE(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterNE(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterNE(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorLIKE(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.String: + return applyFilterLIKE(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorILIKE(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.String: + return applyFilterILIKE(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorGT(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterGT(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterGT(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterGT(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterGT(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorGE(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterGE(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterGE(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterGE(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterGE(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorLT(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterLT(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterLT(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterLT(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterLT(query, tableName, filterField, *filterField.strValue) + } + return nil +} + +func handleOperatorLE(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB { + switch filterField.valueKind { + case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: + return applyFilterLE(query, tableName, filterField, *filterField.intValue) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return applyFilterLE(query, tableName, filterField, *filterField.uintValue) + case reflect.Float32, reflect.Float64: + return applyFilterLE(query, tableName, filterField, *filterField.floatValue) + case reflect.String: + return applyFilterLE(query, tableName, filterField, *filterField.strValue) + } + return nil +}