feat: establish Orbit models, migrations and development baseline
This commit is contained in:
99
internal/storage/mysql/sqlsplit.go
Normal file
99
internal/storage/mysql/sqlsplit.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// splitSQL supports ordinary migration statements, quoted values and comments.
|
||||
// Stored routines and DELIMITER scripts are intentionally unsupported.
|
||||
func splitSQL(src string) ([]string, error) {
|
||||
var out []string
|
||||
var b strings.Builder
|
||||
var quote byte
|
||||
lineComment, blockComment := false, false
|
||||
flush := func() error {
|
||||
s := strings.TrimSpace(b.String())
|
||||
b.Reset()
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
if strings.HasPrefix(strings.ToUpper(s), "DELIMITER") {
|
||||
return errors.New("DELIMITER scripts are unsupported")
|
||||
}
|
||||
out = append(out, s)
|
||||
return nil
|
||||
}
|
||||
for i := 0; i < len(src); i++ {
|
||||
c := src[i]
|
||||
if lineComment {
|
||||
if c == '\n' {
|
||||
lineComment = false
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
continue
|
||||
}
|
||||
if blockComment {
|
||||
if c == '*' && i+1 < len(src) && src[i+1] == '/' {
|
||||
blockComment = false
|
||||
i++
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
continue
|
||||
}
|
||||
if quote != 0 {
|
||||
b.WriteByte(c)
|
||||
if c == '\\' && i+1 < len(src) {
|
||||
i++
|
||||
b.WriteByte(src[i])
|
||||
continue
|
||||
}
|
||||
if c == quote {
|
||||
if i+1 < len(src) && src[i+1] == quote {
|
||||
i++
|
||||
b.WriteByte(src[i])
|
||||
} else {
|
||||
quote = 0
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if c == '#' || c == '-' && i+2 < len(src) && src[i+1] == '-' && src[i+2] <= ' ' {
|
||||
lineComment = true
|
||||
if c == '-' {
|
||||
i++
|
||||
}
|
||||
continue
|
||||
}
|
||||
if c == '/' && i+1 < len(src) && src[i+1] == '*' {
|
||||
if i+2 < len(src) && src[i+2] == '!' {
|
||||
return nil, errors.New("executable SQL comments are unsupported")
|
||||
}
|
||||
blockComment = true
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if c == '\'' || c == '"' || c == '`' {
|
||||
quote = c
|
||||
b.WriteByte(c)
|
||||
continue
|
||||
}
|
||||
if c == ';' {
|
||||
if err := flush(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
b.WriteByte(c)
|
||||
}
|
||||
if quote != 0 || blockComment {
|
||||
return nil, errors.New("unterminated SQL quote or comment")
|
||||
}
|
||||
if err := flush(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return nil, errors.New("empty migration")
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user