2
0

Range types Set method supports its own type, string, and nil

Previously Set would always return an error when called on a range type.
Now it will accept an instance of itself, a pointer to an instance of
itself, a string, or nil. Strings are parsed with the same logic as
DecodeText.
This commit is contained in:
Jack Christensen
2020-03-03 15:25:57 -06:00
parent 55a56add23
commit 8117205a75
8 changed files with 192 additions and 7 deletions
+18 -1
View File
@@ -16,7 +16,24 @@ type Daterange struct {
}
func (dst *Daterange) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Daterange", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Daterange{Status: Null}
return nil
}
switch value := src.(type) {
case Daterange:
*dst = value
case *Daterange:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Daterange", src)
}
return nil
}
func (dst Daterange) Get() interface{} {
+66
View File
@@ -65,3 +65,69 @@ func TestDaterangeNormalize(t *testing.T) {
a.Upper.InfinityModifier == b.Upper.InfinityModifier
})
}
func TestDaterangeSet(t *testing.T) {
successfulTests := []struct {
source interface{}
result pgtype.Daterange
}{
{
source: nil,
result: pgtype.Daterange{Status: pgtype.Null},
},
{
source: &pgtype.Daterange{
Lower: pgtype.Date{Time: time.Date(1990, 12, 31, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
Upper: pgtype.Date{Time: time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
LowerType: pgtype.Inclusive,
UpperType: pgtype.Exclusive,
Status: pgtype.Present,
},
result: pgtype.Daterange{
Lower: pgtype.Date{Time: time.Date(1990, 12, 31, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
Upper: pgtype.Date{Time: time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
LowerType: pgtype.Inclusive,
UpperType: pgtype.Exclusive,
Status: pgtype.Present,
},
},
{
source: pgtype.Daterange{
Lower: pgtype.Date{Time: time.Date(1990, 12, 31, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
Upper: pgtype.Date{Time: time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
LowerType: pgtype.Inclusive,
UpperType: pgtype.Exclusive,
Status: pgtype.Present,
},
result: pgtype.Daterange{
Lower: pgtype.Date{Time: time.Date(1990, 12, 31, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
Upper: pgtype.Date{Time: time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
LowerType: pgtype.Inclusive,
UpperType: pgtype.Exclusive,
Status: pgtype.Present,
},
},
{
source: "[1990-12-31,2028-01-01)",
result: pgtype.Daterange{
Lower: pgtype.Date{Time: time.Date(1990, 12, 31, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
Upper: pgtype.Date{Time: time.Date(2028, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present},
LowerType: pgtype.Inclusive,
UpperType: pgtype.Exclusive,
Status: pgtype.Present,
},
},
}
for i, tt := range successfulTests {
var r pgtype.Daterange
err := r.Set(tt.source)
if err != nil {
t.Errorf("%d: %v", i, err)
}
if r != tt.result {
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
}
}
}
+18 -1
View File
@@ -16,7 +16,24 @@ type Int4range struct {
}
func (dst *Int4range) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Int4range", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Int4range{Status: Null}
return nil
}
switch value := src.(type) {
case Int4range:
*dst = value
case *Int4range:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Int4range", src)
}
return nil
}
func (dst Int4range) Get() interface{} {
+18 -1
View File
@@ -16,7 +16,24 @@ type Int8range struct {
}
func (dst *Int8range) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Int8range", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Int8range{Status: Null}
return nil
}
switch value := src.(type) {
case Int8range:
*dst = value
case *Int8range:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Int8range", src)
}
return nil
}
func (dst Int8range) Get() interface{} {
+18 -1
View File
@@ -16,7 +16,24 @@ type Numrange struct {
}
func (dst *Numrange) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Numrange", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Numrange{Status: Null}
return nil
}
switch value := src.(type) {
case Numrange:
*dst = value
case *Numrange:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Numrange", src)
}
return nil
}
func (dst Numrange) Get() interface{} {
+18 -1
View File
@@ -16,7 +16,24 @@ type Tsrange struct {
}
func (dst *Tsrange) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Tsrange", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Tsrange{Status: Null}
return nil
}
switch value := src.(type) {
case Tsrange:
*dst = value
case *Tsrange:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Tsrange", src)
}
return nil
}
func (dst Tsrange) Get() interface{} {
+18 -1
View File
@@ -16,7 +16,24 @@ type Tstzrange struct {
}
func (dst *Tstzrange) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to Tstzrange", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = Tstzrange{Status: Null}
return nil
}
switch value := src.(type) {
case Tstzrange:
*dst = value
case *Tstzrange:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to Tstzrange", src)
}
return nil
}
func (dst Tstzrange) Get() interface{} {
+18 -1
View File
@@ -18,7 +18,24 @@ type <%= range_type %> struct {
}
func (dst *<%= range_type %>) Set(src interface{}) error {
return errors.Errorf("cannot convert %v to <%= range_type %>", src)
// untyped nil and typed nil interfaces are different
if src == nil {
*dst = <%= range_type %>{Status: Null}
return nil
}
switch value := src.(type) {
case <%= range_type %>:
*dst = value
case *<%= range_type %>:
*dst = *value
case string:
return dst.DecodeText(nil, []byte(value))
default:
return errors.Errorf("cannot convert %v to <%= range_type %>", src)
}
return nil
}
func (dst <%= range_type %>) Get() interface{} {