From 3aa59f87d2d4ba141c81f0d892fc041a25ef649d Mon Sep 17 00:00:00 2001 From: Jochen Voss Date: Sat, 10 Aug 2013 23:30:03 +0100 Subject: [PATCH 1/2] Add support for time.Time objects to gorp. This commit adds support for storing and retriving time.Time objects, by passing through such objects to the underlying driver. This resolves gorp issue #14. The commit is tested and works with the github.com/mattn/go-sqlite3 driver. The commit does not currently work with the github.com/ziutek/mymysql/godrv driver, due to a bug in the mysql driver. This problem is resolved by mymysql pull request #77. I have successfully tested that with the fix from pull request #77 applied to mymysql, and with the current commit applied, gorp can correctly store and retrieve time.Time objects from mysql databases. This commit is NOT tested with the github.com/lib/pq driver. --- dialect.go | 6 ++++++ gorp_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/dialect.go b/dialect.go index 1e8c971d..d17c25e8 100644 --- a/dialect.go +++ b/dialect.go @@ -85,6 +85,8 @@ func (d SqliteDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) return "integer" case "NullableBytes": return "blob" + case "Time": + return "datetime" } if maxsize < 1 { @@ -170,6 +172,8 @@ func (d PostgresDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr boo return "smallint" case "NullableBytes": return "bytea" + case "Time", "NullTime": + return "timestamp" } if maxsize < 1 { @@ -264,6 +268,8 @@ func (m MySQLDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) return "tinyint" case "NullableBytes": return "mediumblob" + case "Time": + return "datetime" } if maxsize < 1 { diff --git a/gorp_test.go b/gorp_test.go index 89ad2bac..37305384 100644 --- a/gorp_test.go +++ b/gorp_test.go @@ -845,6 +845,30 @@ func TestWithStringPk(t *testing.T) { } } +type WithTime struct { + Id int64 + Time time.Time +} + +func TestWithTime(t *testing.T) { + dbmap := initDbMap() + defer dbmap.DropTables() + + t1, err := time.Parse("2006-01-02 15:04:05 -0700 MST", + "2013-08-09 21:30:43 +0800 CST") + if err != nil { + panic(err) + } + w1 := WithTime{1, t1} + _insert(dbmap, &w1) + + obj := _get(dbmap, WithTime{}, w1.Id) + w2 := obj.(*WithTime) + if w1.Time.UnixNano() != w2.Time.UnixNano() { + t.Errorf("%v != %v", w1, w2) + } +} + func TestInvoicePersonView(t *testing.T) { dbmap := initDbMap() defer dbmap.DropTables() @@ -1017,6 +1041,7 @@ func initDbMap() *DbMap { dbmap.AddTableWithName(WithIgnoredColumn{}, "ignored_column_test").SetKeys(true, "Id") dbmap.AddTableWithName(TypeConversionExample{}, "type_conv_test").SetKeys(true, "Id") dbmap.AddTableWithName(WithEmbeddedStruct{}, "embedded_struct_test").SetKeys(true, "Id") + dbmap.AddTableWithName(WithTime{}, "time_test").SetKeys(true, "Id") dbmap.TypeConverter = testTypeConverter{} err := dbmap.CreateTables() if err != nil { From e5a6512ec776ecc8373e11165f992a8a91ac4ae4 Mon Sep 17 00:00:00 2001 From: Jochen Voss Date: Sun, 8 Sep 2013 10:31:45 +0100 Subject: [PATCH 2/2] For PostgreSQL use "timestamp with timezone" as suggested by Joe Shaw on github. --- dialect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dialect.go b/dialect.go index d17c25e8..e997b413 100644 --- a/dialect.go +++ b/dialect.go @@ -173,7 +173,7 @@ func (d PostgresDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr boo case "NullableBytes": return "bytea" case "Time", "NullTime": - return "timestamp" + return "timestamp with time zone" } if maxsize < 1 {