diff --git a/go.mod b/go.mod index d3421e1b..45bcf69c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,11 @@ module github.com/jinzhu/gorm go 1.14 require ( + github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd + github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 + github.com/go-sql-driver/mysql v1.5.0 github.com/jinzhu/inflection v1.0.0 github.com/jinzhu/now v1.1.1 + github.com/lib/pq v1.1.1 + github.com/mattn/go-sqlite3 v2.0.1+incompatible ) diff --git a/statement.go b/statement.go index f3090eb7..1ea5a56c 100644 --- a/statement.go +++ b/statement.go @@ -147,8 +147,24 @@ func (stmt *Statement) AddVar(writer clause.Writer, vars ...interface{}) { writer.WriteString("(NULL)") } default: - stmt.Vars = append(stmt.Vars, v) - stmt.DB.Dialector.BindVarTo(writer, stmt, v) + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Slice, reflect.Array: + if rv.Len() == 0 { + writer.WriteString("(NULL)") + } else { + writer.WriteByte('(') + for i := 0; i < rv.Len(); i++ { + if i > 0 { + writer.WriteByte(',') + } + stmt.AddVar(writer, rv.Index(i).Interface()) + } + writer.WriteByte(')') + } + default: + stmt.Vars = append(stmt.Vars, v) + stmt.DB.Dialector.BindVarTo(writer, stmt, v) + } } } } diff --git a/tests/create.go b/tests/create.go index 428f876c..ec57b8ee 100644 --- a/tests/create.go +++ b/tests/create.go @@ -1,787 +1,65 @@ package tests import ( - "fmt" - "testing" - - "github.com/jinzhu/gorm" + "strconv" + "time" ) -func TestCreate(t *testing.T, db *gorm.DB) { - db.Migrator().DropTable(&User{}) - db.AutoMigrate(&User{}) - - t.Run("Create", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - if user.ID == 0 { - t.Errorf("user's primary key should has value after create, got : %v", user.ID) - } - - if user.CreatedAt.IsZero() { - t.Errorf("user's created at should be not zero") - } - - if user.UpdatedAt.IsZero() { - t.Errorf("user's updated at should be not zero") - } - - var newUser User - if err := db.Where("id = ?", user.ID).First(&newUser).Error; err != nil { - t.Errorf("errors happened when query: %v", err) - } else { - AssertObjEqual(t, newUser, user, "Name", "Age", "Birthday") - } - - TestCreateAssociations(t, db) - }) +type Config struct { + Account bool + Pets int + Toys int + Company bool + Manager bool + Team int + Languages int + Friends int } -func TestCreateAssociations(t *testing.T, db *gorm.DB) { - db.Migrator().DropTable(&Account{}, &Company{}, &Pet{}, &Toy{}, &Language{}) - db.Migrator().AutoMigrate(&Account{}, &Company{}, &Pet{}, &Toy{}, &Language{}) +func GetUser(name string, config Config) User { + var ( + birthday = time.Now() + user = User{ + Name: name, + Age: 18, + Birthday: &birthday, + } + ) - TestCreateBelongsToAssociations(t, db) - TestCreateHasOneAssociations(t, db) - TestCreateHasManyAssociations(t, db) - TestCreateMany2ManyAssociations(t, db) -} - -func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { - check := func(t *testing.T, user User, old User) { - if old.Company.Name != "" { - if user.CompanyID == nil { - t.Errorf("Company's foreign key should be saved") - } else { - var company Company - db.First(&company, "id = ?", *user.CompanyID) - if company.Name != old.Company.Name { - t.Errorf("Company's name should be same") - } else if user.Company.Name != old.Company.Name { - t.Errorf("Company's name should be same") - } - } - } else if user.CompanyID != nil { - t.Errorf("Company should not be created for zero value, got: %+v", user.CompanyID) - } - - if old.Manager != nil { - if user.ManagerID == nil { - t.Errorf("Manager's foreign key should be saved") - } else { - var manager User - db.First(&manager, "id = ?", *user.ManagerID) - if manager.Name != user.Manager.Name { - t.Errorf("Manager's name should be same") - } else if user.Manager.Name != old.Manager.Name { - t.Errorf("Manager's name should be same") - } - } - } else if user.ManagerID != nil { - t.Errorf("Manager should not be created for zero value, got: %+v", user.ManagerID) - } - } - - t.Run("BelongsTo", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association"}, - Manager: &User{Name: "manager-belongs-to-association"}, - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - check(t, user, user) - - var user2 User - db.Preload("Company").Preload("Manager").Find(&user2, "id = ?", user.ID) - check(t, user2, user) - }) - - t.Run("BelongsToForBulkInsert", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-1"}, - Manager: &User{Name: "manager-belongs-to-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-3"}, - Manager: &User{Name: "manager-belongs-to-association-3"}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var userIDs []uint - for _, user := range users { - userIDs = append(userIDs, user.ID) - check(t, user, user) - } - - var users2 []User - db.Preload("Company").Preload("Manager").Find(&users2, "id IN (?)", userIDs) - for idx, user := range users2 { - check(t, user, users[idx]) - } - - var users3 []User - db.Preload("Company").Preload("Manager").Find(users3, "id IN (?)", userIDs) - for idx, user := range users3 { - check(t, user, users[idx]) - } - }) - - t.Run("BelongsToForBulkInsertPtrData", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-1"}, - Manager: &User{Name: "manager-belongs-to-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-3"}, - Manager: &User{Name: "manager-belongs-to-association-3"}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, *user, *user) - } - }) - - t.Run("BelongsToForBulkInsertWithoutPtr", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-1"}, - Manager: &User{Name: "manager-belongs-to-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Company: Company{Name: "company-belongs-to-association-3"}, - Manager: &User{Name: "manager-belongs-to-association-3"}, - }} - - if err := db.Create(users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, *user, *user) - } - }) -} - -func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { - check := func(t *testing.T, user User, old User) { - if user.Account.ID == 0 { - t.Errorf("Account should be saved") - } else if user.Account.UserID.Int64 != int64(user.ID) { - t.Errorf("Account's foreign key should be saved") - } else { - var account Account - db.First(&account, "id = ?", user.Account.ID) - if account.Number != user.Account.Number { - t.Errorf("Account's number should be same") - } else if user.Account.Number != old.Account.Number { - t.Errorf("Account's number should be same") - } - } - } - - t.Run("HasOne", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - Account: Account{Number: "account-has-one-association"}, - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - check(t, user, user) - - var user2 User - db.Preload("Account").Find(&user2, "id = ?", user.ID) - check(t, user2, user) - }) - - t.Run("HasOneForBulkInsert", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-3"}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var userIDs []uint - for _, user := range users { - userIDs = append(userIDs, user.ID) - check(t, user, user) - } - - var users2 []User - db.Preload("Account").Find(&users2, "id IN (?)", userIDs) - for idx, user := range users2 { - check(t, user, users[idx]) - } - }) - - t.Run("HasOneForBulkInsertPtrData", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-3"}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, *user, *user) - } - }) - - t.Run("HasOneForBulkInsertWithoutPtr", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-1"}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-2"}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Account: Account{Number: "account-has-one-association-3"}, - }} - - if err := db.Create(users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, user, user) - } - }) - - checkPet := func(t *testing.T, pet Pet, old Pet) { - if pet.Toy.OwnerID != fmt.Sprint(pet.ID) || pet.Toy.OwnerType != "pets" { - t.Errorf("Failed to create polymorphic has one association - toy owner id %v, owner type %v", pet.Toy.OwnerID, pet.Toy.OwnerType) - } else { - var toy Toy - db.First(&toy, "owner_id = ? and owner_type = ?", pet.Toy.OwnerID, pet.Toy.OwnerType) - if toy.Name != pet.Toy.Name { - t.Errorf("Failed to query saved polymorphic has one association") - } else if old.Toy.Name != pet.Toy.Name { - t.Errorf("Failed to query saved polymorphic has one association") - } - } - } - - t.Run("PolymorphicHasOne", func(t *testing.T) { - var pet = Pet{ - Name: "create", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic"}, - } - - if err := db.Create(&pet).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - checkPet(t, pet, pet) - - var pet2 Pet - db.Preload("Toy").Find(&pet2, "id = ?", pet.ID) - checkPet(t, pet2, pet) - }) - - t.Run("PolymorphicHasOneForBulkInsert", func(t *testing.T) { - var pets = []Pet{{ - Name: "create-1", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, - }, { - Name: "create-2", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, - }, { - Name: "create-3", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, - }} - - if err := db.Create(&pets).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var petIDs []uint - for _, pet := range pets { - petIDs = append(petIDs, pet.ID) - checkPet(t, pet, pet) - } - - var pets2 []Pet - db.Preload("Toy").Find(&pets2, "id IN (?)", petIDs) - for idx, pet := range pets2 { - checkPet(t, pet, pets[idx]) - } - }) - - t.Run("PolymorphicHasOneForBulkInsertPtrData", func(t *testing.T) { - var pets = []*Pet{{ - Name: "create-1", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, - }, { - Name: "create-2", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, - }, { - Name: "create-3", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, - }} - - if err := db.Create(&pets).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, pet := range pets { - checkPet(t, *pet, *pet) - } - }) - - t.Run("PolymorphicHasOneForBulkInsertWithoutPtr", func(t *testing.T) { - var pets = []*Pet{{ - Name: "create-1", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, - }, { - Name: "create-2", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, - }, { - Name: "create-3", - Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, - }} - - if err := db.Create(pets).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, pet := range pets { - checkPet(t, *pet, *pet) - } - }) -} - -func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { - check := func(t *testing.T, user User, old User) { - for idx, pet := range user.Pets { - if pet.ID == 0 { - t.Errorf("Pet's foreign key should be saved") - } - - var result Pet - db.First(&result, "id = ?", pet.ID) - if result.Name != pet.Name { - t.Errorf("Pet's name should be same") - } else if result.UserID != user.ID { - t.Errorf("Pet's foreign key should be saved") - } else if result.Name != old.Pets[idx].Name { - t.Errorf("Pet's name should be same") - } - } - } - - t.Run("HasMany", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - Pets: []*Pet{{Name: "pet1"}, {Name: "pet2"}}, - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - check(t, user, user) - - var user2 User - db.Preload("Pets").Find(&user2, "id = ?", user.ID) - check(t, user2, user) - }) - - t.Run("HasManyForBulkInsert", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-2-1"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var userIDs []uint - for _, user := range users { - userIDs = append(userIDs, user.ID) - check(t, user, user) - } - - var users2 []User - db.Preload("Pets").Find(&users2, "id IN (?)", userIDs) - for idx, user := range users2 { - check(t, user, users[idx]) - } - }) - - t.Run("HasManyForBulkInsertPtrData", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-2-1"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, *user, *user) - } - }) - - t.Run("HasManyForBulkInsertWithoutPtr", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-2-1"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, - }} - - if err := db.Create(users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - check(t, *user, *user) - } - }) - - checkToy := func(t *testing.T, user User, old User) { - for idx, toy := range user.Toys { - if toy.ID == 0 { - t.Fatalf("Failed to create toy #%v", idx) - } - - var result Toy - db.First(&result, "id = ?", toy.ID) - if result.Name != toy.Name { - t.Errorf("Failed to query saved toy") - } else if result.Name != old.Toys[idx].Name { - t.Errorf("Failed to query saved toy") - } else if result.OwnerID != fmt.Sprint(user.ID) || result.OwnerType != "users" { - t.Errorf("Failed to save relation") - } - } - } - - t.Run("PolymorphicHasMany", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}, - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - checkToy(t, user, user) - - var user2 User - db.Preload("Toys").Find(&user2, "id = ?", user.ID) - check(t, user2, user) - }) - - t.Run("PolymorphicHasManyForBulkInsert", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var userIDs []uint - for _, user := range users { - userIDs = append(userIDs, user.ID) - checkToy(t, user, user) - } - - var users2 []User - db.Preload("Toys").Find(&users2, "id IN (?)", userIDs) - for idx, user := range users2 { - check(t, user, users[idx]) - } - }) - - t.Run("PolymorphicHasManyForBulkInsertPtrData", func(t *testing.T) { - var users = []*User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, - }} - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - checkToy(t, *user, *user) - } - }) - - t.Run("PolymorphicHasManyForBulkInsertWithoutPtr", func(t *testing.T) { - var users = []User{{ - Name: "create-1", - Age: 18, - Birthday: Now(), - Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, - }, { - Name: "create-2", - Age: 28, - Birthday: Now(), - Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, - }, { - Name: "create-3", - Age: 38, - Birthday: Now(), - Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, - }} - - if err := db.Create(users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - for _, user := range users { - checkToy(t, user, user) - } - }) -} - -func TestCreateMany2ManyAssociations(t *testing.T, db *gorm.DB) { - check := func(t *testing.T, user User, old User) { - for idx, language := range user.Languages { - var result Language - db.First(&result, "code = ?", language.Code) - if result.Name != language.Name { - t.Errorf("Language's name should be same") - } else if result.Name != old.Languages[idx].Name { - t.Errorf("Language's name should be same") - } - } - - for idx, f := range user.Friends { - if f.ID == 0 { - t.Errorf("Friend's foreign key should be saved") - } - - var result User - db.First(&result, "id = ?", f.ID) - if result.Name != f.Name { - t.Errorf("Friend's name should be same") - } else if result.Name != old.Friends[idx].Name { - t.Errorf("Language's name should be same") - } - } - } - - db.Create(&[]Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}) - - t.Run("Many2Many", func(t *testing.T) { - var user = User{ - Name: "create", - Age: 18, - Birthday: Now(), - Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, - Friends: []*User{{Name: "friend-1"}, {Name: "friend-2"}}, - } - - if err := db.Create(&user).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - check(t, user, user) - - var user2 User - db.Preload("Languages").Preload("Friends").Find(&user2, "id = ?", user.ID) - check(t, user2, user) - }) - - t.Run("Many2ManyForBulkInsert", func(t *testing.T) { - var users = []User{ - { - Name: "create-1", - Age: 18, - Birthday: Now(), - Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, - Friends: []*User{{Name: "friend-1-1"}, {Name: "friend-1-2"}}, - }, - { - Name: "create-2", - Age: 18, - Birthday: Now(), - Languages: []Language{{Code: "zh-CN", Name: "Chinese"}}, - Friends: []*User{{Name: "friend-2-1"}}, - }, - { - Name: "create-3", - Age: 18, - Birthday: Now(), - Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, - Friends: []*User{{Name: "friend-3-1"}, {Name: "friend-3-2"}, {Name: "friend-3-3"}}, - }, - } - - if err := db.Create(&users).Error; err != nil { - t.Fatalf("errors happened when create: %v", err) - } - - var userIDs []uint - for _, user := range users { - userIDs = append(userIDs, user.ID) - check(t, user, user) - } - - var users2 []User - db.Preload("Languages").Preload("Friends").Find(&users2, "id IN (?)", userIDs) - for idx, user := range users2 { - check(t, user, users[idx]) - } - }) + if config.Account { + user.Account = Account{Number: name + "_account"} + } + + for i := 0; i < config.Pets; i++ { + user.Pets = append(user.Pets, &Pet{Name: name + "_pet_" + strconv.Itoa(i+1)}) + } + + for i := 0; i < config.Toys; i++ { + user.Toys = append(user.Toys, Toy{Name: name + "_toy_" + strconv.Itoa(i+1)}) + } + + if config.Company { + user.Company = Company{Name: "company-" + name} + } + + if config.Manager { + manager := GetUser(name+"_manager", Config{}) + user.Manager = &manager + } + + for i := 0; i < config.Team; i++ { + user.Team = append(user.Team, GetUser(name+"_team_"+strconv.Itoa(i+1), Config{})) + } + + for i := 0; i < config.Languages; i++ { + name := "Locale_" + strconv.Itoa(i+0) + user.Languages = append(user.Languages, Language{Code: name, Name: name}) + } + + for i := 0; i < config.Friends; i++ { + f := GetUser(name+"_friend_"+strconv.Itoa(i+1), Config{}) + user.Friends = append(user.Friends, &f) + } + + return user } diff --git a/tests/create_test.go b/tests/create_test.go new file mode 100644 index 00000000..471cecf6 --- /dev/null +++ b/tests/create_test.go @@ -0,0 +1,761 @@ +package tests_test + +import ( + "testing" + + . "github.com/jinzhu/gorm/tests" +) + +func TestCreate(t *testing.T) { + var user = GetUser("create", Config{}) + + if err := DB.Create(&user).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + if user.ID == 0 { + t.Errorf("user's primary key should has value after create, got : %v", user.ID) + } + + if user.CreatedAt.IsZero() { + t.Errorf("user's created at should be not zero") + } + + if user.UpdatedAt.IsZero() { + t.Errorf("user's updated at should be not zero") + } + + var newUser User + if err := DB.Where("id = ?", user.ID).First(&newUser).Error; err != nil { + t.Errorf("errors happened when query: %v", err) + } else { + AssertObjEqual(t, newUser, user, "Name", "Age", "Birthday") + } +} + +func TestCreateWithBelongsToAssociations(t *testing.T) { + check := func(t *testing.T, user User, old User) { + if old.Company.Name != "" { + if user.CompanyID == nil { + t.Errorf("Company's foreign key should be saved") + } else { + var company Company + DB.First(&company, "id = ?", *user.CompanyID) + if company.Name != old.Company.Name { + t.Errorf("Company's name should be same") + } else if user.Company.Name != old.Company.Name { + t.Errorf("Company's name should be same") + } + } + } else if user.CompanyID != nil { + t.Errorf("Company should not be created for zero value, got: %+v", user.CompanyID) + } + + if old.Manager != nil { + if user.ManagerID == nil { + t.Errorf("Manager's foreign key should be saved") + } else { + var manager User + DB.First(&manager, "id = ?", *user.ManagerID) + if manager.Name != user.Manager.Name { + t.Errorf("Manager's name should be same") + } else if user.Manager.Name != old.Manager.Name { + t.Errorf("Manager's name should be same") + } + } + } else if user.ManagerID != nil { + t.Errorf("Manager should not be created for zero value, got: %+v", user.ManagerID) + } + } + + t.Run("Struct", func(t *testing.T) { + var user = User{ + Name: "create", + Age: 18, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association"}, + Manager: &User{Name: "manager-belongs-to-association"}, + } + + if err := DB.Create(&user).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + check(t, user, user) + + var user2 User + DB.Preload("Company").Preload("Manager").Find(&user2, "id = ?", user.ID) + check(t, user2, user) + }) + + t.Run("BulkInsert", func(t *testing.T) { + var users = []User{{ + Name: "create-1", + Age: 18, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-1"}, + Manager: &User{Name: "manager-belongs-to-association-1"}, + }, { + Name: "create-2", + Age: 28, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-2"}, + }, { + Name: "create-3", + Age: 38, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-3"}, + Manager: &User{Name: "manager-belongs-to-association-3"}, + }} + + if err := DB.Create(&users).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + var userIDs []uint + for _, user := range users { + userIDs = append(userIDs, user.ID) + check(t, user, user) + } + + t.Run("Preload", func(t *testing.T) { + var users2 []User + DB.Preload("Company").Preload("Manager").Find(&users2, "id IN ?", userIDs) + for idx, user := range users2 { + check(t, user, users[idx]) + } + }) + }) + + t.Run("BulkInsertPtrData", func(t *testing.T) { + var users = []*User{{ + Name: "create-1", + Age: 18, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-1"}, + Manager: &User{Name: "manager-belongs-to-association-1"}, + }, { + Name: "create-2", + Age: 28, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-2"}, + }, { + Name: "create-3", + Age: 38, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-3"}, + Manager: &User{Name: "manager-belongs-to-association-3"}, + }} + + if err := DB.Create(&users).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + for _, user := range users { + check(t, *user, *user) + } + }) + + t.Run("BulkInsertWithoutPtr", func(t *testing.T) { + var users = []*User{{ + Name: "create-1", + Age: 18, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-1"}, + Manager: &User{Name: "manager-belongs-to-association-1"}, + }, { + Name: "create-2", + Age: 28, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-2"}, + }, { + Name: "create-3", + Age: 38, + Birthday: Now(), + Company: Company{Name: "company-belongs-to-association-3"}, + Manager: &User{Name: "manager-belongs-to-association-3"}, + }} + + if err := DB.Create(users).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + for _, user := range users { + check(t, *user, *user) + } + }) +} + +// func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { +// check := func(t *testing.T, user User, old User) { +// if user.Account.ID == 0 { +// t.Errorf("Account should be saved") +// } else if user.Account.UserID.Int64 != int64(user.ID) { +// t.Errorf("Account's foreign key should be saved") +// } else { +// var account Account +// db.First(&account, "id = ?", user.Account.ID) +// if account.Number != user.Account.Number { +// t.Errorf("Account's number should be same") +// } else if user.Account.Number != old.Account.Number { +// t.Errorf("Account's number should be same") +// } +// } +// } + +// t.Run("HasOne", func(t *testing.T) { +// var user = User{ +// Name: "create", +// Age: 18, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association"}, +// } + +// if err := db.Create(&user).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// check(t, user, user) + +// var user2 User +// db.Preload("Account").Find(&user2, "id = ?", user.ID) +// check(t, user2, user) +// }) + +// t.Run("HasOneForBulkInsert", func(t *testing.T) { +// var users = []User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-1"}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-2"}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-3"}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// var userIDs []uint +// for _, user := range users { +// userIDs = append(userIDs, user.ID) +// check(t, user, user) +// } + +// var users2 []User +// db.Preload("Account").Find(&users2, "id IN (?)", userIDs) +// for idx, user := range users2 { +// check(t, user, users[idx]) +// } +// }) + +// t.Run("HasOneForBulkInsertPtrData", func(t *testing.T) { +// var users = []*User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-1"}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-2"}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-3"}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// check(t, *user, *user) +// } +// }) + +// t.Run("HasOneForBulkInsertWithoutPtr", func(t *testing.T) { +// var users = []User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-1"}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-2"}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Account: Account{Number: "account-has-one-association-3"}, +// }} + +// if err := db.Create(users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// check(t, user, user) +// } +// }) + +// checkPet := func(t *testing.T, pet Pet, old Pet) { +// if pet.Toy.OwnerID != fmt.Sprint(pet.ID) || pet.Toy.OwnerType != "pets" { +// t.Errorf("Failed to create polymorphic has one association - toy owner id %v, owner type %v", pet.Toy.OwnerID, pet.Toy.OwnerType) +// } else { +// var toy Toy +// db.First(&toy, "owner_id = ? and owner_type = ?", pet.Toy.OwnerID, pet.Toy.OwnerType) +// if toy.Name != pet.Toy.Name { +// t.Errorf("Failed to query saved polymorphic has one association") +// } else if old.Toy.Name != pet.Toy.Name { +// t.Errorf("Failed to query saved polymorphic has one association") +// } +// } +// } + +// t.Run("PolymorphicHasOne", func(t *testing.T) { +// var pet = Pet{ +// Name: "create", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic"}, +// } + +// if err := db.Create(&pet).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// checkPet(t, pet, pet) + +// var pet2 Pet +// db.Preload("Toy").Find(&pet2, "id = ?", pet.ID) +// checkPet(t, pet2, pet) +// }) + +// t.Run("PolymorphicHasOneForBulkInsert", func(t *testing.T) { +// var pets = []Pet{{ +// Name: "create-1", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, +// }, { +// Name: "create-2", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, +// }, { +// Name: "create-3", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, +// }} + +// if err := db.Create(&pets).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// var petIDs []uint +// for _, pet := range pets { +// petIDs = append(petIDs, pet.ID) +// checkPet(t, pet, pet) +// } + +// var pets2 []Pet +// db.Preload("Toy").Find(&pets2, "id IN (?)", petIDs) +// for idx, pet := range pets2 { +// checkPet(t, pet, pets[idx]) +// } +// }) + +// t.Run("PolymorphicHasOneForBulkInsertPtrData", func(t *testing.T) { +// var pets = []*Pet{{ +// Name: "create-1", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, +// }, { +// Name: "create-2", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, +// }, { +// Name: "create-3", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, +// }} + +// if err := db.Create(&pets).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, pet := range pets { +// checkPet(t, *pet, *pet) +// } +// }) + +// t.Run("PolymorphicHasOneForBulkInsertWithoutPtr", func(t *testing.T) { +// var pets = []*Pet{{ +// Name: "create-1", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-1"}, +// }, { +// Name: "create-2", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-2"}, +// }, { +// Name: "create-3", +// Toy: Toy{Name: "Create-HasOneAssociation-Polymorphic-3"}, +// }} + +// if err := db.Create(pets).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, pet := range pets { +// checkPet(t, *pet, *pet) +// } +// }) +// } + +// func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { +// check := func(t *testing.T, user User, old User) { +// for idx, pet := range user.Pets { +// if pet.ID == 0 { +// t.Errorf("Pet's foreign key should be saved") +// } + +// var result Pet +// db.First(&result, "id = ?", pet.ID) +// if result.Name != pet.Name { +// t.Errorf("Pet's name should be same") +// } else if result.UserID != user.ID { +// t.Errorf("Pet's foreign key should be saved") +// } else if result.Name != old.Pets[idx].Name { +// t.Errorf("Pet's name should be same") +// } +// } +// } + +// t.Run("HasMany", func(t *testing.T) { +// var user = User{ +// Name: "create", +// Age: 18, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet1"}, {Name: "pet2"}}, +// } + +// if err := db.Create(&user).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// check(t, user, user) + +// var user2 User +// db.Preload("Pets").Find(&user2, "id = ?", user.ID) +// check(t, user2, user) +// }) + +// t.Run("HasManyForBulkInsert", func(t *testing.T) { +// var users = []User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-2-1"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// var userIDs []uint +// for _, user := range users { +// userIDs = append(userIDs, user.ID) +// check(t, user, user) +// } + +// var users2 []User +// db.Preload("Pets").Find(&users2, "id IN (?)", userIDs) +// for idx, user := range users2 { +// check(t, user, users[idx]) +// } +// }) + +// t.Run("HasManyForBulkInsertPtrData", func(t *testing.T) { +// var users = []*User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-2-1"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// check(t, *user, *user) +// } +// }) + +// t.Run("HasManyForBulkInsertWithoutPtr", func(t *testing.T) { +// var users = []*User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-1-1"}, {Name: "pet-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-2-1"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Pets: []*Pet{{Name: "pet-3-1"}, {Name: "pet-3-2"}}, +// }} + +// if err := db.Create(users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// check(t, *user, *user) +// } +// }) + +// checkToy := func(t *testing.T, user User, old User) { +// for idx, toy := range user.Toys { +// if toy.ID == 0 { +// t.Fatalf("Failed to create toy #%v", idx) +// } + +// var result Toy +// db.First(&result, "id = ?", toy.ID) +// if result.Name != toy.Name { +// t.Errorf("Failed to query saved toy") +// } else if result.Name != old.Toys[idx].Name { +// t.Errorf("Failed to query saved toy") +// } else if result.OwnerID != fmt.Sprint(user.ID) || result.OwnerType != "users" { +// t.Errorf("Failed to save relation") +// } +// } +// } + +// t.Run("PolymorphicHasMany", func(t *testing.T) { +// var user = User{ +// Name: "create", +// Age: 18, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy1"}, {Name: "toy2"}}, +// } + +// if err := db.Create(&user).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// checkToy(t, user, user) + +// var user2 User +// db.Preload("Toys").Find(&user2, "id = ?", user.ID) +// check(t, user2, user) +// }) + +// t.Run("PolymorphicHasManyForBulkInsert", func(t *testing.T) { +// var users = []User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// var userIDs []uint +// for _, user := range users { +// userIDs = append(userIDs, user.ID) +// checkToy(t, user, user) +// } + +// var users2 []User +// db.Preload("Toys").Find(&users2, "id IN (?)", userIDs) +// for idx, user := range users2 { +// check(t, user, users[idx]) +// } +// }) + +// t.Run("PolymorphicHasManyForBulkInsertPtrData", func(t *testing.T) { +// var users = []*User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, +// }} + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// checkToy(t, *user, *user) +// } +// }) + +// t.Run("PolymorphicHasManyForBulkInsertWithoutPtr", func(t *testing.T) { +// var users = []User{{ +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-1-1"}, {Name: "toy-1-2"}}, +// }, { +// Name: "create-2", +// Age: 28, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-2-1"}, {Name: "toy-2-2"}}, +// }, { +// Name: "create-3", +// Age: 38, +// Birthday: Now(), +// Toys: []Toy{{Name: "toy-3-1"}, {Name: "toy-3-2"}}, +// }} + +// if err := db.Create(users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// for _, user := range users { +// checkToy(t, user, user) +// } +// }) +// } + +// func TestCreateMany2ManyAssociations(t *testing.T, db *gorm.DB) { +// check := func(t *testing.T, user User, old User) { +// for idx, language := range user.Languages { +// var result Language +// db.First(&result, "code = ?", language.Code) +// if result.Name != language.Name { +// t.Errorf("Language's name should be same") +// } else if result.Name != old.Languages[idx].Name { +// t.Errorf("Language's name should be same") +// } +// } + +// for idx, f := range user.Friends { +// if f.ID == 0 { +// t.Errorf("Friend's foreign key should be saved") +// } + +// var result User +// db.First(&result, "id = ?", f.ID) +// if result.Name != f.Name { +// t.Errorf("Friend's name should be same") +// } else if result.Name != old.Friends[idx].Name { +// t.Errorf("Language's name should be same") +// } +// } +// } + +// db.Create(&[]Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}) + +// t.Run("Many2Many", func(t *testing.T) { +// var user = User{ +// Name: "create", +// Age: 18, +// Birthday: Now(), +// Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, +// Friends: []*User{{Name: "friend-1"}, {Name: "friend-2"}}, +// } + +// if err := db.Create(&user).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// check(t, user, user) + +// var user2 User +// db.Preload("Languages").Preload("Friends").Find(&user2, "id = ?", user.ID) +// check(t, user2, user) +// }) + +// t.Run("Many2ManyForBulkInsert", func(t *testing.T) { +// var users = []User{ +// { +// Name: "create-1", +// Age: 18, +// Birthday: Now(), +// Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, +// Friends: []*User{{Name: "friend-1-1"}, {Name: "friend-1-2"}}, +// }, +// { +// Name: "create-2", +// Age: 18, +// Birthday: Now(), +// Languages: []Language{{Code: "zh-CN", Name: "Chinese"}}, +// Friends: []*User{{Name: "friend-2-1"}}, +// }, +// { +// Name: "create-3", +// Age: 18, +// Birthday: Now(), +// Languages: []Language{{Code: "zh-CN", Name: "Chinese"}, {Code: "en", Name: "English"}}, +// Friends: []*User{{Name: "friend-3-1"}, {Name: "friend-3-2"}, {Name: "friend-3-3"}}, +// }, +// } + +// if err := db.Create(&users).Error; err != nil { +// t.Fatalf("errors happened when create: %v", err) +// } + +// var userIDs []uint +// for _, user := range users { +// userIDs = append(userIDs, user.ID) +// check(t, user, user) +// } + +// var users2 []User +// db.Preload("Languages").Preload("Friends").Find(&users2, "id IN (?)", userIDs) +// for idx, user := range users2 { +// check(t, user, users[idx]) +// } +// }) +// } diff --git a/tests/main_test.go b/tests/main_test.go new file mode 100644 index 00000000..7324ed9e --- /dev/null +++ b/tests/main_test.go @@ -0,0 +1,95 @@ +package tests + +import ( + "log" + "math/rand" + "os" + "path/filepath" + "testing" + "time" + + "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/gorm/logger" +) + +var DB *gorm.DB + +func TestMain(m *testing.M) { + var err error + DB, err = OpenTestConnection() + if err == nil { + RunMigrations() + m.Run() + } else { + log.Printf("failed to connect database, got error %v\n", err) + os.Exit(1) + } +} + +func RunMigrations() { + var err error + allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} + rand.Seed(time.Now().UnixNano()) + rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) + + if err = DB.Migrator().DropTable(allModels...); err != nil { + log.Printf("Failed to drop table, got error %v\n", err) + os.Exit(1) + } + + if err = DB.AutoMigrate(allModels...); err != nil { + log.Printf("Failed to auto migrate, but got error %v\n", err) + os.Exit(1) + } + + for _, m := range allModels { + if !DB.Migrator().HasTable(m) { + log.Printf("Failed to create table for %#v\n", m) + os.Exit(1) + } + } +} + +func OpenTestConnection() (db *gorm.DB, err error) { + dbDSN := os.Getenv("GORM_DSN") + switch os.Getenv("GORM_DIALECT") { + case "mysql": + log.Println("testing mysql...") + if dbDSN == "" { + dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" + } + db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) + case "postgres": + log.Println("testing postgres...") + if dbDSN == "" { + dbDSN = "user=gorm password=gorm DB.name=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" + } + db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{}) + case "mssql": + // CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86'; + // CREATE DATABASE gorm; + // USE gorm; + // CREATE USER gorm FROM LOGIN gorm; + // sp_changedbowner 'gorm'; + log.Println("testing mssql...") + if dbDSN == "" { + dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" + } + db, err = gorm.Open(mssql.Open(dbDSN), &gorm.Config{}) + default: + log.Println("testing sqlite3...") + db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) + } + + if debug := os.Getenv("DEBUG"); debug == "true" { + db.Logger.LogMode(logger.Info) + } else if debug == "false" { + db.Logger.LogMode(logger.Error) + } + + return +} diff --git a/tests/tests.go b/tests/tests.go index 87005a71..809d2e39 100644 --- a/tests/tests.go +++ b/tests/tests.go @@ -13,7 +13,7 @@ func Now() *time.Time { } func RunTestsSuit(t *testing.T, db *gorm.DB) { - TestCreate(t, db) + // TestCreate(t, db) TestFind(t, db) TestUpdate(t, db) TestDelete(t, db)