From 6d555ef8d586a3101131407c60fbf10ae3f3557d Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 31 May 2020 14:18:07 +0800 Subject: [PATCH] Test embedded struct --- schema/field.go | 8 +++ tests/embedded_struct_test.go | 105 ++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 tests/embedded_struct_test.go diff --git a/schema/field.go b/schema/field.go index 57ba3ac7..f52dd6a6 100644 --- a/schema/field.go +++ b/schema/field.go @@ -298,6 +298,14 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { ef.DBName = prefix + ef.DBName } + if val, ok := ef.TagSettings["PRIMARYKEY"]; ok && utils.CheckTruth(val) { + ef.PrimaryKey = true + } else if val, ok := ef.TagSettings["PRIMARY_KEY"]; ok && utils.CheckTruth(val) { + ef.PrimaryKey = true + } else { + ef.PrimaryKey = false + } + for k, v := range field.TagSettings { ef.TagSettings[k] = v } diff --git a/tests/embedded_struct_test.go b/tests/embedded_struct_test.go new file mode 100644 index 00000000..af003786 --- /dev/null +++ b/tests/embedded_struct_test.go @@ -0,0 +1,105 @@ +package tests_test + +import ( + "testing" + + "github.com/jinzhu/gorm" + . "github.com/jinzhu/gorm/tests" +) + +func TestEmbeddedStruct(t *testing.T) { + type BasePost struct { + Id int64 + Title string + URL string + } + + type Author struct { + ID string + Name string + Email string + } + + type HNPost struct { + BasePost + Author `gorm:"EmbeddedPrefix:user_"` // Embedded struct + Upvotes int32 + } + + type EngadgetPost struct { + BasePost BasePost `gorm:"Embedded"` + Author Author `gorm:"Embedded;EmbeddedPrefix:author_"` // Embedded struct + ImageUrl string + } + + DB.Migrator().DropTable(&HNPost{}, &EngadgetPost{}) + if err := DB.Migrator().AutoMigrate(&HNPost{}, &EngadgetPost{}); err != nil { + t.Fatalf("failed to auto migrate, got error: %v", err) + } + + for _, name := range []string{"author_id", "author_name", "author_email"} { + if !DB.Migrator().HasColumn(&EngadgetPost{}, name) { + t.Errorf("should has prefixed column %v", name) + } + } + + stmt := gorm.Statement{DB: DB} + if err := stmt.Parse(&EngadgetPost{}); err != nil { + t.Fatalf("failed to parse embedded struct") + } else if len(stmt.Schema.PrimaryFields) != 1 { + t.Errorf("should have only one primary field with embedded struct, but got %v", len(stmt.Schema.PrimaryFields)) + } + + for _, name := range []string{"user_id", "user_name", "user_email"} { + if !DB.Migrator().HasColumn(&HNPost{}, name) { + t.Errorf("should has prefixed column %v", name) + } + } + + // save embedded struct + DB.Save(&HNPost{BasePost: BasePost{Title: "news"}}) + DB.Save(&HNPost{BasePost: BasePost{Title: "hn_news"}}) + var news HNPost + if err := DB.First(&news, "title = ?", "hn_news").Error; err != nil { + t.Errorf("no error should happen when query with embedded struct, but got %v", err) + } else if news.Title != "hn_news" { + t.Errorf("embedded struct's value should be scanned correctly") + } + + DB.Save(&EngadgetPost{BasePost: BasePost{Title: "engadget_news"}}) + var egNews EngadgetPost + if err := DB.First(&egNews, "title = ?", "engadget_news").Error; err != nil { + t.Errorf("no error should happen when query with embedded struct, but got %v", err) + } else if egNews.BasePost.Title != "engadget_news" { + t.Errorf("embedded struct's value should be scanned correctly") + } +} + +func TestEmbeddedPointerTypeStruct(t *testing.T) { + type BasePost struct { + Id int64 + Title string + URL string + } + + type HNPost struct { + *BasePost + Upvotes int32 + } + + DB.Migrator().DropTable(&HNPost{}) + if err := DB.Migrator().AutoMigrate(&HNPost{}); err != nil { + t.Fatalf("failed to auto migrate, got error: %v", err) + } + + DB.Create(&HNPost{BasePost: &BasePost{Title: "embedded_pointer_type"}}) + + var hnPost HNPost + if err := DB.First(&hnPost, "title = ?", "embedded_pointer_type").Error; err != nil { + t.Errorf("No error should happen when find embedded pointer type, but got %v", err) + } + + if hnPost.Title != "embedded_pointer_type" { + t.Errorf("Should find correct value for embedded pointer type") + } +}