diff --git a/database/main.go b/database/main.go index 5381a68..bd788f7 100644 --- a/database/main.go +++ b/database/main.go @@ -20,6 +20,24 @@ type Database struct { // Run database config - connect and migrate func (config *Database) Run() error { + if err := config.run(); err != nil { + return err + } + return config.migrate(config.Testdata) +} + +// ReRun database config - connect and re migration +func (config *Database) ReRun() error { + if err := config.run(); err != nil { + return err + } + if err := config.Rollback(); err != nil { + return err + } + return config.migrate(config.Testdata) +} + +func (config *Database) run() error { db, err := gorm.Open(postgres.Open(config.Connection), &gorm.Config{ Logger: logger.Default.LogMode(config.LogLevel), }) @@ -32,9 +50,6 @@ func (config *Database) Run() error { } config.DB = db - if err = config.migrate(config.Testdata); err != nil { - return err - } return nil } diff --git a/database/migration.go b/database/migration.go index 2e64c14..fee78fa 100644 --- a/database/migration.go +++ b/database/migration.go @@ -3,7 +3,6 @@ package database import ( "sort" - "github.com/bdlm/log" gormigrate "github.com/go-gormigrate/gormigrate/v2" ) @@ -23,6 +22,24 @@ func (config *Database) sortedMigration(testdata bool) []*gormigrate.Migration { return migrations } +func (config *Database) setupMigrator(testdata bool) (*gormigrate.Gormigrate, error) { + migrations := config.sortedMigration(testdata) + if len(migrations) == 0 { + return nil, ErrNothingToMigrate + } + + return gormigrate.New(config.DB, gormigrate.DefaultOptions, migrations), nil + +} + +func (config *Database) migrate(testdata bool) error { + m, err := config.setupMigrator(testdata) + if err != nil { + return err + } + return m.Migrate() +} + // Migrate run migration func (config *Database) Migrate() error { return config.migrate(false) @@ -32,16 +49,6 @@ func (config *Database) Migrate() error { func (config *Database) MigrateTestdata() error { return config.migrate(true) } -func (config *Database) migrate(testdata bool) error { - migrations := config.sortedMigration(testdata) - if len(migrations) == 0 { - return ErrNothingToMigrate - } - - m := gormigrate.New(config.DB, gormigrate.DefaultOptions, migrations) - - return m.Migrate() -} // AddMigration add to database config migration step func (config *Database) AddMigration(m ...*gormigrate.Migration) { @@ -69,9 +76,32 @@ func (config *Database) addMigrate(testdata bool, m ...*gormigrate.Migration) { } } -// ReRun Rollback und run every migration step again till id -func (config *Database) ReRun(id string) { +// Rollback all migrations steps +func (config *Database) Rollback() error { + m, err := config.setupMigrator(true) + if err != nil { + return err + } + + for { + err = m.RollbackLast() + if err != nil { + if err == gormigrate.ErrNoRunMigration { + return nil + } + return err + } + } +} + +// ReMigrate Rollback und run every migration step again till id +func (config *Database) ReMigrate(id string) error { migrations := config.sortedMigration(true) + m, err := config.setupMigrator(true) + if err != nil { + return err + } + x := 0 for _, m := range migrations { if m.ID == id { @@ -79,20 +109,13 @@ func (config *Database) ReRun(id string) { } x = x + 1 } + // TODO not found for i := len(migrations) - 1; i >= x; i = i - 1 { - m := migrations[i] - log.Warnf("rollback %s", m.ID) - err := m.Rollback(config.DB) - if err != nil { - log.Errorf("rollback %s", err) - } - } - for _, m := range migrations { - log.Warnf("run %s", m.ID) - err := m.Migrate(config.DB) - if err != nil { - log.Errorf("run %s", err) + mStep := migrations[i] + if err := m.RollbackTo(mStep.ID); err != nil { + return err } } + return m.Migrate() } diff --git a/web/auth/api_login_test.go b/web/auth/api_login_test.go index 6053c0e..8842049 100644 --- a/web/auth/api_login_test.go +++ b/web/auth/api_login_test.go @@ -12,12 +12,10 @@ import ( func TestAPILogin(t *testing.T) { assert := assert.New(t) - s, err := webtest.New() + s, err := webtest.NewWithDBSetup(SetupMigration) assert.NoError(err) defer s.Close() assert.NotNil(s) - SetupMigration(s.DB) - s.DB.MigrateTestdata() hErr := web.HTTPError{} // invalid diff --git a/web/auth/api_my_delete_test.go b/web/auth/api_my_delete_test.go index a5c84b3..8f0a45e 100644 --- a/web/auth/api_my_delete_test.go +++ b/web/auth/api_my_delete_test.go @@ -12,12 +12,10 @@ import ( func TestAPIDeleteMyProfil(t *testing.T) { assert := assert.New(t) - s, err := webtest.New() + s, err := webtest.NewWithDBSetup(SetupMigration) assert.NoError(err) defer s.Close() assert.NotNil(s) - SetupMigration(s.DB) - s.DB.MigrateTestdata() hErr := web.HTTPError{} // invalid @@ -37,5 +35,5 @@ func TestAPIDeleteMyProfil(t *testing.T) { assert.NoError(err) assert.True(true) - s.DB.ReRun("10-data-0008-01-user") + s.DB.ReMigrate("10-data-0008-01-user") } diff --git a/web/auth/api_my_password_test.go b/web/auth/api_my_password_test.go index 6d24697..c5ac129 100644 --- a/web/auth/api_my_password_test.go +++ b/web/auth/api_my_password_test.go @@ -12,12 +12,10 @@ import ( func TestAPIPassword(t *testing.T) { assert := assert.New(t) - s, err := webtest.New() + s, err := webtest.NewWithDBSetup(SetupMigration) assert.NoError(err) defer s.Close() assert.NotNil(s) - SetupMigration(s.DB) - s.DB.MigrateTestdata() passwordCurrent := "CHANGEME" passwordNew := "test" diff --git a/web/auth/api_my_status_test.go b/web/auth/api_my_status_test.go index 8e5b414..728fe6a 100644 --- a/web/auth/api_my_status_test.go +++ b/web/auth/api_my_status_test.go @@ -12,12 +12,10 @@ import ( func TestAPIStatus(t *testing.T) { assert := assert.New(t) - s, err := webtest.New() + s, err := webtest.NewWithDBSetup(SetupMigration) assert.NoError(err) defer s.Close() assert.NotNil(s) - SetupMigration(s.DB) - s.DB.MigrateTestdata() hErr := web.HTTPError{} // invalid diff --git a/web/auth/api_password_code_test.go b/web/auth/api_password_code_test.go index 220e27d..ec3de91 100644 --- a/web/auth/api_password_code_test.go +++ b/web/auth/api_password_code_test.go @@ -13,12 +13,10 @@ import ( func TestAPIPasswordCode(t *testing.T) { assert := assert.New(t) - s, err := webtest.New() + s, err := webtest.NewWithDBSetup(SetupMigration) assert.NoError(err) defer s.Close() assert.NotNil(s) - SetupMigration(s.DB) - s.DB.MigrateTestdata() forgetCode := uuid.New() passwordCurrent := "CHANGEME" diff --git a/web/webtest/main.go b/web/webtest/main.go index 5d79e22..aa4205a 100644 --- a/web/webtest/main.go +++ b/web/webtest/main.go @@ -38,6 +38,11 @@ type Login struct { // New starts WebService for testing func New() (*testServer, error) { + return NewWithDBSetup(nil) +} + +// NewWithDBSetup allows to reconfigure before ReRun the database - e.g. for adding Migration-Steps +func NewWithDBSetup(dbCall func(db *database.Database)) (*testServer, error) { // db setup dbConfig := database.Database{ Connection: DBConnection, @@ -45,7 +50,10 @@ func New() (*testServer, error) { Debug: false, LogLevel: 0, } - err := dbConfig.Run() + if dbCall != nil { + dbCall(&dbConfig) + } + err := dbConfig.ReRun() if err != nil && err != database.ErrNothingToMigrate { return nil, err }