Working arrays
This commit is contained in:
@ -10,12 +10,17 @@ type FilterField struct {
|
||||
Name string
|
||||
Operator Operator
|
||||
|
||||
valueKind reflect.Kind
|
||||
boolValue *bool
|
||||
intValue *int64
|
||||
uintValue *uint64
|
||||
floatValue *float64
|
||||
strValue *string
|
||||
valueKind reflect.Kind
|
||||
boolValue *bool
|
||||
intValue *int64
|
||||
uintValue *uint64
|
||||
floatValue *float64
|
||||
strValue *string
|
||||
boolValues *[]bool
|
||||
intValues *[]int64
|
||||
uintValues *[]uint64
|
||||
floatValues *[]float64
|
||||
strValues *[]string
|
||||
}
|
||||
|
||||
func (ff *FilterField) setValueFromReflection(v reflect.Value) {
|
||||
@ -23,6 +28,71 @@ func (ff *FilterField) setValueFromReflection(v reflect.Value) {
|
||||
fn(ff, v)
|
||||
}
|
||||
|
||||
func (ff *FilterField) appendStr(value string) {
|
||||
var valueArray []string
|
||||
|
||||
if ff.strValues == nil {
|
||||
valueArray = make([]string, 0)
|
||||
} else {
|
||||
valueArray = *ff.strValues
|
||||
}
|
||||
valueArray = append(valueArray, value)
|
||||
ff.strValues = &valueArray
|
||||
ff.valueKind = reflect.String
|
||||
}
|
||||
|
||||
func (ff *FilterField) appendBool(value bool) {
|
||||
var valueArray []bool
|
||||
|
||||
if ff.boolValues == nil {
|
||||
valueArray = make([]bool, 0)
|
||||
} else {
|
||||
valueArray = *ff.boolValues
|
||||
}
|
||||
valueArray = append(valueArray, value)
|
||||
ff.boolValues = &valueArray
|
||||
ff.valueKind = reflect.Bool
|
||||
}
|
||||
|
||||
func (ff *FilterField) appendInt(value int64) {
|
||||
var valueArray []int64
|
||||
|
||||
if ff.boolValues == nil {
|
||||
valueArray = make([]int64, 0)
|
||||
} else {
|
||||
valueArray = *ff.intValues
|
||||
}
|
||||
valueArray = append(valueArray, value)
|
||||
ff.intValues = &valueArray
|
||||
ff.valueKind = reflect.Int
|
||||
}
|
||||
|
||||
func (ff *FilterField) appendUint(value uint64) {
|
||||
var valueArray []uint64
|
||||
|
||||
if ff.boolValues == nil {
|
||||
valueArray = make([]uint64, 0)
|
||||
} else {
|
||||
valueArray = *ff.uintValues
|
||||
}
|
||||
valueArray = append(valueArray, value)
|
||||
ff.uintValues = &valueArray
|
||||
ff.valueKind = reflect.Int
|
||||
}
|
||||
|
||||
func (ff *FilterField) appendFloat(value float64) {
|
||||
var valueArray []float64
|
||||
|
||||
if ff.boolValues == nil {
|
||||
valueArray = make([]float64, 0)
|
||||
} else {
|
||||
valueArray = *ff.floatValues
|
||||
}
|
||||
valueArray = append(valueArray, value)
|
||||
ff.floatValues = &valueArray
|
||||
ff.valueKind = reflect.Int
|
||||
}
|
||||
|
||||
type valueGetterFunc func(ff *FilterField, v reflect.Value) error
|
||||
|
||||
func boolValueGetter(ff *FilterField, v reflect.Value) error {
|
||||
@ -121,8 +191,8 @@ func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
|
||||
// return newMapEncoder(t)
|
||||
case reflect.Slice:
|
||||
return newSliceGetter(t)
|
||||
case reflect.Array:
|
||||
return newArrayGetter(t)
|
||||
// case reflect.Array:
|
||||
// return newArrayGetter(t)
|
||||
case reflect.Pointer:
|
||||
return newPtrValueGetter(t)
|
||||
}
|
||||
@ -130,44 +200,64 @@ func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
|
||||
}
|
||||
|
||||
type ptrValueGetter struct {
|
||||
elemEnc valueGetterFunc
|
||||
elemGetter valueGetterFunc
|
||||
}
|
||||
|
||||
func (pvg ptrValueGetter) getValue(ff *FilterField, v reflect.Value) error {
|
||||
pvg.elemEnc(ff, v.Elem())
|
||||
pvg.elemGetter(ff, v.Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
func newPtrValueGetter(t reflect.Type) valueGetterFunc {
|
||||
enc := ptrValueGetter{elemEnc: typeGetter(t.Elem())}
|
||||
enc := ptrValueGetter{elemGetter: typeGetter(t.Elem())}
|
||||
return enc.getValue
|
||||
}
|
||||
|
||||
type arrayGetter struct {
|
||||
elemEnc valueGetterFunc
|
||||
elemGetter valueGetterFunc
|
||||
}
|
||||
|
||||
func (ag arrayGetter) getValue(ff *FilterField, v reflect.Value) error {
|
||||
ag.elemEnc(ff, v.Elem())
|
||||
ag.elemGetter(ff, v.Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
func newArrayGetter(t reflect.Type) valueGetterFunc {
|
||||
enc := arrayGetter{elemEnc: typeGetter(t.Elem())}
|
||||
enc := arrayGetter{elemGetter: typeGetter(t.Elem())}
|
||||
return enc.getValue
|
||||
}
|
||||
|
||||
type sliceGetter struct {
|
||||
elemEnc valueGetterFunc
|
||||
elemGetter valueGetterFunc
|
||||
}
|
||||
|
||||
func (sg sliceGetter) getValue(ff *FilterField, v reflect.Value) error {
|
||||
fmt.Printf("%+v\n", v.Slice(0, 1))
|
||||
sg.elemEnc(ff, v.Elem())
|
||||
for n := range v.Len() {
|
||||
element := v.Index(n)
|
||||
fmt.Printf("ELEMENT: %+v\n", element)
|
||||
|
||||
switch element.Kind() {
|
||||
case reflect.Bool:
|
||||
ff.appendBool(element.Bool())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
ff.appendInt(element.Int())
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
ff.appendUint(element.Uint())
|
||||
case reflect.Float32, reflect.Float64:
|
||||
ff.appendFloat(element.Float())
|
||||
case reflect.String:
|
||||
ff.appendStr(element.String())
|
||||
}
|
||||
}
|
||||
fmt.Println(v.Len())
|
||||
fmt.Printf(">>> getValue %+v\n", v)
|
||||
fmt.Printf(">>> ff %+v\n", ff.strValues)
|
||||
// fmt.Printf("%+v\n", v.Slice(0, 1))
|
||||
// sg.elemGetter(ff, v.Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
func newSliceGetter(t reflect.Type) valueGetterFunc {
|
||||
enc := sliceGetter{elemEnc: typeGetter(t.Elem())}
|
||||
enc := sliceGetter{elemGetter: newArrayGetter(t)}
|
||||
return enc.getValue
|
||||
}
|
||||
|
||||
@ -51,7 +51,13 @@ func applyFilterLE[T bool | int64 | uint64 | float64 | string](
|
||||
}
|
||||
|
||||
func applyFilterIN[T bool | int64 | uint64 | float64 | string](
|
||||
query *gorm.DB, tableName string, filterField *FilterField, value T,
|
||||
query *gorm.DB, tableName string, filterField *FilterField, value *[]T,
|
||||
) *gorm.DB {
|
||||
return query.Where(fmt.Sprintf("%s.%s IN ?", tableName, filterField.Name), value)
|
||||
return query.Where(fmt.Sprintf("%s.%s IN (?)", tableName, filterField.Name), *value)
|
||||
}
|
||||
|
||||
func applyFilterNOT_IN[T bool | int64 | uint64 | float64 | string](
|
||||
query *gorm.DB, tableName string, filterField *FilterField, value *[]T,
|
||||
) *gorm.DB {
|
||||
return query.Where(fmt.Sprintf("%s.%s NOT IN (?)", tableName, filterField.Name), *value)
|
||||
}
|
||||
|
||||
@ -112,14 +112,32 @@ func handleOperatorLE(query *gorm.DB, tableName string, filterField *FilterField
|
||||
|
||||
func handleOperatorIN(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
|
||||
switch filterField.valueKind {
|
||||
case reflect.Bool:
|
||||
return applyFilterIN(query, tableName, filterField, filterField.boolValues)
|
||||
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return applyFilterIN(query, tableName, filterField, *filterField.intValue)
|
||||
return applyFilterIN(query, tableName, filterField, filterField.intValues)
|
||||
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return applyFilterIN(query, tableName, filterField, *filterField.uintValue)
|
||||
return applyFilterIN(query, tableName, filterField, filterField.uintValues)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return applyFilterIN(query, tableName, filterField, *filterField.floatValue)
|
||||
return applyFilterIN(query, tableName, filterField, filterField.floatValues)
|
||||
case reflect.String:
|
||||
return applyFilterIN(query, tableName, filterField, *filterField.strValue)
|
||||
return applyFilterIN(query, tableName, filterField, filterField.strValues)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleOperatorNOT_IN(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
|
||||
switch filterField.valueKind {
|
||||
case reflect.Bool:
|
||||
return applyFilterNOT_IN(query, tableName, filterField, filterField.boolValues)
|
||||
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return applyFilterNOT_IN(query, tableName, filterField, filterField.intValues)
|
||||
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return applyFilterNOT_IN(query, tableName, filterField, filterField.uintValues)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return applyFilterNOT_IN(query, tableName, filterField, filterField.floatValues)
|
||||
case reflect.String:
|
||||
return applyFilterNOT_IN(query, tableName, filterField, filterField.strValues)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3,20 +3,21 @@ package smartfilter
|
||||
type Operator string
|
||||
|
||||
const (
|
||||
OperatorEQ Operator = "EQ"
|
||||
OperatorNE Operator = "NE"
|
||||
OperatorGT Operator = "GT"
|
||||
OperatorGE Operator = "GE"
|
||||
OperatorLT Operator = "LT"
|
||||
OperatorLE Operator = "LE"
|
||||
OperatorLIKE Operator = "LIKE"
|
||||
OperatorILIKE Operator = "ILIKE"
|
||||
OperatorIN Operator = "IN"
|
||||
OperatorEQ Operator = "EQ"
|
||||
OperatorNE Operator = "NE"
|
||||
OperatorGT Operator = "GT"
|
||||
OperatorGE Operator = "GE"
|
||||
OperatorLT Operator = "LT"
|
||||
OperatorLE Operator = "LE"
|
||||
OperatorLIKE Operator = "LIKE"
|
||||
OperatorILIKE Operator = "ILIKE"
|
||||
OperatorIN Operator = "IN"
|
||||
OperatorNOT_IN Operator = "NOT_IN"
|
||||
)
|
||||
|
||||
var OPERATORS = []Operator{
|
||||
OperatorEQ, OperatorNE,
|
||||
OperatorGT, OperatorGE, OperatorLT, OperatorLE,
|
||||
OperatorLIKE, OperatorILIKE,
|
||||
OperatorIN,
|
||||
OperatorIN, OperatorNOT_IN,
|
||||
}
|
||||
|
||||
@ -17,15 +17,16 @@ const TAG_VALUE_SEPARATOR = ","
|
||||
type handlerFunc func(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB
|
||||
|
||||
var operatorHandlers = map[Operator]handlerFunc{
|
||||
OperatorEQ: handleOperatorEQ,
|
||||
OperatorNE: handleOperatorNE,
|
||||
OperatorGT: handleOperatorGT,
|
||||
OperatorGE: handleOperatorGE,
|
||||
OperatorLT: handleOperatorLT,
|
||||
OperatorLE: handleOperatorLE,
|
||||
OperatorLIKE: handleOperatorLIKE,
|
||||
OperatorILIKE: handleOperatorILIKE,
|
||||
OperatorIN: handleOperatorIN,
|
||||
OperatorEQ: handleOperatorEQ,
|
||||
OperatorNE: handleOperatorNE,
|
||||
OperatorGT: handleOperatorGT,
|
||||
OperatorGE: handleOperatorGE,
|
||||
OperatorLT: handleOperatorLT,
|
||||
OperatorLE: handleOperatorLE,
|
||||
OperatorLIKE: handleOperatorLIKE,
|
||||
OperatorILIKE: handleOperatorILIKE,
|
||||
OperatorIN: handleOperatorIN,
|
||||
OperatorNOT_IN: handleOperatorNOT_IN,
|
||||
}
|
||||
|
||||
type CertFilter struct {
|
||||
@ -35,6 +36,7 @@ type CertFilter struct {
|
||||
IssuerContains *string `filterfield:"issuer,ILIKE"`
|
||||
Id *string `filterfield:"id,EQ"`
|
||||
Ids *[]string `filterfield:"id,IN"`
|
||||
IdsNot *[]string `filterfield:"id,NOT_IN"`
|
||||
CreatedAt_Lt *time.Time `filterfield:"created_at,LT"`
|
||||
}
|
||||
|
||||
@ -73,6 +75,8 @@ func getFilterFields(filter interface{}) []ReflectedStructField {
|
||||
value: fieldValue,
|
||||
})
|
||||
}
|
||||
fmt.Println("-------------- RES --------------")
|
||||
fmt.Printf("%+v\n", res)
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user