parser: preserve empty lines in SQL statements (#372)

pull/384/head
Takahiro Ikeuchi 2022-07-13 09:59:24 +09:00 committed by GitHub
parent bc72e7863c
commit 496d7cdf15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 2 deletions

View File

@ -29,6 +29,7 @@ type stateMachine parserState
func (s *stateMachine) Get() parserState {
return parserState(*s)
}
func (s *stateMachine) Set(new parserState) {
verboseInfo("StateMachine: %v => %v", *s, new)
*s = stateMachine(new)
@ -65,6 +66,7 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
stateMachine := stateMachine(start)
useTx = true
firstLineFound := false
for scanner.Scan() {
line := scanner.Text()
if verbose {
@ -76,6 +78,7 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
switch cmd {
case "+goose Up":
firstLineFound = true
switch stateMachine.Get() {
case start:
stateMachine.Set(gooseUp)
@ -85,6 +88,7 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
continue
case "+goose Down":
firstLineFound = true
switch stateMachine.Get() {
case gooseUp, gooseStatementEndUp:
stateMachine.Set(gooseDown)
@ -94,6 +98,7 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
continue
case "+goose StatementBegin":
firstLineFound = true
switch stateMachine.Get() {
case gooseUp, gooseStatementEndUp:
stateMachine.Set(gooseStatementBeginUp)
@ -105,6 +110,7 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
continue
case "+goose StatementEnd":
firstLineFound = true
switch stateMachine.Get() {
case gooseStatementBeginUp:
stateMachine.Set(gooseStatementEndUp)
@ -125,8 +131,8 @@ func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool,
}
}
// Ignore empty lines.
if matchEmptyLines.MatchString(line) {
// Ignore empty lines until first line is found.
if !firstLineFound && matchEmptyLines.MatchString(line) {
verboseInfo("StateMachine: ignore empty line")
continue
}

View File

@ -74,6 +74,25 @@ func TestSplitStatements(t *testing.T) {
}
}
func TestKeepEmptyLines(t *testing.T) {
stmts, _, err := parseSQLMigration(strings.NewReader(emptyLineSQL), true)
if err != nil {
t.Errorf("Failed to parse SQL migration. %v", err)
}
expected := `INSERT INTO post (id, title, body)
VALUES ('id_01', 'my_title', '
this is an insert statement including empty lines.
empty (blank) lines can be meaningful.
leave the lines to keep the text syntax.
');
`
if stmts[0] != expected {
t.Errorf("incorrect stmts. got %v, want %v", stmts, expected)
}
}
func TestUseTransactions(t *testing.T) {
t.Parallel()
@ -138,6 +157,20 @@ SELECT 4; -- 4th stmt
DROP TABLE post; -- 1st stmt
`
var emptyLineSQL = `-- +goose Up
INSERT INTO post (id, title, body)
VALUES ('id_01', 'my_title', '
this is an insert statement including empty lines.
empty (blank) lines can be meaningful.
leave the lines to keep the text syntax.
');
-- +goose Down
TRUNCATE TABLE post;
`
var functxt = `-- +goose Up
CREATE TABLE IF NOT EXISTS histories (
id BIGSERIAL PRIMARY KEY,