feat(schema) test self-reference belongs to
This commit is contained in:
parent
3c9dee889f
commit
6e6b40fb0d
@ -2,11 +2,6 @@ package schema
|
||||
|
||||
import "testing"
|
||||
|
||||
type BelongsTo struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
|
||||
type HasOne struct {
|
||||
ID int
|
||||
MyStructID uint
|
||||
@ -24,13 +19,94 @@ type Many2Many struct {
|
||||
}
|
||||
|
||||
func TestBelongsToRel(t *testing.T) {
|
||||
type BelongsTo struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
|
||||
type MyStruct struct {
|
||||
ID int
|
||||
Name string
|
||||
BelongsToID uint
|
||||
BelongsTo BelongsTo
|
||||
}
|
||||
|
||||
Parse(&MyStruct{})
|
||||
schema := Parse(&MyStruct{})
|
||||
compareFields(schema.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_id", Name: "BelongsToID", BindNames: []string{"BelongsToID"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_id"}, AssociationForeignKey: []string{"id"}}},
|
||||
}, t)
|
||||
|
||||
type MyStruct2 struct {
|
||||
ID int `gorm:"column:my_id"`
|
||||
Name string
|
||||
BelongsToKey uint
|
||||
BelongsTo BelongsTo `gorm:"foreignkey:BelongsToKey"`
|
||||
}
|
||||
|
||||
schema2 := Parse(&MyStruct2{})
|
||||
compareFields(schema2.Fields, []*Field{
|
||||
{DBName: "my_id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true, TagSettings: map[string]string{"COLUMN": "my_id"}},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_key", Name: "BelongsToKey", BindNames: []string{"BelongsToKey"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_key"}, AssociationForeignKey: []string{"id"}}, TagSettings: map[string]string{"FOREIGNKEY": "BelongsToKey"}},
|
||||
}, t)
|
||||
|
||||
type BelongsTo3 struct {
|
||||
ID int `gorm:"column:my_id"`
|
||||
Name string
|
||||
}
|
||||
|
||||
type MyStruct3 struct {
|
||||
ID int
|
||||
Name string
|
||||
BelongsToKey uint
|
||||
BelongsTo BelongsTo3 `gorm:"foreignkey:BelongsToKey"`
|
||||
}
|
||||
|
||||
schema3 := Parse(&MyStruct3{})
|
||||
compareFields(schema3.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_key", Name: "BelongsToKey", BindNames: []string{"BelongsToKey"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_key"}, AssociationForeignKey: []string{"my_id"}}, TagSettings: map[string]string{"FOREIGNKEY": "BelongsToKey"}},
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestSelfReferenceBelongsToRel(t *testing.T) {
|
||||
type MyStruct struct {
|
||||
ID int
|
||||
Name string
|
||||
BelongsToID int
|
||||
BelongsTo *MyStruct
|
||||
}
|
||||
|
||||
// user1 belongs to user2, when creating, will create user2 first
|
||||
schema := Parse(&MyStruct{})
|
||||
compareFields(schema.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_id", Name: "BelongsToID", BindNames: []string{"BelongsToID"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_id"}, AssociationForeignKey: []string{"id"}}},
|
||||
}, t)
|
||||
|
||||
type MyStruct2 struct {
|
||||
ID int
|
||||
Name string
|
||||
BelongsToKey int
|
||||
BelongsTo *MyStruct2 `gorm:"rel:belongs_to;foreignkey:BelongsToKey"`
|
||||
}
|
||||
|
||||
// user1 belongs to user2, when creating, will create user2 first
|
||||
schema2 := Parse(&MyStruct2{})
|
||||
compareFields(schema2.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_key", Name: "BelongsToKey", BindNames: []string{"BelongsToKey"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_key"}, AssociationForeignKey: []string{"id"}}, TagSettings: map[string]string{"FOREIGNKEY": "BelongsToKey"}},
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestHasOneRel(t *testing.T) {
|
||||
@ -43,6 +119,46 @@ func TestHasOneRel(t *testing.T) {
|
||||
Parse(&MyStruct{})
|
||||
}
|
||||
|
||||
func TestSelfReferenceHasOneRel(t *testing.T) {
|
||||
type MyStruct struct {
|
||||
ID int
|
||||
Name string
|
||||
BelongsToID int
|
||||
BelongsTo *MyStruct
|
||||
}
|
||||
|
||||
// user1 belongs to user2, when creating, will create user2 first
|
||||
schema := Parse(&MyStruct{})
|
||||
compareFields(schema.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "belongs_to_id", Name: "BelongsToID", BindNames: []string{"BelongsToID"}, IsNormal: true, IsForeignKey: true},
|
||||
{DBName: "belongs_to", Name: "BelongsTo", BindNames: []string{"BelongsTo"}, Relationship: &Relationship{Kind: "belongs_to", ForeignKey: []string{"belongs_to_id"}, AssociationForeignKey: []string{"id"}}},
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestPolymorphicHasOneRel(t *testing.T) {
|
||||
type HasOne struct {
|
||||
ID int
|
||||
Name string
|
||||
OwnerType string
|
||||
OwnerID string
|
||||
}
|
||||
|
||||
type MyStruct struct {
|
||||
ID int
|
||||
Name string
|
||||
HasOne HasOne `gorm:"polymorphic:Owner"`
|
||||
}
|
||||
|
||||
schema := Parse(&MyStruct{})
|
||||
compareFields(schema.Fields, []*Field{
|
||||
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||
{DBName: "name", Name: "Name", BindNames: []string{"Name"}, IsNormal: true},
|
||||
{DBName: "has_one", Name: "HasOne", BindNames: []string{"HasOne"}, Relationship: &Relationship{Kind: "has_one", PolymorphicType: "OwnerType", PolymorphicDBName: "owner_type", PolymorphicValue: "my_struct", ForeignKey: []string{"owner_id"}, AssociationForeignKey: []string{"id"}}, TagSettings: map[string]string{"POLYMORPHIC": "Owner"}},
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestHasManyRel(t *testing.T) {
|
||||
type MyStruct struct {
|
||||
ID int
|
||||
@ -62,4 +178,3 @@ func TestManyToManyRel(t *testing.T) {
|
||||
|
||||
Parse(&MyStruct{})
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,13 @@ import (
|
||||
"go/ast"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var schemaMap = sync.Map{}
|
||||
|
||||
// Schema model schema definition
|
||||
type Schema struct {
|
||||
ModelType reflect.Type
|
||||
@ -48,6 +52,10 @@ func Parse(dest interface{}) *Schema {
|
||||
return nil
|
||||
}
|
||||
|
||||
if m, ok := schemaMap.Load(reflectType); ok {
|
||||
return m.(*Schema)
|
||||
}
|
||||
|
||||
schema.ModelType = reflectType
|
||||
onConflictFields := map[string]int{}
|
||||
|
||||
@ -221,12 +229,16 @@ func Parse(dest interface{}) *Schema {
|
||||
}
|
||||
|
||||
if len(schema.PrimaryFields) == 0 {
|
||||
if field := getSchemaField("id", schema.Fields); field != nil {
|
||||
for _, field := range schema.Fields {
|
||||
if strings.ToUpper(field.Name) == "ID" || field.DBName == "id" {
|
||||
field.IsPrimaryKey = true
|
||||
schema.PrimaryFields = append(schema.PrimaryFields, field)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
schemaMap.Store(reflectType, &schema)
|
||||
return &schema
|
||||
}
|
||||
|
||||
|
@ -293,5 +293,9 @@ func fieldEqual(got, expected *Field) error {
|
||||
if expected.HasDefaultValue != got.HasDefaultValue {
|
||||
return fmt.Errorf("field HasDefaultValue should be %v, got %v", expected.HasDefaultValue, got.HasDefaultValue)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Relationship, got.Relationship) {
|
||||
return fmt.Errorf("field Relationship should be %#v, got %#v", expected.Relationship, got.Relationship)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user