Add custom struct scan test
This commit is contained in:
parent
00080962ff
commit
3917c84694
2 changed files with 52 additions and 20 deletions
|
|
@ -139,7 +139,7 @@ func mapRowToSlice(scanContext *scanContext, groupKey string, slicePtrValue refl
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rowElemPtr := scanContext.rowElemPtr(index)
|
rowElemPtr := scanContext.rowElemValuePtr(index)
|
||||||
|
|
||||||
if !rowElemPtr.IsNil() {
|
if !rowElemPtr.IsNil() {
|
||||||
updated = true
|
updated = true
|
||||||
|
|
@ -411,7 +411,17 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updated = true
|
updated = true
|
||||||
} else if !isGoBaseType(field.Type) {
|
} else if isGoBaseType(field.Type) {
|
||||||
|
cellValue := getCellValue(scanContext, tableName, fieldName)
|
||||||
|
//spew.Dump(rowElem)
|
||||||
|
|
||||||
|
//spew.Dump(rowColumnValue, fieldValue)
|
||||||
|
if cellValue != nil {
|
||||||
|
updated = true
|
||||||
|
initializeValueIfNil(fieldValue)
|
||||||
|
setReflectValue(reflect.ValueOf(cellValue), fieldValue)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
var changed bool
|
var changed bool
|
||||||
changed, err = mapRowToDestinationValue(scanContext, groupKey, fieldValue, &field)
|
changed, err = mapRowToDestinationValue(scanContext, groupKey, fieldValue, &field)
|
||||||
|
|
||||||
|
|
@ -422,16 +432,6 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
||||||
if changed {
|
if changed {
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
cellValue := getCellValue(scanContext, tableName, fieldName)
|
|
||||||
//spew.Dump(rowElem)
|
|
||||||
|
|
||||||
//spew.Dump(rowColumnValue, fieldValue)
|
|
||||||
if cellValue != nil {
|
|
||||||
updated = true
|
|
||||||
initializeValueIfNil(fieldValue)
|
|
||||||
setReflectValue(reflect.ValueOf(cellValue), fieldValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -518,22 +518,36 @@ func isGoBaseType(objType reflect.Type) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func setReflectValue(source, destination reflect.Value) {
|
func setReflectValue(source, destination reflect.Value) error {
|
||||||
|
var sourceElem reflect.Value
|
||||||
if destination.Kind() == reflect.Ptr {
|
if destination.Kind() == reflect.Ptr {
|
||||||
if source.Kind() == reflect.Ptr {
|
if source.Kind() == reflect.Ptr {
|
||||||
destination.Set(source)
|
sourceElem = source
|
||||||
} else {
|
} else {
|
||||||
newDestination := reflect.New(destination.Type().Elem())
|
if source.CanAddr() {
|
||||||
newDestination.Elem().Set(source)
|
sourceElem = source.Addr()
|
||||||
destination.Set(newDestination)
|
} else {
|
||||||
|
newDestination := reflect.New(destination.Type().Elem())
|
||||||
|
newDestination.Elem().Set(source)
|
||||||
|
|
||||||
|
sourceElem = newDestination
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if source.Kind() == reflect.Ptr {
|
if source.Kind() == reflect.Ptr {
|
||||||
destination.Set(source.Elem())
|
sourceElem = source.Elem()
|
||||||
} else {
|
} else {
|
||||||
destination.Set(source)
|
sourceElem = source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !sourceElem.Type().AssignableTo(destination.Type()) {
|
||||||
|
return errors.New("Can't set " + sourceElem.Type().String() + " to " + destination.Type().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.Set(sourceElem)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIndex(list []string, text string) int {
|
func getIndex(list []string, text string) int {
|
||||||
|
|
@ -639,7 +653,7 @@ func (s *scanContext) rowElem(index int) interface{} {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scanContext) rowElemPtr(index int) reflect.Value {
|
func (s *scanContext) rowElemValuePtr(index int) reflect.Value {
|
||||||
rowElem := s.rowElem(index)
|
rowElem := s.rowElem(index)
|
||||||
rowElemValue := reflect.ValueOf(rowElem)
|
rowElemValue := reflect.ValueOf(rowElem)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,24 @@ func TestScanToStruct(t *testing.T) {
|
||||||
assert.Error(t, err, "Unsupported dest type: Inventory ***model.Inventory")
|
assert.Error(t, err, "Unsupported dest type: Inventory ***model.Inventory")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("custom struct", func(t *testing.T) {
|
||||||
|
type Inventory struct {
|
||||||
|
InventoryID *int32 `sql:"unique"`
|
||||||
|
FilmID int16
|
||||||
|
StoreID *int16
|
||||||
|
}
|
||||||
|
|
||||||
|
dest := Inventory{}
|
||||||
|
|
||||||
|
err := query.Query(db, &dest)
|
||||||
|
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, *dest.InventoryID, int32(1))
|
||||||
|
assert.Equal(t, dest.FilmID, int16(1))
|
||||||
|
assert.Equal(t, *dest.StoreID, int16(1))
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScanToNestedStruct(t *testing.T) {
|
func TestScanToNestedStruct(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue