Add sync.Pool
This commit is contained in:
parent
fb52b97363
commit
07f0438435
8
scan.go
8
scan.go
@ -55,11 +55,13 @@ func (db *DB) scanIntoStruct(sch *schema.Schema, rows *sql.Rows, reflectValue re
|
|||||||
if sch == nil {
|
if sch == nil {
|
||||||
values[idx] = reflectValue.Interface()
|
values[idx] = reflectValue.Interface()
|
||||||
} else if field := sch.LookUpField(column); field != nil && field.Readable {
|
} else if field := sch.LookUpField(column); field != nil && field.Readable {
|
||||||
values[idx] = reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface()
|
values[idx] = field.NewScanValue()
|
||||||
} else if names := strings.Split(column, "__"); len(names) > 1 {
|
defer field.ReleaseScanValue(values[idx])
|
||||||
|
} else if names := strings.Split(column, "__"); len(names) > 2 {
|
||||||
if rel, ok := sch.Relationships.Relations[names[0]]; ok {
|
if rel, ok := sch.Relationships.Relations[names[0]]; ok {
|
||||||
if field := rel.FieldSchema.LookUpField(strings.Join(names[1:], "__")); field != nil && field.Readable {
|
if field := rel.FieldSchema.LookUpField(strings.Join(names[1:], "__")); field != nil && field.Readable {
|
||||||
values[idx] = reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface()
|
values[idx] = field.NewScanValue()
|
||||||
|
defer field.ReleaseScanValue(values[idx])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ type Field struct {
|
|||||||
ReflectValueOf func(context.Context, reflect.Value) reflect.Value
|
ReflectValueOf func(context.Context, reflect.Value) reflect.Value
|
||||||
ValueOf func(context.Context, reflect.Value) (value interface{}, zero bool)
|
ValueOf func(context.Context, reflect.Value) (value interface{}, zero bool)
|
||||||
Set func(context.Context, reflect.Value, interface{}) error
|
Set func(context.Context, reflect.Value, interface{}) error
|
||||||
|
NewScanValue func() interface{}
|
||||||
|
ReleaseScanValue func(interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseField parses reflect.StructField to Field
|
// ParseField parses reflect.StructField to Field
|
||||||
@ -412,13 +414,39 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
|||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
bytesPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
bs := make([]byte, 0, 10)
|
||||||
|
return &bs
|
||||||
|
},
|
||||||
|
}
|
||||||
|
bytesPoolReleaser = func(v interface{}) {
|
||||||
|
bs := v.(*[]byte)
|
||||||
|
*bs = (*bs)[:0]
|
||||||
|
if string(*bs) != "" {
|
||||||
|
fmt.Println(string(*bs))
|
||||||
|
}
|
||||||
|
bytesPool.Put(bs)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// create valuer, setter when parse struct
|
// create valuer, setter when parse struct
|
||||||
func (field *Field) setupValuerAndSetter() {
|
func (field *Field) setupValuerAndSetter() {
|
||||||
// ValueOf returns field's value and if it is zero
|
// Setup NewScanValue
|
||||||
|
switch field.DataType {
|
||||||
|
case Bytes, String:
|
||||||
|
field.NewScanValue = bytesPool.Get
|
||||||
|
field.ReleaseScanValue = bytesPoolReleaser
|
||||||
|
default:
|
||||||
|
field.NewScanValue = func() interface{} {
|
||||||
|
return reflect.New(reflect.PtrTo(field.IndirectFieldType)).Interface()
|
||||||
|
}
|
||||||
|
field.ReleaseScanValue = func(interface{}) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if vr, ok := fv.(GormFieldValuer); ok {
|
// ValueOf returns field's value and if it is zero
|
||||||
// fv, zero = vr.GormFieldValue(ctx, field)
|
|
||||||
// }
|
|
||||||
field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) {
|
field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) {
|
||||||
v = reflect.Indirect(v)
|
v = reflect.Indirect(v)
|
||||||
for _, fieldIdx := range field.StructField.Index {
|
for _, fieldIdx := range field.StructField.Index {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user