diff --git a/.travis.yml b/.travis.yml index 8d058c0..bb9bdd7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ sudo: false language: go go: -- 1.7 -- tip +- 1.8 install: - go get github.com/golang/dep/cmd/dep @@ -10,11 +9,13 @@ install: script: - go test -- go run ./cmd/goose/main.go -dir=example/migrations sqlite3 sql.db up -- go run ./cmd/goose/main.go -dir=example/migrations sqlite3 sql.db version -- go run ./cmd/goose/main.go -dir=example/migrations sqlite3 sql.db down -- go run ./cmd/goose/main.go -dir=example/migrations sqlite3 sql.db status -- go run ./example/migrations-go/cmd/main.go -dir=example/migrations-go sqlite3 go.db up -- go run ./example/migrations-go/cmd/main.go -dir=example/migrations-go sqlite3 go.db version -- go run ./example/migrations-go/cmd/main.go -dir=example/migrations-go sqlite3 go.db down -- go run ./example/migrations-go/cmd/main.go -dir=example/migrations-go sqlite3 go.db status +- go build -i -o goose ./cmd/goose +- ./goose -dir=example/migrations sqlite3 sql.db up +- ./goose -dir=example/migrations sqlite3 sql.db version +- ./goose -dir=example/migrations sqlite3 sql.db down +- ./goose -dir=example/migrations sqlite3 sql.db status +- go build -i -o custom-goose ./example/migrations-go +- ./custom-goose -dir=example/migrations-go sqlite3 go.db up +- ./custom-goose -dir=example/migrations-go sqlite3 go.db version +- ./custom-goose -dir=example/migrations-go sqlite3 go.db down +- ./custom-goose -dir=example/migrations-go sqlite3 go.db status diff --git a/example/migrations-go/00002_rename_root.go b/example/migrations-go/00002_rename_root.go index 7a645aa..069d40a 100644 --- a/example/migrations-go/00002_rename_root.go +++ b/example/migrations-go/00002_rename_root.go @@ -1,4 +1,4 @@ -package migrations +package main import ( "database/sql" @@ -7,10 +7,10 @@ import ( ) func init() { - goose.AddMigration(Up, Down) + goose.AddMigration(Up00002, Down00002) } -func Up(tx *sql.Tx) error { +func Up00002(tx *sql.Tx) error { _, err := tx.Exec("UPDATE users SET username='admin' WHERE username='root';") if err != nil { return err @@ -18,7 +18,7 @@ func Up(tx *sql.Tx) error { return nil } -func Down(tx *sql.Tx) error { +func Down00002(tx *sql.Tx) error { _, err := tx.Exec("UPDATE users SET username='root' WHERE username='admin';") if err != nil { return err diff --git a/example/migrations-go/README.md b/example/migrations-go/README.md new file mode 100644 index 0000000..1ff883c --- /dev/null +++ b/example/migrations-go/README.md @@ -0,0 +1,42 @@ +# SQL + Go migrations + +## Example custom goose binary with built-in Go migrations + +```bash +$ go build -o goose *.go +``` + +``` +$ ./goose sqlite3 ./foo.db status + Applied At Migration + ======================================= + Pending -- 00001_create_users_table.sql + Pending -- 00002_rename_root.go + +$ ./goose sqlite3 ./foo.db up +OK 00001_create_users_table.sql +OK 00002_rename_root.go +goose: no migrations to run. current version: 2 + +$ + Applied At Migration + ======================================= + Mon Jun 19 21:56:00 2017 -- 00001_create_users_table.sql + Mon Jun 19 21:56:00 2017 -- 00002_rename_root.go +``` + +## Best practice: Split migrations into a standalone package + +1. Move [main.go](main.go) into your `cmd/` directory + +2. Rename migration functions to `migrations` pkg + +3. Import `migrations` package from [cmd/main.go](main.go) + + ```go + import ( + _ "github.com/pressly/goose/example/migrations-go" + ) + ``` + + This will cause all `init()` functions to be called within `migrations` pkg, thus registering the migration functions properly. diff --git a/example/migrations-go/cmd/main.go b/example/migrations-go/main.go similarity index 57% rename from example/migrations-go/cmd/main.go rename to example/migrations-go/main.go index 6b7dc7d..c589029 100644 --- a/example/migrations-go/cmd/main.go +++ b/example/migrations-go/main.go @@ -9,8 +9,7 @@ import ( "github.com/pressly/goose" - _ "github.com/pressly/goose/example/migrations-go" - + // Init DB drivers. _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" @@ -27,7 +26,15 @@ func main() { flags.Parse(os.Args[1:]) args := flags.Args() - if len(args) != 3 { + + if len(args) > 1 && args[0] == "create" { + if err := goose.Run("create", nil, *dir, args[1:]...); err != nil { + log.Fatalf("goose run: %v", err) + } + return + } + + if len(args) < 3 { flags.Usage() return } @@ -63,7 +70,12 @@ func main() { log.Fatalf("-dbstring=%q: %v\n", dbstring, err) } - if err := goose.Run(command, db, *dir); err != nil { + arguments := []string{} + if len(args) > 3 { + arguments = append(arguments, args[3:]...) + } + + if err := goose.Run(command, db, *dir, arguments...); err != nil { log.Fatalf("goose run: %v", err) } } @@ -84,23 +96,28 @@ Drivers: redshift Examples: - goose postgres "user=postgres dbname=postgres sslmode=disable" up - goose mysql "user:password@/dbname" down goose sqlite3 ./foo.db status - goose redshift "postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db" create init sql + goose sqlite3 ./foo.db create init sql + goose sqlite3 ./foo.db create add_some_column sql + goose sqlite3 ./foo.db create fetch_user_data go + goose sqlite3 ./foo.db up + + goose postgres "user=postgres dbname=postgres sslmode=disable" status + goose mysql "user:password@/dbname" status + goose redshift "postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db" status Options: ` usageCommands = ` Commands: - up Migrate the DB to the most recent version available - up-to VERSION Migrate the DB to a specific VERSION - down Roll back the version by 1 - down-to VERSION Roll back to a specific VERSION - redo Re-run the latest migration - status Dump the migration status for the current DB - version Print the current version of the database - create Creates a blank migration template + up Migrate the DB to the most recent version available + up-to VERSION Migrate the DB to a specific VERSION + down Roll back the version by 1 + down-to VERSION Roll back to a specific VERSION + redo Re-run the latest migration + status Dump the migration status for the current DB + version Print the current version of the database + create NAME [sql|go] Creates new migration file with next version ` ) diff --git a/example/migrations/README.md b/example/migrations/README.md new file mode 100644 index 0000000..245c3a2 --- /dev/null +++ b/example/migrations/README.md @@ -0,0 +1,26 @@ +# SQL migrations only + +See [second example](../migrations-go) for Go migrations. + +```bash +$ go get -u github.com/pressly/goose/cmd/goose +``` + +```bash +$ goose sqlite3 ./foo.db status + Applied At Migration + ======================================= + Pending -- 00001_create_users_table.sql + Pending -- 00002_rename_root.sql + +$ goose sqlite3 ./foo.db up +OK 00001_create_users_table.sql +OK 00002_rename_root.sql +goose: no migrations to run. current version: 2 + +$ + Applied At Migration + ======================================= + Mon Jun 19 21:56:00 2017 -- 00001_create_users_table.sql + Mon Jun 19 21:56:00 2017 -- 00002_rename_root.sql +```