From 08786898ed9d418cdbff80d3d8833715fd520042 Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Tue, 15 Mar 2022 18:52:57 +0200 Subject: [PATCH 1/6] dialect/sql: without foreign key option for atlas --- dialect/sql/schema/atlas.go | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index a4d68960a9..bb925b9b7c 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -23,7 +23,7 @@ import ( type ( // Differ is the interface that wraps the Diff method. Differ interface { - // Diff creates the given tables in the database. + // Diff returns a list of changes that construct a migration plan. Diff(current, desired *schema.Schema) ([]schema.Change, error) } @@ -98,7 +98,7 @@ const ( DropCheck ) -// Is reports whether c is match the given change king. +// Is reports whether c is match the given change kind. func (k ChangeKind) Is(c ChangeKind) bool { return k == c || k&c != 0 } @@ -159,7 +159,7 @@ func filterChanges(skip ChangeKind) DiffHook { keep = append(keep, c) } } - return + return keep } changes, err := next.Diff(current, desired) if err != nil { @@ -170,6 +170,26 @@ func filterChanges(skip ChangeKind) DiffHook { } } +func withoutForeignKeys(next Differ) Differ { + return DiffFunc(func(current, desired *schema.Schema) ([]schema.Change, error) { + changes, err := next.Diff(current, desired) + if err != nil { + return nil, err + } + for _, c := range changes { + switch c := c.(type) { + case *schema.AddTable: + c.T.ForeignKeys = nil + case *schema.DropTable: + c.T.ForeignKeys = nil + case *schema.ModifyTable: + c.T.ForeignKeys = nil + } + } + return changes, nil + }) +} + type ( // Applier is the interface that wraps the Apply method. Applier interface { @@ -267,9 +287,6 @@ func (m *Migrate) setupAtlas() error { if !m.atlas.enabled { return nil } - if !m.withForeignKeys { - return errors.New("sql/schema: WithForeignKeys(false) does not work in Atlas migration") - } if m.withFixture { return errors.New("sql/schema: WithFixture(true) does not work in Atlas migration") } @@ -286,6 +303,9 @@ func (m *Migrate) setupAtlas() error { if skip != NoChange { m.atlas.diff = append(m.atlas.diff, filterChanges(skip)) } + if !m.withForeignKeys { + m.atlas.diff = append(m.atlas.diff, withoutForeignKeys) + } if m.atlas.dir != nil && m.atlas.fmt == nil { m.atlas.fmt = migrate.DefaultFormatter } From a6d55c900f27a0abe66b33e5a1a477ca13479a1c Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Wed, 16 Mar 2022 14:28:06 +0200 Subject: [PATCH 2/6] handle fks in modifytables --- dialect/sql/schema/atlas.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index bb925b9b7c..e90902b111 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -184,6 +184,14 @@ func withoutForeignKeys(next Differ) Differ { c.T.ForeignKeys = nil case *schema.ModifyTable: c.T.ForeignKeys = nil + for _, change := range c.Changes { + switch change.(type) { + case *schema.AddForeignKey, + *schema.DropForeignKey, + *schema.ModifyForeignKey: + change = nil + } + } } } return changes, nil From dc5318dc6be153aad46fe522a61fe433cafd85f9 Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Wed, 16 Mar 2022 15:59:33 +0200 Subject: [PATCH 3/6] add tests --- dialect/sql/schema/atlas.go | 4 ++ dialect/sql/schema/migrate_test.go | 74 ++++++++++++++++++++++++++++++ go.mod | 2 - go.sum | 5 -- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index e90902b111..10ae71fd49 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -184,14 +184,18 @@ func withoutForeignKeys(next Differ) Differ { c.T.ForeignKeys = nil case *schema.ModifyTable: c.T.ForeignKeys = nil + nChanges := make([]schema.Change, 0, len(c.Changes)) for _, change := range c.Changes { switch change.(type) { case *schema.AddForeignKey, *schema.DropForeignKey, *schema.ModifyForeignKey: change = nil + default: + nChanges = append(nChanges, change) } } + return nChanges, nil } } return changes, nil diff --git a/dialect/sql/schema/migrate_test.go b/dialect/sql/schema/migrate_test.go index f3fc0c7d02..23eab285b4 100644 --- a/dialect/sql/schema/migrate_test.go +++ b/dialect/sql/schema/migrate_test.go @@ -13,6 +13,8 @@ import ( "time" "ariga.io/atlas/sql/migrate" + "ariga.io/atlas/sql/schema" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "github.com/DATA-DOG/go-sqlmock" @@ -90,3 +92,75 @@ func requireFileEqual(t *testing.T, name, contents string) { require.NoError(t, err) require.Equal(t, contents, string(c)) } + +func TestMigrateWithoutForeignKeys(t *testing.T) { + tbl := &schema.Table{ + Name: "tbl", + Columns: []*schema.Column{ + {Name: "id", Type: &schema.ColumnType{Type: &schema.IntegerType{T: "bigint"}}}, + }, + } + fk := &schema.ForeignKey{ + Symbol: "fk", + Table: tbl, + Columns: tbl.Columns[1:], + RefTable: tbl, + RefColumns: tbl.Columns[:1], + OnUpdate: schema.NoAction, + OnDelete: schema.Cascade, + } + tbl.ForeignKeys = append(tbl.ForeignKeys, fk) + t.Run("add table", func(t *testing.T) { + mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { + return []schema.Change{ + &schema.AddTable{ + T: tbl, + }, + }, nil + }) + df, err := withoutForeignKeys(mdiff).Diff(nil, nil) + require.NoError(t, err) + require.Len(t, df, 1) + actual, ok := df[0].(*schema.AddTable) + require.True(t, ok) + require.Nil(t, actual.T.ForeignKeys) + }) + t.Run("drop table", func(t *testing.T) { + mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { + return []schema.Change{ + &schema.DropTable{ + T: tbl, + }, + }, nil + }) + df, err := withoutForeignKeys(mdiff).Diff(nil, nil) + require.NoError(t, err) + require.Len(t, df, 1) + actual, ok := df[0].(*schema.DropTable) + require.True(t, ok) + require.Nil(t, actual.T.ForeignKeys) + }) + t.Run("modify table", func(t *testing.T) { + mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { + return []schema.Change{ + &schema.ModifyTable{ + T: tbl, + Changes: []schema.Change{ + &schema.DropForeignKey{ + F: fk, + }, + &schema.AddColumn{ + C: &schema.Column{Name: "name", Type: &schema.ColumnType{Type: &schema.StringType{T: "varchar(255)"}}}, + }, + }, + }, + }, nil + }) + df, err := withoutForeignKeys(mdiff).Diff(nil, nil) + require.NoError(t, err) + require.Len(t, df, 1) + actual, ok := df[0].(*schema.AddColumn) + require.True(t, ok) + require.EqualValues(t, "name", actual.C.Name) + }) +} diff --git a/go.mod b/go.mod index 8bfebacfb4..2de62cb6b8 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,6 @@ require ( github.com/google/go-cmp v0.5.6 // indirect github.com/hashicorp/hcl/v2 v2.10.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/kr/pretty v0.2.1 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -43,6 +42,5 @@ require ( golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 80fe980d0c..256998b5b8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -ariga.io/atlas v0.3.7-0.20220303204946-787354f533c3 h1:fjG4oFCQEfGrRi0QoxWcH2OO28CE6VYa6DkIr3yDySU= -ariga.io/atlas v0.3.7-0.20220303204946-787354f533c3/go.mod h1:yWGf4VPiD4SW83+kAqzD624txN9VKoJC+bpVXr2pKJA= -ariga.io/atlas v0.3.8-0.20220313134928-770640fc02bf h1:bAt5AUvr91QI8yXHME6qTsMTNM4BtfSB3M9o1cmt51E= -ariga.io/atlas v0.3.8-0.20220313134928-770640fc02bf/go.mod h1:ipw7dUlFanAylr9nvs8lCvOUC8hFG6PGd/gtr+uJMvk= ariga.io/atlas v0.3.8-0.20220314111236-b2171e04c5b2 h1:qbH+CDPAMsV1FIKkHGYzy2aWP9k5QAqPbi9PYZGqz60= ariga.io/atlas v0.3.8-0.20220314111236-b2171e04c5b2/go.mod h1:ipw7dUlFanAylr9nvs8lCvOUC8hFG6PGd/gtr+uJMvk= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -280,7 +276,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= From ae4065ea717502202ad26e12c16aa8f4fa233745 Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Wed, 16 Mar 2022 16:05:08 +0200 Subject: [PATCH 4/6] tests --- dialect/sql/schema/atlas.go | 8 ++++---- dialect/sql/schema/migrate_test.go | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index 10ae71fd49..5fac2f14e8 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -184,18 +184,18 @@ func withoutForeignKeys(next Differ) Differ { c.T.ForeignKeys = nil case *schema.ModifyTable: c.T.ForeignKeys = nil - nChanges := make([]schema.Change, 0, len(c.Changes)) + filtered := make([]schema.Change, 0, len(c.Changes)) for _, change := range c.Changes { switch change.(type) { case *schema.AddForeignKey, *schema.DropForeignKey, *schema.ModifyForeignKey: - change = nil + continue default: - nChanges = append(nChanges, change) + filtered = append(filtered, change) } } - return nChanges, nil + c.Changes = filtered } } return changes, nil diff --git a/dialect/sql/schema/migrate_test.go b/dialect/sql/schema/migrate_test.go index 23eab285b4..dd8492d833 100644 --- a/dialect/sql/schema/migrate_test.go +++ b/dialect/sql/schema/migrate_test.go @@ -159,8 +159,11 @@ func TestMigrateWithoutForeignKeys(t *testing.T) { df, err := withoutForeignKeys(mdiff).Diff(nil, nil) require.NoError(t, err) require.Len(t, df, 1) - actual, ok := df[0].(*schema.AddColumn) + actual, ok := df[0].(*schema.ModifyTable) require.True(t, ok) - require.EqualValues(t, "name", actual.C.Name) + require.Len(t, actual.Changes, 1) + actualChange, ok := actual.Changes[0].(*schema.AddColumn) + require.True(t, ok) + require.EqualValues(t, "name", actualChange.C.Name) }) } From 23bc61f42aeb634cdad43868c11d7dbe2e9e72c8 Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Wed, 16 Mar 2022 16:15:50 +0200 Subject: [PATCH 5/6] Update dialect/sql/schema/atlas.go Co-authored-by: Ariel Mashraki <7413593+a8m@users.noreply.github.com> --- dialect/sql/schema/atlas.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index 5fac2f14e8..03bf6e31d5 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -187,9 +187,7 @@ func withoutForeignKeys(next Differ) Differ { filtered := make([]schema.Change, 0, len(c.Changes)) for _, change := range c.Changes { switch change.(type) { - case *schema.AddForeignKey, - *schema.DropForeignKey, - *schema.ModifyForeignKey: + case *schema.AddForeignKey, *schema.DropForeignKey, *schema.ModifyForeignKey: continue default: filtered = append(filtered, change) From 85d99ccbffb6d40e7760064c3061fe7cc3ca793e Mon Sep 17 00:00:00 2001 From: Zeev Manilovich Date: Wed, 16 Mar 2022 16:29:09 +0200 Subject: [PATCH 6/6] ct and tests --- dialect/sql/schema/atlas.go | 4 +-- dialect/sql/schema/migrate_test.go | 44 ++++++++++++++++-------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index 03bf6e31d5..0efa1be9df 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -159,7 +159,7 @@ func filterChanges(skip ChangeKind) DiffHook { keep = append(keep, c) } } - return keep + return } changes, err := next.Diff(current, desired) if err != nil { @@ -180,8 +180,6 @@ func withoutForeignKeys(next Differ) Differ { switch c := c.(type) { case *schema.AddTable: c.T.ForeignKeys = nil - case *schema.DropTable: - c.T.ForeignKeys = nil case *schema.ModifyTable: c.T.ForeignKeys = nil filtered := make([]schema.Change, 0, len(c.Changes)) diff --git a/dialect/sql/schema/migrate_test.go b/dialect/sql/schema/migrate_test.go index dd8492d833..4c95e8b720 100644 --- a/dialect/sql/schema/migrate_test.go +++ b/dialect/sql/schema/migrate_test.go @@ -110,7 +110,7 @@ func TestMigrateWithoutForeignKeys(t *testing.T) { OnDelete: schema.Cascade, } tbl.ForeignKeys = append(tbl.ForeignKeys, fk) - t.Run("add table", func(t *testing.T) { + t.Run("AddTable", func(t *testing.T) { mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { return []schema.Change{ &schema.AddTable{ @@ -125,30 +125,31 @@ func TestMigrateWithoutForeignKeys(t *testing.T) { require.True(t, ok) require.Nil(t, actual.T.ForeignKeys) }) - t.Run("drop table", func(t *testing.T) { - mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { - return []schema.Change{ - &schema.DropTable{ - T: tbl, - }, - }, nil - }) - df, err := withoutForeignKeys(mdiff).Diff(nil, nil) - require.NoError(t, err) - require.Len(t, df, 1) - actual, ok := df[0].(*schema.DropTable) - require.True(t, ok) - require.Nil(t, actual.T.ForeignKeys) - }) - t.Run("modify table", func(t *testing.T) { + t.Run("ModifyTable", func(t *testing.T) { mdiff := DiffFunc(func(_, _ *schema.Schema) ([]schema.Change, error) { return []schema.Change{ &schema.ModifyTable{ T: tbl, Changes: []schema.Change{ + &schema.AddIndex{ + I: &schema.Index{ + Name: "id_key", + Parts: []*schema.IndexPart{ + {C: tbl.Columns[0]}, + }, + }, + }, &schema.DropForeignKey{ F: fk, }, + &schema.AddForeignKey{ + F: fk, + }, + &schema.ModifyForeignKey{ + From: fk, + To: fk, + Change: schema.ChangeRefColumn, + }, &schema.AddColumn{ C: &schema.Column{Name: "name", Type: &schema.ColumnType{Type: &schema.StringType{T: "varchar(255)"}}}, }, @@ -161,9 +162,12 @@ func TestMigrateWithoutForeignKeys(t *testing.T) { require.Len(t, df, 1) actual, ok := df[0].(*schema.ModifyTable) require.True(t, ok) - require.Len(t, actual.Changes, 1) - actualChange, ok := actual.Changes[0].(*schema.AddColumn) + require.Len(t, actual.Changes, 2) + addIndex, ok := actual.Changes[0].(*schema.AddIndex) + require.True(t, ok) + require.EqualValues(t, "id_key", addIndex.I.Name) + addColumn, ok := actual.Changes[1].(*schema.AddColumn) require.True(t, ok) - require.EqualValues(t, "name", actualChange.C.Name) + require.EqualValues(t, "name", addColumn.C.Name) }) }