1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
// Copyright 2021-present The Atlas Authors. All rights reserved.
// This source code is licensed under the Apache 2.0 license found
// in the LICENSE file in the root directory of this source tree.
package sqlx
import (
"testing"
"ariga.io/atlas/sql/schema"
"github.com/stretchr/testify/require"
)
func TestDetachCycles(t *testing.T) {
users := &schema.Table{
Name: "users",
Columns: []*schema.Column{
{Name: "id", Type: &schema.ColumnType{Raw: "bigint"}},
{Name: "workplace_id", Type: &schema.ColumnType{Raw: "bigint", Null: true}},
},
}
workplaces := &schema.Table{
Name: "workplaces",
Columns: []*schema.Column{
{Name: "id", Type: &schema.ColumnType{Raw: "bigint"}},
{Name: "owner_id", Type: &schema.ColumnType{Raw: "bigint", Null: true}},
},
}
users.ForeignKeys = []*schema.ForeignKey{
{Symbol: "workplace", Table: users, Columns: users.Columns[1:2], RefTable: workplaces, RefColumns: workplaces.Columns[:1]},
}
changes := []schema.Change{&schema.AddTable{T: workplaces}, &schema.AddTable{T: users}}
planned, err := DetachCycles(changes)
require.NoError(t, err)
require.Equal(t, changes, planned)
deletion := []schema.Change{&schema.DropTable{T: users}, &schema.DropTable{T: workplaces}}
planned, err = DetachCycles(deletion)
require.NoError(t, err)
require.Equal(t, deletion, planned)
// Create a circular reference.
workplaces.ForeignKeys = []*schema.ForeignKey{
{Symbol: "owner", Table: workplaces, Columns: workplaces.Columns[1:], RefTable: users, RefColumns: users.Columns[:1]},
}
// Add a self-ref foreign-key.
users.Columns = append(users.Columns, &schema.Column{Name: "spouse_id", Type: &schema.ColumnType{Raw: "bigint", Null: true}})
users.ForeignKeys = append(users.ForeignKeys, &schema.ForeignKey{Symbol: "spouse", Table: users, Columns: users.Columns[2:], RefTable: users, RefColumns: users.Columns[:1]})
planned, err = DetachCycles(changes)
require.NoError(t, err)
require.Len(t, planned, 4)
require.Empty(t, planned[0].(*schema.AddTable).T.ForeignKeys)
require.NotEmpty(t, planned[1].(*schema.AddTable).T.ForeignKeys)
require.Equal(t, &schema.ModifyTable{
T: workplaces,
Changes: []schema.Change{
&schema.AddForeignKey{
F: &schema.ForeignKey{Symbol: "owner", Table: workplaces, Columns: workplaces.Columns[1:], RefTable: users, RefColumns: users.Columns[:1]},
},
},
}, planned[2])
require.Equal(t, &schema.ModifyTable{
T: users,
Changes: []schema.Change{
&schema.AddForeignKey{
F: &schema.ForeignKey{Symbol: "workplace", Table: users, Columns: users.Columns[1:2], RefTable: workplaces, RefColumns: workplaces.Columns[:1]},
},
},
}, planned[3])
planned, err = DetachCycles(deletion)
require.NoError(t, err)
require.Equal(t, &schema.ModifyTable{
T: users,
Changes: []schema.Change{
&schema.DropForeignKey{
F: &schema.ForeignKey{Symbol: "workplace", Table: users, Columns: users.Columns[1:2], RefTable: workplaces, RefColumns: workplaces.Columns[:1]},
},
},
}, planned[0])
require.Equal(t, &schema.ModifyTable{
T: workplaces,
Changes: []schema.Change{
&schema.DropForeignKey{
F: &schema.ForeignKey{Symbol: "owner", Table: workplaces, Columns: workplaces.Columns[1:], RefTable: users, RefColumns: users.Columns[:1]},
},
},
}, planned[1])
users.ForeignKeys = nil
workplaces.ForeignKeys = nil
require.Equal(t, deletion, planned[2:])
}
func TestCheckChangesScope(t *testing.T) {
err := CheckChangesScope([]schema.Change{
&schema.AddSchema{},
})
require.EqualError(t, err, "*schema.AddSchema is not allowed when migration plan is scoped to one schema")
err = CheckChangesScope([]schema.Change{
&schema.ModifySchema{},
})
require.EqualError(t, err, "*schema.ModifySchema is not allowed when migration plan is scoped to one schema")
err = CheckChangesScope([]schema.Change{
&schema.DropSchema{},
})
require.EqualError(t, err, "*schema.DropSchema is not allowed when migration plan is scoped to one schema")
err = CheckChangesScope([]schema.Change{
&schema.AddTable{T: schema.NewTable("users").SetSchema(schema.New("s1"))},
&schema.AddTable{T: schema.NewTable("users").SetSchema(schema.New("s2"))},
})
require.EqualError(t, err, "found 2 schemas when migration plan is scoped to one")
}
|