diff --git a/field.go b/field.go index 11c410b0..acd06e20 100644 --- a/field.go +++ b/field.go @@ -2,6 +2,7 @@ package gorm import ( "database/sql" + "database/sql/driver" "errors" "fmt" "reflect" @@ -44,7 +45,14 @@ func (field *Field) Set(value interface{}) (err error) { if reflectValue.Type().ConvertibleTo(fieldValue.Type()) { fieldValue.Set(reflectValue.Convert(fieldValue.Type())) } else if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { - err = scanner.Scan(reflectValue.Interface()) + v := reflectValue.Interface() + if valuer, ok := v.(driver.Valuer); ok { + if v, err = valuer.Value(); err == nil { + err = scanner.Scan(v) + } + } else { + err = scanner.Scan(v) + } } else { err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type()) } diff --git a/field_test.go b/field_test.go index c3afdff5..03a3b3b7 100644 --- a/field_test.go +++ b/field_test.go @@ -3,6 +3,7 @@ package gorm_test import ( "testing" + "github.com/gofrs/uuid" "github.com/jinzhu/gorm" ) @@ -47,3 +48,20 @@ func TestCalculateField(t *testing.T) { t.Errorf("should find embedded field's tag settings") } } + +func TestFieldSet(t *testing.T) { + type TestFieldSetNullUUID struct { + NullUUID uuid.NullUUID + } + scope := DB.NewScope(&TestFieldSetNullUUID{}) + field := scope.Fields()[0] + err := field.Set(uuid.FromStringOrNil("3034d44a-da03-11e8-b366-4a00070b9f00")) + if err != nil { + t.Fatal(err) + } + if id, ok := field.Field.Addr().Interface().(*uuid.NullUUID); !ok { + t.Fatal() + } else if !id.Valid || id.UUID.String() != "3034d44a-da03-11e8-b366-4a00070b9f00" { + t.Fatal(id) + } +}