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

Commit 84aeba59 by Mick Hansen

Update 2.0.0

2 parents 9d6560ac 061004f0
......@@ -376,9 +376,7 @@ module.exports = (function() {
if (options.hasOwnProperty('include')) {
hasJoin = true
options.include = options.include.map(function(include) {
return validateIncludedElement.call(this, include)
}.bind(this))
validateIncludedElements.call(this, options)
}
// whereCollection is used for non-primary key updates
......@@ -461,9 +459,7 @@ module.exports = (function() {
if (options.hasOwnProperty('include')) {
hasJoin = true
options.include = options.include.map(function(include) {
return validateIncludedElement.call(this, include)
}.bind(this))
validateIncludedElements.call(this, options)
}
// whereCollection is used for non-primary key updates
......@@ -558,7 +554,7 @@ module.exports = (function() {
DAOFactory.prototype.build = function(values, options) {
options = options || { isNewRecord: true, isDirty: true }
if (options.hasOwnProperty('include') && (!options.includeValidated || !options.includeNames)) {
if (options.hasOwnProperty('include') && options.include && (!options.includeValidated || !options.includeNames)) {
options.includeNames = []
options.include = options.include.map(function(include) {
include = validateIncludedElement.call(this, include)
......@@ -795,7 +791,7 @@ module.exports = (function() {
})
.error(function(err) {
emitter.emit('error', err)
}).success(function() {
}).success(function(rows) {
done()
})
}
......@@ -1203,17 +1199,37 @@ module.exports = (function() {
}.bind(this))
}
var validateIncludedElement = function(include) {
var validateIncludedElements = function(options) {
options.includeNames = []
options.includeMap = {}
options.include = options.include.map(function(include) {
include = validateIncludedElement.call(this, include, options.daoFactory)
options.includeMap[include.as] = include
options.includeNames.push(include.as)
return include
}.bind(this))
};
var validateIncludedElement = function(include, parent) {
if (include instanceof DAOFactory) {
include = { daoFactory: include, as: include.tableName }
}
if (typeof parent === "undefined") {
parent = this
}
if (typeof include === 'object') {
if (include.hasOwnProperty('model')) {
include.daoFactory = include.model
delete include.model
}
if (!include.hasOwnProperty('as')) {
include.as = include.daoFactory.tableName
}
if (include.hasOwnProperty('attributes')) {
var primaryKeys;
if (include.daoFactory.hasPrimaryKeys) {
......@@ -1231,7 +1247,7 @@ module.exports = (function() {
if (include.hasOwnProperty('daoFactory') && (include.hasOwnProperty('as'))) {
var usesAlias = (include.as !== include.daoFactory.tableName)
, association = (usesAlias ? this.getAssociationByAlias(include.as) : this.getAssociation(include.daoFactory))
, association = (usesAlias ? parent.getAssociationByAlias(include.as) : parent.getAssociation(include.daoFactory))
// If single (1:1) association, we singularize the alias, so it will match the automatically generated alias of belongsTo/HasOne
if (association && !usesAlias && association.isSingleAssociation) {
......@@ -1242,6 +1258,10 @@ module.exports = (function() {
if (!!association && (!association.options.as || (association.options.as === include.as))) {
include.association = association
if (include.hasOwnProperty('include')) {
validateIncludedElements(include)
}
return include
} else {
var msg = include.daoFactory.name
......
......@@ -541,7 +541,14 @@ module.exports = (function() {
accessor = accessor.slice(0,1).toLowerCase() + accessor.slice(1)
attrs[key].forEach(function(data) {
var daoInstance = include.daoFactory.build(data, { isNewRecord: false, isDirty: false })
var daoInstance = include.daoFactory.build(data, {
isNewRecord: false,
isDirty: false,
include: include.include,
includeNames: include.includeNames,
includeMap: include.includeMap,
includeValidated: true
})
, isEmpty = !Utils.firstValueOfHash(daoInstance.identifiers)
if (association.isSingleAssociation) {
......
......@@ -361,8 +361,9 @@ module.exports = (function() {
- offset -> An offset value to start from. Only useable with limit!
*/
selectQuery: function(tableName, options, factory) {
var table = null,
joinQuery = ""
var table = null
, self = this
, joinQuery = ""
options = options || {}
options.table = table = Array.isArray(tableName) ? tableName.map(function(t) { return this.quoteIdentifiers(t) }.bind(this)).join(", ") : this.quoteIdentifiers(tableName)
......@@ -378,39 +379,59 @@ module.exports = (function() {
if (options.include) {
var optAttributes = options.attributes === '*' ? [options.table + '.*'] : [options.attributes]
options.include.forEach(function(include) {
var attributes = include.attributes.map(function(attr) {
return this.quoteIdentifier(include.as) + "." + this.quoteIdentifier(attr) + " AS " + this.quoteIdentifier(include.as + "." + attr)
}.bind(this))
var generateJoinQuery = function(include, parentTable) {
var table = include.daoFactory.tableName
, as = include.as
, joinQueryItem = ""
, attributes
optAttributes = optAttributes.concat(attributes)
if (tableName !== parentTable) as = parentTable+'.'+include.as
attributes = include.attributes.map(function(attr) {
return self.quoteIdentifier(as) + "." + self.quoteIdentifier(attr) + " AS " + self.quoteIdentifier(as + "." + attr)
})
var table = include.daoFactory.tableName
, as = include.as
if (!(Object(include.association.through) === include.association.through)) {
var primaryKeysLeft = ((include.association.associationType === 'BelongsTo') ? Object.keys(include.association.target.primaryKeys) : Object.keys(include.association.source.primaryKeys))
, tableLeft = ((include.association.associationType === 'BelongsTo') ? include.as : tableName)
, attrLeft = ((primaryKeysLeft.length !== 1) ? 'id' : primaryKeysLeft[0])
, tableRight = ((include.association.associationType === 'BelongsTo') ? tableName : include.as)
, attrRight = include.association.identifier
optAttributes = optAttributes.concat(attributes)
joinQuery += " LEFT OUTER JOIN " + this.quoteIdentifier(table) + " AS " + this.quoteIdentifier(as) + " ON " + this.quoteIdentifier(tableLeft) + "." + this.quoteIdentifier(attrLeft) + " = " + this.quoteIdentifier(tableRight) + "." + this.quoteIdentifier(attrRight)
} else {
if (include.association.doubleLinked) {
var primaryKeysSource = Object.keys(include.association.source.primaryKeys)
, tableSource = tableName
, tableSource = parentTable
, identSource = include.association.identifier
, attrSource = ((!include.association.source.hasPrimaryKeys || primaryKeysSource.length !== 1) ? 'id' : primaryKeysSource[0])
var primaryKeysTarget = Object.keys(include.association.target.primaryKeys)
, tableTarget = include.as
, tableTarget = as
, identTarget = include.association.foreignIdentifier
, attrTarget = ((!include.association.target.hasPrimaryKeys || primaryKeysTarget.length !== 1) ? 'id' : primaryKeysTarget[0])
var tableJunction = include.association.through.tableName
joinQuery += " LEFT OUTER JOIN " + this.quoteIdentifier(tableJunction) + " ON " + this.quoteIdentifier(tableSource) + "." + this.quoteIdentifier(attrSource) + " = " + this.quoteIdentifier(tableJunction) + "." + this.quoteIdentifier(identSource)
joinQuery += " LEFT OUTER JOIN " + this.quoteIdentifier(table) + " AS " + this.quoteIdentifier(as) + " ON " + this.quoteIdentifier(tableTarget) + "." + this.quoteIdentifier(attrTarget) + " = " + this.quoteIdentifier(tableJunction) + "." + this.quoteIdentifier(identTarget)
joinQueryItem += " LEFT OUTER JOIN " + self.quoteIdentifier(tableJunction) + " ON "
joinQueryItem += self.quoteIdentifier(tableSource) + "." + self.quoteIdentifier(attrSource) + " = "
joinQueryItem += self.quoteIdentifier(tableJunction) + "." + self.quoteIdentifier(identSource)
joinQueryItem += " LEFT OUTER JOIN " + self.quoteIdentifier(table) + " AS " + self.quoteIdentifier(as) + " ON "
joinQueryItem += self.quoteIdentifier(tableTarget) + "." + self.quoteIdentifier(attrTarget) + " = "
joinQueryItem += self.quoteIdentifier(tableJunction) + "." + self.quoteIdentifier(identTarget)
} else {
var primaryKeysLeft = ((include.association.associationType === 'BelongsTo') ? Object.keys(include.association.target.primaryKeys) : Object.keys(include.association.source.primaryKeys))
, tableLeft = ((include.association.associationType === 'BelongsTo') ? as : parentTable)
, attrLeft = ((primaryKeysLeft.length !== 1) ? 'id' : primaryKeysLeft[0])
, tableRight = ((include.association.associationType === 'BelongsTo') ? parentTable : as)
, attrRight = include.association.identifier
joinQueryItem += " LEFT OUTER JOIN " + self.quoteIdentifier(table) + " AS " + self.quoteIdentifier(as) + " ON " + self.quoteIdentifier(tableLeft) + "." + self.quoteIdentifier(attrLeft) + " = " + self.quoteIdentifier(tableRight) + "." + self.quoteIdentifier(attrRight)
}
if (include.include) {
include.include.forEach(function(childInclude) {
joinQueryItem += generateJoinQuery(childInclude, as)
}.bind(this))
}
return joinQueryItem
}
options.include.forEach(function(include) {
joinQuery += generateJoinQuery(include, tableName)
}.bind(this))
options.attributes = optAttributes.join(', ')
......
......@@ -191,7 +191,7 @@ module.exports = (function() {
}
var isSelectQuery = function() {
return this.options.type === 'SELECT';
return this.options.type === 'SELECT'
}
var isUpdateQuery = function() {
......@@ -219,16 +219,14 @@ module.exports = (function() {
// Queries with include
} else if (this.options.hasJoin === true) {
this.options.includeNames = this.options.include.map(function (include) {
return include.as
})
results = groupJoinData.call(this, results)
results = groupJoinData(results, this.options)
result = results.map(function(result) {
return this.callee.build(result, {
isNewRecord: false,
isDirty: false,
include:this.options.include,
includeNames: this.options.includeNames,
includeMap: this.options.includeMap,
includeValidated: true
})
}.bind(this))
......@@ -318,18 +316,21 @@ module.exports = (function() {
]
*/
var groupJoinData = function(data) {
var self = this
, results = []
var groupJoinData = function(data, options) {
var results = []
, existingResult
, calleeData
, child
data.forEach(function (row) {
row = Dot.transform(row)
calleeData = _.omit(row, self.options.includeNames)
calleeData = _.omit(row, options.includeNames)
existingResult = _.find(results, function (result) {
return Utils._.isEqual(_.omit(result, self.options.includeNames), calleeData)
if (options.includeNames) {
return Utils._.isEqual(_.omit(result, options.includeNames.concat(['__children'])), calleeData)
}
return Utils._.isEqual(result, calleeData)
})
if (!existingResult) {
......@@ -337,16 +338,23 @@ module.exports = (function() {
}
for (var attrName in row) {
if (row.hasOwnProperty(attrName) && Object(row[attrName]) === row[attrName] && self.options.includeNames.indexOf(attrName) !== -1) {
existingResult[attrName] = existingResult[attrName] || []
var attrRowExists = existingResult[attrName].some(function(attrRow) {
return Utils._.isEqual(attrRow, row[attrName])
})
if (!attrRowExists) {
existingResult[attrName].push(row[attrName])
if (row.hasOwnProperty(attrName)) {
child = Object(row[attrName]) === row[attrName] && options.includeMap && options.includeMap[attrName]
if (child) {
if (!existingResult.__children) existingResult.__children = {}
if (!existingResult.__children[attrName]) existingResult.__children[attrName] = []
existingResult.__children[attrName].push(row[attrName])
}
}
}
}
})
results.forEach(function (result) {
_.each(result.__children, function (children, key) {
result[key] = groupJoinData(children, options.includeMap[key])
})
delete result.__children
})
return results
}
......
......@@ -37,6 +37,7 @@ module.exports = (function() {
query.on('error', function(err) {
receivedError = true
err.sql = sql
self.emit('sql', sql)
self.emit('error', err, self.callee)
})
......@@ -125,6 +126,7 @@ module.exports = (function() {
})
})
}
this.emit('success', this.send('handleSelectQuery', rows))
}
} else if (this.send('isShowOrDescribeQuery')) {
......@@ -140,9 +142,8 @@ module.exports = (function() {
this.callee[key] = record
}
}
}
this.emit('success', this.callee)
}
this.emit('success', this.callee)
} else if (this.send('isUpdateQuery')) {
if(this.callee !== null) { // may happen for bulk updates
for (var key in rows[0]) {
......
......@@ -659,7 +659,7 @@ module.exports = (function() {
}
var sql = this.QueryGenerator.selectQuery(tableName, options, factory)
queryOptions = Utils._.extend({}, queryOptions, { include: options.include })
queryOptions = Utils._.extend({}, queryOptions, { include: options.include, includeNames: options.includeNames, includeMap: options.includeMap })
return queryAndEmit.call(this, [sql, factory, queryOptions], 'select')
}
......
{
"name": "sequelize",
"description": "Multi dialect ORM for Node.JS",
"version": "2.0.0-beta.2",
"version": "1.7.0-beta.3b",
"author": "Sascha Depold <sascha@depold.com>",
"contributors": [
{
......
......@@ -367,14 +367,6 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
done()
})
it('throws an error about missing attributes if include contains an object with daoFactory', function(done) {
var self = this
expect(function() {
self.Worker.find({ include: [ { daoFactory: self.Worker } ] })
}).to.throw(Error, 'Include malformed. Expected attributes: daoFactory, as!')
done()
})
it('throws an error if included DaoFactory is not associated', function(done) {
var self = this
expect(function() {
......
......@@ -482,14 +482,6 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
done()
})
it('throws an error about missing attributes if include contains an object with daoFactory', function(done) {
var self = this
expect(function() {
self.Worker.all({ include: [ { daoFactory: self.Worker } ] })
}).to.throw(Error, 'Include malformed. Expected attributes: daoFactory, as!')
done()
})
it('throws an error if included DaoFactory is not associated', function(done) {
var self = this
expect(function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!