dialect/sql/schema: optimize code and add website documents (#748)

This commit is contained in:
kakaxizhang
2020-10-12 16:08:02 +08:00
parent 90c3d50c39
commit 63421aa9ad
31 changed files with 147 additions and 150 deletions

View File

@@ -59,11 +59,11 @@ func WithFixture(b bool) MigrateOption {
}
}
// WithForeighKeys enables creating foreigh-key in ddl. In some case we are
// not allowed to use foreigh-key. Defaults to true
func WithForeighKeys(b bool) MigrateOption {
// WithForeignKeys enables creating foreign-key in ddl. In some case we are
// not allowed to use foreign-key. Defaults to true
func WithForeignKeys(b bool) MigrateOption {
return func(m *Migrate) {
m.withForeighKeys = b
m.withForeignKeys = b
}
}
@@ -74,26 +74,26 @@ type Migrate struct {
dropColumns bool // drop deleted columns.
dropIndexes bool // drop deleted indexes.
withFixture bool // with fks rename fixture.
withForeighKeys bool // with foreigh keys
withForeignKeys bool // with foreign keys
typeRanges []string // types order by their range.
}
// NewMigrate create a migration structure for the given SQL driver.
func NewMigrate(d dialect.Driver, opts ...MigrateOption) (*Migrate, error) {
m := &Migrate{withFixture: true, withForeighKeys: true}
m := &Migrate{withFixture: true, withForeignKeys: true}
for _, opt := range opts {
opt(m)
}
switch d.Dialect() {
case dialect.MySQL:
m.sqlDialect = &MySQL{Driver: d}
case dialect.SQLite:
m.sqlDialect = &SQLite{Driver: d}
m.sqlDialect = &SQLite{Driver: d, WithForeignKeys: m.withForeignKeys}
case dialect.Postgres:
m.sqlDialect = &Postgres{Driver: d}
default:
return nil, fmt.Errorf("sql/schema: unsupported dialect %q", d.Dialect())
}
for _, opt := range opts {
opt(m)
}
return m, nil
}
@@ -150,14 +150,7 @@ func (m *Migrate) create(ctx context.Context, tx dialect.Tx, tables ...*Table) e
return err
}
default: // !exist
// special case: sqllite driver create foreigh keys during table creating period,
// we need to set foreigh keys empty before it, and get FKS back after Query().
bks := t.ForeignKeys
if _, ok := m.sqlDialect.(*SQLite); ok && !m.withForeighKeys {
t.ForeignKeys = nil
}
query, args := m.tBuilder(t).Query()
t.ForeignKeys = bks
// create table
if err := tx.Exec(ctx, query, args, nil); err != nil {
return fmt.Errorf("create table %q: %v", t.Name, err)
@@ -180,30 +173,29 @@ func (m *Migrate) create(ctx context.Context, tx dialect.Tx, tables ...*Table) e
}
// Create foreign keys after tables were created/altered,
// because circular foreign-key constraints are possible.
for _, t := range tables {
if !m.withForeighKeys || len(t.ForeignKeys) == 0 {
continue
}
fks := make([]*ForeignKey, 0, len(t.ForeignKeys))
for _, fk := range t.ForeignKeys {
exist, err := m.fkExist(ctx, tx, fk.Symbol)
if err != nil {
return err
if m.withForeignKeys {
for _, t := range tables {
fks := make([]*ForeignKey, 0, len(t.ForeignKeys))
for _, fk := range t.ForeignKeys {
exist, err := m.fkExist(ctx, tx, fk.Symbol)
if err != nil {
return err
}
if !exist {
fks = append(fks, fk)
}
}
if !exist {
fks = append(fks, fk)
if len(fks) == 0 {
continue
}
b := sql.Dialect(m.Dialect()).AlterTable(t.Name)
for _, fk := range fks {
b.AddForeignKey(fk.DSL())
}
query, args := b.Query()
if err := tx.Exec(ctx, query, args, nil); err != nil {
return fmt.Errorf("create foreign keys for %q: %v", t.Name, err)
}
}
if len(fks) == 0 {
continue
}
b := sql.Dialect(m.Dialect()).AlterTable(t.Name)
for _, fk := range fks {
b.AddForeignKey(fk.DSL())
}
query, args := b.Query()
if err := tx.Exec(ctx, query, args, nil); err != nil {
return fmt.Errorf("create foreign keys for %q: %v", t.Name, err)
}
}
return nil
@@ -362,7 +354,7 @@ func (m *Migrate) changeSet(curr, new *Table) (*changes, error) {
// fixture is a special migration code for renaming foreign-key columns (issue-#285).
func (m *Migrate) fixture(ctx context.Context, tx dialect.Tx, curr, new *Table) error {
d, ok := m.sqlDialect.(fkRenamer)
if !m.withFixture || !m.withForeighKeys || !ok {
if !m.withFixture || !m.withForeignKeys || !ok {
return nil
}
rename := make(map[string]*Index)

View File

@@ -146,7 +146,7 @@ func TestMySQL_Create(t *testing.T) {
{
name: "create new table with foreign key diabled",
options: []MigrateOption{
WithForeighKeys(false),
WithForeignKeys(false),
},
tables: func() []*Table {
var (

View File

@@ -128,7 +128,7 @@ func TestPostgres_Create(t *testing.T) {
{
name: "create new table with foreign key disabled",
options: []MigrateOption{
WithForeighKeys(false),
WithForeignKeys(false),
},
tables: func() []*Table {
var (

View File

@@ -17,6 +17,7 @@ import (
// SQLite is an SQLite migration driver.
type SQLite struct {
dialect.Driver
WithForeignKeys bool
}
// init makes sure that foreign_keys support is enabled.
@@ -76,8 +77,10 @@ func (d *SQLite) tBuilder(t *Table) *sql.TableBuilder {
// not always valid (because circular foreign-keys situation is possible).
// We stay consistent by not using constraints at all, and just defining the
// foreign keys in the `CREATE TABLE` statement.
for _, fk := range t.ForeignKeys {
b.ForeignKeys(fk.DSL())
if d.WithForeignKeys {
for _, fk := range t.ForeignKeys {
b.ForeignKeys(fk.DSL())
}
}
// If it's an ID based primary key with autoincrement, we add
// the `PRIMARY KEY` clause to the column declaration. Otherwise,

View File

@@ -126,7 +126,7 @@ func TestSQLite_Create(t *testing.T) {
{
name: "create new table with foreign key disabled",
options: []MigrateOption{
WithForeighKeys(false),
WithForeignKeys(false),
},
tables: func() []*Table {
var (