func TestMigrate_Locking(t *testing.T) { db := newDB(t) defer db.Close() migrator := migrate.NewMigrator(db) if *database == Postgres { migrator = migrate.NewPostgresMigrator(db) } err := migrator.Exec(migrate.Up, testMigrations...) assert.NoError(t, err) assertSchema(t, ` people CREATE TABLE people (id int, first_name text) `, db) assert.Equal(t, []int{1, 2}, appliedMigrations(t, db)) var called int // Generates a migration that sends on the given channel when it starts. migration := migrate.Migration{ ID: 3, Up: func(tx *sql.Tx) error { called++ _, err := tx.Exec(`INSERT INTO people (id, first_name) VALUES (1, 'Eric')`) return err }, } m1 := make(chan error) m2 := make(chan error) // Start two migrations in parallel. go func() { m1 <- migrator.Exec(migrate.Up, migration) }() go func() { m2 <- migrator.Exec(migrate.Up, migration) }() assert.Nil(t, <-m1) assert.Nil(t, <-m2) assert.Equal(t, 1, called) assertSchema(t, ` people CREATE TABLE people (id int, first_name text) `, db) assert.Equal(t, []int{1, 2, 3}, appliedMigrations(t, db)) }
func TestMigrate_SingleTransactionMode_Commit(t *testing.T) { db := newDB(t) defer db.Close() migrator := migrate.NewMigrator(db) migrator.TransactionMode = migrate.SingleTransaction err := migrator.Exec(migrate.Up, testMigrations...) assert.NoError(t, err) assert.Equal(t, []int{1, 2}, appliedMigrations(t, db)) assertSchema(t, ` people CREATE TABLE people (id int, first_name text) `, db) }
func TestMigrate_SingleTransactionMode_Rollback(t *testing.T) { db := newDB(t) defer db.Close() migrator := migrate.NewMigrator(db) migrator.TransactionMode = migrate.SingleTransaction migrations := []migrate.Migration{ testMigrations[0], testMigrations[1], migrate.Migration{ ID: 3, Up: func(tx *sql.Tx) error { return errors.New("Rollback") }, }, } err := migrator.Exec(migrate.Up, migrations...) assert.Error(t, err) assert.Equal(t, []int{}, appliedMigrations(t, db)) assertSchema(t, ``, db) }