diff --git a/SHOULDERS.md b/SHOULDERS.md index 7ace7345..5f5528db 100644 --- a/SHOULDERS.md +++ b/SHOULDERS.md @@ -39,6 +39,8 @@ Thank you to the following **GIANTS**: * [github.com/gobuffalo/makr](https://godoc.org/github.com/gobuffalo/makr) +* [github.com/gobuffalo/nulls](https://godoc.org/github.com/gobuffalo/nulls) + * [github.com/gobuffalo/packd](https://godoc.org/github.com/gobuffalo/packd) * [github.com/gobuffalo/plush](https://godoc.org/github.com/gobuffalo/plush) @@ -51,18 +53,6 @@ Thank you to the following **GIANTS**: * [github.com/gobuffalo/plush/token](https://godoc.org/github.com/gobuffalo/plush/token) -* [github.com/gobuffalo/pop](https://godoc.org/github.com/gobuffalo/pop) - -* [github.com/gobuffalo/pop/associations](https://godoc.org/github.com/gobuffalo/pop/associations) - -* [github.com/gobuffalo/pop/columns](https://godoc.org/github.com/gobuffalo/pop/columns) - -* [github.com/gobuffalo/pop/fix](https://godoc.org/github.com/gobuffalo/pop/fix) - -* [github.com/gobuffalo/pop/logging](https://godoc.org/github.com/gobuffalo/pop/logging) - -* [github.com/gobuffalo/pop/nulls](https://godoc.org/github.com/gobuffalo/pop/nulls) - * [github.com/gobuffalo/syncx](https://godoc.org/github.com/gobuffalo/syncx) * [github.com/gobuffalo/tags](https://godoc.org/github.com/gobuffalo/tags) diff --git a/associations/association.go b/associations/association.go index ee1502db..a653d532 100644 --- a/associations/association.go +++ b/associations/association.go @@ -3,8 +3,8 @@ package associations import ( "reflect" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/pop/columns" - "github.com/gobuffalo/pop/nulls" ) // Association represents a definition of a model association diff --git a/associations/belongs_to_association.go b/associations/belongs_to_association.go index dd6a72bb..c1687f76 100644 --- a/associations/belongs_to_association.go +++ b/associations/belongs_to_association.go @@ -5,8 +5,8 @@ import ( "reflect" "github.com/gobuffalo/flect" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/pop/columns" - "github.com/gobuffalo/pop/nulls" "github.com/gobuffalo/x/defaults" ) diff --git a/associations/has_many_association.go b/associations/has_many_association.go index ce654cc2..fddc5bee 100644 --- a/associations/has_many_association.go +++ b/associations/has_many_association.go @@ -5,7 +5,7 @@ import ( "reflect" "github.com/gobuffalo/flect" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/jmoiron/sqlx" ) diff --git a/associations/has_many_association_test.go b/associations/has_many_association_test.go index 56099202..fef4df66 100644 --- a/associations/has_many_association_test.go +++ b/associations/has_many_association_test.go @@ -4,8 +4,8 @@ import ( "reflect" "testing" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/pop/associations" - "github.com/gobuffalo/pop/nulls" "github.com/stretchr/testify/require" ) diff --git a/associations/has_one_association.go b/associations/has_one_association.go index e82deccc..1747d343 100644 --- a/associations/has_one_association.go +++ b/associations/has_one_association.go @@ -5,7 +5,7 @@ import ( "reflect" "github.com/gobuffalo/flect" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/x/defaults" ) diff --git a/associations/has_one_association_test.go b/associations/has_one_association_test.go index 06a3ed72..4bc08931 100644 --- a/associations/has_one_association_test.go +++ b/associations/has_one_association_test.go @@ -4,8 +4,8 @@ import ( "reflect" "testing" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/pop/associations" - "github.com/gobuffalo/pop/nulls" "github.com/gofrs/uuid" "github.com/stretchr/testify/require" ) diff --git a/benchmarks_test.go b/benchmarks_test.go index c0cd456c..10fc5939 100644 --- a/benchmarks_test.go +++ b/benchmarks_test.go @@ -5,7 +5,7 @@ import ( "strconv" "testing" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" ) func Benchmark_Create_Pop(b *testing.B) { diff --git a/executors_test.go b/executors_test.go index 29635e3a..998f5077 100644 --- a/executors_test.go +++ b/executors_test.go @@ -3,7 +3,7 @@ package pop import ( "testing" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/gofrs/uuid" "github.com/stretchr/testify/require" ) diff --git a/finders_test.go b/finders_test.go index 3afbe077..58669d41 100644 --- a/finders_test.go +++ b/finders_test.go @@ -3,7 +3,7 @@ package pop import ( "testing" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/gofrs/uuid" "github.com/stretchr/testify/require" ) diff --git a/nulls/README.md b/nulls/README.md index 054e1c73..6eb2d388 100644 --- a/nulls/README.md +++ b/nulls/README.md @@ -1,5 +1,7 @@ # github.com/gobuffalo/pop/nulls +DEPRECATED: use github.com/gobuffalo/nulls instead. + This package should be used in place of the built-in null types in the `sql` package. The real benefit of this packages comes in its implementation of `MarshalJSON` and `UnmarshalJSON` to properly encode/decode `null` values. diff --git a/nulls/bool.go b/nulls/bool.go index 93fd593a..fafac2d2 100644 --- a/nulls/bool.go +++ b/nulls/bool.go @@ -1,82 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" + "github.com/gobuffalo/nulls" ) // Bool replaces sql.NullBool with an implementation // that supports proper JSON encoding/decoding. -type Bool struct { - Bool bool - Valid bool -} - -// Interface implements the nullable interface. It returns nil if -// the bool is not valid, otherwise it returns the bool value. -func (ns Bool) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Bool -} +type Bool nulls.Bool // NewBool returns a new, properly instantiated -// Boll object. -func NewBool(b bool) Bool { - return Bool{Bool: b, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Bool) Scan(value interface{}) error { - n := sql.NullBool{Bool: ns.Bool} - err := n.Scan(value) - ns.Bool, ns.Valid = n.Bool, n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Bool) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return ns.Bool, nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Bool) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Bool) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the proper representation of that value. The strings -// "true" and "t" will be considered "true", "false" and "f" will -// be treated as "false". All other values will -//be set to null by Valid = false -func (ns *Bool) UnmarshalJSON(text []byte) error { - t := string(text) - if t == "true" || t == "t" { - ns.Valid = true - ns.Bool = true - return nil - } - if t == "false" || t == "f" { - ns.Valid = true - ns.Bool = false - return nil - } - ns.Bool = false - ns.Valid = false - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Bool) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +// Bool object. +var NewBool = nulls.NewBool diff --git a/nulls/byte_slice.go b/nulls/byte_slice.go index 293d4993..9c443bf0 100644 --- a/nulls/byte_slice.go +++ b/nulls/byte_slice.go @@ -1,79 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/base64" - "encoding/json" + "github.com/gobuffalo/nulls" ) // ByteSlice adds an implementation for []byte // that supports proper JSON encoding/decoding. -type ByteSlice struct { - ByteSlice []byte - Valid bool // Valid is true if ByteSlice is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the byte slice is not valid, otherwise it returns the byte slice value. -func (ns ByteSlice) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.ByteSlice -} +type ByteSlice nulls.ByteSlice // NewByteSlice returns a new, properly instantiated // ByteSlice object. -func NewByteSlice(b []byte) ByteSlice { - return ByteSlice{ByteSlice: b, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *ByteSlice) Scan(value interface{}) error { - n := sql.NullString{String: base64.StdEncoding.EncodeToString(ns.ByteSlice)} - err := n.Scan(value) - if err != nil { - return err - } - //ns.Float32, ns.Valid = float32(n.Float64), n.Valid - ns.ByteSlice, err = base64.StdEncoding.DecodeString(n.String) - ns.Valid = n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns ByteSlice) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return base64.StdEncoding.EncodeToString(ns.ByteSlice), nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns ByteSlice) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.ByteSlice) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *ByteSlice) UnmarshalJSON(text []byte) error { - ns.Valid = false - if string(text) == "null" { - return nil - } - - ns.ByteSlice = text - ns.Valid = true - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *ByteSlice) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewByteSlice = nulls.NewByteSlice diff --git a/nulls/float32.go b/nulls/float32.go index c9b0f742..e6c6755e 100644 --- a/nulls/float32.go +++ b/nulls/float32.go @@ -1,80 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // Float32 adds an implementation for float32 // that supports proper JSON encoding/decoding. -type Float32 struct { - Float32 float32 - Valid bool // Valid is true if Float32 is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the float32 is not valid, otherwise it returns the float32 value. -func (ns Float32) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Float32 -} +type Float32 nulls.Float32 // NewFloat32 returns a new, properly instantiated // Float32 object. -func NewFloat32(i float32) Float32 { - return Float32{Float32: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Float32) Scan(value interface{}) error { - n := sql.NullFloat64{Float64: float64(ns.Float32)} - err := n.Scan(value) - ns.Float32, ns.Valid = float32(n.Float64), n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Float32) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return float64(ns.Float32), nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Float32) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Float32) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Float32) UnmarshalJSON(text []byte) error { - txt := string(text) - ns.Valid = true - if txt == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseFloat(txt, 32) - if err != nil { - ns.Valid = false - return err - } - j := float32(i) - ns.Float32 = j - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Float32) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewFloat32 = nulls.NewFloat32 diff --git a/nulls/float64.go b/nulls/float64.go index dcd670dc..1972e3f6 100644 --- a/nulls/float64.go +++ b/nulls/float64.go @@ -1,76 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // Float64 replaces sql.NullFloat64 with an implementation // that supports proper JSON encoding/decoding. -type Float64 sql.NullFloat64 - -// Interface implements the nullable interface. It returns nil if -// the float64 is not valid, otherwise it returns the float64 value. -func (ns Float64) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Float64 -} +type Float64 nulls.Float64 // NewFloat64 returns a new, properly instantiated // Float64 object. -func NewFloat64(i float64) Float64 { - return Float64{Float64: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Float64) Scan(value interface{}) error { - n := sql.NullFloat64{Float64: ns.Float64} - err := n.Scan(value) - ns.Float64, ns.Valid = n.Float64, n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Float64) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return ns.Float64, nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Float64) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Float64) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Float64) UnmarshalJSON(text []byte) error { - t := string(text) - ns.Valid = true - if t == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseFloat(t, 64) - if err != nil { - ns.Valid = false - return err - } - ns.Float64 = i - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Float64) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewFloat64 = nulls.NewFloat64 diff --git a/nulls/int.go b/nulls/int.go index 3c406136..8855800e 100644 --- a/nulls/int.go +++ b/nulls/int.go @@ -1,79 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // Int adds an implementation for int // that supports proper JSON encoding/decoding. -type Int struct { - Int int - Valid bool // Valid is true if Int is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the int is not valid, otherwise it returns the int value. -func (ns Int) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Int -} +type Int nulls.Int // NewInt returns a new, properly instantiated // Int object. -func NewInt(i int) Int { - return Int{Int: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Int) Scan(value interface{}) error { - n := sql.NullInt64{Int64: int64(ns.Int)} - err := n.Scan(value) - ns.Int, ns.Valid = int(n.Int64), n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Int) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return int64(ns.Int), nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Int) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Int) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Int) UnmarshalJSON(text []byte) error { - txt := string(text) - ns.Valid = true - if txt == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseInt(txt, 10, strconv.IntSize) - if err != nil { - ns.Valid = false - return err - } - ns.Int = int(i) - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Int) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewInt = nulls.NewInt diff --git a/nulls/int32.go b/nulls/int32.go index 481c48c9..d77d184d 100644 --- a/nulls/int32.go +++ b/nulls/int32.go @@ -1,80 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // Int32 adds an implementation for int32 // that supports proper JSON encoding/decoding. -type Int32 struct { - Int32 int32 - Valid bool // Valid is true if Int32 is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the int32 is not valid, otherwise it returns the int32 value. -func (ns Int32) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Int32 -} +type Int32 nulls.Int32 // NewInt32 returns a new, properly instantiated // Int object. -func NewInt32(i int32) Int32 { - return Int32{Int32: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Int32) Scan(value interface{}) error { - n := sql.NullInt64{Int64: int64(ns.Int32)} - err := n.Scan(value) - ns.Int32, ns.Valid = int32(n.Int64), n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Int32) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return int64(ns.Int32), nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Int32) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Int32) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Int32) UnmarshalJSON(text []byte) error { - txt := string(text) - ns.Valid = true - if txt == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseInt(txt, 10, 32) - if err != nil { - ns.Valid = false - return err - } - j := int32(i) - ns.Int32 = j - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Int32) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewInt32 = nulls.NewInt32 diff --git a/nulls/int64.go b/nulls/int64.go index 00d911cc..b70b14cb 100644 --- a/nulls/int64.go +++ b/nulls/int64.go @@ -1,76 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // Int64 replaces sql.Int64 with an implementation // that supports proper JSON encoding/decoding. -type Int64 sql.NullInt64 - -// Interface implements the nullable interface. It returns nil if -// the int64 is not valid, otherwise it returns the int64 value. -func (ns Int64) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Int64 -} +type Int64 nulls.Int64 // NewInt64 returns a new, properly instantiated // Int64 object. -func NewInt64(i int64) Int64 { - return Int64{Int64: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Int64) Scan(value interface{}) error { - n := sql.NullInt64{Int64: ns.Int64} - err := n.Scan(value) - ns.Int64, ns.Valid = n.Int64, n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns Int64) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return ns.Int64, nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Int64) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Int64) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Int64) UnmarshalJSON(text []byte) error { - t := string(text) - ns.Valid = true - if t == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseInt(t, 10, 64) - if err != nil { - ns.Valid = false - return err - } - ns.Int64 = i - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Int64) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewInt64 = nulls.NewInt64 diff --git a/nulls/int_test.go b/nulls/int_test.go index b68563c7..eaf407c5 100644 --- a/nulls/int_test.go +++ b/nulls/int_test.go @@ -3,7 +3,7 @@ package nulls_test import ( "testing" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/stretchr/testify/require" ) diff --git a/nulls/schema.go b/nulls/schema.go index 0e1f7cb9..349ef261 100644 --- a/nulls/schema.go +++ b/nulls/schema.go @@ -1,59 +1,8 @@ package nulls -import "reflect" - -type register func(interface{}, func(string) reflect.Value) +import ( + "github.com/gobuffalo/nulls" +) // RegisterWithSchema allows for the nulls package to be used with http://www.gorillatoolkit.org/pkg/schema#Converter -func RegisterWithSchema(reg register) { - reg(String{}, func(s string) reflect.Value { - ns := String{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Bool{}, func(s string) reflect.Value { - ns := Bool{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(ByteSlice{}, func(s string) reflect.Value { - ns := ByteSlice{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Float32{}, func(s string) reflect.Value { - ns := Float32{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Float64{}, func(s string) reflect.Value { - ns := Float64{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Int{}, func(s string) reflect.Value { - ns := Int{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Int32{}, func(s string) reflect.Value { - ns := Int32{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Int64{}, func(s string) reflect.Value { - ns := Int64{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(Time{}, func(s string) reflect.Value { - ns := Time{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) - reg(UInt32{}, func(s string) reflect.Value { - ns := UInt32{} - ns.Scan(s) - return reflect.ValueOf(ns) - }) -} +var RegisterWithSchema = nulls.RegisterWithSchema diff --git a/nulls/string.go b/nulls/string.go index d5c516a1..ce6b0b3c 100644 --- a/nulls/string.go +++ b/nulls/string.go @@ -1,77 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" + "github.com/gobuffalo/nulls" ) // String replaces sql.NullString with an implementation // that supports proper JSON encoding/decoding. -type String sql.NullString - -// Interface implements the nullable interface. It returns nil if -// the string is not valid, otherwise it returns the string value. -func (ns String) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.String -} +type String nulls.String // NewString returns a new, properly instantiated // String object. -func NewString(s string) String { - return String{String: s, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *String) Scan(value interface{}) error { - n := sql.NullString{String: ns.String} - err := n.Scan(value) - ns.String, ns.Valid = n.String, n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns String) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return ns.String, nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns String) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.String) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *String) UnmarshalJSON(text []byte) error { - ns.Valid = false - if string(text) == "null" { - return nil - } - if err := json.Unmarshal(text, &ns.String); err == nil { - ns.Valid = true - } - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *String) UnmarshalText(text []byte) error { - ns.Valid = false - t := string(text) - if t == "null" { - return nil - } - ns.String = t - ns.Valid = true - return nil -} +var NewString = nulls.NewString diff --git a/nulls/time.go b/nulls/time.go index 6d2b085b..5207771c 100644 --- a/nulls/time.go +++ b/nulls/time.go @@ -1,77 +1,13 @@ package nulls import ( - "database/sql/driver" - "encoding/json" - "time" + "github.com/gobuffalo/nulls" ) // Time replaces sql.NullTime with an implementation // that supports proper JSON encoding/decoding. -type Time struct { - Time time.Time - Valid bool // Valid is true if Time is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the Time is not valid, otherwise it returns the Time value. -func (ns Time) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.Time -} +type Time nulls.Time // NewTime returns a new, properly instantiated // Time object. -func NewTime(t time.Time) Time { - return Time{Time: t, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *Time) Scan(value interface{}) error { - ns.Time, ns.Valid = value.(time.Time) - return nil -} - -// Value implements the driver Valuer interface. -func (ns Time) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return ns.Time, nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns Time) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.Time) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *Time) UnmarshalJSON(text []byte) error { - ns.Valid = false - txt := string(text) - if txt == "null" || txt == "" { - return nil - } - - t := time.Time{} - err := t.UnmarshalJSON(text) - if err == nil { - ns.Time = t - ns.Valid = true - } - - return err -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *Time) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewTime = nulls.NewTime diff --git a/nulls/types_test.go b/nulls/types_test.go index 61791153..c55f43f6 100644 --- a/nulls/types_test.go +++ b/nulls/types_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - . "github.com/gobuffalo/pop/nulls" + . "github.com/gobuffalo/nulls" "github.com/gofrs/uuid" "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" diff --git a/nulls/uint32.go b/nulls/uint32.go index 6e631b64..cc58d4cb 100644 --- a/nulls/uint32.go +++ b/nulls/uint32.go @@ -1,80 +1,13 @@ package nulls import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" + "github.com/gobuffalo/nulls" ) // UInt32 adds an implementation for int // that supports proper JSON encoding/decoding. -type UInt32 struct { - UInt32 uint32 - Valid bool // Valid is true if Int is not NULL -} - -// Interface implements the nullable interface. It returns nil if -// the uint32 is not valid, otherwise it returns the uint32 value. -func (ns UInt32) Interface() interface{} { - if !ns.Valid { - return nil - } - return ns.UInt32 -} +type UInt32 nulls.UInt32 // NewUInt32 returns a new, properly instantiated // Int object. -func NewUInt32(i uint32) UInt32 { - return UInt32{UInt32: i, Valid: true} -} - -// Scan implements the Scanner interface. -func (ns *UInt32) Scan(value interface{}) error { - n := sql.NullInt64{Int64: int64(ns.UInt32)} - err := n.Scan(value) - ns.UInt32, ns.Valid = uint32(n.Int64), n.Valid - return err -} - -// Value implements the driver Valuer interface. -func (ns UInt32) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return int64(ns.UInt32), nil -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (ns UInt32) MarshalJSON() ([]byte, error) { - if ns.Valid { - return json.Marshal(ns.UInt32) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (ns *UInt32) UnmarshalJSON(text []byte) error { - txt := string(text) - ns.Valid = true - if txt == "null" { - ns.Valid = false - return nil - } - i, err := strconv.ParseInt(txt, 10, 32) - if err != nil { - ns.Valid = false - return err - } - j := uint32(i) - ns.UInt32 = j - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (ns *UInt32) UnmarshalText(text []byte) error { - return ns.UnmarshalJSON(text) -} +var NewUInt32 = nulls.NewUInt32 diff --git a/nulls/uuid.go b/nulls/uuid.go index 609f3c9d..d43315f5 100644 --- a/nulls/uuid.go +++ b/nulls/uuid.go @@ -1,91 +1,13 @@ package nulls import ( - "database/sql/driver" - "encoding/json" - "strings" - - "github.com/gofrs/uuid" - "github.com/pkg/errors" + "github.com/gobuffalo/nulls" ) // UUID can be used with the standard sql package to represent a // UUID value that can be NULL in the database -type UUID struct { - UUID uuid.UUID - Valid bool -} - -// Interface implements the nullable interface. It returns nil if -// the UUID is not valid, otherwise it returns the UUID value. -func (u UUID) Interface() interface{} { - if !u.Valid { - return nil - } - return u.UUID -} +type UUID nulls.UUID // NewUUID returns a new, properly instantiated // UUID object. -func NewUUID(u uuid.UUID) UUID { - return UUID{UUID: u, Valid: true} -} - -// Value implements the driver.Valuer interface. -func (u UUID) Value() (driver.Value, error) { - if !u.Valid { - return nil, nil - } - // Delegate to UUID Value function - return u.UUID.Value() -} - -// Scan implements the sql.Scanner interface. -func (u *UUID) Scan(src interface{}) error { - if src == nil { - u.UUID, u.Valid = uuid.Nil, false - return nil - } - - // Delegate to UUID Scan function - u.Valid = true - return u.UUID.Scan(src) -} - -// MarshalJSON marshals the underlying value to a -// proper JSON representation. -func (u UUID) MarshalJSON() ([]byte, error) { - if u.Valid { - return json.Marshal(u.UUID.String()) - } - return json.Marshal(nil) -} - -// UnmarshalJSON will unmarshal a JSON value into -// the propert representation of that value. -func (u *UUID) UnmarshalJSON(text []byte) error { - u.Valid = false - u.UUID = uuid.Nil - if string(text) == "null" { - return nil - } - - s := string(text) - s = strings.TrimPrefix(s, "\"") - s = strings.TrimSuffix(s, "\"") - - us, err := uuid.FromString(s) - if err != nil { - return errors.WithStack(err) - } - u.UUID = us - u.Valid = true - - return nil -} - -// UnmarshalText will unmarshal text value into -// the propert representation of that value. -func (u *UUID) UnmarshalText(text []byte) error { - return u.UnmarshalJSON(text) -} +var NewUUID = nulls.NewUUID diff --git a/nulls/uuid_test.go b/nulls/uuid_test.go index a85877d6..8ae51e4a 100644 --- a/nulls/uuid_test.go +++ b/nulls/uuid_test.go @@ -1,9 +1,10 @@ -package nulls +package nulls_test import ( "encoding/json" "testing" + "github.com/gobuffalo/nulls" "github.com/gofrs/uuid" "github.com/stretchr/testify/require" ) @@ -16,7 +17,7 @@ func Test_UUID_UnmarshalJSON(t *testing.T) { b, err := json.Marshal(id) r.NoError(err) - nid := &UUID{} + nid := &nulls.UUID{} r.NoError(nid.UnmarshalJSON(b)) diff --git a/pagination_test.go b/pagination_test.go index 1c4e7c87..c2f7d4cd 100644 --- a/pagination_test.go +++ b/pagination_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/gobuffalo/pop/nulls" + "github.com/gobuffalo/nulls" "github.com/stretchr/testify/require" ) diff --git a/pop_test.go b/pop_test.go index 706729b4..2f4e05f7 100644 --- a/pop_test.go +++ b/pop_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" + "github.com/gobuffalo/nulls" "github.com/gobuffalo/pop/logging" - "github.com/gobuffalo/pop/nulls" "github.com/gobuffalo/validate" "github.com/gobuffalo/validate/validators" "github.com/gofrs/uuid" diff --git a/soda/cmd/generate/attribute.go b/soda/cmd/generate/attribute.go index c3dcee49..108aff1c 100644 --- a/soda/cmd/generate/attribute.go +++ b/soda/cmd/generate/attribute.go @@ -44,7 +44,7 @@ func newAttribute(base string, model *model) (attribute, error) { nullable := strings.HasPrefix(col[1], "nulls.") if !model.HasNulls && nullable { model.HasNulls = true - model.Imports = append(model.Imports, "github.com/gobuffalo/pop/nulls") + model.Imports = append(model.Imports, "github.com/gobuffalo/nulls") } else if !model.HasSlices && strings.HasPrefix(col[1], "slices.") { model.HasSlices = true model.Imports = append(model.Imports, "github.com/gobuffalo/pop/slices")