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

Commit 9f99f42d by Sascha Depold

transaction support for 1:N associations

1 parent 42ede1e9
var Utils = require('./../utils') var Utils = require('./../utils')
, Transaction = require('./../transaction')
module.exports = (function() { module.exports = (function() {
var HasManySingleLinked = function(definition, instance) { var HasManySingleLinked = function(definition, instance) {
...@@ -28,11 +29,12 @@ module.exports = (function() { ...@@ -28,11 +29,12 @@ module.exports = (function() {
return this.__factory.target.all(options) return this.__factory.target.all(options)
} }
HasManySingleLinked.prototype.injectSetter = function(emitter, oldAssociations, newAssociations) { HasManySingleLinked.prototype.injectSetter = function(emitter, oldAssociations, newAssociations, defaultAttributes) {
var self = this var self = this
, associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {daoFactory: {primaryKeys: {}}}).daoFactory.primaryKeys || {}) , associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {daoFactory: {primaryKeys: {}}}).daoFactory.primaryKeys || {})
, associationKey = associationKeys.length === 1 ? associationKeys[0] : 'id' , associationKey = (associationKeys.length === 1) ? associationKeys[0] : 'id'
, chainer = new Utils.QueryChainer() , chainer = new Utils.QueryChainer()
, options = {}
, obsoleteAssociations = oldAssociations.filter(function (old) { , obsoleteAssociations = oldAssociations.filter(function (old) {
return !Utils._.find(newAssociations, function (obj) { return !Utils._.find(newAssociations, function (obj) {
return obj[associationKey] === old[associationKey] return obj[associationKey] === old[associationKey]
...@@ -45,6 +47,11 @@ module.exports = (function() { ...@@ -45,6 +47,11 @@ module.exports = (function() {
}) })
, update , update
if ((defaultAttributes || {}).transaction instanceof Transaction) {
options.transaction = defaultAttributes.transaction
delete defaultAttributes.transaction
}
if (obsoleteAssociations.length > 0) { if (obsoleteAssociations.length > 0) {
// clear the old associations // clear the old associations
var obsoleteIds = obsoleteAssociations.map(function(associatedObject) { var obsoleteIds = obsoleteAssociations.map(function(associatedObject) {
...@@ -54,12 +61,17 @@ module.exports = (function() { ...@@ -54,12 +61,17 @@ module.exports = (function() {
update = {} update = {}
update[self.__factory.identifier] = null update[self.__factory.identifier] = null
var primaryKeys = Object.keys(this.__factory.target.primaryKeys) var primaryKeys = Object.keys(this.__factory.target.primaryKeys)
, primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id' , primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id'
, updateWhere = {} , updateWhere = {}
updateWhere[primaryKey] = obsoleteIds updateWhere[primaryKey] = obsoleteIds
chainer.add(this.__factory.target.update(update, updateWhere, {allowNull: [self.__factory.identifier]})) chainer.add(this.__factory.target.update(
update,
updateWhere,
Utils._.extend(options, { allowNull: [self.__factory.identifier] })
))
} }
if (unassociatedObjects.length > 0) { if (unassociatedObjects.length > 0) {
...@@ -80,7 +92,12 @@ module.exports = (function() { ...@@ -80,7 +92,12 @@ module.exports = (function() {
update = {} update = {}
update[self.__factory.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id) update[self.__factory.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id)
updateWhere[primaryKey] = unassociatedIds updateWhere[primaryKey] = unassociatedIds
chainer.add(this.__factory.target.update(update, updateWhere, {allowNull: [self.__factory.identifier]}))
chainer.add(this.__factory.target.update(
update,
updateWhere,
Utils._.extend(options, { allowNull: [self.__factory.identifier] })
))
} }
chainer chainer
......
...@@ -128,7 +128,7 @@ module.exports = (function() { ...@@ -128,7 +128,7 @@ module.exports = (function() {
var instance = this; var instance = this;
var customEventEmitter = new Utils.CustomEventEmitter(function() { var customEventEmitter = new Utils.CustomEventEmitter(function() {
instance[self.accessors.get]() instance[self.accessors.get]()
.error(function(err){ customEventEmitter.emit('error', err)}) .error(function(err) { customEventEmitter.emit('error', err) })
.success(function(associatedObjects) { .success(function(associatedObjects) {
customEventEmitter.emit('success', customEventEmitter.emit('success',
Utils._.all(objects, function(o) { Utils._.all(objects, function(o) {
...@@ -144,10 +144,10 @@ module.exports = (function() { ...@@ -144,10 +144,10 @@ module.exports = (function() {
return customEventEmitter.run() return customEventEmitter.run()
} }
obj[this.accessors.hasSingle] = function(o) { obj[this.accessors.hasSingle] = function(o, options) {
var instance = this; var instance = this
var customEventEmitter = new Utils.CustomEventEmitter(function() { var customEventEmitter = new Utils.CustomEventEmitter(function() {
instance[self.accessors.get]() instance[self.accessors.get](options)
.error(function(err){ customEventEmitter.emit('error', err)}) .error(function(err){ customEventEmitter.emit('error', err)})
.success(function(associatedObjects) { .success(function(associatedObjects) {
customEventEmitter.emit('success', customEventEmitter.emit('success',
......
...@@ -41,6 +41,37 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -41,6 +41,37 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var Article = sequelize.define('Article', { 'title': DataTypes.STRING })
, Label = sequelize.define('Label', { 'text': DataTypes.STRING })
Article.hasMany(Label)
sequelize.sync({ force: true }).success(function() {
Article.create({ title: 'foo' }).success(function(article) {
Label.create({ text: 'bar' }).success(function(label) {
sequelize.transaction(function(t) {
article.setLabels([ label ], { transaction: t }).success(function() {
Article.all({ transaction: t }).success(function(articles) {
articles[0].hasLabel(label).success(function(hasLabel) {
expect(hasLabel).to.be.false
Article.all({ transaction: t }).success(function(articles) {
articles[0].hasLabel(label, { transaction: t }).success(function(hasLabel) {
expect(hasLabel).to.be.true
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
})
})
})
it('does not have any labels assigned to it initially', function(done) { it('does not have any labels assigned to it initially', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([ var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Articl2e' }), this.Article.create({ title: 'Articl2e' }),
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!