package version import ( "sort" ) // AfterPatchCallback is called after each time a migration is successfully applied (up) or reverted (down). type AfterPatchCallback func(applied, next *Version) // Migration maps provide a simple way to store and run versioned 'patch' functions. type Migration map[string]Patch // Down reverts all patches in reverse version order. func (m Migration) Down(after AfterPatchCallback) error { versions, err := m.Versions() if err != nil { return err } for i := len(versions); i > 0; i-- { v := versions[i-1] patch := m[v.Text] if err := patch.Down(); err != nil { return err } if after != nil { var next *Version if i > 1 { next = versions[i-1] } after(v, next) } } return nil } // Match tests versions against a constraint and returns a new migration map of matching versions only. func (m Migration) Match(constraints ...*Constraint) (Migration, error) { l, err := m.Versions() if err != nil { return nil, err } l = l.Match(constraints...) m2 := Migration{} for _, v := range l { m2[v.Text] = m[v.Text] } return m2, nil } // Up executes all patches in version order. func (m Migration) Up(after AfterPatchCallback) error { versions, err := m.Versions() if err != nil { return err } for i, v := range versions { patch := m[v.Text] if err := patch.Up(); err != nil { return err } if after != nil { var next *Version if i < len(versions)-1 { next = versions[i+1] } after(v, next) } } return nil } // Versions returns a List of all versions in the migration map. func (m Migration) Versions() (List, error) { l := List{} for str := range m { v, err := Parse(str) if err != nil { return nil, err } l = append(l, v) } sort.Stable(l) return l, nil } type Patch struct { Down func() error Up func() error }