From 93a2c6827dd27452485d2e64ad2cb0f4863fb388 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 13:55:01 -0400 Subject: [PATCH 01/13] optionally enabling identity value in SQL INSERT for MS SQL ref: https://github.com/jinzhu/gorm/issues/647 --- common_dialect.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common_dialect.go b/common_dialect.go index 7f08b04f..9b0ea959 100644 --- a/common_dialect.go +++ b/common_dialect.go @@ -115,3 +115,8 @@ func (commonDialect) CurrentDatabase(scope *Scope) (name string) { scope.Err(scope.NewDB().Raw("SELECT DATABASE()").Row().Scan(&name)) return } + +func (commonDialect) EnableIdentityInsert(db *DB, tableName string) *DB { + return db +} + From b71fda1a1aae7b91840918a7a3ad53590d5fe51b Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 13:57:14 -0400 Subject: [PATCH 02/13] skip identity test for table without id column for mssql ref: https://github.com/jinzhu/gorm/issues/647 --- create_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/create_test.go b/create_test.go index 97175980..b25a2ab3 100644 --- a/create_test.go +++ b/create_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" "time" + "os" ) func TestCreate(t *testing.T) { @@ -57,6 +58,11 @@ func TestCreate(t *testing.T) { } func TestCreateWithNoGORMPrimayKey(t *testing.T) { + + if dialect := os.Getenv("GORM_DIALECT"); dialect == "mssql" { + t.Skip("Skipping this because MSSQL will return identity only if the table has an Id column") + } + jt := JoinTable{From: 1, To: 2} err := DB.Create(&jt).Error if err != nil { From a739f8b03547c9b7d6c6a60af51e4fa750b04146 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:04:10 -0400 Subject: [PATCH 03/13] enable identity column insert optionally for mssql ref: https://github.com/jinzhu/gorm/issues/647 --- customize_column_test.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/customize_column_test.go b/customize_column_test.go index cf4f1d1a..8a472bdb 100644 --- a/customize_column_test.go +++ b/customize_column_test.go @@ -32,12 +32,23 @@ func TestCustomizeColumn(t *testing.T) { if scope.PrimaryKey() != col { t.Errorf("CustomizeColumn should have primary key %s, but got %q", col, scope.PrimaryKey()) } + + tableName := "customize_columns" + idInsRes := DB.EnableIdentityInsert(&DB, tableName) + if idInsRes.Error != nil { + t.Errorf("Error while setting IDENTITY_INSERT ON for table:%v :%v", tableName, idInsRes.Error) + } expected := "foo" cc := CustomizeColumn{ID: 666, Name: expected, Date: time.Now()} - if count := DB.Create(&cc).RowsAffected; count != 1 { - t.Error("There should be one record be affected when create record") + res := DB.Create(&cc) + if res.Error != nil { + t.Errorf("Error while creating CustomizeColumn:%v", res.Error) + } + + if count := res.RowsAffected; count != 1 { + t.Errorf("There should be one record be affected when create record. count:%v", count) } var cc1 CustomizeColumn From a3b89f8100f030626fa63704c3ae9a237bfcb474 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:04:43 -0400 Subject: [PATCH 04/13] enable identity column insert optionally for mssql ref: https://github.com/jinzhu/gorm/issues/647 --- dialect.go | 1 + 1 file changed, 1 insertion(+) diff --git a/dialect.go b/dialect.go index 926f8a11..250c6779 100644 --- a/dialect.go +++ b/dialect.go @@ -18,6 +18,7 @@ type Dialect interface { HasIndex(scope *Scope, tableName string, indexName string) bool RemoveIndex(scope *Scope, indexName string) CurrentDatabase(scope *Scope) string + EnableIdentityInsert(db *DB, tableName string) *DB } func NewDialect(driver string) Dialect { From f6873437f4ddab3d0800f61db983156ec24bf1e4 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:05:45 -0400 Subject: [PATCH 05/13] error handling cleanup ref: https://github.com/jinzhu/gorm/issues/647 --- join_table_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/join_table_test.go b/join_table_test.go index 3353aee2..86a91007 100644 --- a/join_table_test.go +++ b/join_table_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/jinzhu/gorm" + "github.com/biju-kalissery/gorm" ) type Person struct { @@ -15,6 +15,7 @@ type Person struct { } type PersonAddress struct { + Id int gorm.JoinTableHandler PersonID int AddressID int @@ -50,7 +51,10 @@ func TestJoinTable(t *testing.T) { address1 := &Address{Address1: "address 1"} address2 := &Address{Address1: "address 2"} person := &Person{Name: "person", Addresses: []*Address{address1, address2}} - DB.Save(person) + res := DB.Save(person) + if res.Error != nil { + t.Errorf("Error while saving person object:%v", res.Error) + } DB.Model(person).Association("Addresses").Delete(address1) From 10cba1556b770ac1f19d4b0156f9f0bfb1f6ea79 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:06:45 -0400 Subject: [PATCH 06/13] enable identity column insert optionally for mssql ref: https://github.com/jinzhu/gorm/issues/647 --- main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.go b/main.go index 657342e9..286b7f51 100644 --- a/main.go +++ b/main.go @@ -451,6 +451,7 @@ func (s *DB) CurrentDatabase() string { return name } + /* Add foreign key to the given scope @@ -550,3 +551,7 @@ func (s *DB) GetErrors() (errors []error) { } return } + +func (s *DB) EnableIdentityInsert(db *DB, tableName string) *DB { + return s.dialect.EnableIdentityInsert(db, tableName) +} From be655f8539b65b06ab561e0cd1da9cf4288818ba Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:10:46 -0400 Subject: [PATCH 07/13] change unique index to simple index on the migrated table because mssql does not allow duplicate NULL values in unique columns ref: https://github.com/jinzhu/gorm/issues/647 --- migration_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/migration_test.go b/migration_test.go index 74c8b94f..131acb07 100644 --- a/migration_test.go +++ b/migration_test.go @@ -88,8 +88,8 @@ type BigEmail struct { Id int64 UserId int64 Email string `sql:"index:idx_email_agent"` - UserAgent string `sql:"index:idx_email_agent"` - RegisteredAt time.Time `sql:"unique_index"` + UserAgent string `sql:"index:idx_user_agent"` + RegisteredAt time.Time `sql:"index:idx_emails_registered_at"` CreatedAt time.Time UpdatedAt time.Time } @@ -100,8 +100,9 @@ func (b BigEmail) TableName() string { func TestAutoMigration(t *testing.T) { DB.AutoMigrate(&Address{}) + if err := DB.Table("emails").AutoMigrate(&BigEmail{}).Error; err != nil { - t.Errorf("Auto Migrate should not raise any error") + t.Errorf("Auto Migrate should not raise any error, but raised: %v", err) } DB.Save(&BigEmail{Email: "jinzhu@example.org", UserAgent: "pc", RegisteredAt: time.Now()}) @@ -111,7 +112,7 @@ func TestAutoMigration(t *testing.T) { t.Errorf("Failed to create index") } - if !scope.Dialect().HasIndex(scope, scope.TableName(), "uix_emails_registered_at") { + if !scope.Dialect().HasIndex(scope, scope.TableName(), "idx_emails_registered_at") { t.Errorf("Failed to create index") } From f8dd9d077d691168955b237ebac97de7e6488afb Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:12:00 -0400 Subject: [PATCH 08/13] enable identity column insert optionally for mssql ref: https://github.com/jinzhu/gorm/issues/647 --- mssql.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mssql.go b/mssql.go index a9bd1e52..0cd8bf03 100644 --- a/mssql.go +++ b/mssql.go @@ -78,3 +78,8 @@ func (s mssql) CurrentDatabase(scope *Scope) (name string) { s.RawScanString(scope, &name, "SELECT DB_NAME() AS [Current Database]") return } + +func (s mssql) EnableIdentityInsert(db *DB, tableName string) *DB { + idSql := "SET IDENTITY_INSERT " + tableName + " ON" + return db.Exec(idSql) +} From e0821942c17049483ffb1233096015e108916b50 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:13:18 -0400 Subject: [PATCH 09/13] error handling refinements ref: https://github.com/jinzhu/gorm/issues/647 --- multi_primary_keys_test.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/multi_primary_keys_test.go b/multi_primary_keys_test.go index 9ca68d13..5e5bf6eb 100644 --- a/multi_primary_keys_test.go +++ b/multi_primary_keys_test.go @@ -34,13 +34,24 @@ func TestManyToManyWithMultiPrimaryKeys(t *testing.T) { }, } - DB.Save(&blog) - DB.Model(&blog).Association("Tags").Append([]Tag{{Locale: "ZH", Value: "tag3"}}) - + res := DB.Save(&blog) + if nil != res.Error { + t.Errorf("Error while saving blog:%v", res.Error) + } + res2 := DB.Model(&blog).Association("Tags").Append([]Tag{{Locale: "ZH", Value: "tag3"}}) + if nil != res2.Error { + t.Errorf("Error while appending tag to blog:%v", res2.Error) + } + var tags []Tag - DB.Model(&blog).Related(&tags, "Tags") - if len(tags) != 3 { - t.Errorf("should found 3 tags with blog") + res = DB.Model(&blog).Related(&tags, "Tags") + if nil != res.Error { + t.Errorf("Error while reading tags related to blog:%v", res.Error) + } + + tagsCount := len(tags) + if tagsCount != 3 { + t.Errorf("should found 3 tags with blog, found:%v", tagsCount) } } } From 7ae37290338eac5c5a08ac72cc8c5f1c8cd78354 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:14:05 -0400 Subject: [PATCH 10/13] error handling refinements ref: https://github.com/jinzhu/gorm/issues/647 --- preload_test.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/preload_test.go b/preload_test.go index 3dcd325b..6f8d2f83 100644 --- a/preload_test.go +++ b/preload_test.go @@ -49,12 +49,23 @@ func checkUserHasPreloadData(user User, t *testing.T) { func TestPreload(t *testing.T) { user1 := getPreloadUser("user1") - DB.Save(user1) + res1 := DB.Save(user1) + if res1.Error != nil { + t.Errorf("Error in save : %v", res1.Error) + } preloadDB := DB.Where("role = ?", "Preload").Preload("BillingAddress").Preload("ShippingAddress"). Preload("CreditCard").Preload("Emails").Preload("Company") + if preloadDB.Error != nil { + t.Errorf("Error in preload : %v", preloadDB.Error) + } + var user User - preloadDB.Find(&user) + res := preloadDB.Find(&user) + if res.Error != nil { + t.Errorf("Error in preload : %v", res.Error) + } + checkUserHasPreloadData(user, t) user2 := getPreloadUser("user2") @@ -628,7 +639,7 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { DB.Table("levels").DropTableIfExists("levels") if err := DB.AutoMigrate(&Level2{}, &Level1{}).Error; err != nil { - panic(err) + t.Fatalf("Error in AutoMigrate:%v", err) } want := Level2{Value: "Bob", LanguageCode: "ru", Level1s: []Level1{ @@ -636,7 +647,7 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { {Value: "en", LanguageCode: "en"}, }} if err := DB.Save(&want).Error; err != nil { - panic(err) + t.Fatalf("Error in Save:%v", err) } want2 := Level2{Value: "Tom", LanguageCode: "zh", Level1s: []Level1{ @@ -644,12 +655,12 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { {Value: "de", LanguageCode: "de"}, }} if err := DB.Save(&want2).Error; err != nil { - panic(err) + t.Fatalf("Error in Save want2:%v", err) } var got Level2 if err := DB.Preload("Level1s").Find(&got, "value = ?", "Bob").Error; err != nil { - panic(err) + t.Fatalf("Error in Preload:%v", err) } if !reflect.DeepEqual(got, want) { @@ -658,7 +669,7 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { var got2 Level2 if err := DB.Preload("Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil { - panic(err) + t.Fatalf("Error in Preload Level1s:%v", err) } if !reflect.DeepEqual(got2, want2) { @@ -667,7 +678,7 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { var got3 []Level2 if err := DB.Preload("Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil { - panic(err) + t.Fatalf("Error in Preload got3 :%v",err) } if !reflect.DeepEqual(got3, []Level2{got, got2}) { @@ -676,7 +687,7 @@ func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { var got4 []Level2 if err := DB.Preload("Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil { - panic(err) + t.Fatalf("Error in Preload got4:%v",err) } var ruLevel1 Level1 From a513a468b4797d8ab4cfd9aced9183ddeb084fab Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 14:15:23 -0400 Subject: [PATCH 11/13] error handling refinements ref: https://github.com/jinzhu/gorm/issues/647 --- slice_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slice_test.go b/slice_test.go index 21410548..c29feca2 100644 --- a/slice_test.go +++ b/slice_test.go @@ -20,13 +20,13 @@ func TestScannableSlices(t *testing.T) { } if err := DB.Save(&r1).Error; err != nil { - t.Errorf("Should save record with slice values") + t.Errorf("Should save record with slice values:%v", err) } var r2 RecordWithSlice if err := DB.Find(&r2).Error; err != nil { - t.Errorf("Should fetch record with slice values") + t.Errorf("Should fetch record with slice values:%v", err) } if len(r2.Strings) != 3 || r2.Strings[0] != "a" || r2.Strings[1] != "b" || r2.Strings[2] != "c" { From b98468710a513734cee801fcd4bf171f2c9937df Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 15:27:37 -0400 Subject: [PATCH 12/13] package ref cleanup ref: https://github.com/jinzhu/gorm/issues/647 --- join_table_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/join_table_test.go b/join_table_test.go index 86a91007..e3288f11 100644 --- a/join_table_test.go +++ b/join_table_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/biju-kalissery/gorm" + "github.com/jizhu/gorm" ) type Person struct { From e540893344764d4861229b31f1b3bc54ce71b7a9 Mon Sep 17 00:00:00 2001 From: biju-kalissery Date: Tue, 8 Sep 2015 15:31:05 -0400 Subject: [PATCH 13/13] package ref cleanup ref: https://github.com/jinzhu/gorm/issues/647 --- join_table_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/join_table_test.go b/join_table_test.go index e3288f11..6e640a53 100644 --- a/join_table_test.go +++ b/join_table_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/jizhu/gorm" + "github.com/jinzhu/gorm" ) type Person struct {