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

Commit 38d1887b by Mick Hansen

Merge pull request #2654 from mbroadst/transaction-support

add ability to test for dialect transaction support
2 parents 5c5cb18a ddcb3c4e
......@@ -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
......@@ -700,22 +702,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 })
......@@ -738,29 +742,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() })
})
})
})
})
......@@ -768,7 +775,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
describe('returns an instance if it already exists', function() {
it('with a single find field', function (done) {
......@@ -828,19 +835,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() })
})
})
})
})
......@@ -848,7 +857,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', {
......@@ -1046,19 +1055,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() })
})
})
})
})
......@@ -1066,7 +1077,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
})
}
it('deletes values that match filter', function(done) {
var self = this
......@@ -1442,25 +1453,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
......@@ -1542,25 +1555,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
......@@ -1631,25 +1646,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
......@@ -2176,25 +2193,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
......@@ -2436,7 +2455,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!