不要怂,就是干,撸起袖子干!

Commit 38157a65 by Sascha Depold

migrations aren't synchronous anymore

1 parent 916473b5
......@@ -5,8 +5,6 @@ var moment = require("moment")
module.exports = (function() {
var Migration = function(migrator, path) {
var split = path.split('/')
this.migrator = migrator
this.path = path
this.filename = Utils._.last(this.path.split('/'))
......@@ -16,7 +14,16 @@ module.exports = (function() {
this.migrationId = parsed.id
this.date = parsed.date;
this.queryInterface = this.migrator.queryInterface
this.undoneMethods = 0
}
for (var methodName in QueryInterface.prototype) {
if (QueryInterface.prototype.hasOwnProperty(methodName) && (typeof QueryInterface.prototype[methodName]) === 'function') {
(function(methodName) {
Migration.prototype[methodName] = function() {
return this.queryInterface[methodName].apply(this.queryInterface, arguments)
}
})(methodName)
}
}
///////////////
......@@ -31,23 +38,11 @@ module.exports = (function() {
}
return {
id: parseInt(matches[1]),
id: parseInt(matches[1], 10),
date: moment(matches.slice(2, 8).join('-'), 'YYYYMMDDHHmmss')
}
}
Migration.migrationHasInterfaceCalls = function(func) {
var functionString = Utils.removeCommentsFromFunctionString(func.toString())
, hasCalls = false
for(var method in QueryInterface.prototype) {
var regex = new RegExp('[\\s\\n\\r]*\\.[\\s\\n\\r]*' + method)
hasCalls = hasCalls || regex.test(functionString)
}
return hasCalls
}
///////////////
// member /////
///////////////
......@@ -59,22 +54,19 @@ module.exports = (function() {
})
Migration.prototype.execute = function(options) {
var self = this
return new Utils.CustomEventEmitter(function(emitter) {
options = Utils._.extend({
method: 'up'
}, options || {})
var onSuccess = function() { emitter.emit('success', null) }
, func = self.migration[options.method]
extendMigrationWithQueryInterfaceMethods.call(self, onSuccess)
func.call(null, self, DataTypes)
if (!Migration.migrationHasInterfaceCalls(func))
onSuccess()
}).run()
this.migration[options.method].call(null, this, DataTypes, function(err) {
if (err) {
emitter.emit('error', err)
} else {
emitter.emit('success', null)
}
})
}.bind(this)).run()
}
Migration.prototype.isBefore = function(dateString, options) {
......@@ -97,36 +89,5 @@ module.exports = (function() {
return options.withoutEqual ? (date < this.date) : (date <= this.date)
}
// extends the Migration prototype with all methods of QueryInterface.prototype
// with additional tracking of start and finish. this is done in order to minimize
// asynchronous handling in migrations
var extendMigrationWithQueryInterfaceMethods = function(callback) {
var self = this
for(var method in QueryInterface.prototype) {
(function(_method) {
self[_method] = function() {
var emitter = self.QueryInterface
, args = Utils._.map(arguments, function(arg, _) { return arg })
self.undoneMethods++
// bind listeners to the query interface
// the event will have the same name like the method
self.queryInterface.on(_method, function(err) {
self.undoneMethods--
if (err) {
throw new Error(err)
} else {
(self.undoneMethods == 0) && callback && callback()
}
})
return self.queryInterface[_method].apply(self.queryInterface, args)
}
})(method)
}
}
return Migration
})()
......@@ -6,7 +6,7 @@ module.exports = (function() {
var QueryInterface = function(sequelize) {
this.sequelize = sequelize
this.QueryGenerator = require('./dialects/' + this.sequelize.options.dialect + '/query-generator')
this.QueryGenerator.options = this.sequelize.options;
this.QueryGenerator.options = this.sequelize.options
}
Utils.addEventEmitter(QueryInterface)
......
module.exports = {
up: function(migration, DataTypes) {
migration.createTable('Person', {
name: DataTypes.STRING,
isBetaMember: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false
}
})
up: function(migration, DataTypes, done) {
migration
.createTable('Person', {
name: DataTypes.STRING,
isBetaMember: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false
}
})
.complete(done)
},
down: function(migration) {
migration.dropTable('Person')
down: function(migration, DataTypes, done) {
migration.dropTable('Person').complete(done)
}
}
module.exports = {
up: function() {},
down: function() {}
up: function(migration, DataTypes, done) { done() },
down: function(migration, DataTypes, done) { done() }
}
module.exports = {
up: function(migration, DataTypes) {
migration.renameTable('Person', 'User')
up: function(migration, DataTypes, done) {
migration.renameTable('Person', 'User').complete(done)
},
down: function(migration, DataTypes) {
migration.renameTable('User', 'Person')
down: function(migration, DataTypes, done) {
migration.renameTable('User', 'Person').complete(done)
}
}
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 })
up: function(migration, DataTypes, done) {
migration
.addColumn('User', 'isAdmin', { type: DataTypes.BOOLEAN, defaultValue: false, allowNull: false })
.complete(function(err) {
if (err) {
done(err)
} else {
migration
.addColumn('User', 'signature', DataTypes.TEXT)
.complete(function(err) {
if (err) {
done(err)
} else {
migration.addColumn('User', 'shopId', { type: DataTypes.INTEGER, allowNull: true }).complete(done)
}
})
}
})
},
down: function(migration, DataTypes) {
migration.removeColumn('User', 'signature')
migration.removeColumn('User', 'shopId')
migration.removeColumn('User', 'isAdmin')
down: function(migration, DataTypes, done) {
migration.removeColumn('User', 'signature').complete(function(err) {
if (err) {
done(err)
} else {
migration.removeColumn('User', 'shopId').complete(function(err) {
if (err) {
done(err)
} else {
migration.removeColumn('User', 'isAdmin').complete(done)
}
})
}
})
}
}
module.exports = {
up: function(migration, DataTypes) {
migration.removeColumn('User', 'shopId')
up: function(migration, DataTypes, done) {
migration.removeColumn('User', 'shopId').complete(done)
},
down: function(migration, DataTypes) {
migration.addColumn('User', 'shopId', { type: DataTypes.INTEGER, allowNull: true })
down: function(migration, DataTypes, done) {
migration.addColumn('User', 'shopId', { type: DataTypes.INTEGER, allowNull: true }).complete(done)
}
}
module.exports = {
up: function(migration, DataTypes) {
up: function(migration, DataTypes, done) {
migration.changeColumn('User', 'signature', {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'Signature'
})
}).complete(done)
},
down: function(migration, DataTypes) {}
down: function(migration, DataTypes, done) { done() }
}
module.exports = {
up: function(migration, DataTypes) {
migration.renameColumn('User', 'signature', 'sig')
up: function(migration, DataTypes, done) {
migration.renameColumn('User', 'signature', 'sig').complete(done)
},
down: function(migration, DataTypes) {
migration.renameColumn('User', 'sig', 'signature')
down: function(migration, DataTypes, done) {
migration.renameColumn('User', 'sig', 'signature').complete(done)
}
}
if(typeof require === 'function') {
const buster = require("buster")
, QueryChainer = require("../lib/query-chainer")
, CustomEventEmitter = require("../lib/emitters/custom-event-emitter")
, Helpers = require('./buster-helpers')
, dialect = Helpers.getTestDialect()
, Migrator = require("../lib/migrator")
, Migration = require("../lib/migration")
}
buster.spec.expose()
buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("Migration"), function() {
describe('migrationHasInterfaceCalls', function() {
// the syntax in the following tests are correct
// don't touch them! the functions will get stringified below
var tests = [
{
topic: function(migration, DataTypes) {
migration.createTable()
},
expectation: true
},
{
topic: function(migration, DataTypes) {
// migration.createTable()
},
expectation: false
},
{
topic: function(migration, DataTypes) {
migration
.createTable()
},
expectation: true
},
{
topic: function(migration, DataTypes) {
migration.
createTable()
},
expectation: true
},
{
topic: function(migration, DataTypes) {
migration . createTable ()
},
expectation: true
},
{
topic: function(migration, DataTypes) {
/*
migration . createTable()
*/
},
expectation: false
},
{
topic: function(migration, DataTypes) {
migration/* noot noot */.createTable()
},
expectation: true
}
]
tests.forEach(function(test) {
it('correctly result in ' + test.expectation + ' for ' + test.topic.toString(), function() {
expect(Migration.migrationHasInterfaceCalls(test.topic)).toEqual(test.expectation)
})
})
})
})
......@@ -8,7 +8,7 @@ if(typeof require === 'function') {
}
buster.spec.expose()
buster.testRunner.timeout = 1000
buster.testRunner.timeout = 10000
describe(Helpers.getTestDialectTeaser("Migrator"), function() {
before(function(done) {
......@@ -186,23 +186,18 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
})
describe('addColumn', function() {
it('//adds a column to the user table', function(done) {
it('adds a column to the user table', function(done) {
this.init({ from: 20111117063700, to: 20111205162700 }, function(migrator) {
migrator.migrate().success(function() {
this.sequelize.getQueryInterface().describeTable('User').success(function(data) {
migrator.migrate().complete(function(err) {
this.sequelize.getQueryInterface().describeTable('User').complete(function(err, data) {
var signature = data.signature
, isAdmin = data.isAdmin
, shopId = data.shopId
expect(signature.Field).toEqual('signature')
expect(signature.Null).toEqual('NO')
expect(isAdmin.Field).toEqual('isAdmin')
expect(isAdmin.Null).toEqual('NO')
expect(isAdmin.Default).toEqual('0')
expect(shopId.Field).toEqual('shopId')
expect(shopId.Null).toEqual('YES')
expect(signature.allowNull).toEqual(true)
expect(isAdmin.allowNull).toEqual(false)
expect(isAdmin.defaultValue).toEqual(false)
expect(shopId.allowNull).toEqual(true)
done()
})
......
......@@ -159,7 +159,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
}.bind(this))
})
itEventually("doesn't save an instance if value is not in the range of enums", function(done) {
it("//doesn't save an instance if value is not in the range of enums", function(done) {
this.Review.create({ status: 'fnord' }).error(function(err) {
expect(1).toEqual(1)
done()
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!