Merge pull request #73 from uber/create_epoch

prefix migration files with epoch
This commit is contained in:
Matthias Kadenbach 2016-12-21 20:51:44 -08:00 committed by GitHub
commit 11b4db8a90
2 changed files with 132 additions and 106 deletions

View File

@ -10,6 +10,7 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/mattes/migrate/driver" "github.com/mattes/migrate/driver"
"github.com/mattes/migrate/file" "github.com/mattes/migrate/file"
@ -229,20 +230,23 @@ func Create(url, migrationsPath, name string) (*file.MigrationFile, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
files, err := file.ReadMigrationFiles(migrationsPath, file.FilenameRegex(d.FilenameExtension())) files, err := file.ReadMigrationFiles(migrationsPath, file.FilenameRegex(d.FilenameExtension()))
if err != nil { if err != nil {
return nil, err return nil, err
} }
version := uint64(0) version := uint64(time.Now().Unix())
if len(files) > 0 {
lastFile := files[len(files)-1] for _, f := range files {
version = lastFile.Version if f.Version == version {
version++
}
} }
version += 1
versionStr := strconv.FormatUint(version, 10) versionStr := strconv.FormatUint(version, 10)
length := 4 // TODO(mattes) check existing files and try to guess length length := 10
if len(versionStr)%length != 0 { if len(versionStr)%length != 0 {
versionStr = strings.Repeat("0", length-len(versionStr)%length) + versionStr versionStr = strings.Repeat("0", length-len(versionStr)%length) + versionStr
} }

View File

@ -3,7 +3,9 @@ package migrate
import ( import (
"io/ioutil" "io/ioutil"
"os" "os"
"regexp"
"testing" "testing"
// Ensure imports for each driver we wish to test // Ensure imports for each driver we wish to test
_ "github.com/mattes/migrate/driver/postgres" _ "github.com/mattes/migrate/driver/postgres"
@ -15,6 +17,11 @@ var driverUrls = []string{
"postgres://postgres@" + os.Getenv("POSTGRES_PORT_5432_TCP_ADDR") + ":" + os.Getenv("POSTGRES_PORT_5432_TCP_PORT") + "/template1?sslmode=disable", "postgres://postgres@" + os.Getenv("POSTGRES_PORT_5432_TCP_ADDR") + ":" + os.Getenv("POSTGRES_PORT_5432_TCP_PORT") + "/template1?sslmode=disable",
} }
func tearDown(driverUrl, tmpdir string) {
DownSync(driverUrl, tmpdir)
os.RemoveAll(tmpdir)
}
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping test in short mode.") t.Skip("skipping test in short mode.")
@ -25,6 +32,7 @@ func TestCreate(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
if _, err := Create(driverUrl, tmpdir, "test_migration"); err != nil { if _, err := Create(driverUrl, tmpdir, "test_migration"); err != nil {
t.Fatal(err) t.Fatal(err)
@ -38,23 +46,33 @@ func TestCreate(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if len(files) != 4 { if len(files) != 4 {
t.Fatal("Expected 2 new files, got", len(files)) t.Fatal("Expected 4 new files, got", len(files))
} }
fileNameRegexp := regexp.MustCompile(`^\d{10}_(.*.[up|down].sql)`)
expectFiles := []string{ expectFiles := []string{
"0001_test_migration.up.sql", "0001_test_migration.down.sql", "test_migration.up.sql", "test_migration.down.sql",
"0002_another_migration.up.sql", "0002_another_migration.down.sql", "another_migration.up.sql", "another_migration.down.sql",
} }
foundCounter := 0
for _, expectFile := range expectFiles { var foundCounter int
for _, file := range files {
if expectFile == file.Name() { for _, file := range files {
foundCounter += 1 if x := fileNameRegexp.FindStringSubmatch(file.Name()); len(x) != 2 {
break t.Errorf("expected %v to match %v", file.Name(), fileNameRegexp)
} else {
for _, expect := range expectFiles {
if expect == x[1] {
foundCounter++
break
}
} }
} }
} }
if foundCounter != len(expectFiles) { if foundCounter != len(expectFiles) {
t.Error("not all expected files have been found") t.Errorf("expected %v files, got %v", len(expectFiles), foundCounter)
} }
} }
} }
@ -65,24 +83,26 @@ func TestReset(t *testing.T) {
} }
for _, driverUrl := range driverUrls { for _, driverUrl := range driverUrls {
t.Logf("Test driver: %s", driverUrl) t.Logf("Test driver: %s", driverUrl)
tmpdir, err := ioutil.TempDir("/", "migrate-test") tmpdir, err := ioutil.TempDir("/tmp", "migrate-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration1") Create(driverUrl, tmpdir, "migration1")
Create(driverUrl, tmpdir, "migration2") f, err := Create(driverUrl, tmpdir, "migration2")
errs, ok := ResetSync(driverUrl, tmpdir)
if !ok {
t.Fatal(errs)
}
version, err := Version(driverUrl, tmpdir)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if err, ok := ResetSync(driverUrl, tmpdir); !ok {
t.Fatal(err)
}
if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != f.Version {
t.Fatalf("Expected version %v, got %v", version, f.Version)
} }
} }
} }
@ -97,32 +117,33 @@ func TestDown(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration1") initVersion, _ := Version(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration2")
errs, ok := ResetSync(driverUrl, tmpdir) firstMigration, _ := Create(driverUrl, tmpdir, "migration1")
if !ok { secondMigration, _ := Create(driverUrl, tmpdir, "migration2")
t.Fatal(errs)
} t.Logf("init %v first %v second %v", initVersion, firstMigration.Version, secondMigration.Version)
version, err := Version(driverUrl, tmpdir)
if err != nil { if err, ok := ResetSync(driverUrl, tmpdir); !ok {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != secondMigration.Version {
t.Fatalf("Expected version %v, got %v", version, secondMigration.Version)
} }
errs, ok = DownSync(driverUrl, tmpdir) if err, ok := DownSync(driverUrl, tmpdir); !ok {
if !ok {
t.Fatal(errs)
}
version, err = Version(driverUrl, tmpdir)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if version != 0 {
t.Fatalf("Expected version 0, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != 0 {
t.Fatalf("Expected 0, got %v", version)
} }
} }
} }
@ -137,32 +158,33 @@ func TestUp(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration1") initVersion, _ := Version(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration2")
errs, ok := DownSync(driverUrl, tmpdir) firstMigration, _ := Create(driverUrl, tmpdir, "migration1")
if !ok { secondMigration, _ := Create(driverUrl, tmpdir, "migration2")
t.Fatal(errs)
} t.Logf("init %v first %v second %v", initVersion, firstMigration.Version, secondMigration.Version)
version, err := Version(driverUrl, tmpdir)
if err != nil { if err, ok := DownSync(driverUrl, tmpdir); !ok {
t.Fatal(err) t.Fatal(err)
} }
if version != 0 {
t.Fatalf("Expected version 0, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != initVersion {
t.Fatalf("Expected initial version %v, got %v", initVersion, version)
} }
errs, ok = UpSync(driverUrl, tmpdir) if err, ok := UpSync(driverUrl, tmpdir); !ok {
if !ok {
t.Fatal(errs)
}
version, err = Version(driverUrl, tmpdir)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != secondMigration.Version {
t.Fatalf("Expected migrated version %v, got %v", secondMigration.Version, version)
} }
} }
} }
@ -177,32 +199,33 @@ func TestRedo(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration1") initVersion, _ := Version(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration2")
errs, ok := ResetSync(driverUrl, tmpdir) firstMigration, _ := Create(driverUrl, tmpdir, "migration1")
if !ok { secondMigration, _ := Create(driverUrl, tmpdir, "migration2")
t.Fatal(errs)
} t.Logf("init %v first %v second %v", initVersion, firstMigration.Version, secondMigration.Version)
version, err := Version(driverUrl, tmpdir)
if err != nil { if err, ok := ResetSync(driverUrl, tmpdir); !ok {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != secondMigration.Version {
t.Fatalf("Expected migrated version %v, got %v", secondMigration.Version, version)
} }
errs, ok = RedoSync(driverUrl, tmpdir) if err, ok := RedoSync(driverUrl, tmpdir); !ok {
if !ok {
t.Fatal(errs)
}
version, err = Version(driverUrl, tmpdir)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != secondMigration.Version {
t.Fatalf("Expected migrated version %v, got %v", secondMigration.Version, version)
} }
} }
} }
@ -217,44 +240,43 @@ func TestMigrate(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer tearDown(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration1") initVersion, _ := Version(driverUrl, tmpdir)
Create(driverUrl, tmpdir, "migration2")
errs, ok := ResetSync(driverUrl, tmpdir) firstMigration, _ := Create(driverUrl, tmpdir, "migration1")
if !ok { secondMigration, _ := Create(driverUrl, tmpdir, "migration2")
t.Fatal(errs)
} t.Logf("init %v first %v second %v", initVersion, firstMigration.Version, secondMigration.Version)
version, err := Version(driverUrl, tmpdir)
if err != nil { if err, ok := ResetSync(driverUrl, tmpdir); !ok {
t.Fatal(err) t.Fatal(err)
} }
if version != 2 {
t.Fatalf("Expected version 2, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != secondMigration.Version {
t.Fatalf("Expected migrated version %v, got %v", secondMigration.Version, version)
} }
errs, ok = MigrateSync(driverUrl, tmpdir, -2) if err, ok := MigrateSync(driverUrl, tmpdir, -2); !ok {
if !ok {
t.Fatal(errs)
}
version, err = Version(driverUrl, tmpdir)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if version != 0 {
t.Fatalf("Expected version 0, got %v", version)
}
errs, ok = MigrateSync(driverUrl, tmpdir, +1) if version, err := Version(driverUrl, tmpdir); err != nil {
if !ok { t.Fatal(err)
t.Fatal(errs) } else if version != 0 {
t.Fatalf("Expected 0, got %v", version)
} }
version, err = Version(driverUrl, tmpdir)
if err != nil { if err, ok := MigrateSync(driverUrl, tmpdir, +1); !ok {
t.Fatal(err) t.Fatal(err)
} }
if version != 1 {
t.Fatalf("Expected version 1, got %v", version) if version, err := Version(driverUrl, tmpdir); err != nil {
t.Fatal(err)
} else if version != firstMigration.Version {
t.Fatalf("Expected first version %v, got %v", firstMigration.Version, version)
} }
} }
} }