From 2492eae46cfd851a34912f64421119039d5f4299 Mon Sep 17 00:00:00 2001 From: Andrey Kuzmin Date: Mon, 22 Apr 2019 00:22:22 +0300 Subject: [PATCH 1/2] Support for pgtype.Date JSON marshal/unmarshal. JSON marshalling for types added on a as-needed basis. Partly closes https://github.com/jackc/pgx/issues/310. --- pgtype/date.go | 29 +++++++++++++++++++++++++++++ pgtype/date_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/pgtype/date.go b/pgtype/date.go index b1d4c11d..658dbf1c 100644 --- a/pgtype/date.go +++ b/pgtype/date.go @@ -3,6 +3,7 @@ package pgtype import ( "database/sql/driver" "encoding/binary" + "encoding/json" "time" "github.com/jackc/pgx/pgio" @@ -207,3 +208,31 @@ func (src *Date) Value() (driver.Value, error) { return nil, errUndefined } } + +func (src *Date) MarshalJSON() ([]byte, error) { + switch src.Status { + case Present: + res, err := src.Time.MarshalJSON() + if err != nil { + return nil, err + } + return res, nil + case Null: + return []byte("null"), nil + case Undefined: + return nil, errUndefined + } + + return nil, errBadStatus +} + +func (dst *Date) UnmarshalJSON(b []byte) error { + var n time.Time + if err := json.Unmarshal(b, &n); err != nil { + return err + } + + *dst = Date{Time: n, Status: Present} + + return nil +} diff --git a/pgtype/date_test.go b/pgtype/date_test.go index d98e1652..178a1ff9 100644 --- a/pgtype/date_test.go +++ b/pgtype/date_test.go @@ -116,3 +116,30 @@ func TestDateAssignTo(t *testing.T) { } } } + +func TestMarshalJSON(t *testing.T) { + r := pgtype.Date{Time: time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC), Status: pgtype.Present} + enc, err := r.MarshalJSON() + if err != nil { + t.Errorf("%v", err) + return + } + + if string(enc) != "\"1900-01-01T00:00:00Z\"" { + t.Errorf("Incorrect json marshal") + } +} + +func TestUnmarshalJSON(t *testing.T) { + var r pgtype.Date + tm := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC) + + if err := r.UnmarshalJSON([]byte(`"` + tm.Format(time.RFC3339) + `"`)); err != nil { + t.Errorf("%v", err) + return + } + + if tm != r.Time { + t.Errorf("Incorrect json unmarshal") + } +} From b4c77819daba7b68ffad9dfcd2d45f55c87937d1 Mon Sep 17 00:00:00 2001 From: Andrey Kuzmin Date: Tue, 23 Apr 2019 21:13:32 +0300 Subject: [PATCH 2/2] Use date as date, not datetime. Marshal/unmarshal date without time part. Date is postgresql type without time. --- pgtype/date.go | 13 +++++-------- pgtype/date_test.go | 8 +++----- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/pgtype/date.go b/pgtype/date.go index 658dbf1c..3c81a32b 100644 --- a/pgtype/date.go +++ b/pgtype/date.go @@ -3,7 +3,7 @@ package pgtype import ( "database/sql/driver" "encoding/binary" - "encoding/json" + "fmt" "time" "github.com/jackc/pgx/pgio" @@ -212,11 +212,8 @@ func (src *Date) Value() (driver.Value, error) { func (src *Date) MarshalJSON() ([]byte, error) { switch src.Status { case Present: - res, err := src.Time.MarshalJSON() - if err != nil { - return nil, err - } - return res, nil + s := fmt.Sprintf("%q", src.Time.Format("2006-01-02")) + return []byte(s), nil case Null: return []byte("null"), nil case Undefined: @@ -227,8 +224,8 @@ func (src *Date) MarshalJSON() ([]byte, error) { } func (dst *Date) UnmarshalJSON(b []byte) error { - var n time.Time - if err := json.Unmarshal(b, &n); err != nil { + n, err := time.Parse("\"2006-01-02\"", string(b)) + if err != nil { return err } diff --git a/pgtype/date_test.go b/pgtype/date_test.go index 178a1ff9..8128d87d 100644 --- a/pgtype/date_test.go +++ b/pgtype/date_test.go @@ -125,21 +125,19 @@ func TestMarshalJSON(t *testing.T) { return } - if string(enc) != "\"1900-01-01T00:00:00Z\"" { + if string(enc) != "\"1900-01-01\"" { t.Errorf("Incorrect json marshal") } } func TestUnmarshalJSON(t *testing.T) { var r pgtype.Date - tm := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC) - - if err := r.UnmarshalJSON([]byte(`"` + tm.Format(time.RFC3339) + `"`)); err != nil { + if err := r.UnmarshalJSON([]byte("\"1900-01-01\"")); err != nil { t.Errorf("%v", err) return } - if tm != r.Time { + if r.Time.Year() != 1900 || r.Time.Month() != 1 || r.Time.Day() != 1 { t.Errorf("Incorrect json unmarshal") } }