Filter field getters

This commit is contained in:
Eden Kirin
2024-06-19 11:49:47 +02:00
parent 0a0ed77794
commit 0fb5d637dd
3 changed files with 136 additions and 16 deletions

View File

@ -0,0 +1,105 @@
package smartfilter
import (
"fmt"
"reflect"
"github.com/google/uuid"
)
type valueGetterFunc func(ff *FilterField, v reflect.Value) error
type FilterField struct {
Name string
Operator Operator
boolValue bool
intValue int64
uintValue uint64
floatValue float64
strValue string
}
func boolValueGetter(ff *FilterField, v reflect.Value) error {
ff.boolValue = v.Bool()
return nil
}
func intValueGetter(ff *FilterField, v reflect.Value) error {
ff.intValue = v.Int()
return nil
}
func uintValueGetter(ff *FilterField, v reflect.Value) error {
ff.uintValue = v.Uint()
return nil
}
func floatValueGetter(ff *FilterField, v reflect.Value) error {
ff.floatValue = v.Float()
return nil
}
func strValueGetter(ff *FilterField, v reflect.Value) error {
ff.strValue = v.String()
return nil
}
func uuidValueGetter(ff *FilterField, v reflect.Value) error {
uid, err := uuid.FromBytes([]byte(v.String()))
if err != nil {
return err
}
ff.strValue = uid.String()
return nil
}
func unsupportedValueGetter(ff *FilterField, v reflect.Value) error {
return fmt.Errorf("unsupported type: %v", v.Type())
}
func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
// If we have a non-pointer value whose type implements
// Marshaler with a value receiver, then we're better off taking
// the address of the value - otherwise we end up with an
// allocation as we cast the value to an interface.
// if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
// return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
// }
// if t.Implements(marshalerType) {
// return marshalerEncoder
// }
// if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
// return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
// }
// if t.Implements(textMarshalerType) {
// return textMarshalerEncoder
// }
switch t.Kind() {
case reflect.Bool:
return boolValueGetter
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return intValueGetter
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return uintValueGetter
case reflect.Float32, reflect.Float64:
return floatValueGetter
case reflect.String:
return strValueGetter
// case reflect.Interface:
// return interfaceEncoder
// case reflect.Struct:
// return newStructEncoder(t)
// case reflect.Map:
// return newMapEncoder(t)
// case reflect.Slice:
// return newSliceEncoder(t)
// case reflect.Array:
// return newArrayEncoder(t)
// case reflect.Pointer:
// return newPtrEncoder(t)
default:
return unsupportedValueGetter
}
}

View File

@ -1,4 +1,4 @@
package repository
package smartfilter
import (
"fmt"
@ -23,11 +23,6 @@ const (
var OPERATORS = []Operator{OperatorEQ, OperatorIN}
type FilterField struct {
Name string
Operator Operator
}
type SmartCertFilter[T schema.Tabler] struct {
Model T
Alive *bool `filterfield:"alive,EQ"`
@ -40,33 +35,46 @@ func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) {
tableName := f.Model.TableName()
fmt.Printf("Table name: %s\n", tableName)
fmt.Printf("%+v\n", f)
// fmt.Printf("%+v\n", f)
st := reflect.TypeOf(f)
modelName := st.Name()
reflectValue := reflect.ValueOf(f)
for i := 0; i < st.NumField(); i++ {
field := st.Field(i)
tagValue := field.Tag.Get(TAG_NAME)
// skip field if filter tag is not present
if len(tagValue) == 0 {
continue
}
fieldReflect := reflectValue.FieldByName(field.Name)
// skip field if value is nil
if fieldReflect.IsNil() {
continue
}
t := fieldReflect.Type()
fmt.Printf(">>> %+v --- %+v\n", field, t)
filterField, err := getFilterField(tagValue)
if err != nil {
return nil, fmt.Errorf("%s.%s: %s", modelName, field.Name, err)
}
fmt.Printf(
"tagValue: %s, Name: %s, Operator: %s\n",
tagValue,
filterField.Name,
filterField.Operator,
)
// fmt.Printf(
// "tagValue: %s, Name: %s, Operator: %s\n",
// tagValue,
// filterField.Name,
// filterField.Operator,
// )
switch filterField.Operator {
case OperatorEQ:
query = applyFilterEQ(query, tableName, filterField)
query = applyFilterEQ[string](query, tableName, filterField)
}
}
@ -75,7 +83,9 @@ func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) {
return query, nil
}
func applyFilterEQ(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
func applyFilterEQ[T int | bool | string](query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
// query = query.Where(fmt.Sprint("%s.%s = ?", tableName, filterField.Name), )
return query
}