From a67be2a1f12503c69fa3de5d3f5a97ddec5a4025 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 23 Feb 2020 08:29:59 +0800 Subject: [PATCH] Refactor reorder migrator models --- dialects/mssql/mssql.go | 2 +- dialects/mysql/mysql.go | 2 +- go.mod | 1 - migrator/migrator.go | 55 +++++++++++++++++++---------------------- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/dialects/mssql/mssql.go b/dialects/mssql/mssql.go index ded49aae..79e36385 100644 --- a/dialects/mssql/mssql.go +++ b/dialects/mssql/mssql.go @@ -67,7 +67,7 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string { return "decimal" case schema.String: size := field.Size - if field.PrimaryKey { + if field.PrimaryKey && size == 0 { size = 256 } if size > 0 && size <= 4000 { diff --git a/dialects/mysql/mysql.go b/dialects/mysql/mysql.go index 5fcc2d69..629b89df 100644 --- a/dialects/mysql/mysql.go +++ b/dialects/mysql/mysql.go @@ -74,7 +74,7 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string { return "double" case schema.String: size := field.Size - if field.PrimaryKey { + if field.PrimaryKey && size == 0 { size = 256 } diff --git a/go.mod b/go.mod index 9046ea99..cdb7e574 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,4 @@ go 1.13 require ( github.com/jinzhu/inflection v1.0.0 github.com/jinzhu/now v1.1.1 - github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect ) diff --git a/migrator/migrator.go b/migrator/migrator.go index 4b52193f..730e8cfe 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -483,55 +483,48 @@ func (m Migrator) CurrentDatabase() (name string) { // ReorderModels reorder models according to constraint dependencies func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []interface{}) { type Dependency struct { - Table string + *gorm.Statement Depends []*schema.Schema } var ( modelNames, orderedModelNames []string orderedModelNamesMap = map[string]bool{} - valuesMap = map[string]*gorm.Statement{} - dependencies = map[string]Dependency{} - insertIntoOrderedMap func(name string) + valuesMap = map[string]Dependency{} + insertIntoOrderedList func(name string) ) - parseDependence := func(value interface{}, addToMap bool) { - stmt := &gorm.Statement{DB: m.DB, Dest: value} - stmt.Parse(value) - dep := Dependency{Table: stmt.Schema.Table} + parseDependence := func(value interface{}, addToList bool) { + dep := Dependency{ + Statement: &gorm.Statement{DB: m.DB, Dest: value}, + } + dep.Parse(value) - for _, rel := range stmt.Schema.Relationships.Relations { - if constraint := rel.ParseConstraint(); constraint != nil { - dep.Depends = append(dep.Depends, constraint.ReferenceSchema) + for _, rel := range dep.Schema.Relationships.Relations { + if c := rel.ParseConstraint(); c != nil && c.Schema != c.ReferenceSchema { + dep.Depends = append(dep.Depends, c.ReferenceSchema) } } - dependencies[stmt.Schema.Table] = dep - if addToMap { - modelNames = append(modelNames, stmt.Schema.Table) - valuesMap[stmt.Schema.Table] = stmt + valuesMap[dep.Schema.Table] = dep + + if addToList { + modelNames = append(modelNames, dep.Schema.Table) } } - for _, value := range values { - parseDependence(value, true) - } - - insertIntoOrderedMap = func(name string) { - // avoid loop + insertIntoOrderedList = func(name string) { if _, ok := orderedModelNamesMap[name]; ok { - return + return // avoid loop } - dep := dependencies[name] + dep := valuesMap[name] for _, d := range dep.Depends { if _, ok := valuesMap[d.Table]; ok { - if _, ok := orderedModelNamesMap[d.Table]; !ok && name != d.Table { - insertIntoOrderedMap(d.Table) - } + insertIntoOrderedList(d.Table) } else if 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 } + for _, value := range values { + parseDependence(value, true) + } + for _, name := range modelNames { - insertIntoOrderedMap(name) + insertIntoOrderedList(name) } for _, name := range orderedModelNames { - results = append(results, valuesMap[name].Dest) + results = append(results, valuesMap[name].Statement.Dest) } return }