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/repository"
"repo-pattern/app/repository/smartfilter"
"time"
"gorm.io/gorm"
)
@ -25,19 +24,19 @@ func doMagic(db *gorm.DB) {
// id := "6dc096ab-5c03-427e-b808-c669f7446131"
// serialNumber := "222"
// serialNumberContains := "323"
issuer := "FINA"
location, _ := time.LoadLocation("UTC")
createdTime := time.Date(2024, 5, 26, 16, 8, 0, 0, location)
// issuer := "FINA"
// location, _ := time.LoadLocation("UTC")
// 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"}
filter := smartfilter.CertFilter{
Alive: &FALSE,
// Alive: &FALSE,
// Id: &id,
// SerialNumber: &serialNumber,
// SerialNumberContains: &serialNumberContains,
Ids: &ids,
IssuerContains: &issuer,
CreatedAt_Lt: &createdTime,
Ids: &ids,
// IssuerContains: &issuer,
// CreatedAt_Lt: &createdTime,
}
query, err = smartfilter.ToQuery(models.Cert{}, filter, query)
@ -113,9 +112,9 @@ func main() {
db := db.InitDB()
repository.Dao = repository.CreateDAO(db)
// doMagic(db)
doMagic(db)
// doList(db)
// doGet(db)
doExists(db)
// doExists(db)
// inheritance.DoInheritanceTest()
}

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
}