diff --git a/GUIDE.md b/GUIDE.md index b58802d..53011af 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -22,13 +22,13 @@ Just do: `go get github.com/cristalhq/dbump/dbump_XXX` with a specific `XXX` and | Mode | Description | |---|---| -| ModeNotSet | Default value in config, should not be used. -| ModeUp | Apply all the migrations that weren't applied yet. -| ModeDown | Revert all the migrations that were applied. -| ModeUpOne | Apply only 1 migration. -| ModeDownOne | Revert only current migration. -| ModeRedo | Revert and apply again current migration. -| ModeDrop | Revert all migrations and remove `dbump` table. +| ModeNotSet | Default value in config, should not be used. +| ModeApplyAll | Apply all the migrations that weren't applied yet. +| ModeApplyN | Apply only 1 migration. +| ModeRevertN | Revert only current migration. +| ModeRevertAll | Revert all the migrations that were applied. +| ModeRedo | Revert and apply again current migration. +| ModeDrop | Revert all migrations and remove `dbump` table. ## ZigZag mode diff --git a/README.md b/README.md index 84d0a62..7143833 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ ctx := context.Background() cfg := dbump.Config{ Migrator: dbump_pg.NewMigrator(db), Loader: dbump.NewFileSysLoader(embed, "/"), - Mode: dbump.ModeUp, + Mode: dbump.ModeApplyAll, } err := dbump.Run(ctx, cfg) diff --git a/dbump.go b/dbump.go index 762c0a6..d5b0faa 100644 --- a/dbump.go +++ b/dbump.go @@ -30,6 +30,10 @@ type Config struct { // Set mode explicitly to show how migration should be done. Mode MigratorMode + // Num is a value for ModeApplyN or ModeRevertN modes. + // Must be greater than 0 for this two modes. + Num int + // Timeout per migration step. Default is 0 which means no timeout. // Only Migrator.DoStep method will be bounded with this timeout. Timeout time.Duration @@ -70,7 +74,7 @@ type Migrator interface { Init(ctx context.Context) error // Drop is used only in ModeDrop to remove dbump database. - // Before drop all the migrations will be reverted (as for ModeDown). + // Before drop all the migrations will be reverted (as for ModeRevertAll). Drop(ctx context.Context) error // Version of the migration. Used only once in the beginning. @@ -105,10 +109,10 @@ type MigratorMode int const ( ModeNotSet MigratorMode = iota - ModeUp - ModeDown - ModeUpOne - ModeDownOne + ModeApplyAll + ModeApplyN + ModeRevertN + ModeRevertAll ModeRedo ModeDrop modeMaxPossible @@ -130,6 +134,8 @@ func Run(ctx context.Context, config Config) error { return errors.New("mode not set") case config.Mode >= modeMaxPossible: return fmt.Errorf("incorrect mode provided: %d", config.Mode) + case config.Num <= 0 && (config.Mode == ModeApplyN || config.Mode == ModeRevertN): + return fmt.Errorf("num must be greater than 0: %d", config.Num) } if config.BeforeStep == nil { @@ -249,29 +255,29 @@ func (m *mig) getCurrAndTargetVersions(ctx context.Context, migrations int) (cur } switch m.Mode { - case ModeUp: + case ModeApplyAll: target = migrations if curr > target { return 0, 0, errors.New("current is greater than target") } - case ModeDown: - if curr > migrations { - return 0, 0, errors.New("current is greater than migrations count") - } - target = 0 - - case ModeUpOne: - target = curr + 1 + case ModeApplyN: + target = curr + m.Num if target > migrations { return 0, 0, errors.New("target is greater than migrations count") } - case ModeDownOne: + case ModeRevertN: if curr > migrations { return 0, 0, errors.New("current is greater than migrations count") } - target = curr - 1 + target = curr - m.Num + + case ModeRevertAll: + if curr > migrations { + return 0, 0, errors.New("current is greater than migrations count") + } + target = 0 case ModeRedo: if curr > migrations { diff --git a/dbump_test.go b/dbump_test.go index ff3a90c..ddd9f9e 100644 --- a/dbump_test.go +++ b/dbump_test.go @@ -39,6 +39,22 @@ func TestRunCheck(t *testing.T) { Mode: modeMaxPossible + 1, }, }, + { + testName: "num not set", + cfg: Config{ + Migrator: &MockMigrator{}, + Loader: NewSliceLoader(nil), + Mode: ModeApplyN, + }, + }, + { + testName: "num not set", + cfg: Config{ + Migrator: &MockMigrator{}, + Loader: NewSliceLoader(nil), + Mode: ModeRevertN, + }, + }, } for _, tc := range testCases { @@ -46,7 +62,7 @@ func TestRunCheck(t *testing.T) { } } -func TestMigrateUp(t *testing.T) { +func TestMigrateApplyAll(t *testing.T) { wantLog := []string{ "lockdb", "init", "getversion", "dostep", "{v:1 q:'SELECT 1;' notx:true}", @@ -61,7 +77,7 @@ func TestMigrateUp(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, DisableTx: true, // for shorter wantLog } @@ -82,14 +98,14 @@ func TestMigrateUpWhenFull(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfErr(t, Run(context.Background(), cfg)) mustEqual(t, mm.log, wantLog) } -func TestMigrateUpOne(t *testing.T) { +func TestMigrateApplyN(t *testing.T) { currVersion := 3 wantLog := []string{ "lockdb", "init", "getversion", @@ -105,14 +121,15 @@ func TestMigrateUpOne(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUpOne, + Mode: ModeApplyN, + Num: 1, } failIfErr(t, Run(context.Background(), cfg)) mustEqual(t, mm.log, wantLog) } -func TestMigrateDown(t *testing.T) { +func TestMigrateRevertAll(t *testing.T) { wantLog := []string{ "lockdb", "init", "getversion", "dostep", "{v:4 q:'SELECT 50;' notx:true}", @@ -131,7 +148,7 @@ func TestMigrateDown(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeDown, + Mode: ModeRevertAll, DisableTx: true, // for shorter wantLog } @@ -139,7 +156,7 @@ func TestMigrateDown(t *testing.T) { mustEqual(t, mm.log, wantLog) } -func TestMigrateDownWhenEmpty(t *testing.T) { +func TestMigrateRevertAllWhenEmpty(t *testing.T) { wantLog := []string{ "lockdb", "init", "getversion", "unlockdb", } @@ -152,14 +169,14 @@ func TestMigrateDownWhenEmpty(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeDown, + Mode: ModeRevertAll, } failIfErr(t, Run(context.Background(), cfg)) mustEqual(t, mm.log, wantLog) } -func TestMigrateDownOne(t *testing.T) { +func TestMigrateRevertN(t *testing.T) { currVersion := 3 wantLog := []string{ "lockdb", "init", "getversion", @@ -175,7 +192,8 @@ func TestMigrateDownOne(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeDownOne, + Mode: ModeRevertN, + Num: 1, } failIfErr(t, Run(context.Background(), cfg)) @@ -253,7 +271,7 @@ func TestBeforeAfterStep(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, BeforeStep: func(ctx context.Context, step Step) { mm.log = append(mm.log, "before", fmt.Sprintf("{v:%d q:'%s' notx:%v}", step.Version, step.Query, step.DisableTx)) }, @@ -286,7 +304,7 @@ func TestTimeout(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, Timeout: 20 * time.Millisecond, } @@ -309,7 +327,7 @@ func TestLockless(t *testing.T) { cfg := Config{ Migrator: AsLocklessMigrator(mm), Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfErr(t, Run(context.Background(), cfg)) @@ -345,7 +363,7 @@ func TestUseForce(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, UseForce: true, DisableTx: true, // for shorter wantLog } @@ -383,7 +401,7 @@ func TestZigZag(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, DisableTx: true, // for shorter wantLog ZigZag: true, } @@ -402,7 +420,7 @@ func TestFailOnInitError(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) @@ -419,7 +437,7 @@ func TestFailOnLockDB(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) @@ -444,7 +462,7 @@ func TestFailOnUnlockDB(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) @@ -463,7 +481,7 @@ func TestFailOnGetVersionError(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) @@ -484,7 +502,7 @@ func TestFailOnDoStepError(t *testing.T) { cfg := Config{ Migrator: mm, Loader: NewSliceLoader(testdataMigrations), - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) @@ -499,7 +517,7 @@ func TestFailOnLoad(t *testing.T) { return nil, errors.New("forgot to commit") }, }, - Mode: ModeUp, + Mode: ModeApplyAll, } failIfOk(t, Run(context.Background(), cfg)) } diff --git a/example_test.go b/example_test.go index 5ad95d5..9c2027e 100644 --- a/example_test.go +++ b/example_test.go @@ -14,7 +14,7 @@ func ExampleMigrator() { err := dbump.Run(ctx, dbump.Config{ Migrator: m, Loader: l, - Mode: dbump.ModeUp, + Mode: dbump.ModeApplyAll, }) if err != nil { panic(err)