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

@ -1,74 +0,0 @@
package inheritance
import "fmt"
type Model struct{}
type MyModel struct {
Model
}
type MethodInitInterface interface {
Init(dbConn int)
}
type RepoBase[T interface{}] struct {
DbConn int
GetMethod[T]
ListMethod[T]
methods []MethodInitInterface
}
func (b *RepoBase[T]) InitMethods(dbConn int) {
for _, method := range b.methods {
method.Init(dbConn)
}
}
type CRUDRepo[T interface{}] struct {
RepoBase[T]
SaveMethod[T]
}
func (m *CRUDRepo[T]) Init(dbConn int) {
m.methods = []MethodInitInterface{&m.GetMethod, &m.ListMethod, &m.SaveMethod}
m.InitMethods(dbConn)
}
func DoInheritanceTest() {
repo := RepoBase[MyModel]{
DbConn: 111,
// GetMethod: GetMethod{
// DbConn: 666,
// },
// ListMethod: ListMethod{
// DbConn: 777,
// },
}
repo.GetMethod.Init(888)
repo.ListMethod.Init(888)
repo.GetMethod.Get()
repo.List()
fmt.Printf("outside Base: %d\n", repo.DbConn)
fmt.Printf("outside GetMethod: %d\n", repo.GetMethod.DbConn)
fmt.Printf("outside ListMethod: %d\n", repo.ListMethod.DbConn)
fmt.Println("----------------")
crudRepo := CRUDRepo[MyModel]{}
crudRepo.Init(999)
crudRepo.Get()
crudRepo.List()
crudRepo.Save()
fmt.Printf("outside GetMethod: %d\n", crudRepo.GetMethod.DbConn)
fmt.Printf("outside ListMethod: %d\n", crudRepo.ListMethod.DbConn)
fmt.Printf("outside SaveMethod: %d\n", crudRepo.SaveMethod.DbConn)
// repo.DbConn = 123
// repo.SomeGetVar = 456
// repo.DoSomething()
}

View File

@ -1,43 +0,0 @@
package inheritance
import "fmt"
type GetMethod[T interface{}] struct {
SomeGetVar int
DbConn int
}
func (m *GetMethod[T]) Init(dbConn int) {
m.DbConn = dbConn
}
func (m GetMethod[T]) Get() T {
var model T
fmt.Printf("Get DbConn: %d\n", m.DbConn)
return model
}
type ListMethod[T interface{}] struct {
SomeListVar int
DbConn int
}
func (m *ListMethod[T]) Init(dbConn int) {
m.DbConn = dbConn
}
func (m ListMethod[T]) List() {
fmt.Printf("List DbConn: %d\n", m.DbConn)
}
type SaveMethod[T interface{}] struct {
DbConn int
}
func (m *SaveMethod[T]) Init(dbConn int) {
m.DbConn = dbConn
}
func (m SaveMethod[T]) Save() {
fmt.Printf("List DbConn: %d\n", m.DbConn)
}

View File

