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

You need to sign in or sign up before continuing.
Commit 5f4a5637 by Mick Hansen

Merge pull request #2605 from mbroadst/restrict-support

only enable RESTRICT fk constraint tests for supporting dialects
2 parents d5cef99f 8a12e05d
...@@ -11,6 +11,9 @@ AbstractDialect.prototype.supports = { ...@@ -11,6 +11,9 @@ AbstractDialect.prototype.supports = {
'VALUES ()': false, 'VALUES ()': false,
'LIMIT ON UPDATE': false, 'LIMIT ON UPDATE': false,
schemas: false, schemas: false,
constraints: {
restrict: true
},
index: { index: {
collate: true, collate: true,
length: false, length: false,
......
...@@ -6,6 +6,7 @@ var chai = require('chai') ...@@ -6,6 +6,7 @@ var chai = require('chai')
, Sequelize = require('../../index') , Sequelize = require('../../index')
, Promise = Sequelize.Promise , Promise = Sequelize.Promise
, assert = require('assert') , assert = require('assert')
, current = Support.sequelize;
chai.config.includeStack = true chai.config.includeStack = true
...@@ -428,6 +429,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -428,6 +429,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
if (current.dialect.supports.constraints.restrict) {
it("can restrict deletes", function(done) { it("can restrict deletes", function(done) {
var self = this var self = this
var Task = this.sequelize.define('Task', { title: DataTypes.STRING }) var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
...@@ -453,11 +455,12 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -453,11 +455,12 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
it("can cascade updates", function(done) { it("can restrict updates", function(done) {
var self = this
var Task = this.sequelize.define('Task', { title: DataTypes.STRING }) var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: DataTypes.STRING }) , User = this.sequelize.define('User', { username: DataTypes.STRING })
Task.belongsTo(User, {onUpdate: 'cascade'}) Task.belongsTo(User, {onUpdate: 'restrict'})
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
...@@ -470,10 +473,10 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -470,10 +473,10 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model) var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.success(function() { .catch(self.sequelize.ForeignKeyConstraintError, function() {
// Should fail due to FK restriction
Task.findAll().success(function(tasks) { Task.findAll().success(function(tasks) {
expect(tasks).to.have.length(1) expect(tasks).to.have.length(1)
expect(tasks[0].UserId).to.equal(999)
done() done()
}) })
}) })
...@@ -483,12 +486,13 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -483,12 +486,13 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
it("can restrict updates", function(done) { }
var self = this
it("can cascade updates", function(done) {
var Task = this.sequelize.define('Task', { title: DataTypes.STRING }) var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: DataTypes.STRING }) , User = this.sequelize.define('User', { username: DataTypes.STRING })
Task.belongsTo(User, {onUpdate: 'restrict'}) Task.belongsTo(User, {onUpdate: 'cascade'})
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
...@@ -501,10 +505,10 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -501,10 +505,10 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model) var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.catch(self.sequelize.ForeignKeyConstraintError, function() { .success(function() {
// Should fail due to FK restriction
Task.findAll().success(function(tasks) { Task.findAll().success(function(tasks) {
expect(tasks).to.have.length(1) expect(tasks).to.have.length(1)
expect(tasks[0].UserId).to.equal(999)
done() done()
}) })
}) })
...@@ -513,6 +517,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() { ...@@ -513,6 +517,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
}) })
}) })
describe("Association column", function() { describe("Association column", function() {
......
...@@ -9,7 +9,8 @@ var chai = require('chai') ...@@ -9,7 +9,8 @@ var chai = require('chai')
, _ = require('lodash') , _ = require('lodash')
, moment = require('moment') , moment = require('moment')
, sinon = require('sinon') , sinon = require('sinon')
, Promise = Sequelize.Promise; , Promise = Sequelize.Promise
, current = Support.sequelize;
chai.config.includeStack = true; chai.config.includeStack = true;
...@@ -2252,57 +2253,58 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -2252,57 +2253,58 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}); });
}); });
it("can restrict deletes", function() { it("can cascade updates", function() {
var self = this;
var Task = this.sequelize.define('Task', { title: DataTypes.STRING }) var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: DataTypes.STRING }); , User = this.sequelize.define('User', { username: DataTypes.STRING });
User.hasMany(Task, {onDelete: 'restrict'}); User.hasMany(Task, {onUpdate: 'cascade'});
return this.sequelize.sync({ force: true }).bind({}).then(function() { return this.sequelize.sync({ force: true }).then(function () {
return Promise.all([ return Promise.all([
User.create({ username: 'foo' }), User.create({ username: 'foo' }),
Task.create({ title: 'task' }), Task.create({ title: 'task' }),
]); ]);
}).spread(function (user, task) { }).spread(function (user, task) {
this.user = user; return user.setTasks([task]).return(user);
this.task = task; }).then(function(user) {
return user.setTasks([task]); // Changing the id of a DAO requires a little dance since
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model);
return user.QueryInterface.update(user, tableName, {id: 999}, user.id);
}).then(function() { }).then(function() {
return this.user.destroy().catch(self.sequelize.ForeignKeyConstraintError, function () {
// Should fail due to FK violation
return Task.findAll(); return Task.findAll();
});
}).then(function(tasks) { }).then(function(tasks) {
expect(tasks).to.have.length(1); expect(tasks).to.have.length(1);
expect(tasks[0].UserId).to.equal(999);
}); });
}); });
it("can cascade updates", function() { if (current.dialect.supports.constraints.restrict) {
it("can restrict deletes", function() {
var self = this;
var Task = this.sequelize.define('Task', { title: DataTypes.STRING }) var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: DataTypes.STRING }); , User = this.sequelize.define('User', { username: DataTypes.STRING });
User.hasMany(Task, {onUpdate: 'cascade'}); User.hasMany(Task, {onDelete: 'restrict'});
return this.sequelize.sync({ force: true }).then(function () { return this.sequelize.sync({ force: true }).bind({}).then(function() {
return Promise.all([ return Promise.all([
User.create({ username: 'foo' }), User.create({ username: 'foo' }),
Task.create({ title: 'task' }), Task.create({ title: 'task' }),
]); ]);
}).spread(function (user, task) { }).spread(function (user, task) {
return user.setTasks([task]).return(user); this.user = user;
}).then(function(user) { this.task = task;
// Changing the id of a DAO requires a little dance since return user.setTasks([task]);
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model);
return user.QueryInterface.update(user, tableName, {id: 999}, user.id);
}).then(function() { }).then(function() {
return this.user.destroy().catch(self.sequelize.ForeignKeyConstraintError, function () {
// Should fail due to FK violation
return Task.findAll(); return Task.findAll();
});
}).then(function(tasks) { }).then(function(tasks) {
expect(tasks).to.have.length(1); expect(tasks).to.have.length(1);
expect(tasks[0].UserId).to.equal(999);
}); });
}); });
...@@ -2335,6 +2337,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -2335,6 +2337,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
expect(tasks).to.have.length(1); expect(tasks).to.have.length(1);
}); });
}); });
}
}); });
describe('n:m', function () { describe('n:m', function () {
...@@ -2382,6 +2387,8 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -2382,6 +2387,8 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}); });
}); });
if (current.dialect.supports.constraints.restrict) {
it("can restrict deletes both ways", function () { it("can restrict deletes both ways", function () {
var self = this var self = this
, spy = sinon.spy(); , spy = sinon.spy();
...@@ -2452,6 +2459,8 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -2452,6 +2459,8 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}); });
}); });
}
it("should be possible to remove all constraints", function () { it("should be possible to remove all constraints", function () {
var self = this; var self = this;
......
...@@ -4,6 +4,7 @@ var chai = require('chai') ...@@ -4,6 +4,7 @@ var chai = require('chai')
, Support = require(__dirname + '/../support') , Support = require(__dirname + '/../support')
, Sequelize = require('../../index') , Sequelize = require('../../index')
, Promise = Sequelize.Promise , Promise = Sequelize.Promise
, current = Support.sequelize;
chai.config.includeStack = true chai.config.includeStack = true
...@@ -386,22 +387,28 @@ describe(Support.getTestDialectTeaser("HasOne"), function() { ...@@ -386,22 +387,28 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
}) })
}) })
it("can restrict deletes", function(done) { it("can cascade updates", function(done) {
var self = this
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var Task = this.sequelize.define('Task', { title: Sequelize.STRING })
, User = this.sequelize.define('User', { username: Sequelize.STRING }) , User = this.sequelize.define('User', { username: Sequelize.STRING })
User.hasOne(Task, {onDelete: 'restrict'}) User.hasOne(Task, {onUpdate: 'cascade'})
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() { Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) { Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() { user.setTask(task).success(function() {
user.destroy().catch(self.sequelize.ForeignKeyConstraintError, function() {
// Should fail due to FK restriction // Changing the id of a DAO requires a little dance since
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model)
user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.success(function() {
Task.findAll().success(function(tasks) { Task.findAll().success(function(tasks) {
expect(tasks).to.have.length(1) expect(tasks).to.have.length(1)
expect(tasks[0].UserId).to.equal(999)
done() done()
}) })
}) })
...@@ -412,28 +419,24 @@ describe(Support.getTestDialectTeaser("HasOne"), function() { ...@@ -412,28 +419,24 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
}) })
}) })
it("can cascade updates", function(done) { if (current.dialect.supports.constraints.restrict) {
it("can restrict deletes", function(done) {
var self = this
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var Task = this.sequelize.define('Task', { title: Sequelize.STRING })
, User = this.sequelize.define('User', { username: Sequelize.STRING }) , User = this.sequelize.define('User', { username: Sequelize.STRING })
User.hasOne(Task, {onUpdate: 'cascade'}) User.hasOne(Task, {onDelete: 'restrict'})
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() { Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) { Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() { user.setTask(task).success(function() {
user.destroy().catch(self.sequelize.ForeignKeyConstraintError, function() {
// Changing the id of a DAO requires a little dance since // Should fail due to FK restriction
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.Model)
user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.success(function() {
Task.findAll().success(function(tasks) { Task.findAll().success(function(tasks) {
expect(tasks).to.have.length(1) expect(tasks).to.have.length(1)
expect(tasks[0].UserId).to.equal(999)
done() done()
}) })
}) })
...@@ -477,6 +480,8 @@ describe(Support.getTestDialectTeaser("HasOne"), function() { ...@@ -477,6 +480,8 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
}) })
}) })
}
}) })
describe("Association column", function() { describe("Association column", function() {
......
...@@ -244,7 +244,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -244,7 +244,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
references: 'level', references: 'level',
referenceKey: 'id', referenceKey: 'id',
onUpdate: 'cascade', onUpdate: 'cascade',
onDelete: 'restrict' onDelete: 'set null'
}); });
}); });
}); });
...@@ -292,7 +292,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -292,7 +292,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
references: 'users', references: 'users',
referenceKey: 'id', referenceKey: 'id',
onUpdate: 'cascade', onUpdate: 'cascade',
onDelete: 'restrict' onDelete: 'set null'
}, },
}) })
}) })
...@@ -308,7 +308,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -308,7 +308,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
if (dialect === "postgres" || dialect === "postgres-native") { if (dialect === "postgres" || dialect === "postgres-native") {
expect(keys).to.have.length(6) expect(keys).to.have.length(6)
expect(keys2).to.have.length(7) expect(keys2).to.have.length(7)
expect(keys3).to.have.length(8) expect(keys3).to.have.length(7)
} else if (dialect === "sqlite") { } else if (dialect === "sqlite") {
expect(keys).to.have.length(8) expect(keys).to.have.length(8)
} else if (dialect === "mysql") { } else if (dialect === "mysql") {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!