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

Commit ddcb3c4e by Matt Broadstone

add ability to test for dialect transaction support

Transaction support is currently very limited in the MSSQL dialect,
this allows us to conditionally skip transaction related tests for
a given dialect. I imagine it's also a nice feature to have when
adding a new dialect, so you don't have to solve all one thousand
errors at the same time
1 parent 49b6352f
......@@ -32,6 +32,7 @@ AbstractDialect.prototype.supports = {
/* What is the dialect's keyword for INSERT IGNORE */
'IGNORE': '',
schemas: false,
transactions: true,
constraints: {
restrict: true
},
......
......@@ -25,26 +25,29 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
describe('getAssociation', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
Group.all({ transaction: t }).success(function(groups) {
groups[0].getUser({ transaction: t }).success(function(associatedUser) {
expect(associatedUser).to.be.not.null
t.rollback().success(function() {
done()
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
Group.all({ transaction: t }).success(function(groups) {
groups[0].getUser({ transaction: t }).success(function(associatedUser) {
expect(associatedUser).to.be.not.null
t.rollback().success(function() {
done()
})
})
})
})
......@@ -56,7 +59,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
})
})
})
}
it('does not modify the passed arguments', function () {
var User = this.sequelize.define('user', {})
......@@ -126,22 +129,25 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
describe('setAssociation', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
t.rollback().success(function() { done() })
})
})
})
})
......@@ -150,7 +156,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
})
})
})
}
it('can set the association with declared primary keys...', function(done) {
var User = this.sequelize.define('UserXYZ', { user_id: {type: DataTypes.INTEGER, primaryKey: true }, username: DataTypes.STRING })
......@@ -277,24 +283,26 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.createUser({ username: 'foo' }, { transaction: t }).success(function() {
group.getUser().success(function(user) {
expect(user).to.be.null
sequelize.sync({ force: true }).success(function() {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.createUser({ username: 'foo' }, { transaction: t }).success(function() {
group.getUser().success(function(user) {
expect(user).to.be.null
group.getUser({ transaction: t }).success(function(user) {
expect(user).not.to.be.null
group.getUser({ transaction: t }).success(function(user) {
expect(user).not.to.be.null
t.rollback().success(function() { done() })
t.rollback().success(function() { done() })
})
})
})
})
......@@ -302,7 +310,7 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
})
})
})
}
})
describe("foreign key", function () {
......
......@@ -50,43 +50,45 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
expect(Object.keys(this.Label.rawAttributes).length).to.equal(3);
});
it('supports transactions', function() {
var Article, Label, sequelize, article, label, t;
return Support.prepareTransactionTest(this.sequelize).then(function(_sequelize) {
sequelize = _sequelize;
Article = sequelize.define('Article', { 'title': DataTypes.STRING });
Label = sequelize.define('Label', { 'text': DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
var Article, Label, sequelize, article, label, t;
return Support.prepareTransactionTest(this.sequelize).then(function(_sequelize) {
sequelize = _sequelize;
Article = sequelize.define('Article', { 'title': DataTypes.STRING });
Label = sequelize.define('Label', { 'text': DataTypes.STRING });
Article.hasMany(Label);
Article.hasMany(Label);
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
Article.create({ title: 'foo' }),
Label.create({ text: 'bar' })
]);
}).spread(function (_article, _label) {
article = _article;
label = _label;
return sequelize.transaction();
}).then(function(_t) {
t = _t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return Article.all({ transaction: t });
}).then(function(articles) {
return articles[0].hasLabel(label).then(function(hasLabel) {
expect(hasLabel).to.be.false;
});
}).then(function () {
return Article.all({ transaction: t });
}).then(function(articles) {
return articles[0].hasLabel(label, { transaction: t }).then(function(hasLabel) {
expect(hasLabel).to.be.true;
return t.rollback();
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
Article.create({ title: 'foo' }),
Label.create({ text: 'bar' })
]);
}).spread(function (_article, _label) {
article = _article;
label = _label;
return sequelize.transaction();
}).then(function(_t) {
t = _t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return Article.all({ transaction: t });
}).then(function(articles) {
return articles[0].hasLabel(label).then(function(hasLabel) {
expect(hasLabel).to.be.false;
});
}).then(function () {
return Article.all({ transaction: t });
}).then(function(articles) {
return articles[0].hasLabel(label, { transaction: t }).then(function(hasLabel) {
expect(hasLabel).to.be.true;
return t.rollback();
});
});
});
});
}
it('does not have any labels assigned to it initially', function() {
return Promise.all([
......@@ -155,41 +157,43 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
return this.sequelize.sync({ force: true });
});
it('supports transactions', function () {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function () {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
this.Article.hasMany(this.Label);
return this.sequelize.sync({ force: true });
}).then(function () {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' })
]);
}).spread(function (article, label) {
this.article = article;
this.label = label;
return this.sequelize.transaction();
}).then(function(t) {
this.t = t;
return this.article.setLabels([ this.label ], { transaction: t });
}).then(function() {
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return Promise.all([
articles[0].hasLabels([ this.label ]),
articles[0].hasLabels([ this.label ], { transaction: this.t })
]);
}).spread(function(hasLabel1, hasLabel2) {
expect(hasLabel1).to.be.false;
expect(hasLabel2).to.be.true;
return this.sequelize.sync({ force: true });
}).then(function () {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' })
]);
}).spread(function (article, label) {
this.article = article;
this.label = label;
return this.sequelize.transaction();
}).then(function(t) {
this.t = t;
return this.article.setLabels([ this.label ], { transaction: t });
}).then(function() {
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return Promise.all([
articles[0].hasLabels([ this.label ]),
articles[0].hasLabels([ this.label ], { transaction: this.t })
]);
}).spread(function(hasLabel1, hasLabel2) {
expect(hasLabel1).to.be.false;
expect(hasLabel2).to.be.true;
return this.t.rollback();
return this.t.rollback();
});
});
});
}
it('answers false if only some labels have been assigned', function() {
return Promise.all([
......@@ -249,36 +253,39 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
describe('setAssociations', function() {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' }),
this.sequelize.transaction()
]);
}).spread(function(article, label, t) {
this.article = article;
this. t = t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: undefined });
}).then(function(labels) {
expect(labels.length).to.equal(0);
this.Article.hasMany(this.Label);
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' }),
this.sequelize.transaction()
]);
}).spread(function(article, label, t) {
this.article = article;
this. t = t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: undefined });
}).then(function(labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
});
});
});
}
it("clears associations when passing null to the set-method", function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
......@@ -366,37 +373,39 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
describe('addAssociations', function() {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' })
]);
}).spread(function (article, label) {
this.article = article;
this.label = label;
return this.sequelize.transaction();
}).then(function (t) {
this.t = t;
return this.article.addLabel(this.label, { transaction: this.t });
}).then(function () {
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: undefined });
}).then(function (labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' })
]);
}).spread(function (article, label) {
this.article = article;
this.label = label;
return this.sequelize.transaction();
}).then(function (t) {
this.t = t;
return this.article.addLabel(this.label, { transaction: this.t });
}).then(function () {
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: undefined });
}).then(function (labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }, transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
});
});
});
}
it('supports passing the primary key instead of an object', function () {
var Article = this.sequelize.define('Article', { 'title': DataTypes.STRING })
......@@ -521,36 +530,38 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
});
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
this.Article.hasMany(this.Label);
return sequelize.sync({ force: true});
}).then(function () {
return this.Article.create({ title: 'foo' });
}).then(function(article) {
this.article = article;
return this.sequelize.transaction();
}).then(function (t) {
this.t = t;
return this.article.createLabel({ text: 'bar' }, { transaction: this.t });
}).then(function() {
return this.Label.findAll();
}).then(function (labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }});
}).then(function(labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }}, { transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
return sequelize.sync({ force: true});
}).then(function () {
return this.Article.create({ title: 'foo' });
}).then(function(article) {
this.article = article;
return this.sequelize.transaction();
}).then(function (t) {
this.t = t;
return this.article.createLabel({ text: 'bar' }, { transaction: this.t });
}).then(function() {
return this.Label.findAll();
}).then(function (labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }});
}).then(function(labels) {
expect(labels.length).to.equal(0);
return this.Label.findAll({ where: { ArticleId: this.article.id }}, { transaction: this.t });
}).then(function(labels) {
expect(labels.length).to.equal(1);
return this.t.rollback();
});
});
});
}
it('supports passing the field option', function () {
var Article = this.sequelize.define('Article', {
......@@ -774,39 +785,41 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
});
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.sequelize = sequelize;
this.Article = sequelize.define('Article', { 'title': DataTypes.STRING });
this.Label = sequelize.define('Label', { 'text': DataTypes.STRING });
this.Article.hasMany(this.Label);
this.Label.hasMany(this.Article);
this.Article.hasMany(this.Label);
this.Label.hasMany(this.Article);
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' }),
this.sequelize.transaction()
]);
}).spread(function (article, label, t) {
this.t = t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return articles[0].getLabels();
}).then(function(labels) {
expect(labels).to.have.length(0);
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return articles[0].getLabels({ transaction: this.t });
}).then(function(labels) {
expect(labels).to.have.length(1);
return this.t.rollback();
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Article.create({ title: 'foo' }),
this.Label.create({ text: 'bar' }),
this.sequelize.transaction()
]);
}).spread(function (article, label, t) {
this.t = t;
return article.setLabels([ label ], { transaction: t });
}).then(function() {
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return articles[0].getLabels();
}).then(function(labels) {
expect(labels).to.have.length(0);
return this.Article.all({ transaction: this.t });
}).then(function(articles) {
return articles[0].getLabels({ transaction: this.t });
}).then(function(labels) {
expect(labels).to.have.length(1);
return this.t.rollback();
});
});
});
}
it('gets all associated objects with all fields', function() {
return this.User.find({where: {username: 'John'}}).then(function (john) {
......@@ -1095,36 +1108,38 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
});
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
this.User.hasMany(this.Task);
this.Task.hasMany(this.User);
this.User.hasMany(this.Task);
this.Task.hasMany(this.User);
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Task.create({ title: 'task' }),
this.sequelize.transaction()
]);
}).spread(function(task, t) {
this.task = task;
this.t = t;
return task.createUser({ username: 'foo' }, { transaction: t });
}).then(function() {
return this.task.getUsers();
}).then(function(users) {
expect(users).to.have.length(0);
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.Task.create({ title: 'task' }),
this.sequelize.transaction()
]);
}).spread(function(task, t) {
this.task = task;
this.t = t;
return task.createUser({ username: 'foo' }, { transaction: t });
}).then(function() {
return this.task.getUsers();
}).then(function(users) {
expect(users).to.have.length(0);
return this.task.getUsers({ transaction: this.t });
}).then(function(users) {
expect(users).to.have.length(1);
return this.t.rollback();
return this.task.getUsers({ transaction: this.t });
}).then(function(users) {
expect(users).to.have.length(1);
return this.t.rollback();
});
});
});
}
it('supports setting through table attributes', function () {
var User = this.sequelize.define('user', {})
......@@ -1207,77 +1222,78 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
});
});
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
if (current.dialect.supports.transactions) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
this.User.hasMany(this.Task);
this.Task.hasMany(this.User);
this.User.hasMany(this.Task);
this.Task.hasMany(this.User);
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.User.create({ username: 'foo' }),
this.Task.create({ title: 'task' }),
this.sequelize.transaction()
]);
}).spread(function(user, task, t){
this.task = task;
this.user = user;
this.t = t;
return task.addUser(user, { transaction: t });
}).then(function() {
return this.task.hasUser(this.user);
}).then(function(hasUser) {
expect(hasUser).to.be.false;
return this.task.hasUser(this.user, { transaction: this.t });
}).then(function(hasUser) {
expect(hasUser).to.be.true;
return this.t.rollback();
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.User.create({ username: 'foo' }),
this.Task.create({ title: 'task' }),
this.sequelize.transaction()
]);
}).spread(function(user, task, t){
this.task = task;
this.user = user;
this.t = t;
return task.addUser(user, { transaction: t });
}).then(function() {
return this.task.hasUser(this.user);
}).then(function(hasUser) {
expect(hasUser).to.be.false;
return this.task.hasUser(this.user, { transaction: this.t });
}).then(function(hasUser) {
expect(hasUser).to.be.true;
return this.t.rollback();
});
});
});
it('supports transactions when updating a through model', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
it('supports transactions when updating a through model', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
this.User = sequelize.define('User', { username: DataTypes.STRING });
this.Task = sequelize.define('Task', { title: DataTypes.STRING });
this.UserTask = sequelize.define('UserTask', {
status: Sequelize.STRING
});
this.UserTask = sequelize.define('UserTask', {
status: Sequelize.STRING
});
this.User.hasMany(this.Task, { through: this.UserTask });
this.Task.hasMany(this.User, { through: this.UserTask });
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.User.create({ username: 'foo' }),
this.Task.create({ title: 'task' }),
this.sequelize.transaction({ isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED })
]);
}).spread(function(user, task, t){
this.task = task;
this.user = user;
this.t = t;
return task.addUser(user, { status: 'pending' }); // Create without transaction, so the old value is accesible from outside the transaction
}).then(function() {
return this.task.addUser(this.user, { transaction: this.t, status: 'completed' }); // Add an already exisiting user in a transaction, updating a value in the join table
}).then(function(hasUser) {
return Promise.all([
this.user.getTasks(),
this.user.getTasks({ transaction: this.t })
]);
}).spread(function(tasks, transactionTasks) {
expect(tasks[0].UserTask.status).to.equal('pending');
expect(transactionTasks[0].UserTask.status).to.equal('completed');
this.User.hasMany(this.Task, { through: this.UserTask });
this.Task.hasMany(this.User, { through: this.UserTask });
this.sequelize = sequelize;
return sequelize.sync({ force: true });
}).then(function() {
return Promise.all([
this.User.create({ username: 'foo' }),
this.Task.create({ title: 'task' }),
this.sequelize.transaction({ isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED })
]);
}).spread(function(user, task, t){
this.task = task;
this.user = user;
this.t = t;
return task.addUser(user, { status: 'pending' }); // Create without transaction, so the old value is accesible from outside the transaction
}).then(function() {
return this.task.addUser(this.user, { transaction: this.t, status: 'completed' }); // Add an already exisiting user in a transaction, updating a value in the join table
}).then(function(hasUser) {
return Promise.all([
this.user.getTasks(),
this.user.getTasks({ transaction: this.t })
]);
}).spread(function(tasks, transactionTasks) {
expect(tasks[0].UserTask.status).to.equal('pending');
expect(transactionTasks[0].UserTask.status).to.equal('completed');
return this.t.rollback();
return this.t.rollback();
});
});
});
}
it('supports passing the primary key instead of an object', function () {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
......
......@@ -23,28 +23,30 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
describe('getAssocation', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.hasOne(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(fakeUser) {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
Group.all({ transaction: t }).success(function(groups) {
groups[0].getUser({ transaction: t }).success(function(associatedUser) {
expect(associatedUser).not.to.be.null
expect(associatedUser.id).to.equal(user.id)
expect(associatedUser.id).not.to.equal(fakeUser.id)
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.hasOne(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(fakeUser) {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group.setUser(user, { transaction: t }).success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
Group.all({ transaction: t }).success(function(groups) {
groups[0].getUser({ transaction: t }).success(function(associatedUser) {
expect(associatedUser).not.to.be.null
expect(associatedUser.id).to.equal(user.id)
expect(associatedUser.id).not.to.equal(fakeUser.id)
t.rollback().success(function() { done() })
})
})
})
})
......@@ -56,7 +58,7 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
})
})
})
}
it('does not modify the passed arguments', function () {
var User = this.sequelize.define('user', {})
......@@ -98,36 +100,38 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
describe('setAssociation', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.hasOne(User)
Group.hasOne(User)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group
.setUser(user, { transaction: t })
.success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
t.rollback().success(function() { done() })
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction().then(function(t) {
group
.setUser(user, { transaction: t })
.success(function() {
Group.all().success(function(groups) {
groups[0].getUser().success(function(associatedUser) {
expect(associatedUser).to.be.null
t.rollback().success(function() { done() })
})
})
})
})
.on('sql', function(sql, uuid) {
expect(uuid).to.not.equal('default')
})
.on('sql', function(sql, uuid) {
expect(uuid).to.not.equal('default')
})
})
})
})
})
})
})
})
}
it('can set an association with predefined primary keys', function(done) {
var User = this.sequelize.define('UserXYZZ', { userCoolIdTag: { type: Sequelize.INTEGER, primaryKey: true }, username: Sequelize.STRING })
......@@ -227,24 +231,26 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
, Group = sequelize.define('Group', { name: Sequelize.STRING })
User.hasOne(Group)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'bob' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.createGroup({ name: 'testgroup' }, { transaction: t }).success(function() {
User.all().success(function (users) {
users[0].getGroup().success(function (group) {
expect(group).to.be.null;
User.all({ transaction: t }).success(function (users) {
users[0].getGroup({ transaction: t }).success(function (group) {
expect(group).to.be.not.null;
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
, Group = sequelize.define('Group', { name: Sequelize.STRING })
User.hasOne(Group)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'bob' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.createGroup({ name: 'testgroup' }, { transaction: t }).success(function() {
User.all().success(function (users) {
users[0].getGroup().success(function (group) {
expect(group).to.be.null;
User.all({ transaction: t }).success(function (users) {
users[0].getGroup({ transaction: t }).success(function (group) {
expect(group).to.be.not.null;
t.rollback().success(function() { done() })
})
})
})
})
......@@ -254,7 +260,8 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
})
})
})
}
})
describe('foreign key', function () {
......
......@@ -12,6 +12,8 @@ var chai = require('chai')
, _ = require('lodash')
, moment = require('moment')
, async = require('async')
, current = Support.sequelize;
chai.use(datetime)
chai.config.includeStack = true
......@@ -694,22 +696,24 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('find', function() {
it('supports the transaction option in the first parameter', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports the transaction option in the first parameter', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({ where: { username: 'foo' }, transaction: t }).success(function(user) {
expect(user).to.not.be.null
t.rollback().success(function() { done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({ where: { username: 'foo' }, transaction: t }).success(function(user) {
expect(user).to.not.be.null
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
}
it('should not fail if model is paranoid and where is an empty array', function(done) {
var User = this.sequelize.define('User', { username: Sequelize.STRING }, { paranoid: true })
......@@ -732,29 +736,32 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('findOrInitialize', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findOrInitialize({
where: {username: 'foo'}
}).spread(function(user1) {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findOrInitialize({
where: {username: 'foo'},
transaction: t
}).spread(function(user2) {
where: {username: 'foo'}
}).spread(function(user1) {
User.findOrInitialize({
where: {username: 'foo'},
defaults: { foo: 'asd' },
transaction: t
}).spread(function(user3) {
expect(user1.isNewRecord).to.be.true
expect(user2.isNewRecord).to.be.false
expect(user3.isNewRecord).to.be.false
t.commit().success(function() { done() })
}).spread(function(user2) {
User.findOrInitialize({
where: {username: 'foo'},
defaults: { foo: 'asd' },
transaction: t
}).spread(function(user3) {
expect(user1.isNewRecord).to.be.true
expect(user2.isNewRecord).to.be.false
expect(user3.isNewRecord).to.be.false
t.commit().success(function() { done() })
})
})
})
})
......@@ -762,7 +769,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
describe('returns an instance if it already exists', function() {
it('with a single find field', function (done) {
......@@ -822,19 +829,21 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('update', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).done(function() {
User.create({ username: 'foo' }).done(function() {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).done(function(err) {
User.all().done(function(err, users1) {
User.all({ transaction: t }).done(function(err, users2) {
expect(users1[0].username).to.equal('foo')
expect(users2[0].username).to.equal('bar')
t.rollback().success(function(){ done() })
User.sync({ force: true }).done(function() {
User.create({ username: 'foo' }).done(function() {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).done(function(err) {
User.all().done(function(err, users1) {
User.all({ transaction: t }).done(function(err, users2) {
expect(users1[0].username).to.equal('foo')
expect(users2[0].username).to.equal('bar')
t.rollback().success(function(){ done() })
})
})
})
})
......@@ -842,7 +851,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
it('updates the attributes that we select only without updating createdAt', function(done) {
var User = this.sequelize.define('User1', {
......@@ -1040,19 +1049,21 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('destroy', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function() {
sequelize.transaction().then(function(t) {
User.destroy({transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(1)
expect(count2).to.equal(0)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function() {
sequelize.transaction().then(function(t) {
User.destroy({transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(1)
expect(count2).to.equal(0)
t.rollback().success(function(){ done() })
})
})
})
})
......@@ -1060,7 +1071,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
it('deletes values that match filter', function(done) {
var self = this
......@@ -1436,25 +1447,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('count', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(1)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(1)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it('counts all created objects', function(done) {
var self = this
......@@ -1536,25 +1549,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.min('age').success(function(min1) {
User.min('age', { transaction: t }).success(function(min2) {
expect(min1).to.be.not.ok
expect(min2).to.equal(2)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.min('age').success(function(min1) {
User.min('age', { transaction: t }).success(function(min2) {
expect(min1).to.be.not.ok
expect(min2).to.equal(2)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it("should return the min value", function(done) {
var self = this
......@@ -1625,25 +1640,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.max('age').success(function(min1) {
User.max('age', { transaction: t }).success(function(min2) {
expect(min1).to.be.not.ok
expect(min2).to.equal(5)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.max('age').success(function(min1) {
User.max('age', { transaction: t }).success(function(min2) {
expect(min1).to.be.not.ok
expect(min2).to.equal(5)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it("should return the max value for a field named the same as an SQL reserved keyword", function(done) {
var self = this
......@@ -2170,25 +2187,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
.then(function() { done() })
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.where({ username: "foo" }).exec().success(function(users1) {
User.where({ username: "foo" }).exec({ transaction: t }).success(function(users2) {
expect(users1).to.have.length(0)
expect(users2).to.have.length(1)
t.rollback().success(function() { done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.where({ username: "foo" }).exec().success(function(users1) {
User.where({ username: "foo" }).exec({ transaction: t }).success(function(users2) {
expect(users1).to.have.length(0)
expect(users2).to.have.length(1)
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
}
it("selects all users with name 'foo'", function(done) {
this
......@@ -2430,7 +2449,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
if (dialect !== 'sqlite') {
if (dialect !== 'sqlite' && current.dialect.supports.transactions) {
it('supports multiple async transactions', function(done) {
this.timeout(25000);
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
......
......@@ -10,6 +10,8 @@ var chai = require('chai')
, datetime = require('chai-datetime')
, _ = require('lodash')
, assert = require('assert')
, current = Support.sequelize;
chai.use(datetime)
chai.config.includeStack = true
......@@ -41,35 +43,37 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
});
describe('findOrCreate', function () {
it("supports transactions", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username' }, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.User.count().success(function(count) {
expect(count).to.equal(0)
t.commit().success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(1)
done()
if (current.dialect.supports.transactions) {
it("supports transactions", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username' }, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.User.count().success(function(count) {
expect(count).to.equal(0)
t.commit().success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(1)
done()
})
})
})
})
})
})
})
it("supports more than one models per transaction", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username'}, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.Account.findOrCreate({ where: { accountName: 'accountName'}}, { transaction: t}).then(function(){
t.commit().success(function() {
done()
it("supports more than one models per transaction", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username'}, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.Account.findOrCreate({ where: { accountName: 'accountName'}}, { transaction: t}).then(function(){
t.commit().success(function() {
done()
})
})
})
})
})
})
}
it("returns instance if already existent. Single find field.", function(done) {
var self = this,
......@@ -137,55 +141,59 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
it("should release transaction when meeting errors", function(){
var self = this
if (current.dialect.supports.transactions) {
it("should release transaction when meeting errors", function(){
var self = this
var test = function(times) {
if (times > 10) {
return true;
}
return self.Student.findOrCreate({
where: {
no: 1
var test = function(times) {
if (times > 10) {
return true;
}
})
.timeout(1000)
.catch(Promise.TimeoutError,function(e){
throw new Error(e)
})
.catch(Sequelize.ValidationError,function(err){
return test(times+1);
})
}
return self.Student.findOrCreate({
where: {
no: 1
}
})
.timeout(1000)
.catch(Promise.TimeoutError,function(e){
throw new Error(e)
})
.catch(Sequelize.ValidationError,function(err){
return test(times+1);
})
}
return test(0);
})
return test(0);
})
}
describe('several concurrent calls', function () {
it('works with a transaction', function () {
return this.sequelize.transaction().bind(this).then(function (transaction) {
return Promise.join(
this.User.findOrCreate({ where: { uniqueName: 'winner' }}, { transaction: transaction }),
this.User.findOrCreate({ where: { uniqueName: 'winner' }}, { transaction: transaction }),
function (first, second) {
var firstInstance = first[0]
, firstCreated = first[1]
, secondInstance = second[0]
, secondCreated = second[1];
// Depending on execution order and MAGIC either the first OR the second call should return true
expect(firstCreated ? !secondCreated : secondCreated).to.be.ok // XOR
expect(firstInstance).to.be.ok;
expect(secondInstance).to.be.ok;
expect(firstInstance.id).to.equal(secondInstance.id);
return transaction.commit();
}
);
if (current.dialect.supports.transactions) {
it('works with a transaction', function () {
return this.sequelize.transaction().bind(this).then(function (transaction) {
return Promise.join(
this.User.findOrCreate({ where: { uniqueName: 'winner' }}, { transaction: transaction }),
this.User.findOrCreate({ where: { uniqueName: 'winner' }}, { transaction: transaction }),
function (first, second) {
var firstInstance = first[0]
, firstCreated = first[1]
, secondInstance = second[0]
, secondCreated = second[1];
// Depending on execution order and MAGIC either the first OR the second call should return true
expect(firstCreated ? !secondCreated : secondCreated).to.be.ok // XOR
expect(firstInstance).to.be.ok;
expect(secondInstance).to.be.ok;
expect(firstInstance.id).to.equal(secondInstance.id);
return transaction.commit();
}
);
});
});
});
}
// Creating two concurrent transactions and selecting / inserting from the same table throws sqlite off
(dialect !== 'sqlite' ? it : it.skip)('works without a transaction', function () {
......@@ -287,22 +295,24 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
});
});
it('supports transactions', function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.create({ username: 'user' }, { transaction: t }).success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(0)
t.commit().success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(1)
done()
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.create({ username: 'user' }, { transaction: t }).success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(0)
t.commit().success(function() {
self.User.count().success(function(count) {
expect(count).to.equal(1)
done()
})
})
})
})
})
})
})
}
it('is possible to use casting when creating an instance', function (done) {
var self = this
......@@ -960,22 +970,24 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('bulkCreate', function() {
it("supports transactions", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User
.bulkCreate([{ username: 'foo' }, { username: 'bar' }], { transaction: t })
.success(function() {
self.User.count().success(function(count1) {
self.User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(2)
t.rollback().success(function(){ done() })
if (current.dialect.supports.transactions) {
it("supports transactions", function(done) {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User
.bulkCreate([{ username: 'foo' }, { username: 'bar' }], { transaction: t })
.success(function() {
self.User.count().success(function(count1) {
self.User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(2)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
}
it('properly handles disparate field lists', function(done) {
var self = this
......
......@@ -11,6 +11,8 @@ var chai = require('chai')
, promised = require("chai-as-promised")
, _ = require('lodash')
, async = require('async')
, current = Support.sequelize;
chai.use(promised);
chai.use(datetime)
......@@ -33,24 +35,26 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('find', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({
where: { username: 'foo' }
}).success(function(user1) {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({
where: { username: 'foo' },
}, { transaction: t }).success(function(user2) {
expect(user1).to.be.null
expect(user2).to.not.be.null
t.rollback().success(function() {
done()
where: { username: 'foo' }
}).success(function(user1) {
User.find({
where: { username: 'foo' },
}, { transaction: t }).success(function(user2) {
expect(user1).to.be.null
expect(user2).to.not.be.null
t.rollback().success(function() {
done()
})
})
})
})
......@@ -58,7 +62,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
describe('general / basic function', function() {
beforeEach(function(done) {
......
......@@ -11,6 +11,8 @@ var chai = require('chai')
, _ = require('lodash')
, moment = require('moment')
, async = require('async')
, current = Support.sequelize;
chai.use(datetime)
chai.config.includeStack = true
......@@ -33,22 +35,24 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
describe('findAll', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAll({ username: 'foo' }).success(function(users1) {
User.findAll({ transaction: t }).success(function(users2) {
User.findAll({ username: 'foo' }, { transaction: t }).success(function(users3) {
expect(users1.length).to.equal(0)
expect(users2.length).to.equal(1)
expect(users3.length).to.equal(1)
t.rollback().success(function() {
done()
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAll({ username: 'foo' }).success(function(users1) {
User.findAll({ transaction: t }).success(function(users2) {
User.findAll({ username: 'foo' }, { transaction: t }).success(function(users3) {
expect(users1.length).to.equal(0)
expect(users2.length).to.equal(1)
expect(users3.length).to.equal(1)
t.rollback().success(function() {
done()
})
})
})
})
......@@ -57,7 +61,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
describe('special where conditions/smartWhere object', function() {
beforeEach(function(done) {
......@@ -1364,26 +1368,28 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAndCountAll().success(function(info1) {
User.findAndCountAll({ transaction: t }).success(function(info2) {
expect(info1.count).to.equal(0)
expect(info2.count).to.equal(1)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAndCountAll().success(function(info1) {
User.findAndCountAll({ transaction: t }).success(function(info2) {
expect(info1.count).to.equal(0)
expect(info2.count).to.equal(1)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it("handles where clause [only]", function(done) {
this.User.findAndCountAll({where: "id != " + this.users[0].id}).success(function(info) {
......@@ -1503,25 +1509,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1.length).to.equal(0)
expect(users2.length).to.equal(1)
t.rollback().success(function(){ done() })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1.length).to.equal(0)
expect(users2.length).to.equal(1)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it("should return all users", function(done) {
this.User.all().on('success', function(users) {
......
......@@ -9,6 +9,8 @@ var chai = require('chai')
, datetime = require('chai-datetime')
, uuid = require('node-uuid')
, _ = require('lodash')
, current = Support.sequelize;
chai.use(datetime)
chai.config.includeStack = true
......@@ -272,19 +274,21 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER })
User.sync({ force: true }).success(function() {
User.create({ number: 1 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.increment('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].number).to.equal(1)
expect(users2[0].number).to.equal(3)
t.rollback().success(function() { done() })
User.sync({ force: true }).success(function() {
User.create({ number: 1 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.increment('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].number).to.equal(1)
expect(users2[0].number).to.equal(3)
t.rollback().success(function() { done() })
})
})
})
})
......@@ -292,7 +296,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
}
it('supports where conditions', function(done) {
var self = this
......@@ -416,19 +420,21 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).complete(done)
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER })
User.sync({ force: true }).success(function() {
User.create({ number: 3 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.decrement('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].number).to.equal(3)
expect(users2[0].number).to.equal(1)
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER })
User.sync({ force: true }).success(function() {
User.create({ number: 3 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.decrement('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].number).to.equal(3)
expect(users2[0].number).to.equal(1)
t.rollback().success(function() { done() })
})
})
})
})
......@@ -436,7 +442,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
}
it('with array', function(done) {
var self = this
......@@ -544,19 +550,21 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
describe('reload', function () {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).success(function() {
user.reload().success(function(user) {
expect(user.username).to.equal('foo')
user.reload({ transaction: t }).success(function(user) {
expect(user.username).to.equal('bar')
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).success(function() {
user.reload().success(function(user) {
expect(user.username).to.equal('foo')
user.reload({ transaction: t }).success(function(user) {
expect(user.username).to.equal('bar')
t.rollback().success(function() { done() })
})
})
})
})
......@@ -564,7 +572,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
}
it("should return a reference to the same DAO instead of creating a new one", function(done) {
this.User.create({ username: 'John Doe' }).complete(function(err, originalUser) {
......@@ -748,25 +756,27 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
describe('save', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.build({ username: 'foo' }).save({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(1)
t.rollback().success(function(){ done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.build({ username: 'foo' }).save({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(0)
expect(count2).to.equal(1)
t.rollback().success(function(){ done() })
})
})
})
})
})
})
})
})
}
it('only updates fields in passed array', function(done) {
var self = this
......@@ -1600,19 +1610,21 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
describe('updateAttributes', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.updateAttributes({ username: 'bar' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].username).to.equal('foo')
expect(users2[0].username).to.equal('bar')
t.rollback().success(function(){ done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.updateAttributes({ username: 'bar' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
expect(users1[0].username).to.equal('foo')
expect(users2[0].username).to.equal('bar')
t.rollback().success(function(){ done() })
})
})
})
})
......@@ -1620,7 +1632,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
}
it("updates attributes in the database", function(done) {
this.User.create({ username: 'user' }).success(function(user) {
......@@ -1734,19 +1746,21 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
describe('destroy', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.destroy({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(1)
expect(count2).to.equal(0)
t.rollback().success(function() { done() })
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.destroy({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(1)
expect(count2).to.equal(0)
t.rollback().success(function() { done() })
})
})
})
})
......@@ -1754,7 +1768,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
}
it('deletes a record from the database if dao is not paranoid', function(done) {
var UserDestroy = this.sequelize.define('UserDestroy', {
......
......@@ -11,6 +11,8 @@ var chai = require('chai')
, Transaction = require(__dirname + '/../lib/transaction')
, path = require('path')
, sinon = require('sinon')
, current = Support.sequelize;
chai.config.includeStack = true
......@@ -866,61 +868,63 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
describe('transaction', function() {
beforeEach(function(done) {
var self = this
if (current.dialect.supports.transactions) {
describe('transaction', function() {
beforeEach(function(done) {
var self = this
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
self.sequelizeWithTransaction = sequelize
done()
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
self.sequelizeWithTransaction = sequelize
done()
})
})
})
it('is a transaction method available', function() {
expect(Support.Sequelize).to.respondTo('transaction')
})
it('is a transaction method available', function() {
expect(Support.Sequelize).to.respondTo('transaction')
})
it('passes a transaction object to the callback', function(done) {
this.sequelizeWithTransaction.transaction().then(function(t) {
expect(t).to.be.instanceOf(Transaction)
done()
it('passes a transaction object to the callback', function(done) {
this.sequelizeWithTransaction.transaction().then(function(t) {
expect(t).to.be.instanceOf(Transaction)
done()
})
})
})
it('allows me to define a callback on the result', function(done) {
this
.sequelizeWithTransaction
.transaction().then(function(t) { t.commit() })
.done(done)
})
it('allows me to define a callback on the result', function(done) {
this
.sequelizeWithTransaction
.transaction().then(function(t) { t.commit() })
.done(done)
})
if (dialect === 'sqlite') {
it("correctly scopes transaction from other connections", function(done) {
var TransactionTest = this.sequelizeWithTransaction.define('TransactionTest', { name: DataTypes.STRING }, { timestamps: false })
, self = this
if (dialect === 'sqlite') {
it("correctly scopes transaction from other connections", function(done) {
var TransactionTest = this.sequelizeWithTransaction.define('TransactionTest', { name: DataTypes.STRING }, { timestamps: false })
, self = this
var count = function(transaction, callback) {
var sql = self.sequelizeWithTransaction.getQueryInterface().QueryGenerator.selectQuery('TransactionTests', { attributes: [['count(*)', 'cnt']] })
var count = function(transaction, callback) {
var sql = self.sequelizeWithTransaction.getQueryInterface().QueryGenerator.selectQuery('TransactionTests', { attributes: [['count(*)', 'cnt']] })
self
.sequelizeWithTransaction
.query(sql, null, { plain: true, raw: true, transaction: transaction })
.success(function(result) { callback(result.cnt) })
}
self
.sequelizeWithTransaction
.query(sql, null, { plain: true, raw: true, transaction: transaction })
.success(function(result) { callback(result.cnt) })
}
TransactionTest.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'foo\');', null, { plain: true, raw: true, transaction: t1 }).success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(0)
TransactionTest.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'foo\');', null, { plain: true, raw: true, transaction: t1 }).success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(0)
count(t1, function(cnt) {
expect(cnt).to.equal(1)
count(t1, function(cnt) {
expect(cnt).to.equal(1)
t1.commit().success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(1)
done()
t1.commit().success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(1)
done()
})
})
})
})
......@@ -928,43 +932,43 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
})
})
} else {
it("correctly handles multiple transactions", function(done) {
var TransactionTest = this.sequelizeWithTransaction.define('TransactionTest', { name: DataTypes.STRING }, { timestamps: false })
, self = this
var count = function(transaction, callback) {
var sql = self.sequelizeWithTransaction.getQueryInterface().QueryGenerator.selectQuery('TransactionTests', { attributes: [['count(*)', 'cnt']] })
self
.sequelizeWithTransaction
.query(sql, null, { plain: true, raw: true, transaction: transaction })
.success(function(result) { callback(parseInt(result.cnt, 10)) })
}
TransactionTest.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'foo\');', null, { plain: true, raw: true, transaction: t1 }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t2) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'bar\');', null, { plain: true, raw: true, transaction: t2 }).success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(0)
} else {
it("correctly handles multiple transactions", function(done) {
var TransactionTest = this.sequelizeWithTransaction.define('TransactionTest', { name: DataTypes.STRING }, { timestamps: false })
, self = this
var count = function(transaction, callback) {
var sql = self.sequelizeWithTransaction.getQueryInterface().QueryGenerator.selectQuery('TransactionTests', { attributes: [['count(*)', 'cnt']] })
self
.sequelizeWithTransaction
.query(sql, null, { plain: true, raw: true, transaction: transaction })
.success(function(result) { callback(parseInt(result.cnt, 10)) })
}
count(t1, function(cnt) {
expect(cnt).to.equal(1)
TransactionTest.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'foo\');', null, { plain: true, raw: true, transaction: t1 }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t2) {
self.sequelizeWithTransaction.query('INSERT INTO ' + qq('TransactionTests') + ' (' + qq('name') + ') VALUES (\'bar\');', null, { plain: true, raw: true, transaction: t2 }).success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(0)
count(t2, function(cnt) {
count(t1, function(cnt) {
expect(cnt).to.equal(1)
t2.rollback().success(function() {
count(t2, function(cnt) {
expect(cnt).to.equal(0)
count(t2, function(cnt) {
expect(cnt).to.equal(1)
t2.rollback().success(function() {
count(t2, function(cnt) {
expect(cnt).to.equal(0)
t1.commit().success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(1)
done();
t1.commit().success(function() {
count(null, function(cnt) {
expect(cnt).to.equal(1)
done();
})
})
})
})
......@@ -977,25 +981,25 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
})
})
}
}
it('supports nested transactions using savepoints', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.commit().then(function() {
user.reload({ transaction: t1 }).success(function(newUser) {
expect(newUser.username).to.equal('bar')
t1.commit().then(function() {
done()
});
it('supports nested transactions using savepoints', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.commit().then(function() {
user.reload({ transaction: t1 }).success(function(newUser) {
expect(newUser.username).to.equal('bar')
t1.commit().then(function() {
done()
});
})
})
})
})
......@@ -1003,87 +1007,87 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
})
})
describe('supports rolling back to savepoints', function () {
beforeEach(function () {
this.User = this.sequelizeWithTransaction.define('user', {});
return this.sequelizeWithTransaction.sync({ force: true });
})
describe('supports rolling back to savepoints', function () {
beforeEach(function () {
this.User = this.sequelizeWithTransaction.define('user', {});
return this.sequelizeWithTransaction.sync({ force: true });
})
it('rolls back to the first savepoint, undoing everything', function () {
return this.sequelizeWithTransaction.transaction().bind(this).then(function(transaction) {
this.transaction = transaction;
return this.sequelizeWithTransaction.transaction({ transaction: transaction });
}).then(function (sp1) {
this.sp1 = sp1;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.sequelizeWithTransaction.transaction({ transaction: this.transaction });
}).then(function (sp2) {
this.sp2 = sp2;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(2);
return this.sp1.rollback();
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(0);
return this.transaction.rollback();
it('rolls back to the first savepoint, undoing everything', function () {
return this.sequelizeWithTransaction.transaction().bind(this).then(function(transaction) {
this.transaction = transaction;
return this.sequelizeWithTransaction.transaction({ transaction: transaction });
}).then(function (sp1) {
this.sp1 = sp1;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.sequelizeWithTransaction.transaction({ transaction: this.transaction });
}).then(function (sp2) {
this.sp2 = sp2;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(2);
return this.sp1.rollback();
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(0);
return this.transaction.rollback();
});
});
});
it('rolls back to the most recent savepoint, only undoing recent changes', function () {
return this.sequelizeWithTransaction.transaction().bind(this).then(function(transaction) {
this.transaction = transaction;
return this.sequelizeWithTransaction.transaction({ transaction: transaction });
}).then(function (sp1) {
this.sp1 = sp1;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.sequelizeWithTransaction.transaction({ transaction: this.transaction });
}).then(function (sp2) {
this.sp2 = sp2;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(2);
return this.sp2.rollback();
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(1);
return this.transaction.rollback();
it('rolls back to the most recent savepoint, only undoing recent changes', function () {
return this.sequelizeWithTransaction.transaction().bind(this).then(function(transaction) {
this.transaction = transaction;
return this.sequelizeWithTransaction.transaction({ transaction: transaction });
}).then(function (sp1) {
this.sp1 = sp1;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.sequelizeWithTransaction.transaction({ transaction: this.transaction });
}).then(function (sp2) {
this.sp2 = sp2;
return this.User.create({}, { transaction: this.transaction });
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(2);
return this.sp2.rollback();
}).then(function () {
return this.User.findAll({}, { transaction: this.transaction });
}).then(function (users) {
expect(users).to.have.length(1);
return this.transaction.rollback();
});
});
});
});
it('supports rolling back a nested transaction', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.rollback().then(function() {
user.reload({ transaction: t2 }).success(function(newUser) {
expect(newUser.username).to.equal('foo')
t1.commit().then(function() {
done()
});
it('supports rolling back a nested transaction', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.rollback().then(function() {
user.reload({ transaction: t2 }).success(function(newUser) {
expect(newUser.username).to.equal('foo')
t1.commit().then(function() {
done()
});
})
})
})
})
......@@ -1091,21 +1095,21 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
})
})
it('supports rolling back outermost transaction', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t1.rollback().then(function() {
User.findAll().success(function(users) {
expect(users.length).to.equal(0);
done()
it('supports rolling back outermost transaction', function(done) {
var self = this
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING })
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t1.rollback().then(function() {
User.findAll().success(function(users) {
expect(users.length).to.equal(0);
done()
})
})
})
})
......@@ -1114,6 +1118,6 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
})
})
})
})
}
})
})
......@@ -3,6 +3,10 @@ var chai = require('chai')
, Support = require(__dirname + '/support')
, Promise = require(__dirname + '/../lib/promise')
, Transaction = require(__dirname + '/../lib/transaction')
, current = Support.sequelize;
if (current.dialect.supports.transactions) {
describe(Support.getTestDialectTeaser("Sequelize#transaction"), function () {
this.timeout(4000);
......@@ -182,3 +186,5 @@ describe(Support.getTestDialectTeaser("Sequelize#transaction"), function () {
})
})
})
}
......@@ -4,7 +4,6 @@ var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/support')
, dialect = Support.getTestDialect()
, Transaction = require(__dirname + '/../lib/transaction')
, Sequelize = require(__dirname + '/../index')
, Promise = Sequelize.Promise
, sinon = require('sinon');
......
......@@ -7,6 +7,8 @@ var chai = require('chai')
, sinon = require('sinon')
, current = Support.sequelize;
if (current.dialect.supports.transactions) {
describe(Support.getTestDialectTeaser("Transaction"), function () {
this.timeout(4000);
describe('constructor', function() {
......@@ -173,3 +175,5 @@ describe(Support.getTestDialectTeaser("Transaction"), function () {
});
}
});
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!