]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: add NullTime
authorDaniel Theophanes <kardianos@gmail.com>
Fri, 5 Apr 2019 17:23:15 +0000 (10:23 -0700)
committerDaniel Theophanes <kardianos@gmail.com>
Fri, 5 Apr 2019 18:03:45 +0000 (18:03 +0000)
This matches NullBool, NullFloat64, and NullInt64.

Fixes #30305

Change-Id: I79bfcf04a3d43b965d2a3159b0ac22f3e8084a53
Reviewed-on: https://go-review.googlesource.com/c/go/+/170699
Run-TryBot: Daniel Theophanes <kardianos@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/database/sql/fakedb_test.go
src/database/sql/sql.go
src/database/sql/sql_test.go

index dcdd264baa8422e51ed3a20e1585fc0e5f7c9864..f30edc00ea56d1335c81a38130007276f0036dfd 100644 (file)
@@ -1158,7 +1158,9 @@ func converterForType(typ string) driver.ValueConverter {
                // TODO(coopernurse): add type-specific converter
                return driver.Null{Converter: driver.DefaultParameterConverter}
        case "datetime":
-               return driver.DefaultParameterConverter
+               return driver.NotNull{Converter: driver.DefaultParameterConverter}
+       case "nulldatetime":
+               return driver.Null{Converter: driver.DefaultParameterConverter}
        case "any":
                return anyTypeConverter{}
        }
index 8cdc903c6808d173e9cddec8be34bddff6d0d771..3b3ac274364560357eeaf509854d7eade7ce3393 100644 (file)
@@ -286,6 +286,32 @@ func (n NullBool) Value() (driver.Value, error) {
        return n.Bool, nil
 }
 
+// NullTime represents a time.Time that may be null.
+// NullTime implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullTime struct {
+       Time  time.Time
+       Valid bool // Valid is true if Time is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullTime) Scan(value interface{}) error {
+       if value == nil {
+               n.Time, n.Valid = time.Time{}, false
+               return nil
+       }
+       n.Valid = true
+       return convertAssign(&n.Time, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullTime) Value() (driver.Value, error) {
+       if !n.Valid {
+               return nil, nil
+       }
+       return n.Time, nil
+}
+
 // Scanner is an interface used by Scan.
 type Scanner interface {
        // Scan assigns a value from a database driver.
index 64b9dfea5c21303c25b8d185159a9e3909be1126..c07c5d3bd23cee687bd864d5c37ebeee47f82bef 100644 (file)
@@ -1695,6 +1695,21 @@ func TestNullBoolParam(t *testing.T) {
        nullTestRun(t, spec)
 }
 
+func TestNullTimeParam(t *testing.T) {
+       t0 := time.Time{}
+       t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
+       t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
+       spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
+               {NullTime{t1, true}, t2, NullTime{t1, true}},
+               {NullTime{t1, false}, t2, NullTime{t0, false}},
+               {t1, t2, NullTime{t1, true}},
+               {NullTime{t1, true}, t2, NullTime{t1, true}},
+               {NullTime{t1, false}, t2, NullTime{t0, false}},
+               {t2, NullTime{t1, false}, nil},
+       }}
+       nullTestRun(t, spec)
+}
+
 func nullTestRun(t *testing.T, spec nullTestSpec) {
        db := newTestDB(t, "")
        defer closeDB(t, db)