Working arrays

This commit is contained in:
Eden Kirin
2024-06-22 21:59:39 +02:00
parent 14bc29d7e3
commit b67bc14e5e
8 changed files with 171 additions and 170 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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,
}

View File

@ -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
}