Time filter
This commit is contained in:
18
app/main.go
18
app/main.go
@ -8,6 +8,7 @@ import (
|
||||
"repo-pattern/app/models"
|
||||
"repo-pattern/app/repository"
|
||||
"repo-pattern/app/repository/smartfilter"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -21,17 +22,20 @@ func doMagic(db *gorm.DB) {
|
||||
var err error
|
||||
query := db
|
||||
|
||||
// id, _ := uuid.FromBytes([]byte("6dc096ab-5c03-427e-b808-c669f7446131"))
|
||||
// id := "6dc096ab-5c03-427e-b808-c669f7446131"
|
||||
// serialNumber := "222"
|
||||
// serialNumberContains := "323"
|
||||
issuer := "FINA"
|
||||
// issuer := "FINA"
|
||||
location, _ := time.LoadLocation("UTC")
|
||||
createdTime := time.Date(2024, 5, 26, 16, 8, 0, 0, location)
|
||||
|
||||
f := smartfilter.SmartCertFilter[models.Cert]{
|
||||
Alive: &FALSE,
|
||||
// Id: &id,
|
||||
// Alive: &FALSE,
|
||||
// Id: &id,
|
||||
// SerialNumber: &serialNumber,
|
||||
// SerialNumberContains: &serialNumberContains,
|
||||
IssuerContains: &issuer,
|
||||
// IssuerContains: &issuer,
|
||||
CreatedAt_Lt: &createdTime,
|
||||
}
|
||||
|
||||
query, err = f.ToQuery(query)
|
||||
@ -41,9 +45,9 @@ func doMagic(db *gorm.DB) {
|
||||
|
||||
var certs []models.Cert
|
||||
|
||||
query.Find(&certs)
|
||||
query.Order("created_at").Find(&certs)
|
||||
for n, cert := range certs {
|
||||
fmt.Printf(">> [%d] %+v\n", n, cert.Id)
|
||||
fmt.Printf(">> [%d] %+v %s\n", n, cert.Id, cert.CreatedAt)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user