ent/schema: fix indexes in mysql versions <= 5.6

Summary: move property type uniqueness enforment to ent schema

Reviewed By: alexsn

Differential Revision: D16767355

fbshipit-source-id: db6ba4853a8816fd5f6299a34c0b780028d75da1
This commit is contained in:
Ariel Mashraki
2019-08-13 07:38:36 -07:00
committed by Facebook Github Bot
parent 930cf29367
commit 4ac1b595bf
4 changed files with 33 additions and 13 deletions

View File

@@ -103,6 +103,7 @@ func (m *Migrate) Create(ctx context.Context, tables ...*Table) error {
func (m *Migrate) create(ctx context.Context, tx dialect.Tx, tables ...*Table) error {
for _, t := range tables {
t.linkColumns()
switch exist, err := m.tableExist(ctx, tx, t.Name); {
case err != nil:
return err

View File

@@ -55,7 +55,7 @@ func (d *MySQL) table(ctx context.Context, tx dialect.Tx, name string) (*Table,
}
// call `Close` in cases of failures (`Close` is idempotent).
defer rows.Close()
t := &Table{Name: name}
t := NewTable(name)
for rows.Next() {
c := &Column{}
if err := c.ScanMySQL(rows); err != nil {
@@ -64,7 +64,7 @@ func (d *MySQL) table(ctx context.Context, tx dialect.Tx, name string) (*Table,
if c.PrimaryKey() {
t.PrimaryKey = append(t.PrimaryKey, c)
}
t.Columns = append(t.Columns, c)
t.AddColumn(c)
}
if err := rows.Close(); err != nil {
return nil, fmt.Errorf("mysql: closing rows %v", err)
@@ -73,7 +73,10 @@ func (d *MySQL) table(ctx context.Context, tx dialect.Tx, name string) (*Table,
if err != nil {
return nil, err
}
t.Indexes = indexes
// add and link indexes to table columns.
for _, idx := range indexes {
t.AddIndex(idx.Name, idx.Unique, idx.columns)
}
return t, nil
}

View File

@@ -62,12 +62,22 @@ func (t *Table) AddIndex(name string, unique bool, columns []string) *Table {
c, ok := t.columns[name]
if ok {
idx.Columns[i] = c
c.indexes = append(c.indexes, idx)
}
}
t.Indexes = append(t.Indexes, idx)
return t
}
// linkColumns links the table columns to their indexes for later referencing.
func (t *Table) linkColumns() {
for _, idx := range t.Indexes {
for _, c := range idx.Columns {
c.indexes.append(idx)
}
}
}
// MySQL returns the MySQL DSL query for table creation.
func (t *Table) MySQL(version string) *sql.TableBuilder {
b := sql.CreateTable(t.Name).IfNotExists()
@@ -148,6 +158,7 @@ type Column struct {
Default string // default value.
Charset string // column character set.
Collation string // column collation.
indexes Indexes // linked indexes.
}
// UniqueKey returns boolean indicates if this column is a unique key.
@@ -372,18 +383,23 @@ func (c *Column) nullable(b *sql.ColumnBuilder) {
}
}
// defaultSize returns the default size for MySQL varchar
// type based on column size, charset and table indexes.
// defaultSize returns the default size for MySQL varchar type based
// on column size, charset and table indexes, in order to avoid index
// prefix key limit (767).
func (c *Column) defaultSize(version string) int {
size := DefaultStringLen
parts := strings.Split(version, ".")
// non-unique or invalid version.
if !c.Unique || len(parts) == 1 || parts[0] == "" || parts[1] == "" {
return DefaultStringLen
switch {
// invalid version.
case len(parts) == 1 || parts[0] == "" || parts[1] == "":
// version is > 5.6.*.
case parts[0] > "5" || parts[1] > "6":
// non-unique, or not part of any index (reaching the error 1071).
case !c.Unique && len(c.indexes) == 0:
default:
size = 191
}
if major, minor := parts[0], parts[1]; major > "5" || minor > "6" {
return DefaultStringLen
}
return 191
return size
}
// ForeignKey definition for creation.