Przeglądaj źródła

fix only add column if not exists for mysql

Marcus Efraimsson 7 lat temu
rodzic
commit
12f3c8f9d6

+ 10 - 0
pkg/services/sqlstore/migrator/conditions.go

@@ -36,3 +36,13 @@ type IfIndexNotExistsCondition struct {
 func (c *IfIndexNotExistsCondition) Sql(dialect Dialect) (string, []interface{}) {
 	return dialect.IndexCheckSql(c.TableName, c.IndexName)
 }
+
+type IfColumnNotExistsCondition struct {
+	NotExistsMigrationCondition
+	TableName  string
+	ColumnName string
+}
+
+func (c *IfColumnNotExistsCondition) Sql(dialect Dialect) (string, []interface{}) {
+	return dialect.ColumnCheckSql(c.TableName, c.ColumnName)
+}

+ 5 - 0
pkg/services/sqlstore/migrator/dialect.go

@@ -33,6 +33,7 @@ type Dialect interface {
 	UpdateTableSql(tableName string, columns []*Column) string
 
 	IndexCheckSql(tableName, indexName string) (string, []interface{})
+	ColumnCheckSql(tableName, columnName string) (string, []interface{})
 
 	ColString(*Column) string
 	ColStringNoPk(*Column) string
@@ -183,6 +184,10 @@ func (db *BaseDialect) RenameTable(oldName string, newName string) string {
 	return fmt.Sprintf("ALTER TABLE %s RENAME TO %s", quote(oldName), quote(newName))
 }
 
+func (db *BaseDialect) ColumnCheckSql(tableName, columnName string) (string, []interface{}) {
+	return "", nil
+}
+
 func (db *BaseDialect) DropIndexSql(tableName string, index *Index) string {
 	quote := db.dialect.Quote
 	name := index.XName(tableName)

+ 3 - 1
pkg/services/sqlstore/migrator/migrations.go

@@ -85,7 +85,9 @@ type AddColumnMigration struct {
 }
 
 func NewAddColumnMigration(table Table, col *Column) *AddColumnMigration {
-	return &AddColumnMigration{tableName: table.Name, column: col}
+	m := &AddColumnMigration{tableName: table.Name, column: col}
+	m.Condition = &IfColumnNotExistsCondition{TableName: table.Name, ColumnName: col.Name}
+	return m
 }
 
 func (m *AddColumnMigration) Table(tableName string) *AddColumnMigration {

+ 12 - 9
pkg/services/sqlstore/migrator/migrator.go

@@ -121,16 +121,19 @@ func (mg *Migrator) exec(m Migration, sess *xorm.Session) error {
 	condition := m.GetCondition()
 	if condition != nil {
 		sql, args := condition.Sql(mg.Dialect)
-		mg.Logger.Debug("Executing migration condition sql", "id", m.Id(), "sql", sql, "args", args)
-		results, err := sess.SQL(sql, args...).Query()
-		if err != nil {
-			mg.Logger.Error("Executing migration condition failed", "id", m.Id(), "error", err)
-			return err
-		}
 
-		if !condition.IsFulfilled(results) {
-			mg.Logger.Warn("Skipping migration: Already executed, but not recorded in migration log", "id", m.Id())
-			return nil
+		if sql != "" {
+			mg.Logger.Debug("Executing migration condition sql", "id", m.Id(), "sql", sql, "args", args)
+			results, err := sess.SQL(sql, args...).Query()
+			if err != nil {
+				mg.Logger.Error("Executing migration condition failed", "id", m.Id(), "error", err)
+				return err
+			}
+
+			if !condition.IsFulfilled(results) {
+				mg.Logger.Warn("Skipping migration: Already executed, but not recorded in migration log", "id", m.Id())
+				return nil
+			}
 		}
 	}
 

+ 6 - 0
pkg/services/sqlstore/migrator/mysql_dialect.go

@@ -108,6 +108,12 @@ func (db *Mysql) IndexCheckSql(tableName, indexName string) (string, []interface
 	return sql, args
 }
 
+func (db *Mysql) ColumnCheckSql(tableName, columnName string) (string, []interface{}) {
+	args := []interface{}{tableName, columnName}
+	sql := "SELECT 1 FROM " + db.Quote("INFORMATION_SCHEMA") + "." + db.Quote("COLUMNS") + " WHERE " + db.Quote("TABLE_SCHEMA") + " = DATABASE() AND " + db.Quote("TABLE_NAME") + "=? AND " + db.Quote("COLUMN_NAME") + "=?"
+	return sql, args
+}
+
 func (db *Mysql) CleanDB() error {
 	tables, _ := db.engine.DBMetas()
 	sess := db.engine.NewSession()