aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/rubenv/sql-migrate/sqlparse
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/rubenv/sql-migrate/sqlparse')
-rw-r--r--vendor/github.com/rubenv/sql-migrate/sqlparse/LICENSE22
-rw-r--r--vendor/github.com/rubenv/sql-migrate/sqlparse/README.md7
-rw-r--r--vendor/github.com/rubenv/sql-migrate/sqlparse/sqlparse.go235
3 files changed, 264 insertions, 0 deletions
diff --git a/vendor/github.com/rubenv/sql-migrate/sqlparse/LICENSE b/vendor/github.com/rubenv/sql-migrate/sqlparse/LICENSE
new file mode 100644
index 0000000..9c12525
--- /dev/null
+++ b/vendor/github.com/rubenv/sql-migrate/sqlparse/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (C) 2014-2017 by Ruben Vermeersch <ruben@rocketeer.be>
+Copyright (C) 2012-2014 by Liam Staskawicz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/rubenv/sql-migrate/sqlparse/README.md b/vendor/github.com/rubenv/sql-migrate/sqlparse/README.md
new file mode 100644
index 0000000..fa5341a
--- /dev/null
+++ b/vendor/github.com/rubenv/sql-migrate/sqlparse/README.md
@@ -0,0 +1,7 @@
+# SQL migration parser
+
+Based on the [goose](https://bitbucket.org/liamstask/goose) migration parser.
+
+## License
+
+This library is distributed under the [MIT](LICENSE) license.
diff --git a/vendor/github.com/rubenv/sql-migrate/sqlparse/sqlparse.go b/vendor/github.com/rubenv/sql-migrate/sqlparse/sqlparse.go
new file mode 100644
index 0000000..d336e77
--- /dev/null
+++ b/vendor/github.com/rubenv/sql-migrate/sqlparse/sqlparse.go
@@ -0,0 +1,235 @@
+package sqlparse
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+
+ "strings"
+)
+
+const (
+ sqlCmdPrefix = "-- +migrate "
+ optionNoTransaction = "notransaction"
+)
+
+type ParsedMigration struct {
+ UpStatements []string
+ DownStatements []string
+
+ DisableTransactionUp bool
+ DisableTransactionDown bool
+}
+
+var (
+ // LineSeparator can be used to split migrations by an exact line match. This line
+ // will be removed from the output. If left blank, it is not considered. It is defaulted
+ // to blank so you will have to set it manually.
+ // Use case: in MSSQL, it is convenient to separate commands by GO statements like in
+ // SQL Query Analyzer.
+ LineSeparator = ""
+)
+
+func errNoTerminator() error {
+ if len(LineSeparator) == 0 {
+ return errors.New(`ERROR: The last statement must be ended by a semicolon or '-- +migrate StatementEnd' marker.
+ See https://github.com/rubenv/sql-migrate for details.`)
+ }
+
+ return errors.New(fmt.Sprintf(`ERROR: The last statement must be ended by a semicolon, a line whose contents are %q, or '-- +migrate StatementEnd' marker.
+ See https://github.com/rubenv/sql-migrate for details.`, LineSeparator))
+}
+
+// Checks the line to see if the line has a statement-ending semicolon
+// or if the line contains a double-dash comment.
+func endsWithSemicolon(line string) bool {
+
+ prev := ""
+ scanner := bufio.NewScanner(strings.NewReader(line))
+ scanner.Split(bufio.ScanWords)
+
+ for scanner.Scan() {
+ word := scanner.Text()
+ if strings.HasPrefix(word, "--") {
+ break
+ }
+ prev = word
+ }
+
+ return strings.HasSuffix(prev, ";")
+}
+
+type migrationDirection int
+
+const (
+ directionNone migrationDirection = iota
+ directionUp
+ directionDown
+)
+
+type migrateCommand struct {
+ Command string
+ Options []string
+}
+
+func (c *migrateCommand) HasOption(opt string) bool {
+ for _, specifiedOption := range c.Options {
+ if specifiedOption == opt {
+ return true
+ }
+ }
+
+ return false
+}
+
+func parseCommand(line string) (*migrateCommand, error) {
+ cmd := &migrateCommand{}
+
+ if !strings.HasPrefix(line, sqlCmdPrefix) {
+ return nil, errors.New("ERROR: not a sql-migrate command")
+ }
+
+ fields := strings.Fields(line[len(sqlCmdPrefix):])
+ if len(fields) == 0 {
+ return nil, errors.New(`ERROR: incomplete migration command`)
+ }
+
+ cmd.Command = fields[0]
+
+ cmd.Options = fields[1:]
+
+ return cmd, nil
+}
+
+// Split the given sql script into individual statements.
+//
+// The base case is to simply split on semicolons, as these
+// naturally terminate a statement.
+//
+// However, more complex cases like pl/pgsql can have semicolons
+// 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 ParseMigration(r io.ReadSeeker) (*ParsedMigration, error) {
+ p := &ParsedMigration{}
+
+ _, err := r.Seek(0, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ var buf bytes.Buffer
+ scanner := bufio.NewScanner(r)
+ scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
+
+ statementEnded := false
+ ignoreSemicolons := false
+ currentDirection := directionNone
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ // ignore comment except beginning with '-- +'
+ if strings.HasPrefix(line, "-- ") && !strings.HasPrefix(line, "-- +") {
+ continue
+ }
+
+ // handle any migrate-specific commands
+ if strings.HasPrefix(line, sqlCmdPrefix) {
+ cmd, err := parseCommand(line)
+ if err != nil {
+ return nil, err
+ }
+
+ switch cmd.Command {
+ case "Up":
+ if len(strings.TrimSpace(buf.String())) > 0 {
+ return nil, errNoTerminator()
+ }
+ currentDirection = directionUp
+ if cmd.HasOption(optionNoTransaction) {
+ p.DisableTransactionUp = true
+ }
+ break
+
+ case "Down":
+ if len(strings.TrimSpace(buf.String())) > 0 {
+ return nil, errNoTerminator()
+ }
+ currentDirection = directionDown
+ if cmd.HasOption(optionNoTransaction) {
+ p.DisableTransactionDown = true
+ }
+ break
+
+ case "StatementBegin":
+ if currentDirection != directionNone {
+ ignoreSemicolons = true
+ }
+ break
+
+ case "StatementEnd":
+ if currentDirection != directionNone {
+ statementEnded = (ignoreSemicolons == true)
+ ignoreSemicolons = false
+ }
+ break
+ }
+ }
+
+ if currentDirection == directionNone {
+ continue
+ }
+
+ isLineSeparator := !ignoreSemicolons && len(LineSeparator) > 0 && line == LineSeparator
+
+ if !isLineSeparator && !strings.HasPrefix(line, "-- +") {
+ if _, err := buf.WriteString(line + "\n"); err != nil {
+ return nil, err
+ }
+ }
+
+ // Wrap up the two supported cases: 1) basic with semicolon; 2) psql statement
+ // Lines that end with semicolon that are in a statement block
+ // do not conclude statement.
+ if (!ignoreSemicolons && (endsWithSemicolon(line) || isLineSeparator)) || statementEnded {
+ statementEnded = false
+ switch currentDirection {
+ case directionUp:
+ p.UpStatements = append(p.UpStatements, buf.String())
+
+ case directionDown:
+ p.DownStatements = append(p.DownStatements, buf.String())
+
+ default:
+ panic("impossible state")
+ }
+
+ buf.Reset()
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, err
+ }
+
+ // diagnose likely migration script errors
+ if ignoreSemicolons {
+ return nil, errors.New("ERROR: saw '-- +migrate StatementBegin' with no matching '-- +migrate StatementEnd'")
+ }
+
+ if currentDirection == directionNone {
+ return nil, errors.New(`ERROR: no Up/Down annotations found, so no statements were executed.
+ See https://github.com/rubenv/sql-migrate for details.`)
+ }
+
+ // allow comment without sql instruction. Example:
+ // -- +migrate Down
+ // -- nothing to downgrade!
+ if len(strings.TrimSpace(buf.String())) > 0 && !strings.HasPrefix(buf.String(), "-- +") {
+ return nil, errNoTerminator()
+ }
+
+ return p, nil
+}