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
|
||||
}
|
||||
}
|
||||
rowElemPtr := scanContext.rowElemPtr(index)
|
||||
rowElemPtr := scanContext.rowElemValuePtr(index)
|
||||
|
||||
if !rowElemPtr.IsNil() {
|
||||
updated = true
|
||||
|
|
@ -411,7 +411,17 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
|||
return
|
||||
}
|
||||
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
|
||||
changed, err = mapRowToDestinationValue(scanContext, groupKey, fieldValue, &field)
|
||||
|
||||
|
|
@ -422,16 +432,6 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
|||
if changed {
|
||||
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
|
||||
}
|
||||
|
||||
func setReflectValue(source, destination reflect.Value) {
|
||||
func setReflectValue(source, destination reflect.Value) error {
|
||||
var sourceElem reflect.Value
|
||||
if destination.Kind() == reflect.Ptr {
|
||||
if source.Kind() == reflect.Ptr {
|
||||
destination.Set(source)
|
||||
sourceElem = source
|
||||
} else {
|
||||
if source.CanAddr() {
|
||||
sourceElem = source.Addr()
|
||||
} else {
|
||||
newDestination := reflect.New(destination.Type().Elem())
|
||||
newDestination.Elem().Set(source)
|
||||
destination.Set(newDestination)
|
||||
|
||||
sourceElem = newDestination
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if source.Kind() == reflect.Ptr {
|
||||
destination.Set(source.Elem())
|
||||
sourceElem = source.Elem()
|
||||
} 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 {
|
||||
|
|
@ -639,7 +653,7 @@ func (s *scanContext) rowElem(index int) interface{} {
|
|||
return value
|
||||
}
|
||||
|
||||
func (s *scanContext) rowElemPtr(index int) reflect.Value {
|
||||
func (s *scanContext) rowElemValuePtr(index int) reflect.Value {
|
||||
rowElem := s.rowElem(index)
|
||||
rowElemValue := reflect.ValueOf(rowElem)
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,24 @@ func TestScanToStruct(t *testing.T) {
|
|||
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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue