Time filter

This commit is contained in:
Eden Kirin
2024-06-20 00:52:40 +02:00
parent 8f4ea5b648
commit 43e01b4bca
3 changed files with 55 additions and 60 deletions

View File

@ -3,9 +3,7 @@ package smartfilter
import (
"fmt"
"reflect"
"strconv"
"github.com/google/uuid"
"time"
)
type FilterField struct {
@ -18,44 +16,25 @@ type FilterField struct {
uintValue *uint64
floatValue *float64
strValue *string
timeValue *time.Time
}
func (ff *FilterField) getValue(v reflect.Value) string {
func (ff *FilterField) setValueFromReflection(v reflect.Value) {
fn := typeGetter(v.Type())
fn(ff, v)
switch ff.valueKind {
case reflect.Bool:
if *ff.boolValue {
return "TRUE"
} else {
return "FALSE"
}
case reflect.Int:
return strconv.FormatInt(*ff.intValue, 10)
case reflect.Uint:
return strconv.FormatUint(*ff.uintValue, 10)
case reflect.Float32:
return "some float 32"
case reflect.Float64:
return "some float 64"
case reflect.String:
return *ff.strValue
}
return "???"
}
func (ff *FilterField) getValueWithOperator(v reflect.Value) string {
value := ff.getValue(v)
// func (ff *FilterField) getValueWithOperator(v reflect.Value) string {
// value := ff.getValue(v)
switch ff.valueKind {
case reflect.Bool:
return fmt.Sprintf("IS %s", value)
case reflect.Int, reflect.Uint, reflect.Float32, reflect.Float64, reflect.String:
return fmt.Sprintf("= %s", value)
}
return "???"
}
// switch ff.valueKind {
// case reflect.Bool:
// return fmt.Sprintf("IS %s", value)
// case reflect.Int, reflect.Uint, reflect.Float32, reflect.Float64, reflect.String:
// return fmt.Sprintf("= %s", value)
// }
// return "???"
// }
type valueGetterFunc func(ff *FilterField, v reflect.Value) error
@ -94,12 +73,13 @@ func strValueGetter(ff *FilterField, v reflect.Value) error {
return nil
}
func uuidValueGetter(ff *FilterField, v reflect.Value) error {
uid, err := uuid.FromBytes([]byte(v.String()))
if err != nil {
return err
func timeValueGetter(ff *FilterField, v reflect.Value) error {
timeValue, ok := v.Interface().(time.Time)
if !ok {
return fmt.Errorf("error converting interface to time")
}
value := uid.String()
value := timeValue.Format(time.RFC3339)
ff.strValue = &value
ff.valueKind = reflect.String
return nil
@ -144,8 +124,12 @@ func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
return strValueGetter
// case reflect.Interface:
// return interfaceEncoder
// case reflect.Struct:
// return newStructEncoder(t)
case reflect.Struct:
// check if value type is time
timeType := reflect.TypeOf(time.Time{})
if t == timeType {
return timeValueGetter
}
// case reflect.Map:
// return newMapEncoder(t)
// case reflect.Slice:
@ -154,9 +138,8 @@ func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
// return newArrayEncoder(t)
case reflect.Pointer:
return newPtrValueGetter(t)
default:
return unsupportedValueGetter
}
return unsupportedValueGetter
}
type ptrValueGetter struct {

View File

@ -5,8 +5,8 @@ import (
"reflect"
"slices"
"strings"
"time"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
@ -29,13 +29,13 @@ var operatorHandlers = map[Operator]handlerFunc{
type SmartCertFilter[T schema.Tabler] struct {
Model T
Alive *bool `filterfield:"alive,EQ"`
SerialNumber *string `filterfield:"serial_number,NE"`
SerialNumberContains *string `filterfield:"serial_number,LIKE"`
IssuerContains *string `filterfield:"issuer,ILIKE"`
Id *uuid.UUID `filterfield:"id,EQ"`
Ids *[]uuid.UUID `filterfield:"id,IN"`
CompanyId *uuid.UUID `filterfield:"company_id,EQ"`
Alive *bool `filterfield:"alive,EQ"`
SerialNumber *string `filterfield:"serial_number,NE"`
SerialNumberContains *string `filterfield:"serial_number,LIKE"`
IssuerContains *string `filterfield:"issuer,ILIKE"`
Id *string `filterfield:"id,EQ"`
Ids *[]string `filterfield:"id,IN"`
CreatedAt_Lt *time.Time `filterfield:"created_at,LT"`
}
func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) {
@ -72,8 +72,8 @@ func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) {
return nil, fmt.Errorf("%s.%s: %s", modelName, field.Name, err)
}
strValue := filterField.getValue(fieldReflect)
fmt.Printf(">>> filterField: %+v ==== %s\n", filterField, strValue)
// must be called!
filterField.setValueFromReflection(fieldReflect)
operatorHandler, ok := operatorHandlers[filterField.Operator]
if !ok {
@ -173,6 +173,8 @@ func handleOperatorGT(query *gorm.DB, tableName string, filterField *FilterField
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)
}
@ -193,6 +195,8 @@ func handleOperatorGE(query *gorm.DB, tableName string, filterField *FilterField
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)
}
@ -213,6 +217,8 @@ func handleOperatorLT(query *gorm.DB, tableName string, filterField *FilterField
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)
}
@ -233,6 +239,8 @@ func handleOperatorLE(query *gorm.DB, tableName string, filterField *FilterField
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)
}