From c811590d4e06e5991a50222dd5628ffb027c71bf Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sat, 5 Mar 2016 18:54:59 +0800 Subject: [PATCH] Add dialects for supported databases for easier to use --- CHANGELOG.md | 4 ++- dialect_postgres.go | 51 +--------------------------------- dialects/mssql/mssql.go | 3 ++ dialects/mysql/mysql.go | 3 ++ dialects/postgres/postgres.go | 52 +++++++++++++++++++++++++++++++++++ dialects/sqlite/sqlite.go | 3 ++ main_test.go | 21 +++++++------- 7 files changed, 75 insertions(+), 62 deletions(-) create mode 100644 dialects/mssql/mssql.go create mode 100644 dialects/mysql/mysql.go create mode 100644 dialects/postgres/postgres.go create mode 100644 dialects/sqlite/sqlite.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 528fe1b7..949ad386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ #### Breaking Changes -* **`gorm.Open` return type `*gorm.DB` instead of `gorm.DB`** +* **`gorm.Open` return `*gorm.DB` instead of `gorm.DB`** * **Updating will only update changed fields** @@ -52,3 +52,5 @@ So field `HTTP`'s db name will be `http` not `h_t_t_p`, but some other initialisms like `SKU` that not in golint, it's db name will be `s_k_u`, this release fixed this, any upper case initialisms should be converted correctly. If your applications using some upper case initialisms which doesn't exist in [golint](https://github.com/golang/lint/blob/master/lint.go#L702), you need to overwrite generated column name with tag, like `sql:"column:s_k_u"`, or alert your database's column name according to new logic + +* **Builtin `Hstore` struct for postgres has been moved to `github.com/jinzhu/gorm/dialects/postgres`** diff --git a/dialect_postgres.go b/dialect_postgres.go index 3c18acc2..3d188a65 100644 --- a/dialect_postgres.go +++ b/dialect_postgres.go @@ -1,14 +1,10 @@ package gorm import ( - "database/sql" - "database/sql/driver" "fmt" "reflect" "strings" "time" - - "github.com/lib/pq/hstore" ) type postgres struct { @@ -55,7 +51,7 @@ func (postgres) DataTypeOf(field *StructField) string { sqlType = "timestamp with time zone" } case reflect.Map: - if dataValue.Type() == hstoreType { + if dataValue.Type().Name() == "Hstore" { sqlType = "hstore" } default: @@ -108,51 +104,6 @@ func (postgres) SupportLastInsertId() bool { return false } -var hstoreType = reflect.TypeOf(Hstore{}) - -type Hstore map[string]*string - -func (h Hstore) Value() (driver.Value, error) { - hstore := hstore.Hstore{Map: map[string]sql.NullString{}} - if len(h) == 0 { - return nil, nil - } - - for key, value := range h { - var s sql.NullString - if value != nil { - s.String = *value - s.Valid = true - } - hstore.Map[key] = s - } - return hstore.Value() -} - -func (h *Hstore) Scan(value interface{}) error { - hstore := hstore.Hstore{} - - if err := hstore.Scan(value); err != nil { - return err - } - - if len(hstore.Map) == 0 { - return nil - } - - *h = Hstore{} - for k := range hstore.Map { - if hstore.Map[k].Valid { - s := hstore.Map[k].String - (*h)[k] = &s - } else { - (*h)[k] = nil - } - } - - return nil -} - func isByteArrayOrSlice(value reflect.Value) bool { return (value.Kind() == reflect.Array || value.Kind() == reflect.Slice) && value.Type().Elem() == reflect.TypeOf(uint8(0)) } diff --git a/dialects/mssql/mssql.go b/dialects/mssql/mssql.go new file mode 100644 index 00000000..26bb38eb --- /dev/null +++ b/dialects/mssql/mssql.go @@ -0,0 +1,3 @@ +package mssql + +import _ "github.com/denisenkom/go-mssqldb" diff --git a/dialects/mysql/mysql.go b/dialects/mysql/mysql.go new file mode 100644 index 00000000..9deba48a --- /dev/null +++ b/dialects/mysql/mysql.go @@ -0,0 +1,3 @@ +package mysql + +import _ "github.com/go-sql-driver/mysql" diff --git a/dialects/postgres/postgres.go b/dialects/postgres/postgres.go new file mode 100644 index 00000000..37881090 --- /dev/null +++ b/dialects/postgres/postgres.go @@ -0,0 +1,52 @@ +package postgres + +import ( + "database/sql" + "database/sql/driver" + + _ "github.com/lib/pq" + "github.com/lib/pq/hstore" +) + +type Hstore map[string]*string + +func (h Hstore) Value() (driver.Value, error) { + hstore := hstore.Hstore{Map: map[string]sql.NullString{}} + if len(h) == 0 { + return nil, nil + } + + for key, value := range h { + var s sql.NullString + if value != nil { + s.String = *value + s.Valid = true + } + hstore.Map[key] = s + } + return hstore.Value() +} + +func (h *Hstore) Scan(value interface{}) error { + hstore := hstore.Hstore{} + + if err := hstore.Scan(value); err != nil { + return err + } + + if len(hstore.Map) == 0 { + return nil + } + + *h = Hstore{} + for k := range hstore.Map { + if hstore.Map[k].Valid { + s := hstore.Map[k].String + (*h)[k] = &s + } else { + (*h)[k] = nil + } + } + + return nil +} diff --git a/dialects/sqlite/sqlite.go b/dialects/sqlite/sqlite.go new file mode 100644 index 00000000..069ad3a9 --- /dev/null +++ b/dialects/sqlite/sqlite.go @@ -0,0 +1,3 @@ +package sqlite + +import _ "github.com/mattn/go-sqlite3" diff --git a/main_test.go b/main_test.go index dff91828..c732e7fc 100644 --- a/main_test.go +++ b/main_test.go @@ -4,20 +4,19 @@ import ( "database/sql" "database/sql/driver" "fmt" + "os" "reflect" "strconv" - - _ "github.com/denisenkom/go-mssqldb" - testdb "github.com/erikstmartin/go-testdb" - _ "github.com/go-sql-driver/mysql" - "github.com/jinzhu/gorm" - "github.com/jinzhu/now" - _ "github.com/lib/pq" - _ "github.com/mattn/go-sqlite3" - - "os" "testing" "time" + + "github.com/erikstmartin/go-testdb" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mssql" + _ "github.com/jinzhu/gorm/dialects/mysql" + "github.com/jinzhu/gorm/dialects/postgres" + _ "github.com/jinzhu/gorm/dialects/sqlite" + "github.com/jinzhu/now" ) var ( @@ -624,7 +623,7 @@ func TestTimeWithZone(t *testing.T) { func TestHstore(t *testing.T) { type Details struct { Id int64 - Bulk gorm.Hstore + Bulk postgres.Hstore } if dialect := os.Getenv("GORM_DIALECT"); dialect != "postgres" {