feat(schema) test self-reference belongs to
This commit is contained in:
parent
3c9dee889f
commit
6e6b40fb0d
@ -2,11 +2,6 @@ package schema
|
|||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
type BelongsTo struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type HasOne struct {
|
type HasOne struct {
|
||||||
ID int
|
ID int
|
||||||
MyStructID uint
|
MyStructID uint
|
||||||
@ -24,13 +19,94 @@ type Many2Many struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBelongsToRel(t *testing.T) {
|
func TestBelongsToRel(t *testing.T) {
|
||||||
type MyStruct struct {
|
type BelongsTo struct {
|
||||||
ID int
|
ID int
|
||||||
Name string
|
Name string
|
||||||
BelongsTo BelongsTo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Parse(&MyStruct{})
|
type MyStruct struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
BelongsToID uint
|
||||||
|
BelongsTo BelongsTo
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func TestHasOneRel(t *testing.T) {
|
||||||
@ -43,6 +119,46 @@ func TestHasOneRel(t *testing.T) {
|
|||||||
Parse(&MyStruct{})
|
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) {
|
func TestHasManyRel(t *testing.T) {
|
||||||
type MyStruct struct {
|
type MyStruct struct {
|
||||||
ID int
|
ID int
|
||||||
@ -62,4 +178,3 @@ func TestManyToManyRel(t *testing.T) {
|
|||||||
|
|
||||||
Parse(&MyStruct{})
|
Parse(&MyStruct{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,13 @@ import (
|
|||||||
"go/ast"
|
"go/ast"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var schemaMap = sync.Map{}
|
||||||
|
|
||||||
// Schema model schema definition
|
// Schema model schema definition
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
ModelType reflect.Type
|
ModelType reflect.Type
|
||||||
@ -48,6 +52,10 @@ func Parse(dest interface{}) *Schema {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m, ok := schemaMap.Load(reflectType); ok {
|
||||||
|
return m.(*Schema)
|
||||||
|
}
|
||||||
|
|
||||||
schema.ModelType = reflectType
|
schema.ModelType = reflectType
|
||||||
onConflictFields := map[string]int{}
|
onConflictFields := map[string]int{}
|
||||||
|
|
||||||
@ -221,12 +229,16 @@ func Parse(dest interface{}) *Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(schema.PrimaryFields) == 0 {
|
if len(schema.PrimaryFields) == 0 {
|
||||||
if field := getSchemaField("id", schema.Fields); field != nil {
|
for _, field := range schema.Fields {
|
||||||
field.IsPrimaryKey = true
|
if strings.ToUpper(field.Name) == "ID" || field.DBName == "id" {
|
||||||
schema.PrimaryFields = append(schema.PrimaryFields, field)
|
field.IsPrimaryKey = true
|
||||||
|
schema.PrimaryFields = append(schema.PrimaryFields, field)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schemaMap.Store(reflectType, &schema)
|
||||||
return &schema
|
return &schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,5 +293,9 @@ func fieldEqual(got, expected *Field) error {
|
|||||||
if expected.HasDefaultValue != got.HasDefaultValue {
|
if expected.HasDefaultValue != got.HasDefaultValue {
|
||||||
return fmt.Errorf("field HasDefaultValue should be %v, got %v", 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
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user