diff --git a/bool.go b/bool.go index 903c87d..a899dc3 100644 --- a/bool.go +++ b/bool.go @@ -5,7 +5,6 @@ import ( "database/sql/driver" "encoding/json" "errors" - "github.com/volatiletech/null/v9/convert" ) @@ -148,3 +147,11 @@ func (b Bool) Value() (driver.Value, error) { } return b.Bool, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t Bool) ValueOrDefault() bool { + if !t.Valid { + return false + } + return t.Bool +} diff --git a/bool_test.go b/bool_test.go index 68bef49..161a854 100644 --- a/bool_test.go +++ b/bool_test.go @@ -162,6 +162,18 @@ func TestBoolScan(t *testing.T) { assertNullBool(t, null, "scanned null") } +func TestBoolValueOrDefault(t *testing.T) { + valid := NewBool(true, true) + if valid.ValueOrDefault() != true { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewBool(true, false) + if invalid.ValueOrDefault() != false { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertBool(t *testing.T, b Bool, from string) { if b.Bool != true { t.Errorf("bad %s bool: %v ≠ %v\n", from, b.Bool, true) diff --git a/byte.go b/byte.go index cf745da..2da633a 100644 --- a/byte.go +++ b/byte.go @@ -148,3 +148,11 @@ func (b Byte) Value() (driver.Value, error) { } return []byte{b.Byte}, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t Byte) ValueOrDefault() byte { + if !t.Valid { + return 0 + } + return t.Byte +} diff --git a/byte_test.go b/byte_test.go index 6d18ff6..456fb0d 100644 --- a/byte_test.go +++ b/byte_test.go @@ -145,6 +145,18 @@ func TestByteScan(t *testing.T) { assertNullByte(t, null, "scanned null") } +func TestByteValueOrDefault(t *testing.T) { + valid := NewByte(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewByte(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertByte(t *testing.T, i Byte, from string) { if i.Byte != 'b' { t.Errorf("bad %s int: %d ≠ %d\n", from, i.Byte, 'b') diff --git a/bytes.go b/bytes.go index 32c43d5..3101cb9 100644 --- a/bytes.go +++ b/bytes.go @@ -4,7 +4,6 @@ import ( "bytes" "database/sql/driver" "encoding/json" - "github.com/volatiletech/null/v9/convert" ) @@ -139,3 +138,11 @@ func (b Bytes) Value() (driver.Value, error) { } return b.Bytes, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t Bytes) ValueOrDefault() []byte { + if !t.Valid { + return []byte{} + } + return t.Bytes +} diff --git a/bytes_test.go b/bytes_test.go index 514469b..c68dbe5 100644 --- a/bytes_test.go +++ b/bytes_test.go @@ -3,6 +3,7 @@ package null import ( "bytes" "encoding/json" + "reflect" "testing" ) @@ -153,6 +154,18 @@ func TestBytesScan(t *testing.T) { assertNullBytes(t, null, "scanned null") } +func TestBytesValueOrDefault(t *testing.T) { + valid := NewBytes([]byte{1}, true) + if !reflect.DeepEqual(valid.ValueOrDefault(), []byte{1}) { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewBytes([]byte{1}, false) + if reflect.DeepEqual(valid.ValueOrDefault(), []byte{}) { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertBytes(t *testing.T, i Bytes, from string) { if !bytes.Equal(i.Bytes, hello) { t.Errorf("bad %s []byte: %v ≠ %v\n", from, string(i.Bytes), "hello") diff --git a/float32.go b/float32.go index ba05b16..6df2d06 100644 --- a/float32.go +++ b/float32.go @@ -4,9 +4,8 @@ import ( "bytes" "database/sql/driver" "encoding/json" - "strconv" - "github.com/volatiletech/null/v9/convert" + "strconv" ) // Float32 is a nullable float32. @@ -137,3 +136,11 @@ func (f Float32) Value() (driver.Value, error) { } return float64(f.Float32), nil } + +// ValueOrDefault returns the inner value if valid, otherwise zero. +func (t Float32) ValueOrDefault() float32 { + if !t.Valid { + return 0.0 + } + return t.Float32 +} diff --git a/float32_test.go b/float32_test.go index cfb335e..042a528 100644 --- a/float32_test.go +++ b/float32_test.go @@ -145,6 +145,18 @@ func TestFloat32Scan(t *testing.T) { assertNullFloat32(t, null, "scanned null") } +func TestFloat32ValueOrDefault(t *testing.T) { + valid := NewFloat32(1.0, true) + if valid.ValueOrDefault() != 1.0 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewFloat32(1.0, false) + if invalid.ValueOrDefault() != 0.0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertFloat32(t *testing.T, f Float32, from string) { if f.Float32 != 1.2345 { t.Errorf("bad %s float32: %f ≠ %f\n", from, f.Float32, 1.2345) diff --git a/float64.go b/float64.go index 914b408..0fd38dd 100644 --- a/float64.go +++ b/float64.go @@ -132,3 +132,11 @@ func (f Float64) Value() (driver.Value, error) { } return f.Float64, nil } + +// ValueOrDefault returns the inner value if valid, otherwise zero. +func (t Float64) ValueOrDefault() float64 { + if !t.Valid { + return 0.0 + } + return t.Float64 +} diff --git a/float64_test.go b/float64_test.go index 7c78e09..28d9233 100644 --- a/float64_test.go +++ b/float64_test.go @@ -145,6 +145,18 @@ func TestFloat64Scan(t *testing.T) { assertNullFloat64(t, null, "scanned null") } +func TestFloat64ValueOrDefault(t *testing.T) { + valid := NewFloat64(1.0, true) + if valid.ValueOrDefault() != 1.0 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewFloat64(1.0, false) + if invalid.ValueOrDefault() != 0.0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertFloat64(t *testing.T, f Float64, from string) { if f.Float64 != 1.2345 { t.Errorf("bad %s float64: %f ≠ %f\n", from, f.Float64, 1.2345) diff --git a/int.go b/int.go index 11a58a2..df15615 100644 --- a/int.go +++ b/int.go @@ -138,3 +138,11 @@ func (i Int) Value() (driver.Value, error) { } return int64(i.Int), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (i Int) ValueOrDefault() int { + if !i.Valid { + return 0 + } + return i.Int +} diff --git a/int16.go b/int16.go index 8d6e850..bcf8d94 100644 --- a/int16.go +++ b/int16.go @@ -141,3 +141,11 @@ func (i Int16) Value() (driver.Value, error) { } return int64(i.Int16), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (i Int16) ValueOrDefault() int16 { + if !i.Valid { + return 0 + } + return i.Int16 +} diff --git a/int16_test.go b/int16_test.go index ca5ed00..bbdbb0c 100644 --- a/int16_test.go +++ b/int16_test.go @@ -171,6 +171,18 @@ func TestInt16Scan(t *testing.T) { assertNullInt16(t, null, "scanned null") } +func TestInt16ValueOrDefault(t *testing.T) { + valid := NewInt16(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewInt16(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertInt16(t *testing.T, i Int16, from string) { if i.Int16 != 32766 { t.Errorf("bad %s int16: %d ≠ %d\n", from, i.Int16, 32766) diff --git a/int32.go b/int32.go index 92430e4..a4cdafe 100644 --- a/int32.go +++ b/int32.go @@ -143,3 +143,11 @@ func (i Int32) Value() (driver.Value, error) { } return int64(i.Int32), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (i Int32) ValueOrDefault() int32 { + if !i.Valid { + return 0 + } + return i.Int32 +} diff --git a/int32_test.go b/int32_test.go index 00f6f85..127e4d6 100644 --- a/int32_test.go +++ b/int32_test.go @@ -172,6 +172,18 @@ func TestInt32Scan(t *testing.T) { assertNullInt32(t, null, "scanned null") } +func TestInt32ValueOrDefault(t *testing.T) { + valid := NewInt32(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewInt32(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertInt32(t *testing.T, i Int32, from string) { if i.Int32 != 2147483646 { t.Errorf("bad %s int32: %d ≠ %d\n", from, i.Int32, 2147483646) diff --git a/int64.go b/int64.go index 8636ce1..fd8d001 100644 --- a/int64.go +++ b/int64.go @@ -132,3 +132,11 @@ func (i Int64) Value() (driver.Value, error) { } return i.Int64, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (i Int64) ValueOrDefault() int64 { + if !i.Valid { + return 0 + } + return i.Int64 +} diff --git a/int64_test.go b/int64_test.go index 9e6fc13..1823c6c 100644 --- a/int64_test.go +++ b/int64_test.go @@ -172,6 +172,18 @@ func TestInt64Scan(t *testing.T) { assertNullInt64(t, null, "scanned null") } +func TestInt64ValueOrDefault(t *testing.T) { + valid := NewInt64(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewInt64(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertInt64(t *testing.T, i Int64, from string) { if i.Int64 != 9223372036854775806 { t.Errorf("bad %s int64: %d ≠ %d\n", from, i.Int64, 9223372036854775806) diff --git a/int8.go b/int8.go index d98e001..0162a29 100644 --- a/int8.go +++ b/int8.go @@ -143,3 +143,11 @@ func (i Int8) Value() (driver.Value, error) { } return int64(i.Int8), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (i Int8) ValueOrDefault() int8 { + if !i.Valid { + return 0 + } + return i.Int8 +} diff --git a/int8_test.go b/int8_test.go index 58d37f9..96caee6 100644 --- a/int8_test.go +++ b/int8_test.go @@ -172,6 +172,18 @@ func TestInt8Scan(t *testing.T) { assertNullInt8(t, null, "scanned null") } +func TestInt8ValueOrDefault(t *testing.T) { + valid := NewInt8(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewInt8(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertInt8(t *testing.T, i Int8, from string) { if i.Int8 != 126 { t.Errorf("bad %s int8: %d ≠ %d\n", from, i.Int8, 126) diff --git a/int_test.go b/int_test.go index 1f1d204..a957aa3 100644 --- a/int_test.go +++ b/int_test.go @@ -154,6 +154,18 @@ func TestIntScan(t *testing.T) { assertNullInt(t, null, "scanned null") } +func TestIntValueOrDefault(t *testing.T) { + valid := NewInt(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewInt(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertInt(t *testing.T, i Int, from string) { if i.Int != 12345 { t.Errorf("bad %s int: %d ≠ %d\n", from, i.Int, 12345) diff --git a/json.go b/json.go index 98c190f..dd6eecb 100644 --- a/json.go +++ b/json.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/volatiletech/null/v9/convert" ) @@ -80,9 +79,9 @@ func (j JSON) Unmarshal(dest interface{}) error { // // Example if you have a struct with a null.JSON called v: // -// {} -> does not call unmarshaljson: !set & !valid -// {"v": null} -> calls unmarshaljson, set & !valid -// {"v": {}} -> calls unmarshaljson, set & valid (json value is '{}') +// {} -> does not call unmarshaljson: !set & !valid +// {"v": null} -> calls unmarshaljson, set & !valid +// {"v": {}} -> calls unmarshaljson, set & valid (json value is '{}') // // That's to say if 'null' is passed in at the json level we do not capture that // value - instead we set the value-level null flag so that an sql value will @@ -188,3 +187,11 @@ func (j JSON) Value() (driver.Value, error) { } return j.JSON, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t JSON) ValueOrDefault() []byte { + if !t.Valid { + return []byte{} + } + return t.JSON +} diff --git a/json_test.go b/json_test.go index 2855ffe..d6259e7 100644 --- a/json_test.go +++ b/json_test.go @@ -3,6 +3,7 @@ package null import ( "bytes" "encoding/json" + "reflect" "testing" ) @@ -276,6 +277,18 @@ func TestJSONScan(t *testing.T) { assertNullJSON(t, null, "scanned null") } +func TestJSONValueOrDefault(t *testing.T) { + valid := NewJSON([]byte{1}, true) + if !reflect.DeepEqual(valid.ValueOrDefault(), []byte{1}) { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewJSON([]byte{1}, false) + if reflect.DeepEqual(invalid.ValueOrDefault(), []byte{1}) { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } +} + func assertJSON(t *testing.T, i JSON, from string) { t.Helper() if !bytes.Equal(i.JSON, []byte(`"hello"`)) { diff --git a/string.go b/string.go index 2043ab5..0e9e097 100644 --- a/string.go +++ b/string.go @@ -4,7 +4,6 @@ import ( "bytes" "database/sql/driver" "encoding/json" - "github.com/volatiletech/null/v9/convert" ) @@ -131,3 +130,11 @@ func (s String) Value() (driver.Value, error) { } return s.String, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t String) ValueOrDefault() string { + if !t.Valid { + return "" + } + return t.String +} diff --git a/string_test.go b/string_test.go index fc09254..ae59dac 100644 --- a/string_test.go +++ b/string_test.go @@ -174,6 +174,18 @@ func TestStringScan(t *testing.T) { assertNullStr(t, null, "scanned null") } +func TestStringValueOrDefault(t *testing.T) { + valid := NewString("test", true) + if valid.ValueOrDefault() != "test" { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewString("test", false) + if invalid.ValueOrDefault() != "" { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func maybePanic(err error) { if err != nil { panic(err) diff --git a/time.go b/time.go index ba4d7df..27a1993 100644 --- a/time.go +++ b/time.go @@ -139,3 +139,11 @@ func (t Time) Value() (driver.Value, error) { } return t.Time, nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (t Time) ValueOrDefault() time.Time { + if !t.Valid { + return time.Time{} + } + return t.Time +} diff --git a/time_test.go b/time_test.go index 29688ca..5fb8b16 100644 --- a/time_test.go +++ b/time_test.go @@ -154,6 +154,21 @@ func TestTimeScanValue(t *testing.T) { assertNullTime(t, wrong, "scanned wrong") } +func TestTimeValueOrDefault(t *testing.T) { + now := time.Now() + + valid := NewTime(now, true) + if valid.ValueOrDefault() != now { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + defaultTime := time.Time{} + invalid := NewTime(now, false) + if invalid.ValueOrDefault() != defaultTime { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertTime(t *testing.T, ti Time, from string) { if ti.Time != timeValue { t.Errorf("bad %v time: %v ≠ %v\n", from, ti.Time, timeValue) diff --git a/uint.go b/uint.go index 14a7ff4..91fdcb6 100644 --- a/uint.go +++ b/uint.go @@ -137,3 +137,11 @@ func (u Uint) Value() (driver.Value, error) { } return int64(u.Uint), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (u Uint) ValueOrDefault() uint { + if !u.Valid { + return 0 + } + return u.Uint +} diff --git a/uint16.go b/uint16.go index 554e0ae..e995c3f 100644 --- a/uint16.go +++ b/uint16.go @@ -143,3 +143,11 @@ func (u Uint16) Value() (driver.Value, error) { } return int64(u.Uint16), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (u Uint16) ValueOrDefault() uint16 { + if !u.Valid { + return 0 + } + return u.Uint16 +} diff --git a/uint16_test.go b/uint16_test.go index a67c1a1..1e4b167 100644 --- a/uint16_test.go +++ b/uint16_test.go @@ -172,6 +172,18 @@ func TestUint16Scan(t *testing.T) { assertNullUint16(t, null, "scanned null") } +func TestUint16ValueOrDefault(t *testing.T) { + valid := NewUint16(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewUint16(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertUint16(t *testing.T, i Uint16, from string) { if i.Uint16 != 65534 { t.Errorf("bad %s uint16: %d ≠ %d\n", from, i.Uint16, 65534) diff --git a/uint32.go b/uint32.go index a6883b6..a05d3d8 100644 --- a/uint32.go +++ b/uint32.go @@ -143,3 +143,11 @@ func (u Uint32) Value() (driver.Value, error) { } return int64(u.Uint32), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (u Uint32) ValueOrDefault() uint32 { + if !u.Valid { + return 0 + } + return u.Uint32 +} diff --git a/uint32_test.go b/uint32_test.go index c2b5ffe..6909910 100644 --- a/uint32_test.go +++ b/uint32_test.go @@ -172,6 +172,18 @@ func TestUint32Scan(t *testing.T) { assertNullUint32(t, null, "scanned null") } +func TestUint32ValueOrDefault(t *testing.T) { + valid := NewUint32(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewUint32(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertUint32(t *testing.T, i Uint32, from string) { if i.Uint32 != 4294967294 { t.Errorf("bad %s uint32: %d ≠ %d\n", from, i.Uint32, 4294967294) diff --git a/uint64.go b/uint64.go index dd590e8..300570a 100644 --- a/uint64.go +++ b/uint64.go @@ -147,3 +147,11 @@ func (u Uint64) Value() (driver.Value, error) { return int64(u.Uint64), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (u Uint64) ValueOrDefault() uint64 { + if !u.Valid { + return 0 + } + return u.Uint64 +} diff --git a/uint64_test.go b/uint64_test.go index 7ed0f11..ff963c8 100644 --- a/uint64_test.go +++ b/uint64_test.go @@ -157,6 +157,18 @@ func TestUint64Scan(t *testing.T) { assertNullUint64(t, i, "scanned null") } +func TestUint64ValueOrDefault(t *testing.T) { + valid := NewUint64(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewUint64(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertUint64(t *testing.T, i Uint64, from string) { if i.Uint64 != 18446744073709551614 { t.Errorf("bad %s uint64: %d ≠ %d\n", from, i.Uint64, uint64(18446744073709551614)) diff --git a/uint8.go b/uint8.go index 15be4bc..4685936 100644 --- a/uint8.go +++ b/uint8.go @@ -143,3 +143,11 @@ func (u Uint8) Value() (driver.Value, error) { } return int64(u.Uint8), nil } + +// ValueOrDefault returns the inner value if valid, otherwise default. +func (u Uint8) ValueOrDefault() uint8 { + if !u.Valid { + return 0 + } + return u.Uint8 +} diff --git a/uint8_test.go b/uint8_test.go index 3b39563..ac93f69 100644 --- a/uint8_test.go +++ b/uint8_test.go @@ -172,6 +172,18 @@ func TestUint8Scan(t *testing.T) { assertNullUint8(t, null, "scanned null") } +func TestUint8ValueOrDefault(t *testing.T) { + valid := NewUint8(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewUint8(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertUint8(t *testing.T, i Uint8, from string) { if i.Uint8 != 254 { t.Errorf("bad %s uint8: %d ≠ %d\n", from, i.Uint8, 254) diff --git a/uint_test.go b/uint_test.go index 7bb68cb..f982131 100644 --- a/uint_test.go +++ b/uint_test.go @@ -154,6 +154,18 @@ func TestUintScan(t *testing.T) { assertNullUint(t, null, "scanned null") } +func TestUintValueOrDefault(t *testing.T) { + valid := NewUint(1, true) + if valid.ValueOrDefault() != 1 { + t.Error("unexpected ValueOrDefault", valid.ValueOrDefault()) + } + + invalid := NewUint(1, false) + if invalid.ValueOrDefault() != 0 { + t.Error("unexpected ValueOrDefault", invalid.ValueOrDefault()) + } +} + func assertUint(t *testing.T, i Uint, from string) { if i.Uint != 12345 { t.Errorf("bad %s uint: %d ≠ %d\n", from, i.Uint, 12345)