// OpenDB returns a new gorm.DB instance. func OpenDB(uri string) (*DB, error) { u, err := url.Parse(uri) if err != nil { return nil, err } conn, err := sql.Open(u.Scheme, uri) if err != nil { return nil, err } db, err := gorm.Open(u.Scheme, conn) if err != nil { return nil, err } m := migrate.NewPostgresMigrator(conn) // Run all migrations in a single transaction, so they will be rolled // back as one. This is almost always the behavior that users would want // when upgrading Empire. If a new release has multiple migrations, and // one of those fails, it's easier for them if the entire upgrade rolls // back instead of getting stuck in failed state. m.TransactionMode = migrate.SingleTransaction return &DB{ DB: &db, uri: uri, migrator: m, }, nil }
// migrate runs all available migrations on a pgSQL database. func migrateDatabase(db *sql.DB) error { log.Info("running database migrations") err := migrate.NewPostgresMigrator(db).Exec(migrate.Up, migrations.Migrations...) if err != nil { return fmt.Errorf("pgsql: an error occured while running migrations: %v", err) } log.Info("database migration ran successfully") return nil }
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)) }