Skip to content

Commit 1648e29

Browse files
committed
Fix auto migration with transaction, close go-gorm/gorm#5175
1 parent 915f678 commit 1648e29

File tree

1 file changed

+69
-66
lines changed

1 file changed

+69
-66
lines changed

migrator.go

Lines changed: 69 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -155,90 +155,93 @@ func (m Migrator) ColumnTypes(value interface{}) ([]gorm.ColumnType, error) {
155155
return err
156156
}
157157

158-
defer func() {
159-
err = rows.Close()
160-
}()
161-
162-
var (
163-
rawColumnTypes, _ = rows.ColumnTypes()
164-
columnTypeSQL = "SELECT column_name, data_type, column_default, is_nullable, character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale, datetime_precision FROM INFORMATION_SCHEMA.COLUMNS WHERE table_catalog = ? AND table_name = ?"
165-
columns, rowErr = m.DB.Raw(columnTypeSQL, m.CurrentDatabase(), stmt.Table).Rows()
166-
)
167-
168-
if rowErr != nil {
169-
return rowErr
170-
}
171-
172-
defer columns.Close()
158+
rawColumnTypes, _ := rows.ColumnTypes()
159+
rows.Close()
173160

174-
for columns.Next() {
161+
{
175162
var (
176-
column = migrator.ColumnType{
177-
PrimaryKeyValue: sql.NullBool{Valid: true},
178-
UniqueValue: sql.NullBool{Valid: true},
179-
}
180-
datetimePrecision sql.NullInt64
181-
radixValue sql.NullInt64
182-
nullableValue sql.NullString
183-
values = []interface{}{
184-
&column.NameValue, &column.ColumnTypeValue, &column.DefaultValueValue, &nullableValue, &column.LengthValue, &column.DecimalSizeValue, &radixValue, &column.ScaleValue, &datetimePrecision,
185-
}
163+
columnTypeSQL = "SELECT column_name, data_type, column_default, is_nullable, character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale, datetime_precision FROM INFORMATION_SCHEMA.COLUMNS WHERE table_catalog = ? AND table_name = ?"
164+
columns, rowErr = m.DB.Raw(columnTypeSQL, m.CurrentDatabase(), stmt.Table).Rows()
186165
)
187166

188-
if scanErr := columns.Scan(values...); scanErr != nil {
189-
return scanErr
167+
if rowErr != nil {
168+
return rowErr
190169
}
191170

192-
if nullableValue.Valid {
193-
column.NullableValue = sql.NullBool{Bool: strings.EqualFold(nullableValue.String, "YES"), Valid: true}
194-
}
171+
for columns.Next() {
172+
var (
173+
column = migrator.ColumnType{
174+
PrimaryKeyValue: sql.NullBool{Valid: true},
175+
UniqueValue: sql.NullBool{Valid: true},
176+
}
177+
datetimePrecision sql.NullInt64
178+
radixValue sql.NullInt64
179+
nullableValue sql.NullString
180+
values = []interface{}{
181+
&column.NameValue, &column.ColumnTypeValue, &column.DefaultValueValue, &nullableValue, &column.LengthValue, &column.DecimalSizeValue, &radixValue, &column.ScaleValue, &datetimePrecision,
182+
}
183+
)
195184

196-
if datetimePrecision.Valid {
197-
column.DecimalSizeValue = datetimePrecision
198-
}
185+
if scanErr := columns.Scan(values...); scanErr != nil {
186+
return scanErr
187+
}
199188

200-
if column.DefaultValueValue.Valid {
201-
matches := defaultValueTrimRegexp.FindStringSubmatch(column.DefaultValueValue.String)
202-
for len(matches) > 1 {
203-
column.DefaultValueValue.String = matches[1]
204-
matches = defaultValueTrimRegexp.FindStringSubmatch(column.DefaultValueValue.String)
189+
if nullableValue.Valid {
190+
column.NullableValue = sql.NullBool{Bool: strings.EqualFold(nullableValue.String, "YES"), Valid: true}
191+
}
192+
193+
if datetimePrecision.Valid {
194+
column.DecimalSizeValue = datetimePrecision
195+
}
196+
197+
if column.DefaultValueValue.Valid {
198+
matches := defaultValueTrimRegexp.FindStringSubmatch(column.DefaultValueValue.String)
199+
for len(matches) > 1 {
200+
column.DefaultValueValue.String = matches[1]
201+
matches = defaultValueTrimRegexp.FindStringSubmatch(column.DefaultValueValue.String)
202+
}
203+
} else {
204+
column.DefaultValueValue.Valid = true
205205
}
206-
} else {
207-
column.DefaultValueValue.Valid = true
208-
}
209206

210-
for _, c := range rawColumnTypes {
211-
if c.Name() == column.NameValue.String {
212-
column.SQLColumnType = c
213-
break
207+
for _, c := range rawColumnTypes {
208+
if c.Name() == column.NameValue.String {
209+
column.SQLColumnType = c
210+
break
211+
}
214212
}
213+
214+
columnTypes = append(columnTypes, column)
215215
}
216216

217-
columnTypes = append(columnTypes, column)
217+
columns.Close()
218218
}
219219

220-
columnTypeRows, err := m.DB.Raw("SELECT c.column_name, t.constraint_type FROM information_schema.table_constraints t JOIN information_schema.constraint_column_usage c ON c.constraint_name=t.constraint_name WHERE t.constraint_type IN ('PRIMARY KEY', 'UNIQUE') AND c.table_catalog = ? AND c.table_name = ?", m.CurrentDatabase(), stmt.Table).Rows()
221-
if err != nil {
222-
return err
223-
}
224-
defer columnTypeRows.Close()
225-
226-
for columnTypeRows.Next() {
227-
var name, columnType string
228-
columnTypeRows.Scan(&name, &columnType)
229-
for idx, c := range columnTypes {
230-
mc := c.(migrator.ColumnType)
231-
if mc.NameValue.String == name {
232-
switch columnType {
233-
case "PRIMARY KEY":
234-
mc.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
235-
case "UNIQUE":
236-
mc.UniqueValue = sql.NullBool{Bool: true, Valid: true}
220+
{
221+
columnTypeRows, err := m.DB.Raw("SELECT c.column_name, t.constraint_type FROM information_schema.table_constraints t JOIN information_schema.constraint_column_usage c ON c.constraint_name=t.constraint_name WHERE t.constraint_type IN ('PRIMARY KEY', 'UNIQUE') AND c.table_catalog = ? AND c.table_name = ?", m.CurrentDatabase(), stmt.Table).Rows()
222+
if err != nil {
223+
return err
224+
}
225+
226+
for columnTypeRows.Next() {
227+
var name, columnType string
228+
columnTypeRows.Scan(&name, &columnType)
229+
for idx, c := range columnTypes {
230+
mc := c.(migrator.ColumnType)
231+
if mc.NameValue.String == name {
232+
switch columnType {
233+
case "PRIMARY KEY":
234+
mc.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true}
235+
case "UNIQUE":
236+
mc.UniqueValue = sql.NullBool{Bool: true, Valid: true}
237+
}
238+
columnTypes[idx] = mc
239+
break
237240
}
238-
columnTypes[idx] = mc
239-
break
240241
}
241242
}
243+
244+
columnTypeRows.Close()
242245
}
243246

244247
return

0 commit comments

Comments
 (0)