From ef470b1e30f0caa6436b1b55a56251b3083faf05 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Thu, 18 Jul 2013 08:32:31 -0500 Subject: [PATCH] Add date transcoding --- sanitize.go | 3 +++ value_transcoder.go | 22 ++++++++++++++++++++++ value_transcoder_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 value_transcoder_test.go diff --git a/sanitize.go b/sanitize.go index d774be17..a3b00d4e 100644 --- a/sanitize.go +++ b/sanitize.go @@ -6,6 +6,7 @@ import ( "regexp" "strconv" "strings" + "time" ) var literalPattern *regexp.Regexp = regexp.MustCompile(`\$\d+`) @@ -43,6 +44,8 @@ func (c *Connection) SanitizeSql(sql string, args ...interface{}) (output string return strconv.FormatInt(int64(arg), 10) case int64: return strconv.FormatInt(int64(arg), 10) + case time.Time: + return c.QuoteString(arg.Format("2006-01-02 15:04:05.999999999 -0700")) case uint: return strconv.FormatUint(uint64(arg), 10) case uint8: diff --git a/value_transcoder.go b/value_transcoder.go index ad7602be..025748c0 100644 --- a/value_transcoder.go +++ b/value_transcoder.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "strconv" + "time" "unsafe" ) @@ -88,6 +89,11 @@ func init() { // varchar -- same as text ValueTranscoders[Oid(1043)] = ValueTranscoders[Oid(25)] + // date + ValueTranscoders[Oid(1082)] = &ValueTranscoder{ + DecodeText: decodeDateFromText, + EncodeTo: encodeDate} + // use text transcoder for anything we don't understand defaultTranscoder = ValueTranscoders[Oid(25)] } @@ -262,3 +268,19 @@ func encodeBytea(w *MessageWriter, value interface{}) { w.Write(int32(len(b))) w.Write(b) } + +func decodeDateFromText(mr *MessageReader, size int32) interface{} { + s := mr.ReadByteString(size) + t, err := time.ParseInLocation("2006-01-02", s, time.Local) + if err != nil { + panic("Can't decode date") + } + return t +} + +func encodeDate(w *MessageWriter, value interface{}) { + t := value.(time.Time) + s := t.Format("2006-01-02") + w.Write(int32(len(s))) + w.WriteString(s) +} diff --git a/value_transcoder_test.go b/value_transcoder_test.go new file mode 100644 index 00000000..20daa0d8 --- /dev/null +++ b/value_transcoder_test.go @@ -0,0 +1,34 @@ +package pgx_test + +import ( + "testing" + "time" +) + +func TestDateTranscode(t *testing.T) { + conn := getSharedConnection() + + actualDate := time.Date(2013, 1, 2, 0, 0, 0, 0, time.Local) + + var v interface{} + var d time.Time + + v = mustSelectValue(t, conn, "select $1::date", actualDate) + d = v.(time.Time) + if !actualDate.Equal(d) { + t.Errorf("Did not transcode date successfully: %v is not %v", v, actualDate) + } + + mustPrepare(t, conn, "testTranscode", "select $1::date") + defer func() { + if err := conn.Deallocate("testTranscode"); err != nil { + t.Fatalf("Unable to deallocate prepared statement: %v", err) + } + }() + + v = mustSelectValue(t, conn, "testTranscode", actualDate) + d = v.(time.Time) + if !actualDate.Equal(d) { + t.Errorf("Did not transcode date successfully: %v is not %v", v, actualDate) + } +}