Refactor reorder migrator models

This commit is contained in:
Jinzhu 2020-02-23 08:29:59 +08:00
parent 1d803dfdd9
commit a67be2a1f1
4 changed files with 28 additions and 32 deletions

View File

@ -67,7 +67,7 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string {
return "decimal" return "decimal"
case schema.String: case schema.String:
size := field.Size size := field.Size
if field.PrimaryKey { if field.PrimaryKey && size == 0 {
size = 256 size = 256
} }
if size > 0 && size <= 4000 { if size > 0 && size <= 4000 {

View File

@ -74,7 +74,7 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string {
return "double" return "double"
case schema.String: case schema.String:
size := field.Size size := field.Size
if field.PrimaryKey { if field.PrimaryKey && size == 0 {
size = 256 size = 256
} }

1
go.mod
View File

@ -5,5 +5,4 @@ go 1.13
require ( require (
github.com/jinzhu/inflection v1.0.0 github.com/jinzhu/inflection v1.0.0
github.com/jinzhu/now v1.1.1 github.com/jinzhu/now v1.1.1
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
) )

View File

@ -483,55 +483,48 @@ func (m Migrator) CurrentDatabase() (name string) {
// ReorderModels reorder models according to constraint dependencies // ReorderModels reorder models according to constraint dependencies
func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []interface{}) { func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []interface{}) {
type Dependency struct { type Dependency struct {
Table string *gorm.Statement
Depends []*schema.Schema Depends []*schema.Schema
} }
var ( var (
modelNames, orderedModelNames []string modelNames, orderedModelNames []string
orderedModelNamesMap = map[string]bool{} orderedModelNamesMap = map[string]bool{}
valuesMap = map[string]*gorm.Statement{} valuesMap = map[string]Dependency{}
dependencies = map[string]Dependency{} insertIntoOrderedList func(name string)
insertIntoOrderedMap func(name string)
) )
parseDependence := func(value interface{}, addToMap bool) { parseDependence := func(value interface{}, addToList bool) {
stmt := &gorm.Statement{DB: m.DB, Dest: value} dep := Dependency{
stmt.Parse(value) Statement: &gorm.Statement{DB: m.DB, Dest: value},
dep := Dependency{Table: stmt.Schema.Table} }
dep.Parse(value)
for _, rel := range stmt.Schema.Relationships.Relations { for _, rel := range dep.Schema.Relationships.Relations {
if constraint := rel.ParseConstraint(); constraint != nil { if c := rel.ParseConstraint(); c != nil && c.Schema != c.ReferenceSchema {
dep.Depends = append(dep.Depends, constraint.ReferenceSchema) dep.Depends = append(dep.Depends, c.ReferenceSchema)
} }
} }
dependencies[stmt.Schema.Table] = dep
if addToMap { valuesMap[dep.Schema.Table] = dep
modelNames = append(modelNames, stmt.Schema.Table)
valuesMap[stmt.Schema.Table] = stmt if addToList {
modelNames = append(modelNames, dep.Schema.Table)
} }
} }
for _, value := range values { insertIntoOrderedList = func(name string) {
parseDependence(value, true)
}
insertIntoOrderedMap = func(name string) {
// avoid loop
if _, ok := orderedModelNamesMap[name]; ok { if _, ok := orderedModelNamesMap[name]; ok {
return return // avoid loop
} }
dep := dependencies[name] dep := valuesMap[name]
for _, d := range dep.Depends { for _, d := range dep.Depends {
if _, ok := valuesMap[d.Table]; ok { if _, ok := valuesMap[d.Table]; ok {
if _, ok := orderedModelNamesMap[d.Table]; !ok && name != d.Table { insertIntoOrderedList(d.Table)
insertIntoOrderedMap(d.Table)
}
} else if autoAdd { } else if autoAdd {
parseDependence(reflect.New(d.ModelType).Interface(), autoAdd) parseDependence(reflect.New(d.ModelType).Interface(), autoAdd)
insertIntoOrderedMap(d.Table) insertIntoOrderedList(d.Table)
} }
} }
@ -539,12 +532,16 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i
orderedModelNamesMap[name] = true orderedModelNamesMap[name] = true
} }
for _, value := range values {
parseDependence(value, true)
}
for _, name := range modelNames { for _, name := range modelNames {
insertIntoOrderedMap(name) insertIntoOrderedList(name)
} }
for _, name := range orderedModelNames { for _, name := range orderedModelNames {
results = append(results, valuesMap[name].Dest) results = append(results, valuesMap[name].Statement.Dest)
} }
return return
} }