snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
62
internal/migrations/migrations.go
Normal file
62
internal/migrations/migrations.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// psqlMetaCommand matches a psql meta-command (a line that begins with a
|
||||
// backslash followed by a command name). pg_dump emits these starting with
|
||||
// PostgreSQL 17.6 / 16.10 / 15.14 / 14.19 / 13.22 (e.g. `\restrict KEY` and
|
||||
// `\unrestrict KEY`), and sqlc's SQL parsers cannot handle them.
|
||||
var psqlMetaCommand = regexp.MustCompile(`^\\[A-Za-z!?;][^\n]*$`)
|
||||
|
||||
// Remove all lines after a rollback comment.
|
||||
//
|
||||
// goose: -- +goose Down
|
||||
// sql-migrate: -- +migrate Down
|
||||
// tern: ---- create above / drop below ----
|
||||
// dbmate: -- migrate:down
|
||||
func RemoveRollbackStatements(contents string) string {
|
||||
s := bufio.NewScanner(strings.NewReader(contents))
|
||||
var lines []string
|
||||
for s.Scan() {
|
||||
statement := strings.ToLower(s.Text())
|
||||
if strings.HasPrefix(statement, "-- +goose down") {
|
||||
break
|
||||
}
|
||||
if strings.HasPrefix(statement, "-- +migrate down") {
|
||||
break
|
||||
}
|
||||
if strings.HasPrefix(statement, "---- create above / drop below ----") {
|
||||
break
|
||||
}
|
||||
if strings.HasPrefix(statement, "-- migrate:down") {
|
||||
break
|
||||
}
|
||||
lines = append(lines, s.Text())
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// RemovePsqlMetaCommands strips psql meta-command lines (e.g. `\restrict KEY`,
|
||||
// `\unrestrict KEY`, `\connect foo`) from SQL input. These are emitted by
|
||||
// pg_dump but are not valid SQL, so they must be removed before parsing.
|
||||
func RemovePsqlMetaCommands(contents string) string {
|
||||
s := bufio.NewScanner(strings.NewReader(contents))
|
||||
var lines []string
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
if psqlMetaCommand.MatchString(line) {
|
||||
continue
|
||||
}
|
||||
lines = append(lines, line)
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func IsDown(filename string) bool {
|
||||
// Remove golang-migrate rollback files.
|
||||
return strings.HasSuffix(filename, ".down.sql")
|
||||
}
|
||||
107
internal/migrations/migrations_test.go
Normal file
107
internal/migrations/migrations_test.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
const inputGoose = `
|
||||
-- +goose Up
|
||||
ALTER TABLE archived_jobs ADD COLUMN expires_at TIMESTAMP WITH TIME ZONE;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE archived_jobs DROP COLUMN expires_at;
|
||||
`
|
||||
|
||||
const outputGoose = `
|
||||
-- +goose Up
|
||||
ALTER TABLE archived_jobs ADD COLUMN expires_at TIMESTAMP WITH TIME ZONE;
|
||||
`
|
||||
|
||||
const inputMigrate = `
|
||||
-- +migrate Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
CREATE TABLE people (id int);
|
||||
|
||||
-- +migrate Down
|
||||
-- SQL section 'Down' is executed when this migration is rolled back
|
||||
DROP TABLE people;
|
||||
`
|
||||
|
||||
const outputMigrate = `
|
||||
-- +migrate Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
CREATE TABLE people (id int);
|
||||
`
|
||||
|
||||
const inputTern = `
|
||||
-- Write your migrate up statements here
|
||||
ALTER TABLE todo RENAME COLUMN done TO is_done;
|
||||
---- create above / drop below ----
|
||||
ALTER TABLE todo RENAME COLUMN is_done TO done;
|
||||
`
|
||||
|
||||
const outputTern = `
|
||||
-- Write your migrate up statements here
|
||||
ALTER TABLE todo RENAME COLUMN done TO is_done;`
|
||||
|
||||
const inputDbmate = `
|
||||
-- migrate:up
|
||||
CREATE TABLE foo (bar int);
|
||||
-- migrate:down
|
||||
DROP TABLE foo;`
|
||||
|
||||
const outputDbmate = `
|
||||
-- migrate:up
|
||||
CREATE TABLE foo (bar int);`
|
||||
|
||||
const inputPsqlMeta = `\restrict auwherpfqaiuwrhgp
|
||||
|
||||
CREATE TABLE foo (id int);
|
||||
|
||||
\unrestrict auwherpfqaiuwrhgp
|
||||
`
|
||||
|
||||
const outputPsqlMeta = `
|
||||
CREATE TABLE foo (id int);
|
||||
`
|
||||
|
||||
func TestRemoveRollback(t *testing.T) {
|
||||
if diff := cmp.Diff(outputGoose, RemoveRollbackStatements(inputGoose)); diff != "" {
|
||||
t.Errorf("goose migration mismatch:\n%s", diff)
|
||||
}
|
||||
if diff := cmp.Diff(outputMigrate, RemoveRollbackStatements(inputMigrate)); diff != "" {
|
||||
t.Errorf("sql-migrate migration mismatch:\n%s", diff)
|
||||
}
|
||||
if diff := cmp.Diff(outputTern, RemoveRollbackStatements(inputTern)); diff != "" {
|
||||
t.Errorf("tern migration mismatch:\n%s", diff)
|
||||
}
|
||||
if diff := cmp.Diff(outputDbmate, RemoveRollbackStatements(inputDbmate)); diff != "" {
|
||||
t.Errorf("dbmate migration mismatch:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovePsqlMetaCommands(t *testing.T) {
|
||||
if diff := cmp.Diff(outputPsqlMeta, RemovePsqlMetaCommands(inputPsqlMeta)); diff != "" {
|
||||
t.Errorf("psql meta-command mismatch:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveGolangMigrateRollback(t *testing.T) {
|
||||
filenames := map[string]bool{
|
||||
// make sure we let through golang-migrate files that aren't rollbacks
|
||||
"migrations/1.up.sql": false,
|
||||
// make sure we let through other sql files
|
||||
"migrations/2.sql": false,
|
||||
"migrations/foo.sql": false,
|
||||
"migrations/1.down.sql": true,
|
||||
}
|
||||
|
||||
for filename, want := range filenames {
|
||||
got := IsDown(filename)
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("IsDown mismatch: %s\n %s", filename, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user