Merge branch 'ncw/uuid-convs' of https://github.com/NWilson/pgx into NWilson-ncw/uuid-convs

pull/589/head
Jack Christensen 2019-08-17 13:20:53 -05:00
commit 05597c2155
3 changed files with 53 additions and 3 deletions

View File

@ -149,7 +149,7 @@ func underlyingTimeType(val interface{}) (interface{}, bool) {
switch refVal.Kind() {
case reflect.Ptr:
if refVal.IsNil() {
return time.Time{}, false
return nil, false
}
convVal := refVal.Elem().Interface()
return convVal, true
@ -160,7 +160,28 @@ func underlyingTimeType(val interface{}) (interface{}, bool) {
return refVal.Convert(timeType).Interface(), true
}
return time.Time{}, false
return nil, false
}
// underlyingUUIDType gets the underlying type that can be converted to [16]byte
func underlyingUUIDType(val interface{}) (interface{}, bool) {
refVal := reflect.ValueOf(val)
switch refVal.Kind() {
case reflect.Ptr:
if refVal.IsNil() {
return time.Time{}, false
}
convVal := refVal.Elem().Interface()
return convVal, true
}
uuidType := reflect.TypeOf([16]byte{})
if refVal.Type().ConvertibleTo(uuidType) {
return refVal.Convert(uuidType).Interface(), true
}
return nil, false
}
// underlyingSliceType gets the underlying slice type
@ -401,6 +422,14 @@ func GetAssignToDstType(dst interface{}) (interface{}, bool) {
}
}
if dstVal.Kind() == reflect.Array {
if baseElemType, ok := kindTypes[dstVal.Type().Elem().Kind()]; ok {
baseArrayType := reflect.PtrTo(reflect.ArrayOf(dstVal.Len(), baseElemType))
nextDst := dstPtr.Convert(baseArrayType)
return nextDst.Interface(), dstPtr.Type() != nextDst.Type()
}
}
return nil, false
}

View File

@ -39,7 +39,7 @@ func (dst *UUID) Set(src interface{}) error {
}
*dst = UUID{Bytes: uuid, Status: Present}
default:
if originalSrc, ok := underlyingPtrType(src); ok {
if originalSrc, ok := underlyingUUIDType(src); ok {
return dst.Set(originalSrc)
}
return errors.Errorf("cannot convert %v to UUID", value)

View File

@ -15,6 +15,8 @@ func TestUUIDTranscode(t *testing.T) {
})
}
type SomeUUIDType [16]byte
func TestUUIDSet(t *testing.T) {
successfulTests := []struct {
source interface{}
@ -32,6 +34,10 @@ func TestUUIDSet(t *testing.T) {
source: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
result: pgtype.UUID{Bytes: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, Status: pgtype.Present},
},
{
source: SomeUUIDType{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
result: pgtype.UUID{Bytes: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, Status: pgtype.Present},
},
{
source: ([]byte)(nil),
result: pgtype.UUID{Status: pgtype.Null},
@ -86,6 +92,21 @@ func TestUUIDAssignTo(t *testing.T) {
}
}
{
src := pgtype.UUID{Bytes: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, Status: pgtype.Present}
var dst SomeUUIDType
expected := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
err := src.AssignTo(&dst)
if err != nil {
t.Error(err)
}
if dst != expected {
t.Errorf("expected %v to assign %v, but result was %v", src, expected, dst)
}
}
{
src := pgtype.UUID{Bytes: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, Status: pgtype.Present}
var dst string