aboutsummaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
authorDaniel Theophanes <kardianos@gmail.com>2019-04-05 10:23:15 -0700
committerDaniel Theophanes <kardianos@gmail.com>2019-04-05 18:03:45 +0000
commitd47da9497f7e17aab1d4b3169604f62b491a9dd1 (patch)
treece2597d7b1f59dd5d774109114ef64f8c1fd3372 /src/database
parentc7a4099b9926b466b55c7271868d9dfb0271117e (diff)
downloadgo-d47da9497f7e17aab1d4b3169604f62b491a9dd1.tar.gz
go-d47da9497f7e17aab1d4b3169604f62b491a9dd1.zip
database/sql: add NullTime
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>
Diffstat (limited to 'src/database')
-rw-r--r--src/database/sql/fakedb_test.go4
-rw-r--r--src/database/sql/sql.go26
-rw-r--r--src/database/sql/sql_test.go15
3 files changed, 44 insertions, 1 deletions
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
index dcdd264baa..f30edc00ea 100644
--- a/src/database/sql/fakedb_test.go
+++ b/src/database/sql/fakedb_test.go
@@ -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{}
}
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 8cdc903c68..3b3ac27436 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -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.
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index 64b9dfea5c..c07c5d3bd2 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -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)