refactor: move sql parser into internal package (#444)

pull/445/head
Michael Fridman 2023-01-19 09:19:13 -05:00 committed by GitHub
parent db8feddea6
commit 2636c84dc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 14 deletions

View File

@ -1,15 +1,15 @@
package goose
package sqlparser
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"log"
"regexp"
"strings"
"sync"
"errors"
)
type parserState int
@ -55,7 +55,7 @@ var bufferPool = sync.Pool{
// within a statement. For these cases, we provide the explicit annotations
// 'StatementBegin' and 'StatementEnd' to allow the script to
// tell us to ignore semicolons.
func parseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool, err error) {
func ParseSQLMigration(r io.Reader, direction bool) (stmts []string, useTx bool, err error) {
var buf bytes.Buffer
scanBuf := bufferPool.Get().([]byte)
defer bufferPool.Put(scanBuf)
@ -229,3 +229,20 @@ func endsWithSemicolon(line string) bool {
return strings.HasSuffix(prev, ";")
}
var verbose bool
func SetVersbose(b bool) {
verbose = b
}
const (
grayColor = "\033[90m"
resetColor = "\033[00m"
)
func verboseInfo(s string, args ...interface{}) {
if verbose {
log.Printf(grayColor+s+resetColor, args...)
}
}

View File

@ -1,4 +1,4 @@
package goose
package sqlparser
import (
"fmt"
@ -55,7 +55,7 @@ func TestSplitStatements(t *testing.T) {
for i, test := range tt {
// up
stmts, _, err := parseSQLMigration(strings.NewReader(test.sql), true)
stmts, _, err := ParseSQLMigration(strings.NewReader(test.sql), true)
if err != nil {
t.Error(fmt.Errorf("tt[%v] unexpected error: %w", i, err))
}
@ -64,7 +64,7 @@ func TestSplitStatements(t *testing.T) {
}
// down
stmts, _, err = parseSQLMigration(strings.NewReader(test.sql), false)
stmts, _, err = ParseSQLMigration(strings.NewReader(test.sql), false)
if err != nil {
t.Error(fmt.Errorf("tt[%v] unexpected error: %w", i, err))
}
@ -75,7 +75,7 @@ func TestSplitStatements(t *testing.T) {
}
func TestKeepEmptyLines(t *testing.T) {
stmts, _, err := parseSQLMigration(strings.NewReader(emptyLineSQL), true)
stmts, _, err := ParseSQLMigration(strings.NewReader(emptyLineSQL), true)
if err != nil {
t.Errorf("Failed to parse SQL migration. %v", err)
}
@ -102,9 +102,9 @@ func TestUseTransactions(t *testing.T) {
}
tests := []testData{
{fileName: "./examples/sql-migrations/00001_create_users_table.sql", useTransactions: true},
{fileName: "./examples/sql-migrations/00002_rename_root.sql", useTransactions: true},
{fileName: "./examples/sql-migrations/00003_no_transaction.sql", useTransactions: false},
{fileName: "testdata/valid-txn/00001_create_users_table.sql", useTransactions: true},
{fileName: "testdata/valid-txn/00002_rename_root.sql", useTransactions: true},
{fileName: "testdata/valid-txn/00003_no_transaction.sql", useTransactions: false},
}
for _, test := range tests {
@ -112,7 +112,7 @@ func TestUseTransactions(t *testing.T) {
if err != nil {
t.Error(err)
}
_, useTx, err := parseSQLMigration(f, true)
_, useTx, err := ParseSQLMigration(f, true)
if err != nil {
t.Error(err)
}
@ -132,7 +132,7 @@ func TestParsingErrors(t *testing.T) {
downFirst,
}
for i, sql := range tt {
_, _, err := parseSQLMigration(strings.NewReader(sql), true)
_, _, err := ParseSQLMigration(strings.NewReader(sql), true)
if err == nil {
t.Errorf("expected error on tt[%v] %q", i, sql)
}

View File

@ -0,0 +1,14 @@
-- +goose Up
CREATE TABLE users (
id int NOT NULL PRIMARY KEY,
username text,
name text,
surname text
);
INSERT INTO users VALUES
(0, 'root', '', ''),
(1, 'vojtechvitek', 'Vojtech', 'Vitek');
-- +goose Down
DROP TABLE users;

View File

@ -0,0 +1,9 @@
-- +goose Up
-- +goose StatementBegin
UPDATE users SET username='admin' WHERE username='root';
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
UPDATE users SET username='root' WHERE username='admin';
-- +goose StatementEnd

View File

@ -0,0 +1,11 @@
-- +goose NO TRANSACTION
-- +goose Up
CREATE TABLE post (
id int NOT NULL,
title text,
body text,
PRIMARY KEY(id)
);
-- +goose Down
DROP TABLE post;

View File

@ -8,6 +8,8 @@ import (
"strconv"
"strings"
"time"
"github.com/pressly/goose/v3/internal/sqlparser"
)
// MigrationRecord struct.
@ -58,7 +60,8 @@ func (m *Migration) run(db *sql.DB, direction bool) error {
}
defer f.Close()
statements, useTx, err := parseSQLMigration(f, direction)
sqlparser.SetVersbose(verbose)
statements, useTx, err := sqlparser.ParseSQLMigration(f, direction)
if err != nil {
return fmt.Errorf("ERROR %v: failed to parse SQL migration file: %w", filepath.Base(m.Source), err)
}