Add custom struct scan test

This commit is contained in:
zer0sub 2019-05-21 17:34:43 +02:00
parent 00080962ff
commit 3917c84694
2 changed files with 52 additions and 20 deletions

View file

@ -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 {
if source.CanAddr() {
sourceElem = source.Addr()
} else { } else {
newDestination := reflect.New(destination.Type().Elem()) newDestination := reflect.New(destination.Type().Elem())
newDestination.Elem().Set(source) newDestination.Elem().Set(source)
destination.Set(newDestination)
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)

View file

@ -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) {