mirror of https://github.com/pressly/goose.git
parent
43bbf73c63
commit
11a1b26516
41
README.md
41
README.md
|
@ -37,38 +37,43 @@ Drivers:
|
|||
redshift
|
||||
|
||||
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
|
||||
|
||||
Options:
|
||||
-dir string
|
||||
directory with migration files (default ".")
|
||||
|
||||
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
|
||||
```
|
||||
## create
|
||||
|
||||
Create a new Go migration.
|
||||
Create a new SQL migration.
|
||||
|
||||
$ goose create AddSomeColumns
|
||||
$ goose: created db/migrations/20130106093224_AddSomeColumns.go
|
||||
$ goose create add_some_column sql
|
||||
$ Created new file: 00001_add_some_column.sql
|
||||
|
||||
Edit the newly created script to define the behavior of your migration.
|
||||
Edit the newly created file to define the behavior of your migration.
|
||||
|
||||
You can also create an SQL migration:
|
||||
You can also create a Go migration, if you then invoke it with [your own goose binary](#go-migrations):
|
||||
|
||||
$ goose create AddSomeColumns sql
|
||||
$ goose: created db/migrations/20130106093224_AddSomeColumns.sql
|
||||
$ goose create fetch_user_data go
|
||||
$ Created new file: 00002_fetch_user_data.go
|
||||
|
||||
## up
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/pressly/goose"
|
||||
|
||||
// Init DB drivers.
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
@ -95,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
|
||||
`
|
||||
)
|
||||
|
|
76
create.go
76
create.go
|
@ -3,16 +3,86 @@ package goose
|
|||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// Create writes a new blank migration file.
|
||||
func Create(db *sql.DB, dir, name, migrationType string) error {
|
||||
path, err := CreateMigration(name, migrationType, dir, time.Now())
|
||||
migrations, err := CollectMigrations(dir, minVersion, maxVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(fmt.Sprintf("Created %s migration at %s", migrationType, path))
|
||||
|
||||
// Initial version.
|
||||
version := "00001"
|
||||
|
||||
if last, err := migrations.Last(); err == nil {
|
||||
version = fmt.Sprintf("%05v", last.Version+1)
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v_%v.%v", version, name, migrationType)
|
||||
|
||||
fpath := filepath.Join(dir, filename)
|
||||
tmpl := sqlMigrationTemplate
|
||||
if migrationType == "go" {
|
||||
tmpl = goSQLMigrationTemplate
|
||||
}
|
||||
|
||||
path, err := writeTemplateToFile(fpath, tmpl, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Created new file: %s\n", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTemplateToFile(path string, t *template.Template, version string) (string, error) {
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("failed to create file: %v already exists", path)
|
||||
}
|
||||
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = t.Execute(f, version)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return f.Name(), nil
|
||||
}
|
||||
|
||||
var sqlMigrationTemplate = template.Must(template.New("goose.sql-migration").Parse(`-- +goose Up
|
||||
-- SQL in this section is executed when the migration is applied.
|
||||
|
||||
-- +goose Down
|
||||
-- SQL in this section is executed when the migration is rolled back.
|
||||
`))
|
||||
|
||||
var goSQLMigrationTemplate = template.Must(template.New("goose.go-migration").Parse(`package migration
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/pressly/goose"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigration(Up{{.}}, Down{{.}})
|
||||
}
|
||||
|
||||
func Up{{.}}(tx *sql.Tx) error {
|
||||
// This code is executed when the migration is applied.
|
||||
return nil
|
||||
}
|
||||
|
||||
func Down{{.}}(tx *sql.Tx) error {
|
||||
// This code is executed when the migration is rolled back.
|
||||
return nil
|
||||
}
|
||||
`))
|
||||
|
|
55
migration.go
55
migration.go
|
@ -8,7 +8,6 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -102,27 +101,6 @@ func NumericComponent(name string) (int64, error) {
|
|||
return n, e
|
||||
}
|
||||
|
||||
// CreateMigration creates a migration.
|
||||
func CreateMigration(name, migrationType, dir string, t time.Time) (path string, err error) {
|
||||
|
||||
if migrationType != "go" && migrationType != "sql" {
|
||||
return "", errors.New("migration type must be 'go' or 'sql'")
|
||||
}
|
||||
|
||||
timestamp := t.Format("20060102150405")
|
||||
filename := fmt.Sprintf("%v_%v.%v", timestamp, name, migrationType)
|
||||
|
||||
fpath := filepath.Join(dir, filename)
|
||||
tmpl := sqlMigrationTemplate
|
||||
if migrationType == "go" {
|
||||
tmpl = goSQLMigrationTemplate
|
||||
}
|
||||
|
||||
path, err = writeTemplateToFile(fpath, tmpl, timestamp)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FinalizeMigration updates the version table for the given migration,
|
||||
// and finalize the transaction.
|
||||
func FinalizeMigration(tx *sql.Tx, direction bool, v int64) error {
|
||||
|
@ -136,36 +114,3 @@ func FinalizeMigration(tx *sql.Tx, direction bool, v int64) error {
|
|||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
var sqlMigrationTemplate = template.Must(template.New("goose.sql-migration").Parse(`
|
||||
-- +goose Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
|
||||
|
||||
-- +goose Down
|
||||
-- SQL section 'Down' is executed when this migration is rolled back
|
||||
|
||||
`))
|
||||
|
||||
var goSQLMigrationTemplate = template.Must(template.New("goose.go-migration").Parse(`
|
||||
package migration
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/pressly/goose"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigration(Up{{.}}, Down{{.}})
|
||||
}
|
||||
|
||||
// Up{{.}} updates the database to the new requirements
|
||||
func Up{{.}}(tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Down{{.}} should send the database back to the state it was from before Up was ran
|
||||
func Down{{.}}(tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
`))
|
||||
|
|
40
util.go
40
util.go
|
@ -1,40 +0,0 @@
|
|||
package goose
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// common routines
|
||||
|
||||
func writeTemplateToFile(path string, t *template.Template, data interface{}) (string, error) {
|
||||
f, e := os.Create(path)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
e = t.Execute(f, data)
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
|
||||
return f.Name(), nil
|
||||
}
|
||||
|
||||
func copyFile(dst, src string) (int64, error) {
|
||||
sf, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer sf.Close()
|
||||
|
||||
df, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer df.Close()
|
||||
|
||||
return io.Copy(df, sf)
|
||||
}
|
Loading…
Reference in New Issue