1
0

module.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package migres
  2. import (
  3. "slices"
  4. "sort"
  5. "github.com/annybs/go-version"
  6. )
  7. // Module provides migrations keyed by version string.
  8. // This helps to organise migrations execute upgrades or downgrades in the correct version order.
  9. //
  10. // For example:
  11. //
  12. // mod := Module{"1": migration1, "3": migration3, "2": migration2}
  13. // mod.Upgrade("1", "3")
  14. //
  15. // Here, the module's three migrations will be sorted into the proper order of 1-2-3, then their upgrades will be performed in that same order.
  16. type Module map[string]Migration
  17. // Downgrade migrations at versions after from until (and including) to.
  18. func (mod Module) Downgrade(from, to string) error {
  19. fromVersion, err := version.Parse(from)
  20. if err != nil {
  21. return err
  22. }
  23. toVersion, err := version.Parse(to)
  24. if err != nil {
  25. return err
  26. }
  27. versions, err := mod.Versions()
  28. if err != nil {
  29. return err
  30. }
  31. versions = versions.Match(&version.Constraint{
  32. Lte: fromVersion,
  33. Gt: toVersion,
  34. })
  35. sort.Stable(versions)
  36. slices.Reverse(versions)
  37. var lastVersion *version.Version
  38. for _, version := range versions {
  39. m := mod[version.Text]
  40. if err := m.Downgrade(); err != nil {
  41. return failMigration(err, version, lastVersion)
  42. }
  43. lastVersion = version
  44. }
  45. return nil
  46. }
  47. // Upgrade migrations at versions after from until (and including) to.
  48. func (mod Module) Upgrade(from, to string) error {
  49. fromVersion, err := version.Parse(from)
  50. if err != nil {
  51. return err
  52. }
  53. toVersion, err := version.Parse(to)
  54. if err != nil {
  55. return err
  56. }
  57. versions, err := mod.Versions()
  58. if err != nil {
  59. return err
  60. }
  61. versions = versions.Match(&version.Constraint{
  62. Gt: fromVersion,
  63. Lte: toVersion,
  64. })
  65. sort.Stable(versions)
  66. var lastVersion *version.Version
  67. for _, version := range versions {
  68. m := mod[version.Text]
  69. if err := m.Upgrade(); err != nil {
  70. return failMigration(err, version, lastVersion)
  71. }
  72. lastVersion = version
  73. }
  74. return nil
  75. }
  76. // Versions gets a list of all versions in the module.
  77. func (mod Module) Versions() (version.List, error) {
  78. list := version.List{}
  79. for str := range mod {
  80. v, err := version.Parse(str)
  81. if err != nil {
  82. return nil, err
  83. }
  84. list = append(list, v)
  85. }
  86. return list, nil
  87. }