Merge pull request #21 from divoxx/mysql_version_table_issue

WIP: Prevents MySQL driver to failing when version table alredy exists
This commit is contained in:
Matthias Kadenbach 2014-12-05 13:07:42 -08:00
commit 6b535262fd
1 changed files with 50 additions and 43 deletions

View File

@ -50,9 +50,12 @@ func (driver *Driver) Close() error {
}
func (driver *Driver) ensureVersionTableExists() error {
if _, err := driver.db.Exec("CREATE TABLE IF NOT EXISTS " + tableName + " (version int not null primary key);"); err != nil {
_, err := driver.db.Exec("CREATE TABLE IF NOT EXISTS " + tableName + " (version int not null primary key);")
if _, isWarn := err.(mysql.MySQLWarnings); err != nil && !isWarn {
return err
}
return nil
}
@ -100,54 +103,58 @@ func (driver *Driver) Migrate(f file.File, pipe chan interface{}) {
sqlStmts := bytes.Split(f.Content, []byte(";"))
for _, sqlStmt := range sqlStmts {
if len(bytes.TrimSpace(sqlStmt)) > 0 {
sqlStmt = bytes.TrimSpace(sqlStmt)
if len(sqlStmt) > 0 {
if _, err := tx.Exec(string(sqlStmt)); err != nil {
mysqlErr := err.(*mysql.MySQLError)
mysqlErr, isErr := err.(*mysql.MySQLError)
if isErr {
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
// 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())
}
if err := tx.Rollback(); err != nil {
pipe <- err
}
return
}
}
}