From bce40e6d6a16c3c5775f036425feec9fc6d039d5 Mon Sep 17 00:00:00 2001 From: yrong1997 Date: Sun, 31 Jan 2021 13:39:00 +0800 Subject: [PATCH 01/10] Add field tag to ignore migration --- .gitignore | 1 + migrator/migrator.go | 2 +- schema/field.go | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c14d600500..e1b9ecea1b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ TODO* documents coverage.txt _book +.idea diff --git a/migrator/migrator.go b/migrator/migrator.go index 91dd8e830c..4e5051cf3c 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -396,7 +396,7 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy } } - if alterColumn { + if alterColumn && !field.IgnoreMigration { return m.DB.Migrator().AlterColumn(value, field.Name) } diff --git a/schema/field.go b/schema/field.go index 17cc6c4342..77c0b47a54 100644 --- a/schema/field.go +++ b/schema/field.go @@ -70,6 +70,7 @@ type Field struct { ReflectValueOf func(reflect.Value) reflect.Value ValueOf func(reflect.Value) (value interface{}, zero bool) Set func(reflect.Value, interface{}) error + IgnoreMigration bool } func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { @@ -188,6 +189,10 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } + if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { + field.IgnoreMigration = true + } + // default value is function or null or blank (primary keys) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && strings.Contains(field.DefaultValue, ")") || strings.ToLower(field.DefaultValue) == "null" || field.DefaultValue == "" From 4a1096bcff22a37fb91fd86816c142d32b8eb513 Mon Sep 17 00:00:00 2001 From: yrong Date: Sat, 6 Feb 2021 11:29:34 +0800 Subject: [PATCH 02/10] Fix null value with space --- schema/field.go | 1 + 1 file changed, 1 insertion(+) diff --git a/schema/field.go b/schema/field.go index 77c0b47a54..23dcd82fd8 100644 --- a/schema/field.go +++ b/schema/field.go @@ -194,6 +194,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { } // default value is function or null or blank (primary keys) + field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && strings.Contains(field.DefaultValue, ")") || strings.ToLower(field.DefaultValue) == "null" || field.DefaultValue == "" switch reflect.Indirect(fieldValue).Kind() { From 8771f3c27c1fb73b4b1a21cf706f6d81819b9f41 Mon Sep 17 00:00:00 2001 From: yrong Date: Tue, 9 Feb 2021 15:48:39 +0800 Subject: [PATCH 03/10] refactor migration tag --- schema/field.go | 26 +++++++++++++++++--------- tests/migrate_test.go | 22 ++++++++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/schema/field.go b/schema/field.go index 23dcd82fd8..5e792ed171 100644 --- a/schema/field.go +++ b/schema/field.go @@ -189,10 +189,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } - if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { - field.IgnoreMigration = true - } - // default value is function or null or blank (primary keys) field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && @@ -301,11 +297,23 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { } // setup permission - if _, ok := field.TagSettings["-"]; ok { - field.Creatable = false - field.Updatable = false - field.Readable = false - field.DataType = "" + if val, ok := field.TagSettings["-"]; ok { + val = strings.ToLower(strings.TrimSpace(val)) + switch val { + case "-": + field.Creatable = false + field.Updatable = false + field.Readable = false + field.DataType = "" + case "all": + field.Creatable = false + field.Updatable = false + field.Readable = false + field.DataType = "" + field.IgnoreMigration = true + case "migration": + field.IgnoreMigration = true + } } if v, ok := field.TagSettings["->"]; ok { diff --git a/tests/migrate_test.go b/tests/migrate_test.go index ca28dfbcb9..51843062b9 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -62,10 +62,11 @@ func TestSmartMigrateColumn(t *testing.T) { DB.AutoMigrate(&UserMigrateColumn{}) type UserMigrateColumn2 struct { - ID uint - Name string `gorm:"size:128"` - Salary float64 `gorm:"precision:2"` - Birthday time.Time `gorm:"precision:2"` + ID uint + Name string `gorm:"size:128"` + Salary float64 `gorm:"precision:2"` + Birthday time.Time `gorm:"precision:2"` + NameIgnoreMigration string `gorm:"size:100"` } if err := DB.Table("user_migrate_columns").AutoMigrate(&UserMigrateColumn2{}); err != nil { @@ -95,10 +96,11 @@ func TestSmartMigrateColumn(t *testing.T) { } type UserMigrateColumn3 struct { - ID uint - Name string `gorm:"size:256"` - Salary float64 `gorm:"precision:3"` - Birthday time.Time `gorm:"precision:3"` + ID uint + Name string `gorm:"size:256"` + Salary float64 `gorm:"precision:3"` + Birthday time.Time `gorm:"precision:3"` + NameIgnoreMigration string `gorm:"size:128;-:migration"` } if err := DB.Table("user_migrate_columns").AutoMigrate(&UserMigrateColumn3{}); err != nil { @@ -124,6 +126,10 @@ func TestSmartMigrateColumn(t *testing.T) { if precision, _, _ := columnType.DecimalSize(); (fullSupported || precision != 0) && precision != 3 { t.Fatalf("birthday's precision should be 2, but got %v", precision) } + case "name_ignore_migration": + if length, _ := columnType.Length(); (fullSupported || length != 0) && length != 100 { + t.Fatalf("name_ignore_migration's length should still be 100 but got %v", length) + } } } From fca7a9c3e881cba3f7dabc963afcffc9933edb12 Mon Sep 17 00:00:00 2001 From: yrong1997 Date: Sun, 31 Jan 2021 13:39:00 +0800 Subject: [PATCH 04/10] Add field tag to ignore migration --- schema/field.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schema/field.go b/schema/field.go index ce0e3c130f..8cca578817 100644 --- a/schema/field.go +++ b/schema/field.go @@ -189,6 +189,10 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } + if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { + field.IgnoreMigration = true + } + // default value is function or null or blank (primary keys) field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && From e62a53b23db3f8b5fac31ffcf90fb505080eaa32 Mon Sep 17 00:00:00 2001 From: yrong Date: Tue, 9 Feb 2021 15:48:39 +0800 Subject: [PATCH 05/10] refactor migration tag --- schema/field.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/schema/field.go b/schema/field.go index 8cca578817..ce0e3c130f 100644 --- a/schema/field.go +++ b/schema/field.go @@ -189,10 +189,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } - if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { - field.IgnoreMigration = true - } - // default value is function or null or blank (primary keys) field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && From 14a8ccddea8f4a86cfdf5ed33164ecb6ee490536 Mon Sep 17 00:00:00 2001 From: Mitt <10653144+MittWillson@users.noreply.github.com> Date: Mon, 27 Sep 2021 19:09:56 +0800 Subject: [PATCH 06/10] fix: temp remove Pluck table name condition --- finisher_api.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/finisher_api.go b/finisher_api.go index 34e1596bb7..061a3e9cf5 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -483,8 +483,6 @@ func (db *DB) Pluck(column string, dest interface{}) (tx *DB) { column = f.DBName } } - } else if tx.Statement.Table == "" { - tx.AddError(ErrModelValueRequired) } if len(tx.Statement.Selects) != 1 { From 551393aa4eafecdca4f3fdbbc7765e0391ef5d8d Mon Sep 17 00:00:00 2001 From: Mitt <10653144+MittWillson@users.noreply.github.com> Date: Tue, 28 Sep 2021 10:35:07 +0800 Subject: [PATCH 07/10] feat: add ignoreMigration support for ParseField --- schema/field.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schema/field.go b/schema/field.go index ce0e3c130f..8cca578817 100644 --- a/schema/field.go +++ b/schema/field.go @@ -189,6 +189,10 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } + if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { + field.IgnoreMigration = true + } + // default value is function or null or blank (primary keys) field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && From 7cf93c47303384ec9b1adf6ff145c223f48dcd86 Mon Sep 17 00:00:00 2001 From: Mitt <10653144+MittWillson@users.noreply.github.com> Date: Tue, 28 Sep 2021 15:21:06 +0800 Subject: [PATCH 08/10] Revert "feat: add ignoreMigration support for ParseField" This reverts commit 551393aa4eafecdca4f3fdbbc7765e0391ef5d8d. --- schema/field.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/schema/field.go b/schema/field.go index 8cca578817..ce0e3c130f 100644 --- a/schema/field.go +++ b/schema/field.go @@ -189,10 +189,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { field.Comment = val } - if _, ok := field.TagSettings["IGNOREMIGRATION"]; ok { - field.IgnoreMigration = true - } - // default value is function or null or blank (primary keys) field.DefaultValue = strings.TrimSpace(field.DefaultValue) skipParseDefaultValue := strings.Contains(field.DefaultValue, "(") && From c3db379c901140acaeb75c730fec16e661fdcfb6 Mon Sep 17 00:00:00 2001 From: Mitt <10653144+MittWillson@users.noreply.github.com> Date: Tue, 28 Sep 2021 15:35:34 +0800 Subject: [PATCH 09/10] feat: Safety option for skip column changes --- gorm.go | 2 ++ migrator/migrator.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gorm.go b/gorm.go index 7f7bad2628..8369503b5c 100644 --- a/gorm.go +++ b/gorm.go @@ -39,6 +39,8 @@ type Config struct { DisableForeignKeyConstraintWhenMigrating bool // DisableNestedTransaction disable nested transaction DisableNestedTransaction bool + // SafetyAutoMigration disable columns alter when it exists + SafetyAutoMigration bool // AllowGlobalUpdate allow global update AllowGlobalUpdate bool // QueryFields executes the SQL query with all fields of the table diff --git a/migrator/migrator.go b/migrator/migrator.go index 48db151e07..4bf438a08c 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -112,6 +112,8 @@ func (m Migrator) AutoMigrate(values ...interface{}) error { if err := tx.Migrator().AddColumn(value, field.DBName); err != nil { return err } + } else if m.DB.SafetyAutoMigration { + // skip MigrationColumn } else if err := m.DB.Migrator().MigrateColumn(value, field, foundColumn); err != nil { // found, smart migrate return err From 4cafbc3dc8384634afd9f9399f0d3912ce4224b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 06:57:34 +0000 Subject: [PATCH 10/10] chore(deps): bump gorm.io/driver/postgres from 1.3.10 to 1.5.0 in /tests Bumps [gorm.io/driver/postgres](https://github.com/go-gorm/postgres) from 1.3.10 to 1.5.0. - [Release notes](https://github.com/go-gorm/postgres/releases) - [Commits](https://github.com/go-gorm/postgres/compare/v1.3.10...v1.5.0) --- updated-dependencies: - dependency-name: gorm.io/driver/postgres dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/go.mod | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index ebebabc0bc..aca525b0ed 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -9,12 +9,11 @@ require ( github.com/jinzhu/now v1.1.5 github.com/lib/pq v1.10.7 github.com/mattn/go-sqlite3 v1.14.15 // indirect - golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 // indirect gorm.io/driver/mysql v1.3.6 - gorm.io/driver/postgres v1.3.10 + gorm.io/driver/postgres v1.5.0 gorm.io/driver/sqlite v1.3.6 gorm.io/driver/sqlserver v1.3.2 - gorm.io/gorm v1.23.9 + gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 ) replace gorm.io/gorm => ../