v0.0.351 sq value converter
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m30s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m30s
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/jmoiron/sqlx/reflectx"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -15,9 +16,10 @@ type StructScanner struct {
|
||||
Mapper *reflectx.Mapper
|
||||
unsafe bool
|
||||
|
||||
fields [][]int
|
||||
values []any
|
||||
columns []string
|
||||
fields [][]int
|
||||
values []any
|
||||
converter []DBTypeConverter
|
||||
columns []string
|
||||
}
|
||||
|
||||
func NewStructScanner(rows *sqlx.Rows, unsafe bool) *StructScanner {
|
||||
@@ -47,13 +49,15 @@ func (r *StructScanner) Start(dest any) error {
|
||||
return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
|
||||
}
|
||||
r.values = make([]interface{}, len(columns))
|
||||
r.converter = make([]DBTypeConverter, len(columns))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StructScanExt forked from github.com/jmoiron/sqlx@v1.3.5/sqlx.go
|
||||
// does also wok with nullabel structs (from LEFT JOIN's)
|
||||
func (r *StructScanner) StructScanExt(dest any) error {
|
||||
// does also work with nullabel structs (from LEFT JOIN's)
|
||||
// does also work with custom value converters
|
||||
func (r *StructScanner) StructScanExt(q Queryable, dest any) error {
|
||||
v := reflect.ValueOf(dest)
|
||||
|
||||
if v.Kind() != reflect.Ptr {
|
||||
@@ -64,7 +68,7 @@ func (r *StructScanner) StructScanExt(dest any) error {
|
||||
|
||||
v = v.Elem()
|
||||
|
||||
err := fieldsByTraversalExtended(v, r.fields, r.values)
|
||||
err := fieldsByTraversalExtended(q, v, r.fields, r.values, r.converter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -131,7 +135,6 @@ func (r *StructScanner) StructScanExt(dest any) error {
|
||||
|
||||
val1 := reflect.ValueOf(r.values[i])
|
||||
val2 := val1.Elem()
|
||||
val3 := val2.Elem()
|
||||
|
||||
if val2.IsNil() {
|
||||
if f.Kind() != reflect.Pointer {
|
||||
@@ -140,7 +143,16 @@ func (r *StructScanner) StructScanExt(dest any) error {
|
||||
|
||||
f.Set(reflect.Zero(f.Type())) // set to nil
|
||||
} else {
|
||||
f.Set(val3)
|
||||
if r.converter[i] != nil {
|
||||
val3 := val2.Elem().Interface()
|
||||
conv3, err := r.converter[i].DBToModel(val3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Set(reflect.ValueOf(conv3))
|
||||
} else {
|
||||
f.Set(val2.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -172,7 +184,7 @@ func (r *StructScanner) StructScanBase(dest any) error {
|
||||
}
|
||||
|
||||
// fieldsByTraversal forked from github.com/jmoiron/sqlx@v1.3.5/sqlx.go
|
||||
func fieldsByTraversalExtended(v reflect.Value, traversals [][]int, values []interface{}) error {
|
||||
func fieldsByTraversalExtended(q Queryable, v reflect.Value, traversals [][]int, values []interface{}, converter []DBTypeConverter) error {
|
||||
v = reflect.Indirect(v)
|
||||
if v.Kind() != reflect.Struct {
|
||||
return errors.New("argument not a struct")
|
||||
@@ -185,7 +197,23 @@ func fieldsByTraversalExtended(v reflect.Value, traversals [][]int, values []int
|
||||
}
|
||||
f := reflectx.FieldByIndexes(v, traversal)
|
||||
|
||||
values[i] = reflect.New(reflect.PointerTo(f.Type())).Interface()
|
||||
typeStr := f.Type().String()
|
||||
|
||||
foundConverter := false
|
||||
for _, conv := range q.ListConverter() {
|
||||
if conv.ModelTypeString() == typeStr {
|
||||
_v := langext.Ptr[any](nil)
|
||||
values[i] = _v
|
||||
foundConverter = true
|
||||
converter[i] = conv
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundConverter {
|
||||
values[i] = reflect.New(reflect.PointerTo(f.Type())).Interface()
|
||||
converter[i] = nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user