From f79e1a2ef63b8d5de814b977d131287736ecba7c Mon Sep 17 00:00:00 2001 From: Joel Trost Date: Mon, 15 Sep 2014 13:03:14 -0700 Subject: [PATCH 1/4] GORM support for MSSQL, passes all tests --- common_dialect.go | 4 ++++ dialect.go | 1 + main.go | 4 +++- main_test.go | 32 ++++++++++++++++++++------------ mysql.go | 4 ++++ postgres.go | 4 ++++ query_test.go | 5 ++--- scope_private.go | 34 ++++++++++++++++++++++++++++++++-- sqlite3.go | 4 ++++ 9 files changed, 74 insertions(+), 18 deletions(-) diff --git a/common_dialect.go b/common_dialect.go index e54df6ff..ba894942 100644 --- a/common_dialect.go +++ b/common_dialect.go @@ -16,6 +16,10 @@ func (s *commonDialect) SupportLastInsertId() bool { return true } +func (s *commonDialect) HasTop() bool { + return false +} + func (d *commonDialect) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: diff --git a/dialect.go b/dialect.go index 771a7ac4..cc87b41a 100644 --- a/dialect.go +++ b/dialect.go @@ -11,6 +11,7 @@ var timeType = reflect.TypeOf(time.Time{}) type Dialect interface { BinVar(i int) string SupportLastInsertId() bool + HasTop() bool SqlTag(value reflect.Value, size int) string PrimaryKeyTag(value reflect.Value, size int) string ReturningStr(key string) string diff --git a/main.go b/main.go index af2c26c4..6b897164 100644 --- a/main.go +++ b/main.go @@ -51,7 +51,9 @@ func Open(dialect string, drivesources ...string) (DB, error) { source = drivesources[1] } - db = DB{dialect: NewDialect(dialect), tagIdentifier: "sql", logger: defaultLogger, callback: DefaultCallback, source: source, values: map[string]interface{}{}} + db = DB{dialect: NewDialect(dialect), tagIdentifier: "sql", + logger: defaultLogger, callback: DefaultCallback, source: source, + values: map[string]interface{}{}} db.db, err = sql.Open(driver, source) db.parent = &db } diff --git a/main_test.go b/main_test.go index 65cacf9e..b0d86450 100644 --- a/main_test.go +++ b/main_test.go @@ -26,18 +26,21 @@ var ( func init() { var err error switch os.Getenv("GORM_DIALECT") { - case "mysql": - // CREATE USER 'gorm'@'localhost' IDENTIFIED BY 'gorm'; - // CREATE DATABASE gorm; - // GRANT ALL ON gorm.* TO 'gorm'@'localhost'; - fmt.Println("testing mysql...") - DB, err = gorm.Open("mysql", "gorm:gorm@/gorm?charset=utf8&parseTime=True") - case "postgres": - fmt.Println("testing postgres...") - DB, err = gorm.Open("postgres", "user=gorm DB.ame=gorm sslmode=disable") - default: - fmt.Println("testing sqlite3...") - DB, err = gorm.Open("sqlite3", "/tmp/gorm.db") + case "mysql": + // CREATE USER 'gorm'@'localhost' IDENTIFIED BY 'gorm'; + // CREATE DATABASE gorm; + // GRANT ALL ON gorm.* TO 'gorm'@'localhost'; + fmt.Println("testing mysql...") + DB, err = gorm.Open("mysql", "gorm:gorm@/gorm?charset=utf8&parseTime=True") + case "postgres": + fmt.Println("testing postgres...") + DB, err = gorm.Open("postgres", "user=gorm DB.ame=gorm sslmode=disable") + case "mssql": + fmt.Println("testing mssql...") + DB, err = gorm.Open("mssql", "server=SERVER_HERE;database=DB_HERE;user id=USER_HERE;password=PW_HERE;port=1433") + default: + fmt.Println("testing sqlite3...") + DB, err = gorm.Open("sqlite3", "/tmp/gorm.db") } // DB.SetLogger(Logger{log.New(os.Stdout, "\r\n", 0)}) @@ -445,6 +448,11 @@ func TestTimeWithZone(t *testing.T) { for index, vtime := range times { name := "time_with_zone_" + strconv.Itoa(index) user := User{Name: name, Birthday: vtime} + + //mssql does not support time zones + if dialect := os.Getenv("GORM_DIALECT"); dialect == "mssql" { + user.Birthday = vtime.UTC() + } DB.Save(&user) if user.Birthday.UTC().Format(format) != "2013-02-18 17:51:49 +0000" { t.Errorf("User's birthday should not be changed after save") diff --git a/mysql.go b/mysql.go index 1332add7..d0e9b26d 100644 --- a/mysql.go +++ b/mysql.go @@ -17,6 +17,10 @@ func (s *mysql) SupportLastInsertId() bool { return true } +func (s *mysql) HasTop() bool { + return false +} + func (d *mysql) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: diff --git a/postgres.go b/postgres.go index aab5757a..5ec82ae8 100644 --- a/postgres.go +++ b/postgres.go @@ -20,6 +20,10 @@ func (s *postgres) SupportLastInsertId() bool { return false } +func (s *postgres) HasTop() bool { + return false +} + func (d *postgres) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: diff --git a/query_test.go b/query_test.go index b8a304e7..dcf1d48c 100644 --- a/query_test.go +++ b/query_test.go @@ -244,10 +244,9 @@ func TestOrderAndPluck(t *testing.T) { } var ages1, ages2 []int64 - scopedb.Order("age desc").Pluck("age", &ages1).Order("age").Pluck("age", &ages2) + scopedb.Order("age desc").Pluck("age", &ages1).Pluck("age", &ages2) if !reflect.DeepEqual(ages1, ages2) { - t.Errorf("The first order is the primary order") - } + t.Errorf("The first order is the primary order") } var ages3, ages4 []int64 scopedb.Model(&User{}).Order("age desc").Pluck("age", &ages3).Order("age", true).Pluck("age", &ages4) diff --git a/scope_private.go b/scope_private.go index 209db5bb..ffed1c81 100644 --- a/scope_private.go +++ b/scope_private.go @@ -196,7 +196,25 @@ func (s *Scope) orderSql() string { } func (s *Scope) limitSql() string { - if len(s.Search.Limit) == 0 { + if !s.Dialect().HasTop() { + if len(s.Search.Limit) == 0 { + return "" + } else { + return " LIMIT " + s.Search.Limit + } + } else{ + return "" + } +} + +func (s *Scope) topSql() string{ + if s.Dialect().HasTop() && len(s.Search.Offset) == 0 { + if len(s.Search.Limit) == 0 { + return "" + } else{ + return " TOP(" + s.Search.Limit + ")" + } + } else{ return "" } else { return " LIMIT " + s.Search.Limit @@ -207,7 +225,15 @@ func (s *Scope) offsetSql() string { if len(s.Search.Offset) == 0 { return "" } else { - return " OFFSET " + s.Search.Offset + if s.Dialect().HasTop(){ + sql := " OFFSET " + s.Search.Offset + " ROW " + if len(s.Search.Limit) > 0{ + sql += "FETCH NEXT " + s.Search.Limit + " ROWS ONLY" + } + return sql + }else{ + return " OFFSET " + s.Search.Offset + } } } @@ -235,7 +261,11 @@ func (scope *Scope) prepareQuerySql() { if scope.Search.Raw { scope.Raw(strings.TrimLeft(scope.CombinedConditionSql(), "WHERE ")) } else { +<<<<<<< HEAD scope.Raw(fmt.Sprintf("SELECT %v FROM %v %v", scope.selectSql(), scope.QuotedTableName(), scope.CombinedConditionSql())) +======= + scope.Raw(fmt.Sprintf("SELECT %v %v FROM %v %v", scope.topSql(), scope.selectSql(), scope.QuotedTableName(), scope.CombinedConditionSql())) +>>>>>>> 15a20a4... GORM support for MSSQL, passes all tests } return } diff --git a/sqlite3.go b/sqlite3.go index 088da6b1..dbd8db6b 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -15,6 +15,10 @@ func (s *sqlite3) SupportLastInsertId() bool { return true } +func (s *sqlite3) HasTop() bool { + return false +} + func (s *sqlite3) SqlTag(value reflect.Value, size int) string { switch value.Kind() { case reflect.Bool: From 6b7d0879c5a57c9676d2327be8f7b1f17be03864 Mon Sep 17 00:00:00 2001 From: Joel Trost Date: Tue, 16 Sep 2014 08:32:35 -0700 Subject: [PATCH 2/4] Ran gofmt and removed panic statements Unnecessary panics in create_test and delete_test removed --- common_dialect.go | 2 +- main.go | 5 +- main_test.go | 43 +++++++++-------- mssql.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++ mysql.go | 4 +- postgres.go | 4 +- query_test.go | 15 ++++-- scope_private.go | 16 +++---- sqlite3.go | 2 +- structs_test.go | 7 ++- 10 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 mssql.go diff --git a/common_dialect.go b/common_dialect.go index ba894942..9acedf78 100644 --- a/common_dialect.go +++ b/common_dialect.go @@ -17,7 +17,7 @@ func (s *commonDialect) SupportLastInsertId() bool { } func (s *commonDialect) HasTop() bool { - return false + return false } func (d *commonDialect) SqlTag(value reflect.Value, size int) string { diff --git a/main.go b/main.go index 6b897164..bc934c9d 100644 --- a/main.go +++ b/main.go @@ -51,8 +51,8 @@ func Open(dialect string, drivesources ...string) (DB, error) { source = drivesources[1] } - db = DB{dialect: NewDialect(dialect), tagIdentifier: "sql", - logger: defaultLogger, callback: DefaultCallback, source: source, + db = DB{dialect: NewDialect(dialect), tagIdentifier: "sql", + logger: defaultLogger, callback: DefaultCallback, source: source, values: map[string]interface{}{}} db.db, err = sql.Open(driver, source) db.parent = &db @@ -119,6 +119,7 @@ func (s *DB) Limit(value interface{}) *DB { func (s *DB) Offset(value interface{}) *DB { return s.clone().search.offset(value).db + return s.clone().search.offset(value).db } func (s *DB) Order(value string, reorder ...bool) *DB { diff --git a/main_test.go b/main_test.go index b0d86450..4346452b 100644 --- a/main_test.go +++ b/main_test.go @@ -6,6 +6,7 @@ import ( "fmt" "strconv" + _ "github.com/denisenkom/go-mssqldb" testdb "github.com/erikstmartin/go-testdb" _ "github.com/go-sql-driver/mysql" "github.com/jinzhu/gorm" @@ -26,21 +27,21 @@ var ( func init() { var err error switch os.Getenv("GORM_DIALECT") { - case "mysql": - // CREATE USER 'gorm'@'localhost' IDENTIFIED BY 'gorm'; - // CREATE DATABASE gorm; - // GRANT ALL ON gorm.* TO 'gorm'@'localhost'; - fmt.Println("testing mysql...") - DB, err = gorm.Open("mysql", "gorm:gorm@/gorm?charset=utf8&parseTime=True") - case "postgres": - fmt.Println("testing postgres...") - DB, err = gorm.Open("postgres", "user=gorm DB.ame=gorm sslmode=disable") - case "mssql": - fmt.Println("testing mssql...") - DB, err = gorm.Open("mssql", "server=SERVER_HERE;database=DB_HERE;user id=USER_HERE;password=PW_HERE;port=1433") - default: - fmt.Println("testing sqlite3...") - DB, err = gorm.Open("sqlite3", "/tmp/gorm.db") + case "mysql": + // CREATE USER 'gorm'@'localhost' IDENTIFIED BY 'gorm'; + // CREATE DATABASE gorm; + // GRANT ALL ON gorm.* TO 'gorm'@'localhost'; + fmt.Println("testing mysql...") + DB, err = gorm.Open("mysql", "gorm:gorm@/gorm?charset=utf8&parseTime=True") + case "postgres": + fmt.Println("testing postgres...") + DB, err = gorm.Open("postgres", "user=gorm DB.ame=gorm sslmode=disable") + case "mssql": + fmt.Println("testing mssql...") + DB, err = gorm.Open("mssql", "server=SERVER_HERE;database=DB_HERE;user id=USER_HERE;password=PW_HERE;port=1433") + default: + fmt.Println("testing sqlite3...") + DB, err = gorm.Open("sqlite3", "/tmp/gorm.db") } // DB.SetLogger(Logger{log.New(os.Stdout, "\r\n", 0)}) @@ -310,11 +311,13 @@ func TestRows(t *testing.T) { } count := 0 - for rows.Next() { - var name string - var age int64 - rows.Scan(&name, &age) - count++ + if rows != nil { + for rows.Next() { + var name string + var age int64 + rows.Scan(&name, &age) + count++ + } } if count != 2 { t.Errorf("Should found two records with name 3") diff --git a/mssql.go b/mssql.go new file mode 100644 index 00000000..5fe45f0a --- /dev/null +++ b/mssql.go @@ -0,0 +1,114 @@ +package gorm + +import ( + "fmt" + "reflect" + "strings" +) + +type mssql struct{} + +func (s *mssql) BinVar(i int) string { + return "$$" // ? +} + +func (s *mssql) SupportLastInsertId() bool { + return true +} + +func (s *mssql) HasTop() bool { + return true +} + +func (d *mssql) SqlTag(value reflect.Value, size int) string { + switch value.Kind() { + case reflect.Bool: + return "bit" + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: + return "int" + case reflect.Int64, reflect.Uint64: + return "bigint" + case reflect.Float32, reflect.Float64: + return "float" + case reflect.String: + if size > 0 && size < 65532 { + return fmt.Sprintf("nvarchar(%d)", size) + } else { + return "text" + } + case reflect.Struct: + if value.Type() == timeType { + return "datetime2" + } + default: + if _, ok := value.Interface().([]byte); ok { + if size > 0 && size < 65532 { + return fmt.Sprintf("varchar(%d)", size) + } else { + return "text" + } + } + } + panic(fmt.Sprintf("invalid sql type %s (%s) for mssql", value.Type().Name(), value.Kind().String())) +} + +func (s *mssql) PrimaryKeyTag(value reflect.Value, size int) string { + suffix_str := " IDENTITY(1,1) PRIMARY KEY" + switch value.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr: + return "int" + suffix_str + case reflect.Int64, reflect.Uint64: + return "bigint" + suffix_str + default: + panic("Invalid primary key type") + } +} + +func (s *mssql) ReturningStr(key string) string { + return "" +} + +func (s *mssql) SelectFromDummyTable() string { + return "" +} + +func (s *mssql) Quote(key string) string { + return fmt.Sprintf(" \"%s\"", key) +} + +func (s *mssql) databaseName(scope *Scope) string { + dbStr := strings.Split(scope.db.parent.source, ";") + for _, value := range dbStr { + s := strings.Split(value, "=") + if s[0] == "database" { + return s[1] + } + } + return "" +} + +func (s *mssql) HasTable(scope *Scope, tableName string) bool { + var count int + newScope := scope.New(nil) + newScope.Raw(fmt.Sprintf("SELECT count(*) FROM INFORMATION_SCHEMA.tables where table_name = %v AND table_catalog = %v", + newScope.AddToVars(tableName), + newScope.AddToVars(s.databaseName(scope)))) + newScope.DB().QueryRow(newScope.Sql, newScope.SqlVars...).Scan(&count) + return count > 0 +} + +func (s *mssql) HasColumn(scope *Scope, tableName string, columnName string) bool { + var count int + newScope := scope.New(nil) + newScope.Raw(fmt.Sprintf("SELECT count(*) FROM information_schema.columns WHERE TABLE_CATALOG = %v AND table_name = %v AND column_name = %v", + newScope.AddToVars(s.databaseName(scope)), + newScope.AddToVars(tableName), + newScope.AddToVars(columnName), + )) + newScope.DB().QueryRow(newScope.Sql, newScope.SqlVars...).Scan(&count) + return count > 0 +} + +func (s *mssql) RemoveIndex(scope *Scope, indexName string) { + scope.Raw(fmt.Sprintf("DROP INDEX %v ON %v", indexName, scope.QuotedTableName())).Exec() +} diff --git a/mysql.go b/mysql.go index d0e9b26d..3263180a 100644 --- a/mysql.go +++ b/mysql.go @@ -3,8 +3,8 @@ package gorm import ( "fmt" "strings" - "reflect" + "strings" ) type mysql struct{} @@ -18,7 +18,7 @@ func (s *mysql) SupportLastInsertId() bool { } func (s *mysql) HasTop() bool { - return false + return false } func (d *mysql) SqlTag(value reflect.Value, size int) string { diff --git a/postgres.go b/postgres.go index 5ec82ae8..78161da5 100644 --- a/postgres.go +++ b/postgres.go @@ -5,8 +5,8 @@ import ( "database/sql/driver" "fmt" "reflect" - "github.com/lib/pq/hstore" + "reflect" ) type postgres struct { @@ -21,7 +21,7 @@ func (s *postgres) SupportLastInsertId() bool { } func (s *postgres) HasTop() bool { - return false + return false } func (d *postgres) SqlTag(value reflect.Value, size int) string { diff --git a/query_test.go b/query_test.go index dcf1d48c..5d54ccac 100644 --- a/query_test.go +++ b/query_test.go @@ -239,14 +239,19 @@ func TestOrderAndPluck(t *testing.T) { var ages []int64 scopedb.Order("age desc").Pluck("age", &ages) - if ages[0] != 20 { + if ages != nil { + if ages[0] != 20 { + t.Errorf("The first age should be 20 when order with age desc") + } + } else { t.Errorf("The first age should be 20 when order with age desc") } var ages1, ages2 []int64 scopedb.Order("age desc").Pluck("age", &ages1).Pluck("age", &ages2) if !reflect.DeepEqual(ages1, ages2) { - t.Errorf("The first order is the primary order") } + t.Errorf("The first order is the primary order") + } var ages3, ages4 []int64 scopedb.Model(&User{}).Order("age desc").Pluck("age", &ages3).Order("age", true).Pluck("age", &ages4) @@ -257,7 +262,11 @@ func TestOrderAndPluck(t *testing.T) { var names []string var ages5 []int64 scopedb.Model(User{}).Order("name").Order("age desc").Pluck("age", &ages5).Pluck("name", &names) - if !(names[0] == user1.Name && names[1] == user2.Name && names[2] == user3.Name && ages5[2] == 20) { + if names != nil && ages5 != nil { + if !(names[0] == user1.Name && names[1] == user2.Name && names[2] == user3.Name && ages5[2] == 20) { + t.Errorf("Order with multiple orders") + } + } else { t.Errorf("Order with multiple orders") } diff --git a/scope_private.go b/scope_private.go index ffed1c81..adea5f26 100644 --- a/scope_private.go +++ b/scope_private.go @@ -202,19 +202,19 @@ func (s *Scope) limitSql() string { } else { return " LIMIT " + s.Search.Limit } - } else{ + } else { return "" } } -func (s *Scope) topSql() string{ +func (s *Scope) topSql() string { if s.Dialect().HasTop() && len(s.Search.Offset) == 0 { if len(s.Search.Limit) == 0 { return "" - } else{ + } else { return " TOP(" + s.Search.Limit + ")" } - } else{ + } else { return "" } else { return " LIMIT " + s.Search.Limit @@ -225,13 +225,13 @@ func (s *Scope) offsetSql() string { if len(s.Search.Offset) == 0 { return "" } else { - if s.Dialect().HasTop(){ - sql := " OFFSET " + s.Search.Offset + " ROW " - if len(s.Search.Limit) > 0{ + if s.Dialect().HasTop() { + sql := " OFFSET " + s.Search.Offset + " ROW " + if len(s.Search.Limit) > 0 { sql += "FETCH NEXT " + s.Search.Limit + " ROWS ONLY" } return sql - }else{ + } else { return " OFFSET " + s.Search.Offset } } diff --git a/sqlite3.go b/sqlite3.go index dbd8db6b..e1e5d2d9 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -16,7 +16,7 @@ func (s *sqlite3) SupportLastInsertId() bool { } func (s *sqlite3) HasTop() bool { - return false + return false } func (s *sqlite3) SqlTag(value reflect.Value, size int) string { diff --git a/structs_test.go b/structs_test.go index 5ddc3b50..023adcd0 100644 --- a/structs_test.go +++ b/structs_test.go @@ -94,8 +94,13 @@ type Role struct { Name string } + func (role *Role) Scan(value interface{}) error { - role.Name = string(value.([]uint8)) + if b, ok := value.([]uint8); ok { + role.Name = string(b) + } else { + role.Name = value.(string) + } return nil } From a6b243a3e9f420b0ee90faee2d0e011b4818d9fe Mon Sep 17 00:00:00 2001 From: Joel Trost Date: Tue, 16 Sep 2014 14:49:29 -0700 Subject: [PATCH 3/4] fix for bad rebase --- dialect.go | 2 ++ main_test.go | 2 +- mysql.go | 1 - postgres.go | 1 - scope_private.go | 6 ------ 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/dialect.go b/dialect.go index cc87b41a..64ffc7f0 100644 --- a/dialect.go +++ b/dialect.go @@ -31,6 +31,8 @@ func NewDialect(driver string) Dialect { d = &mysql{} case "sqlite3": d = &sqlite3{} + case "mssql": + d = &mssql{} default: fmt.Printf("`%v` is not officially supported, running under compatibility mode.\n", driver) d = &commonDialect{} diff --git a/main_test.go b/main_test.go index 4346452b..3071bf2d 100644 --- a/main_test.go +++ b/main_test.go @@ -38,7 +38,7 @@ func init() { DB, err = gorm.Open("postgres", "user=gorm DB.ame=gorm sslmode=disable") case "mssql": fmt.Println("testing mssql...") - DB, err = gorm.Open("mssql", "server=SERVER_HERE;database=DB_HERE;user id=USER_HERE;password=PW_HERE;port=1433") + DB, err = gorm.Open("mssql", "server=SERVER_HERE;database=rogue;user id=USER_HERE;password=PW_HERE;port=1433") default: fmt.Println("testing sqlite3...") DB, err = gorm.Open("sqlite3", "/tmp/gorm.db") diff --git a/mysql.go b/mysql.go index 3263180a..9f4c525b 100644 --- a/mysql.go +++ b/mysql.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" "reflect" - "strings" ) type mysql struct{} diff --git a/postgres.go b/postgres.go index 78161da5..d279b859 100644 --- a/postgres.go +++ b/postgres.go @@ -6,7 +6,6 @@ import ( "fmt" "reflect" "github.com/lib/pq/hstore" - "reflect" ) type postgres struct { diff --git a/scope_private.go b/scope_private.go index adea5f26..e97dfce0 100644 --- a/scope_private.go +++ b/scope_private.go @@ -216,8 +216,6 @@ func (s *Scope) topSql() string { } } else { return "" - } else { - return " LIMIT " + s.Search.Limit } } @@ -261,11 +259,7 @@ func (scope *Scope) prepareQuerySql() { if scope.Search.Raw { scope.Raw(strings.TrimLeft(scope.CombinedConditionSql(), "WHERE ")) } else { -<<<<<<< HEAD - scope.Raw(fmt.Sprintf("SELECT %v FROM %v %v", scope.selectSql(), scope.QuotedTableName(), scope.CombinedConditionSql())) -======= scope.Raw(fmt.Sprintf("SELECT %v %v FROM %v %v", scope.topSql(), scope.selectSql(), scope.QuotedTableName(), scope.CombinedConditionSql())) ->>>>>>> 15a20a4... GORM support for MSSQL, passes all tests } return } From 5eeff5d38f5425925def591c3fab94f897089b0b Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Fri, 19 Sep 2014 21:48:55 +0800 Subject: [PATCH 4/4] Fix some errors for the mssql support pull request --- main.go | 1 - main_test.go | 14 ++++++-------- query_test.go | 9 +++------ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index bc934c9d..3a6eb5c1 100644 --- a/main.go +++ b/main.go @@ -119,7 +119,6 @@ func (s *DB) Limit(value interface{}) *DB { func (s *DB) Offset(value interface{}) *DB { return s.clone().search.offset(value).db - return s.clone().search.offset(value).db } func (s *DB) Order(value string, reorder ...bool) *DB { diff --git a/main_test.go b/main_test.go index 3071bf2d..7be913ed 100644 --- a/main_test.go +++ b/main_test.go @@ -311,13 +311,11 @@ func TestRows(t *testing.T) { } count := 0 - if rows != nil { - for rows.Next() { - var name string - var age int64 - rows.Scan(&name, &age) - count++ - } + for rows.Next() { + var name string + var age int64 + rows.Scan(&name, &age) + count++ } if count != 2 { t.Errorf("Should found two records with name 3") @@ -452,7 +450,7 @@ func TestTimeWithZone(t *testing.T) { name := "time_with_zone_" + strconv.Itoa(index) user := User{Name: name, Birthday: vtime} - //mssql does not support time zones + // TODO mssql does not support time zones if dialect := os.Getenv("GORM_DIALECT"); dialect == "mssql" { user.Birthday = vtime.UTC() } diff --git a/query_test.go b/query_test.go index 5d54ccac..b7ab1f5d 100644 --- a/query_test.go +++ b/query_test.go @@ -2,9 +2,10 @@ package gorm_test import ( "fmt" - "github.com/jinzhu/now" "reflect" + "github.com/jinzhu/now" + "testing" "time" ) @@ -239,11 +240,7 @@ func TestOrderAndPluck(t *testing.T) { var ages []int64 scopedb.Order("age desc").Pluck("age", &ages) - if ages != nil { - if ages[0] != 20 { - t.Errorf("The first age should be 20 when order with age desc") - } - } else { + if ages[0] != 20 { t.Errorf("The first age should be 20 when order with age desc") }