sdepold/sequelize — pull request #433 by fzaninotto (2013-02-01 12:44:39+00:00)
Title: Allow migrations to process asynchronous code

Currently, only methods from QueryInterface can run asynchronously inside a migration, because only these methods can trigger the `success` event. So for instance, it is not possible to run arbitrary queries (cf #313) in migrations.

In addition, when putting several calls to a QueryInterface method in a migration, they run in parallel - which is unexpected.

```js
module.exports = {
up: function(migration, DataTypes) {
migration.addColumn('User', 'signature', DataTypes.TEXT)
migration.addColumn('User', 'shopId', { type: DataTypes.INTEGER, allowNull: true })
migration.addColumn('User', 'isAdmin', { type: DataTypes.BOOLEAN, defaultValue: false, allowNull: false })
},

down: function(migration, DataTypes) {
migration.removeColumn('User', 'signature')
migration.removeColumn('User', 'shopId')
migration.removeColumn('User', 'isAdmin')
}
}
```

Even worse: if I try to use QueryInterface mapped methods with a promise, it doesn't work, since these methods are wrapped with `extendMigrationWithQueryInterfaceMethods` (cf. #215).

What I propose is to allow asynchronous migrations to tell when they're finished - the usual Node.js way:

```js
module.exports = {
up: function(migration, DataTypes, callback) {
// do stuff like reading an SQL file and running queries in series
if (err) return callback(err); // error
callback(null); // success
},
down: function(migration, DataTypes, callback) {
// you get the idea
}
}
```

The patch is simple and doesn't break the existing QueryInterface method copy hack.

Final note: This is just my opinion, but the voodoo done in `Migration.prototype.execute`, `Migration.migrationHasInterfaceCalls`, and `extendMigrationWithQueryInterfaceMethods` is kinda unintuitive for a Node.js developer. And we're used to promises/async/callback spaghetti, so why implement a pseudo-Fiber interface in migrations?