@ -8,7 +8,6 @@ import (
"repo-pattern/app/models" "repo-pattern/app/models"
"repo-pattern/app/repository" "repo-pattern/app/repository"
"repo-pattern/app/repository/smartfilter" "repo-pattern/app/repository/smartfilter"
"time"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -25,19 +24,19 @@ func doMagic(db *gorm.DB) {
// id := "6dc096ab-5c03-427e-b808-c669f7446131" // id := "6dc096ab-5c03-427e-b808-c669f7446131"
// serialNumber := "222" // serialNumber := "222"
// serialNumberContains := "323" // serialNumberContains := "323"
issuer := "FINA" // issuer := "FINA"
location, _ := time.LoadLocation("UTC") // location, _ := time.LoadLocation("UTC")
createdTime := time.Date(2024, 5, 26, 16, 8, 0, 0, location) // createdTime := time.Date(2024, 5, 26, 16, 8, 0, 0, location)
ids := []string{"eb2bcac6-5173-4dbb-93b7-e7c03b924a03", "db9fb837-3483-4736-819d-f427dc8cda23", "1fece5e7-8e8d-4828-8298-3b1f07fd29ff"} ids := []string{"eb2bcac6-5173-4dbb-93b7-e7c03b924a03", "db9fb837-3483-4736-819d-f427dc8cda23", "1fece5e7-8e8d-4828-8298-3b1f07fd29ff"}
filter := smartfilter.CertFilter{ filter := smartfilter.CertFilter{
Alive: &FALSE, // Alive: &FALSE,
// Id: &id, // Id: &id,
// SerialNumber: &serialNumber, // SerialNumber: &serialNumber,
// SerialNumberContains: &serialNumberContains, // SerialNumberContains: &serialNumberContains,
Ids: &ids, Ids: &ids,
IssuerContains: &issuer, // IssuerContains: &issuer,
CreatedAt_Lt: &createdTime, // CreatedAt_Lt: &createdTime,
} }
query, err = smartfilter.ToQuery(models.Cert{}, filter, query) query, err = smartfilter.ToQuery(models.Cert{}, filter, query)
@ -113,9 +112,9 @@ func main() {
db := db.InitDB() db := db.InitDB()
repository.Dao = repository.CreateDAO(db) repository.Dao = repository.CreateDAO(db)
// doMagic(db) doMagic(db)
// doList(db) // doList(db)
// doGet(db) // doGet(db)
doExists(db) // doExists(db)
// inheritance.DoInheritanceTest() // inheritance.DoInheritanceTest()
} }

View File

@ -10,12 +10,17 @@ type FilterField struct {
Name string Name string
Operator Operator Operator Operator
valueKind reflect.Kind valueKind reflect.Kind
boolValue *bool boolValue *bool
intValue *int64 intValue *int64
uintValue *uint64 uintValue *uint64
floatValue *float64 floatValue *float64
strValue *string strValue *string
boolValues *[]bool
intValues *[]int64
uintValues *[]uint64
floatValues *[]float64
strValues *[]string
} }
func (ff *FilterField) setValueFromReflection(v reflect.Value) { func (ff *FilterField) setValueFromReflection(v reflect.Value) {
@ -23,6 +28,71 @@ func (ff *FilterField) setValueFromReflection(v reflect.Value) {
fn(ff, v) 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 type valueGetterFunc func(ff *FilterField, v reflect.Value) error
func boolValueGetter(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) // return newMapEncoder(t)
case reflect.Slice: case reflect.Slice:
return newSliceGetter(t) return newSliceGetter(t)
case reflect.Array: // case reflect.Array:
return newArrayGetter(t) // return newArrayGetter(t)
case reflect.Pointer: case reflect.Pointer:
return newPtrValueGetter(t) return newPtrValueGetter(t)
} }
@ -130,44 +200,64 @@ func newTypeGetter(t reflect.Type, allowAddr bool) valueGetterFunc {
} }
type ptrValueGetter struct { type ptrValueGetter struct {
elemEnc valueGetterFunc elemGetter valueGetterFunc
} }
func (pvg ptrValueGetter) getValue(ff *FilterField, v reflect.Value) error { func (pvg ptrValueGetter) getValue(ff *FilterField, v reflect.Value) error {
pvg.elemEnc(ff, v.Elem()) pvg.elemGetter(ff, v.Elem())
return nil return nil
} }
func newPtrValueGetter(t reflect.Type) valueGetterFunc { func newPtrValueGetter(t reflect.Type) valueGetterFunc {
enc := ptrValueGetter{elemEnc: typeGetter(t.Elem())} enc := ptrValueGetter{elemGetter: typeGetter(t.Elem())}
return enc.getValue return enc.getValue
} }
type arrayGetter struct { type arrayGetter struct {
elemEnc valueGetterFunc elemGetter valueGetterFunc
} }
func (ag arrayGetter) getValue(ff *FilterField, v reflect.Value) error { func (ag arrayGetter) getValue(ff *FilterField, v reflect.Value) error {
ag.elemEnc(ff, v.Elem()) ag.elemGetter(ff, v.Elem())
return nil return nil
} }
func newArrayGetter(t reflect.Type) valueGetterFunc { func newArrayGetter(t reflect.Type) valueGetterFunc {
enc := arrayGetter{elemEnc: typeGetter(t.Elem())} enc := arrayGetter{elemGetter: typeGetter(t.Elem())}
return enc.getValue return enc.getValue
} }
type sliceGetter struct { type sliceGetter struct {
elemEnc valueGetterFunc elemGetter valueGetterFunc
} }
func (sg sliceGetter) getValue(ff *FilterField, v reflect.Value) error { func (sg sliceGetter) getValue(ff *FilterField, v reflect.Value) error {
fmt.Printf("%+v\n", v.Slice(0, 1)) for n := range v.Len() {
sg.elemEnc(ff, v.Elem()) 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 return nil
} }
func newSliceGetter(t reflect.Type) valueGetterFunc { func newSliceGetter(t reflect.Type) valueGetterFunc {
enc := sliceGetter{elemEnc: typeGetter(t.Elem())} enc := sliceGetter{elemGetter: newArrayGetter(t)}
return enc.getValue 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]( 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 { ) *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 { func handleOperatorIN(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
switch filterField.valueKind { switch filterField.valueKind {
case reflect.Bool:
return applyFilterIN(query, tableName, filterField, filterField.boolValues)
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: 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: 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: case reflect.Float32, reflect.Float64:
return applyFilterIN(query, tableName, filterField, *filterField.floatValue) return applyFilterIN(query, tableName, filterField, filterField.floatValues)
case reflect.String: 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 return nil
} }

View File

@ -3,20 +3,21 @@ package smartfilter
type Operator string type Operator string
const ( const (
OperatorEQ Operator = "EQ" OperatorEQ Operator = "EQ"
OperatorNE Operator = "NE" OperatorNE Operator = "NE"
OperatorGT Operator = "GT" OperatorGT Operator = "GT"
OperatorGE Operator = "GE" OperatorGE Operator = "GE"
OperatorLT Operator = "LT" OperatorLT Operator = "LT"
OperatorLE Operator = "LE" OperatorLE Operator = "LE"
OperatorLIKE Operator = "LIKE" OperatorLIKE Operator = "LIKE"
OperatorILIKE Operator = "ILIKE" OperatorILIKE Operator = "ILIKE"
OperatorIN Operator = "IN" OperatorIN Operator = "IN"
OperatorNOT_IN Operator = "NOT_IN"
) )
var OPERATORS = []Operator{ var OPERATORS = []Operator{
OperatorEQ, OperatorNE, OperatorEQ, OperatorNE,
OperatorGT, OperatorGE, OperatorLT, OperatorLE, OperatorGT, OperatorGE, OperatorLT, OperatorLE,
OperatorLIKE, OperatorILIKE, 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 type handlerFunc func(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB
var operatorHandlers = map[Operator]handlerFunc{ var operatorHandlers = map[Operator]handlerFunc{
OperatorEQ: handleOperatorEQ, OperatorEQ: handleOperatorEQ,
OperatorNE: handleOperatorNE, OperatorNE: handleOperatorNE,
OperatorGT: handleOperatorGT, OperatorGT: handleOperatorGT,
OperatorGE: handleOperatorGE, OperatorGE: handleOperatorGE,
OperatorLT: handleOperatorLT, OperatorLT: handleOperatorLT,
OperatorLE: handleOperatorLE, OperatorLE: handleOperatorLE,
OperatorLIKE: handleOperatorLIKE, OperatorLIKE: handleOperatorLIKE,
OperatorILIKE: handleOperatorILIKE, OperatorILIKE: handleOperatorILIKE,
OperatorIN: handleOperatorIN, OperatorIN: handleOperatorIN,
OperatorNOT_IN: handleOperatorNOT_IN,
} }
type CertFilter struct { type CertFilter struct {
@ -35,6 +36,7 @@ type CertFilter struct {
IssuerContains *string `filterfield:"issuer,ILIKE"` IssuerContains *string `filterfield:"issuer,ILIKE"`
Id *string `filterfield:"id,EQ"` Id *string `filterfield:"id,EQ"`
Ids *[]string `filterfield:"id,IN"` Ids *[]string `filterfield:"id,IN"`
IdsNot *[]string `filterfield:"id,NOT_IN"`
CreatedAt_Lt *time.Time `filterfield:"created_at,LT"` CreatedAt_Lt *time.Time `filterfield:"created_at,LT"`
} }
@ -73,6 +75,8 @@ func getFilterFields(filter interface{}) []ReflectedStructField {
value: fieldValue, value: fieldValue,
}) })
} }
fmt.Println("-------------- RES --------------")
fmt.Printf("%+v\n", res)
return res return res
} }