diff --git a/field_test.go b/field_test.go index 03a3b3b7..715661f0 100644 --- a/field_test.go +++ b/field_test.go @@ -1,9 +1,11 @@ package gorm_test import ( + "database/sql/driver" + "encoding/hex" + "fmt" "testing" - "github.com/gofrs/uuid" "github.com/jinzhu/gorm" ) @@ -49,17 +51,78 @@ func TestCalculateField(t *testing.T) { } } +type UUID [16]byte + +type NullUUID struct { + UUID + Valid bool +} + +func FromString(input string) (u UUID) { + src := []byte(input) + return FromBytes(src) +} + +func FromBytes(src []byte) (u UUID) { + dst := u[:] + hex.Decode(dst[0:4], src[0:8]) + hex.Decode(dst[4:6], src[9:13]) + hex.Decode(dst[6:8], src[14:18]) + hex.Decode(dst[8:10], src[19:23]) + hex.Decode(dst[10:], src[24:]) + return +} + +func (u UUID) String() string { + buf := make([]byte, 36) + src := u[:] + hex.Encode(buf[0:8], src[0:4]) + buf[8] = '-' + hex.Encode(buf[9:13], src[4:6]) + buf[13] = '-' + hex.Encode(buf[14:18], src[6:8]) + buf[18] = '-' + hex.Encode(buf[19:23], src[8:10]) + buf[23] = '-' + hex.Encode(buf[24:], src[10:]) + return string(buf) +} + +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case UUID: // support gorm convert from UUID to NullUUID + *u = src + return nil + case []byte: + *u = FromBytes(src) + return nil + case string: + *u = FromString(src) + return nil + } + return fmt.Errorf("uuid: cannot convert %T to UUID", src) +} + +func (u *NullUUID) Scan(src interface{}) error { + u.Valid = true + return u.UUID.Scan(src) +} + func TestFieldSet(t *testing.T) { type TestFieldSetNullUUID struct { - NullUUID uuid.NullUUID + NullUUID NullUUID } scope := DB.NewScope(&TestFieldSetNullUUID{}) field := scope.Fields()[0] - err := field.Set(uuid.FromStringOrNil("3034d44a-da03-11e8-b366-4a00070b9f00")) + err := field.Set(FromString("3034d44a-da03-11e8-b366-4a00070b9f00")) if err != nil { t.Fatal(err) } - if id, ok := field.Field.Addr().Interface().(*uuid.NullUUID); !ok { + if id, ok := field.Field.Addr().Interface().(*NullUUID); !ok { t.Fatal() } else if !id.Valid || id.UUID.String() != "3034d44a-da03-11e8-b366-4a00070b9f00" { t.Fatal(id) diff --git a/go.mod b/go.mod index f675334d..024f73ca 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,9 @@ require ( github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289 github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 github.com/go-sql-driver/mysql v1.4.1 - github.com/gofrs/uuid v3.2.0+incompatible github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a github.com/jinzhu/now v1.0.0 github.com/lib/pq v1.0.0 github.com/mattn/go-sqlite3 v1.10.0 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect - google.golang.org/appengine v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 25f61146..894ee21b 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -34,6 +32,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -132,7 +131,6 @@ google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx1 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= diff --git a/model_struct.go b/model_struct.go index a1e6c0e2..f646910a 100644 --- a/model_struct.go +++ b/model_struct.go @@ -625,6 +625,9 @@ func (scope *Scope) GetStructFields() (fields []*StructField) { func parseTagSetting(tags reflect.StructTag) map[string]string { setting := map[string]string{} for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} { + if str == "" { + continue + } tags := strings.Split(str, ";") for _, value := range tags { v := strings.Split(value, ":")