improve constraint matching, migration structure
This commit is contained in:
@@ -4,11 +4,19 @@ package version
|
||||
type List []*Version
|
||||
|
||||
// Match tests versions against a constraint and returns a new List of matching versions only.
|
||||
func (list List) Match(c *Constraint) List {
|
||||
func (list List) Match(constraints ...*Constraint) List {
|
||||
filtered := List{}
|
||||
|
||||
for _, v := range list {
|
||||
if v.Match(c) {
|
||||
ok := true
|
||||
for _, c := range constraints {
|
||||
if !v.Match(c) {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ok {
|
||||
filtered = append(filtered, v)
|
||||
}
|
||||
}
|
||||
|
||||
+67
-43
@@ -4,11 +4,71 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Migration maps provide a simple way to run functions wrapped in version constraints.
|
||||
type Migration map[string]func() error
|
||||
// Migration maps provide a simple way to store and run versioned 'patch' functions.
|
||||
type Migration map[string]Patch
|
||||
|
||||
// AllVersions returns a List of all versions in the migration map.
|
||||
func (m Migration) AllVersions() (List, error) {
|
||||
// Down reverts all patches in reverse version order.
|
||||
func (m Migration) Down(after func(*Version)) 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 {
|
||||
after(v)
|
||||
}
|
||||
}
|
||||
|
||||
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 func(*Version)) error {
|
||||
versions, err := m.Versions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range versions {
|
||||
patch := m[v.Text]
|
||||
if err := patch.Up(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if after != nil {
|
||||
after(v)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -24,43 +84,7 @@ func (m Migration) AllVersions() (List, error) {
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// RequiredVersions returns a List of all versions in the migration map that are newer than a given (presumed current) version.
|
||||
// If currentVersion is nil, this is identical to AllVersions.
|
||||
func (m Migration) RequiredVersions(currentVersion *Version) (List, error) {
|
||||
l, err := m.AllVersions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if currentVersion != nil {
|
||||
c := &Constraint{
|
||||
Gt: currentVersion,
|
||||
}
|
||||
l = l.Match(c)
|
||||
}
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// Run all required migration functions in the migration map.
|
||||
// If currentVersion is nil, all migrations will be run.
|
||||
// If afterEachCallback is not nil, it will be called after each successful migration.
|
||||
func (m Migration) Run(currentVersion *Version, afterEachCallback func(*Version)) error {
|
||||
versions, err := m.RequiredVersions(currentVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range versions {
|
||||
f := m[v.Text]
|
||||
if err := f(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if afterEachCallback != nil {
|
||||
afterEachCallback(v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
type Patch struct {
|
||||
Down func() error
|
||||
Up func() error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user