diff --git a/driver/mysql/mysql.go b/driver/mysql/mysql.go index 5f91560..d0be043 100644 --- a/driver/mysql/mysql.go +++ b/driver/mysql/mysql.go @@ -94,52 +94,55 @@ func (driver *Driver) Migrate(f file.File, pipe chan interface{}) { sqlStmts := bytes.Split(f.Content, []byte(";")) for _, sqlStmt := range sqlStmts { - if _, err := tx.Exec(string(sqlStmt)); err != nil { - mysqlErr := err.(*mysql.MySQLError) + if len(bytes.TrimSpace(sqlStmt)) > 0 { + if _, err := tx.Exec(string(sqlStmt)); err != nil { + mysqlErr := err.(*mysql.MySQLError) + + re, err := regexp.Compile(`at line ([0-9]+)$`) + if err != nil { + pipe <- err + if err := tx.Rollback(); err != nil { + pipe <- err + } + } + + var lineNo int + lineNoRe := re.FindStringSubmatch(mysqlErr.Message) + if len(lineNoRe) == 2 { + lineNo, err = strconv.Atoi(lineNoRe[1]) + } + if err == nil { + + // get white-space offset + // TODO this is broken, because we use sqlStmt instead of f.Content + wsLineOffset := 0 + b := bufio.NewReader(bytes.NewBuffer(sqlStmt)) + for { + line, _, err := b.ReadLine() + if err != nil { + break + } + if bytes.TrimSpace(line) == nil { + wsLineOffset += 1 + } else { + break + } + } + + message := mysqlErr.Error() + message = re.ReplaceAllString(message, fmt.Sprintf("at line %v", lineNo+wsLineOffset)) + + errorPart := file.LinesBeforeAndAfter(sqlStmt, lineNo, 5, 5, true) + pipe <- errors.New(fmt.Sprintf("%s\n\n%s", message, string(errorPart))) + } else { + pipe <- errors.New(mysqlErr.Error()) + } - re, err := regexp.Compile(`at line ([0-9]+)$`) - if err != nil { - pipe <- err if err := tx.Rollback(); err != nil { pipe <- err } + return } - - var lineNo int - lineNoRe := re.FindStringSubmatch(mysqlErr.Message) - if len(lineNoRe) == 2 { - lineNo, err = strconv.Atoi(lineNoRe[1]) - } - if err == nil { - - // get white-space offset - wsLineOffset := 0 - b := bufio.NewReader(bytes.NewBuffer(f.Content)) - for { - line, _, err := b.ReadLine() - if err != nil { - break - } - if bytes.TrimSpace(line) == nil { - wsLineOffset += 1 - } else { - break - } - } - - message := mysqlErr.Error() - message = re.ReplaceAllString(message, fmt.Sprintf("at line %v", lineNo+wsLineOffset)) - - errorPart := file.LinesBeforeAndAfter(f.Content, lineNo, 5, 5, true) - pipe <- errors.New(fmt.Sprintf("%s\n\n%s", message, string(errorPart))) - } else { - pipe <- errors.New(mysqlErr.Error()) - } - - if err := tx.Rollback(); err != nil { - pipe <- err - } - return } } diff --git a/driver/mysql/mysql_test.go b/driver/mysql/mysql_test.go index 31a1d13..b09f9ed 100644 --- a/driver/mysql/mysql_test.go +++ b/driver/mysql/mysql_test.go @@ -19,10 +19,7 @@ func TestMigrate(t *testing.T) { t.Fatal(err) } - if _, err := connection.Exec(` - DROP TABLE IF EXISTS yolo; - DROP TABLE IF EXISTS yolo1; - DROP TABLE IF EXISTS ` + tableName + `;`); err != nil { + if _, err := connection.Exec(`DROP TABLE IF EXISTS yolo, yolo1, ` + tableName); err != nil { t.Fatal(err) } @@ -44,7 +41,7 @@ func TestMigrate(t *testing.T) { ); CREATE TABLE yolo1 ( - id int(11) not null primary key auto_increment + id int(11) not nfull primary key auto_increment ); `), }, @@ -95,9 +92,6 @@ func TestMigrate(t *testing.T) { t.Error("Expected test case to fail") } - // TODO remove after debugging - t.Error(errs) - if err := d.Close(); err != nil { t.Fatal(err) }