From f7699f1dec88e29259ab9cb2e64e1b4e9da7769b Mon Sep 17 00:00:00 2001 From: Matthias Kadenbach Date: Tue, 7 Feb 2017 22:59:12 -0800 Subject: [PATCH] update go-bindata with latest source.Migration helper --- README.md | 2 +- source/go-bindata/README.md | 4 +- source/go-bindata/go-bindata.go | 141 +++++---------------------- source/go-bindata/go-bindata_test.go | 2 +- 4 files changed, 30 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index ab17b36..be50791 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ is easy. Just implement the [source/driver interface](source/driver.go). ## CLI usage -```bash +``` # dowload, build and install the CLI tool # -tags takes database and source drivers and will only build those $ go get -u -tags 'postgres' -o migrate github.com/mattes/migrate/cli diff --git a/source/go-bindata/README.md b/source/go-bindata/README.md index fa82e0d..c774543 100644 --- a/source/go-bindata/README.md +++ b/source/go-bindata/README.md @@ -33,8 +33,8 @@ import ( ) func main() { - // Wrap assets into Resource - resource := bindata.Resource(migrations.AssetNames(), + // wrap assets into Resource + s := bindata.Resource(migrations.AssetNames(), func(name string) ([]byte, error) { return migrations.Asset(name) }) diff --git a/source/go-bindata/go-bindata.go b/source/go-bindata/go-bindata.go index 447c814..7426db7 100644 --- a/source/go-bindata/go-bindata.go +++ b/source/go-bindata/go-bindata.go @@ -6,9 +6,6 @@ import ( "io" "io/ioutil" "os" - "regexp" - "sort" - "strconv" "github.com/mattes/migrate/source" ) @@ -31,15 +28,10 @@ func init() { source.Register("go-bindata", &Bindata{}) } -// filename example: `123_name.up.ext` -// filename example: `123_name.down.ext` -var filenameRegex = regexp.MustCompile(`^([0-9]+)_(.*)\.(` + string(down) + `|` + string(up) + `)\.(.*)$`) - type Bindata struct { path string - filesIndex uintSlice - files map[uint]map[direction]file assetSource *AssetSource + migrations *source.Migrations } func (b *Bindata) Open(url string) (source.Driver, error) { @@ -59,35 +51,20 @@ func WithInstance(instance interface{}) (source.Driver, error) { bn := &Bindata{ path: "", assetSource: as, + migrations: source.NewMigrations(), } - // parse file names and create internal data structure - bn.files = make(map[uint]map[direction]file) for _, fi := range as.Names { - pf, err := parseFilename(fi) + m, err := source.DefaultParse(fi) if err != nil { continue // ignore files that we can't parse } - if bn.files[pf.version] == nil { - bn.files[pf.version] = make(map[direction]file) + if !bn.migrations.Append(m) { + return nil, fmt.Errorf("unable to parse file %v", fi) } - - // reject duplicate versions - if dupf, dup := bn.files[pf.version][pf.direction]; dup { - return nil, fmt.Errorf("duplicate file: %v and %v", dupf.filename, fi) - } - - bn.files[pf.version][pf.direction] = *pf } - // create index and sort - bn.filesIndex = make(uintSlice, 0) - for version, _ := range bn.files { - bn.filesIndex = append(bn.filesIndex, version) - } - sort.Sort(bn.filesIndex) - return bn, nil } @@ -96,113 +73,47 @@ func (b *Bindata) Close() error { } func (b *Bindata) First() (version uint, err error) { - if len(b.filesIndex) == 0 { + if v, ok := b.migrations.First(); !ok { return 0, &os.PathError{"first", b.path, os.ErrNotExist} + } else { + return v, nil } - return b.filesIndex[0], nil } func (b *Bindata) Prev(version uint) (prevVersion uint, err error) { - pos := b.findPos(version) - if pos >= 1 && len(b.filesIndex) > pos-1 { - return b.filesIndex[pos-1], nil + if v, ok := b.migrations.Prev(version); !ok { + return 0, &os.PathError{fmt.Sprintf("prev for version %v", version), b.path, os.ErrNotExist} + } else { + return v, nil } - return 0, &os.PathError{fmt.Sprintf("prev for version %v", version), b.path, os.ErrNotExist} } func (b *Bindata) Next(version uint) (nextVersion uint, err error) { - pos := b.findPos(version) - if pos >= 0 && len(b.filesIndex) > pos+1 { - return b.filesIndex[pos+1], nil + if v, ok := b.migrations.Next(version); !ok { + return 0, &os.PathError{fmt.Sprintf("next for version %v", version), b.path, os.ErrNotExist} + } else { + return v, nil } - return 0, &os.PathError{fmt.Sprintf("next for version %v", version), b.path, os.ErrNotExist} } func (b *Bindata) ReadUp(version uint) (r io.ReadCloser, identifier string, err error) { - if _, ok := b.files[version]; ok { - if upFile, ok := b.files[version][up]; ok { - body, err := b.assetSource.AssetFunc(upFile.filename) - if err != nil { - return nil, "", err - } - return ioutil.NopCloser(bytes.NewReader(body)), upFile.name, nil + if m, ok := b.migrations.Up(version); ok { + body, err := b.assetSource.AssetFunc(m.Raw) + if err != nil { + return nil, "", err } + return ioutil.NopCloser(bytes.NewReader(body)), m.Identifier, nil } return nil, "", &os.PathError{fmt.Sprintf("read version %v", version), b.path, os.ErrNotExist} } func (b *Bindata) ReadDown(version uint) (r io.ReadCloser, identifier string, err error) { - if _, ok := b.files[version]; ok { - if downFile, ok := b.files[version][down]; ok { - body, err := b.assetSource.AssetFunc(downFile.filename) - if err != nil { - return nil, "", err - } - return ioutil.NopCloser(bytes.NewReader(body)), downFile.name, nil + if m, ok := b.migrations.Down(version); ok { + body, err := b.assetSource.AssetFunc(m.Raw) + if err != nil { + return nil, "", err } + return ioutil.NopCloser(bytes.NewReader(body)), m.Identifier, nil } return nil, "", &os.PathError{fmt.Sprintf("read version %v", version), b.path, os.ErrNotExist} } - -// findPos finds the position of a file in the index -// returns -1 if the version can't be found -func (b *Bindata) findPos(version uint) int { - if len(b.filesIndex) > 0 { - for i, v := range b.filesIndex { - if v == version { - return i - } - } - } - return -1 -} - -// file contains parsed filename details -type file struct { - version uint - name string - direction direction - extension string - filename string -} - -var errParseFilenameNoMatch = fmt.Errorf("no match") - -func parseFilename(filename string) (*file, error) { - m := filenameRegex.FindStringSubmatch(filename) - if len(m) == 5 { - versionUint64, err := strconv.ParseUint(m[1], 10, 32) - if err != nil { - return nil, err - } - return &file{ - version: uint(versionUint64), - name: m[2], - direction: direction(m[3]), - extension: m[4], - filename: filename, - }, nil - } - return nil, errParseFilenameNoMatch -} - -type direction string - -const ( - down direction = "down" - up = "up" -) - -type uintSlice []uint - -func (s uintSlice) Len() int { - return len(s) -} - -func (s uintSlice) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s uintSlice) Less(i, j int) bool { - return s[i] < s[j] -} diff --git a/source/go-bindata/go-bindata_test.go b/source/go-bindata/go-bindata_test.go index 58eadf1..746a7b9 100644 --- a/source/go-bindata/go-bindata_test.go +++ b/source/go-bindata/go-bindata_test.go @@ -22,7 +22,7 @@ func Test(t *testing.T) { } func TestWithInstance(t *testing.T) { - // wrap assets into Resource first + // wrap assets into Resource s := Resource(testdata.AssetNames(), func(name string) ([]byte, error) { return testdata.Asset(name)