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

Commit 18243c9f by Jan Aagaard Meier

Initial commit for join table model

1 parent 4dbb571f
......@@ -18,14 +18,13 @@ module.exports = (function() {
where[self.__factory.connectorDAO.tableName+"."+self.__factory.identifier] = self.instance[instancePrimaryKey]
var primaryKeys = Object.keys(self.__factory.connectorDAO.rawAttributes)
var primaryKeys = Object.keys(self.__factory.connectorDAO.primaryKeys)
, foreignKey = primaryKeys.filter(function(pk) { return pk != self.__factory.identifier })[0]
, foreignPrimary = Object.keys(self.__factory.target.primaryKeys)
foreignPrimary = foreignPrimary.length === 1 ? foreignPrimary[0] : 'id'
where[self.__factory.connectorDAO.tableName+"."+foreignKey] = {join: self.__factory.target.tableName+"."+foreignPrimary}
if (options.where) {
if (Array.isArray(options.where)) {
smart = Utils.smartWhere([where, options.where], self.__factory.target.daoFactoryManager.sequelize.options.dialect)
......@@ -53,26 +52,41 @@ module.exports = (function() {
return customEventEmitter.run()
}
HasManyDoubleLinked.prototype.injectSetter = function(emitterProxy, oldAssociations, newAssociations) {
HasManyDoubleLinked.prototype.injectSetter = function(emitterProxy, oldAssociations, newAssociations, defaultAttributes) {
var self = this
, chainer = new Utils.QueryChainer()
, association = self.__factory.target.associations[self.__factory.associationAccessor]
, foreignIdentifier = association.isSelfAssociation ? association.foreignIdentifier : association.identifier
, sourceKeys = Object.keys(self.__factory.source.primaryKeys)
, targetKeys = Object.keys(self.__factory.target.primaryKeys)
, obsoleteAssociations = []
, changedAssociations = []
, unassociatedObjects;
var obsoleteAssociations = oldAssociations.filter(function (old) {
// Return only those old associations that are not found in new
return !Utils._.find(newAssociations, function (obj) {
return ((targetKeys.length === 1) ? obj[targetKeys[0]] === old[targetKeys[0]] : obj.id === old.id)
unassociatedObjects = newAssociations.filter(function (obj) {
return !Utils._.find(oldAssociations, function (old) {
return (!!obj[foreignIdentifier] && !!old[foreignIdentifier] ? obj[foreignIdentifier] === old[foreignIdentifier] : obj.id === old.id)
})
})
var unassociatedObjects = newAssociations.filter(function (obj) {
// Return only those associations that are new
return !Utils._.find(oldAssociations, function (old) {
return ((targetKeys.length === 1) ? obj[targetKeys[0]] === old[targetKeys[0]] : obj.id === old.id)
oldAssociations.forEach(function (old) {
var newObj = Utils._.find(newAssociations, function (obj) {
return (!!obj[foreignIdentifier] && !!old[foreignIdentifier] ? obj[foreignIdentifier] === old[foreignIdentifier] : obj.id === old.id)
})
if (!newObj) {
obsoleteAssociations.push(obj)
} else if (association.customJoinTableModel) {
var changedAssociation = {
where: {},
attributes: Utils._.defaults({}, newObj[self.__factory.connectorDAO.name], defaultAttributes)
}
changedAssociation.where[self.__factory.identifier] = self.instance[self.__factory.identifier] || self.instance.id
changedAssociation.where[foreignIdentifier] = newObj[foreignIdentifier] || newObj.id
changedAssociations.push(changedAssociation)
}
})
if (obsoleteAssociations.length > 0) {
......@@ -93,12 +107,22 @@ module.exports = (function() {
attributes[self.__factory.identifier] = ((sourceKeys.length === 1) ? self.instance[sourceKeys[0]] : self.instance.id)
attributes[foreignIdentifier] = ((targetKeys.length === 1) ? unassociatedObject[targetKeys[0]] : unassociatedObject.id)
if (association.customJoinTableModel) {
attributes = Utils._.defaults(attributes, unassociatedObject[association.connectorDAO.name], defaultAttributes)
}
return attributes
})
chainer.add(self.__factory.connectorDAO.bulkCreate(bulk))
}
if (changedAssociations.length > 0) {
changedAssociations.forEach(function (assoc) {
chainer.add(self.__factory.connectorDAO.update(assoc.attributes, assoc.where))
})
}
chainer
.run()
.success(function() { emitterProxy.emit('success', newAssociations) })
......@@ -106,7 +130,7 @@ module.exports = (function() {
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
}
HasManyDoubleLinked.prototype.injectAdder = function(emitterProxy, newAssociation) {
HasManyDoubleLinked.prototype.injectAdder = function(emitterProxy, newAssociation, additionalAttributes, exists) {
var attributes = {}
, association = this.__factory.target.associations[this.__factory.associationAccessor]
, foreignIdentifier = association.isSelfAssociation ? association.foreignIdentifier : association.identifier;
......@@ -117,10 +141,21 @@ module.exports = (function() {
attributes[this.__factory.identifier] = ((sourceKeys.length === 1) ? this.instance[sourceKeys[0]] : this.instance.id)
attributes[foreignIdentifier] = ((targetKeys.length === 1) ? newAssociation[targetKeys[0]] : newAssociation.id)
this.__factory.connectorDAO.create(attributes)
.success(function() { emitterProxy.emit('success', newAssociation) })
.error(function(err) { emitterProxy.emit('error', err) })
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
if (exists) { // implies customJoinTableModel === true
var where = attributes
attributes = Utils._.defaults({}, newAssociation[association.connectorDAO.name], additionalAttributes)
association.connectorDAO.update(attributes, where).proxy(emitterProxy)
} else {
if (association.customJoinTableModel === true) {
attributes = Utils._.defaults(attributes, newAssociation[association.connectorDAO.name], additionalAttributes)
}
this.__factory.connectorDAO.create(attributes)
.success(function() { emitterProxy.emit('success', newAssociation) })
.error(function(err) { emitterProxy.emit('error', err) })
.on('sql', function(sql) { emitterProxy.emit('sql', sql) })
}
}
return HasManyDoubleLinked
......
......@@ -13,13 +13,20 @@ module.exports = (function() {
this.options = options
this.useJunctionTable = this.options.useJunctionTable === undefined ? true : this.options.useJunctionTable
this.isSelfAssociation = (this.source.tableName === this.target.tableName)
this.customJoinTableModel = !!this.options.joinTableModel
var combinedTableName = Utils.combineTableNames(
this.source.tableName,
this.isSelfAssociation ? (this.options.as || this.target.tableName) : this.target.tableName
)
this.associationAccessor = this.combinedName = (this.options.joinTableName || combinedTableName)
this.options.tableName = this.combinedName
var combinedTableName;
if (this.customJoinTableModel) {
combinedTableName = this.options.joinTableModel.tableName
} else if (this.options.joinTableName) {
combinedTableName = this.options.joinTableName
} else {
Utils.combineTableNames(
this.source.tableName,
this.isSelfAssociation ? (this.options.as || this.target.tableName) : this.target.tableName
)
}
this.options.tableName = this.associationAccessor = this.combinedName = combinedTableName
var as = (this.options.as || Utils.pluralize(this.target.tableName, this.target.options.language))
......@@ -61,7 +68,17 @@ module.exports = (function() {
combinedTableAttributes[this.identifier] = {type: sourceKeyType, primaryKey: true}
combinedTableAttributes[this.foreignIdentifier] = {type: targetKeyType, primaryKey: true}
this.connectorDAO = this.source.daoFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
if (this.customJoinTableModel === true) {
this.connectorDAO = this.options.joinTableModel
this.connectorDAO.rawAttributes = Utils._.merge(this.connectorDAO.rawAttributes, combinedTableAttributes)
// FIXME - Should we do this? Normally join tables does not have an id, and it is not needed,
// but users might wonder what hapened if they defined the ID themselves
delete this.connectorDAO.rawAttributes.id
this.connectorDAO.init(this.connectorDAO.daoFactoryManager)
} else {
this.connectorDAO = this.source.daoFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
}
if (!this.isSelfAssociation) {
this.target.associations[this.associationAccessor].connectorDAO = this.connectorDAO
......@@ -92,7 +109,7 @@ module.exports = (function() {
return new Class(self, this).injectGetter(options)
}
obj[this.accessors.hasAll] = function(objects) {
obj[this.accessors.hasAll] = function(objects) {
var instance = this;
var customEventEmitter = new Utils.CustomEventEmitter(function() {
instance[self.accessors.get]()
......@@ -135,7 +152,7 @@ module.exports = (function() {
HasMany.prototype.injectSetter = function(obj) {
var self = this
obj[this.accessors.set] = function(newAssociatedObjects) {
obj[this.accessors.set] = function(newAssociatedObjects, defaultAttributes) {
if (newAssociatedObjects === null) {
newAssociatedObjects = []
}
......@@ -147,7 +164,7 @@ module.exports = (function() {
instance[self.accessors.get]()
.success(function(oldAssociatedObjects) {
var Class = self.connectorDAO ? HasManyMultiLinked : HasManySingleLinked
new Class(self, instance).injectSetter(emitter, oldAssociatedObjects, newAssociatedObjects)
new Class(self, instance).injectSetter(emitter, oldAssociatedObjects, newAssociatedObjects, defaultAttributes)
})
.error(function(err) {
emitter.emit('error', err)
......@@ -158,20 +175,21 @@ module.exports = (function() {
}).run()
}
obj[this.accessors.add] = function(newAssociatedObject) {
obj[this.accessors.add] = function(newAssociatedObject, additionalAttributes) {
var instance = this
, primaryKeys = Object.keys(newAssociatedObject.daoFactory.primaryKeys || {})
, primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id'
, where = {}
where[newAssociatedObject.daoFactory.tableName+'.'+primaryKey] = newAssociatedObject[primaryKey]
return new Utils.CustomEventEmitter(function(emitter) {
instance[self.accessors.get]({ where: where })
.error(function(err){ emitter.emit('error', err)})
.success(function(currentAssociatedObjects) {
if (currentAssociatedObjects.length === 0) {
if (currentAssociatedObjects.length === 0 || self.customJoinTableModel === true) {
var Class = self.connectorDAO ? HasManyMultiLinked : HasManySingleLinked
new Class(self, instance).injectAdder(emitter, newAssociatedObject)
new Class(self, instance).injectAdder(emitter, newAssociatedObject, additionalAttributes, !!currentAssociatedObjects.length)
} else {
emitter.emit('success', newAssociatedObject);
}
......@@ -186,8 +204,9 @@ module.exports = (function() {
var newAssociations = []
currentAssociatedObjects.forEach(function(association) {
if (!Utils._.isEqual(oldAssociatedObject.identifiers, association.identifiers))
if (!Utils._.isEqual(oldAssociatedObject.identifiers, association.identifiers)) {
newAssociations.push(association)
}
})
instance[self.accessors.set](newAssociations)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!