123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- package schema_test
- import (
- "database/sql/driver"
- "fmt"
- "reflect"
- "strings"
- "testing"
- "github.com/jinzhu/gorm/schema"
- "github.com/jinzhu/gorm/tests"
- )
- func checkSchema(t *testing.T, s *schema.Schema, v schema.Schema, primaryFields []string) {
- t.Run("CheckSchema/"+s.Name, func(t *testing.T) {
- tests.AssertEqual(t, s, v, "Name", "Table")
- for idx, field := range primaryFields {
- var found bool
- for _, f := range s.PrimaryFields {
- if f.Name == field {
- found = true
- }
- }
- if idx == 0 {
- if field != s.PrioritizedPrimaryField.Name {
- t.Errorf("schema %v prioritized primary field should be %v, but got %v", s, field, s.PrioritizedPrimaryField.Name)
- }
- }
- if !found {
- t.Errorf("schema %v failed to found priamry key: %v", s, field)
- }
- }
- })
- }
- func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(*schema.Field)) {
- t.Run("CheckField/"+f.Name, func(t *testing.T) {
- if fc != nil {
- fc(f)
- }
- if f.TagSettings == nil {
- if f.Tag != "" {
- f.TagSettings = schema.ParseTagSetting(f.Tag.Get("gorm"), ";")
- } else {
- f.TagSettings = map[string]string{}
- }
- }
- if parsedField, ok := s.FieldsByName[f.Name]; !ok {
- t.Errorf("schema %v failed to look up field with name %v", s, f.Name)
- } else {
- tests.AssertEqual(t, parsedField, f, "Name", "DBName", "BindNames", "DataType", "DBDataType", "PrimaryKey", "AutoIncrement", "Creatable", "Updatable", "HasDefaultValue", "DefaultValue", "NotNull", "Unique", "Comment", "Size", "Precision", "Tag", "TagSettings")
- if field, ok := s.FieldsByDBName[f.DBName]; !ok || parsedField != field {
- t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName)
- }
- for _, name := range []string{f.DBName, f.Name} {
- if field := s.LookUpField(name); field == nil || parsedField != field {
- t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName)
- }
- }
- if f.PrimaryKey {
- var found bool
- for _, primaryField := range s.PrimaryFields {
- if primaryField == parsedField {
- found = true
- }
- }
- if !found {
- t.Errorf("schema %v doesn't include field %v", s, f.Name)
- }
- }
- }
- })
- }
- type Relation struct {
- Name string
- Type schema.RelationshipType
- Schema string
- FieldSchema string
- Polymorphic Polymorphic
- JoinTable JoinTable
- References []Reference
- }
- type Polymorphic struct {
- ID string
- Type string
- Value string
- }
- type JoinTable struct {
- Name string
- Table string
- Fields []schema.Field
- }
- type Reference struct {
- PrimaryKey string
- PrimarySchema string
- ForeignKey string
- ForeignSchema string
- PrimaryValue string
- OwnPrimaryKey bool
- }
- func checkSchemaRelation(t *testing.T, s *schema.Schema, relation Relation) {
- t.Run("CheckRelation/"+relation.Name, func(t *testing.T) {
- if r, ok := s.Relationships.Relations[relation.Name]; ok {
- if r.Name != relation.Name {
- t.Errorf("schema %v relation name expects %v, but got %v", s, r.Name, relation.Name)
- }
- if r.Type != relation.Type {
- t.Errorf("schema %v relation name expects %v, but got %v", s, r.Type, relation.Type)
- }
- if r.Schema.Name != relation.Schema {
- t.Errorf("schema %v relation's schema expects %v, but got %v", s, relation.Schema, r.Schema.Name)
- }
- if r.FieldSchema.Name != relation.FieldSchema {
- t.Errorf("schema %v relation's schema expects %v, but got %v", s, relation.Schema, r.Schema.Name)
- }
- if r.Polymorphic != nil {
- if r.Polymorphic.PolymorphicID.Name != relation.Polymorphic.ID {
- t.Errorf("schema %v relation's polymorphic id field expects %v, but got %v", s, relation.Polymorphic.ID, r.Polymorphic.PolymorphicID.Name)
- }
- if r.Polymorphic.PolymorphicType.Name != relation.Polymorphic.Type {
- t.Errorf("schema %v relation's polymorphic type field expects %v, but got %v", s, relation.Polymorphic.Type, r.Polymorphic.PolymorphicType.Name)
- }
- if r.Polymorphic.Value != relation.Polymorphic.Value {
- t.Errorf("schema %v relation's polymorphic value expects %v, but got %v", s, relation.Polymorphic.Value, r.Polymorphic.Value)
- }
- }
- if r.JoinTable != nil {
- if r.JoinTable.Name != relation.JoinTable.Name {
- t.Errorf("schema %v relation's join table name expects %v, but got %v", s, relation.JoinTable.Name, r.JoinTable.Name)
- }
- if r.JoinTable.Table != relation.JoinTable.Table {
- t.Errorf("schema %v relation's join table tablename expects %v, but got %v", s, relation.JoinTable.Table, r.JoinTable.Table)
- }
- for _, f := range relation.JoinTable.Fields {
- checkSchemaField(t, r.JoinTable, &f, nil)
- }
- }
- if len(relation.References) != len(r.References) {
- t.Errorf("schema %v relation's reference's count doesn't match, expects %v, but got %v", s, len(relation.References), len(r.References))
- }
- for _, ref := range relation.References {
- var found bool
- for _, rf := range r.References {
- if (rf.PrimaryKey == nil || (rf.PrimaryKey.Name == ref.PrimaryKey && rf.PrimaryKey.Schema.Name == ref.PrimarySchema)) && (rf.PrimaryValue == ref.PrimaryValue) && (rf.ForeignKey.Name == ref.ForeignKey && rf.ForeignKey.Schema.Name == ref.ForeignSchema) && (rf.OwnPrimaryKey == ref.OwnPrimaryKey) {
- found = true
- }
- }
- if !found {
- var refs []string
- for _, rf := range r.References {
- var primaryKey, primaryKeySchema string
- if rf.PrimaryKey != nil {
- primaryKey, primaryKeySchema = rf.PrimaryKey.Name, rf.PrimaryKey.Schema.Name
- }
- refs = append(refs, fmt.Sprintf(
- "{PrimaryKey: %v PrimaryKeySchame: %v ForeignKey: %v ForeignKeySchema: %v PrimaryValue: %v OwnPrimaryKey: %v}",
- primaryKey, primaryKeySchema, rf.ForeignKey.Name, rf.ForeignKey.Schema.Name, rf.PrimaryValue, rf.OwnPrimaryKey,
- ))
- }
- t.Errorf("schema %v relation %v failed to found reference %+v, has %v", s, relation.Name, ref, strings.Join(refs, ", "))
- }
- }
- } else {
- t.Errorf("schema %v failed to find relations by name %v", s, relation.Name)
- }
- })
- }
- func checkField(t *testing.T, s *schema.Schema, value reflect.Value, values map[string]interface{}) {
- for k, v := range values {
- t.Run("CheckField/"+k, func(t *testing.T) {
- var (
- checker func(fv interface{}, v interface{})
- field = s.FieldsByDBName[k]
- fv, _ = field.ValueOf(value)
- )
- checker = func(fv interface{}, v interface{}) {
- if reflect.ValueOf(fv).Type() == reflect.ValueOf(v).Type() && fv != v {
- t.Errorf("expects: %p, but got %p", v, fv)
- } else if reflect.ValueOf(v).Type().ConvertibleTo(reflect.ValueOf(fv).Type()) {
- if reflect.ValueOf(v).Convert(reflect.ValueOf(fv).Type()).Interface() != fv {
- t.Errorf("expects: %p, but got %p", v, fv)
- }
- } else if reflect.ValueOf(fv).Type().ConvertibleTo(reflect.ValueOf(v).Type()) {
- if reflect.ValueOf(fv).Convert(reflect.ValueOf(fv).Type()).Interface() != v {
- t.Errorf("expects: %p, but got %p", v, fv)
- }
- } else if valuer, isValuer := fv.(driver.Valuer); isValuer {
- valuerv, _ := valuer.Value()
- checker(valuerv, v)
- } else if valuer, isValuer := v.(driver.Valuer); isValuer {
- valuerv, _ := valuer.Value()
- checker(fv, valuerv)
- } else if reflect.ValueOf(fv).Kind() == reflect.Ptr {
- checker(reflect.ValueOf(fv).Elem().Interface(), v)
- } else if reflect.ValueOf(v).Kind() == reflect.Ptr {
- checker(fv, reflect.ValueOf(v).Elem().Interface())
- } else {
- t.Errorf("expects: %+v, but got %+v", v, fv)
- }
- }
- checker(fv, v)
- })
- }
- }
|