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

Commit 6501dca6 by Mick Hansen

Merge pull request #1555 from sequelize/perf

Performance improvements on includes
2 parents 6dbdde03 cfd0db95
......@@ -13,8 +13,6 @@ module.exports = (function() {
this._previousDataValues = {}
this.__options = this.Model.options
this.options = options
this.hasPrimaryKeys = this.Model.options.hasPrimaryKeys
this.__eagerlyLoadedAssociations = []
this.isNewRecord = options.isNewRecord
initValues.call(this, values, options);
......@@ -161,7 +159,9 @@ module.exports = (function() {
}
} else {
options || (options = {})
if (!options.raw) {
originalValue = this.dataValues[key]
}
// If not raw, and there's a customer setter
if (!options.raw && this._customSetters[key]) {
......@@ -169,13 +169,15 @@ module.exports = (function() {
} else {
// Check if we have included models, and if this key matches the include model names/aliases
if (this.options && this.options.include && this.options.includeNames.indexOf(key) !== -1) {
if (this.options && this.options.include && this.options.includeNames.indexOf(key) !== -1 && value) {
// Pass it on to the include handler
this._setInclude(key, value, options)
return
} else {
// If not raw, and attribute is not in model definition, return
if (!options.raw && !this._isAttribute(key)) {
// Bunch of stuff we won't do when its raw
if (!options.raw) {
// If attribute is not in model definition, return
if (!this._isAttribute(key)) {
return;
}
......@@ -185,21 +187,22 @@ module.exports = (function() {
}
// If attempting to set read only attributes, return
if (!options.raw && this.Model._hasReadOnlyAttributes && this.Model._isReadOnlyAttribute(key)) {
if (this.Model._hasReadOnlyAttributes && this.Model._isReadOnlyAttribute(key)) {
return
}
// Convert boolean-ish values to booleans
if (this.Model._hasBooleanAttributes && this.Model._isBooleanAttribute(key) && value !== null && value !== undefined) {
value = !!value
}
// Convert date fields to real date objects
if (this.Model._hasDateAttributes && this.Model._isDateAttribute(key) && value !== null && !(value instanceof Date)) {
value = new Date(value)
}
}
// Convert boolean-ish values to booleans
if (this.Model._hasBooleanAttributes && this.Model._isBooleanAttribute(key) && value !== null && value !== undefined) {
value = !!value
}
if (originalValue !== value) {
if (!options.raw && originalValue !== value) {
this._previousDataValues[key] = originalValue
}
this.dataValues[key] = value
......
......@@ -350,37 +350,41 @@ module.exports = (function() {
})
delete result.__children
},
primaryKeyAttribute
// Identify singular primaryKey attribute for equality check (if possible)
if (includeOptions.daoFactory.primaryKeyAttributes.length === 1) {
primaryKeyAttribute = includeOptions.daoFactory.primaryKeyAttributes[0]
} else if (includeOptions.daoFactory.rawAttributes.id) {
primaryKeyAttribute = 'id'
}
primaryKeyAttribute,
primaryKeyMap = {}
// Ignore all include keys on main data
if (includeOptions.includeNames) {
calleeDataIgnore = calleeDataIgnore.concat(includeOptions.includeNames)
}
if (includeOptions.daoFactory.primaryKeyAttributes.length === 1) {
primaryKeyAttribute = includeOptions.daoFactory.primaryKeyAttribute
}
data.forEach(function (row) {
data.forEach(function parseRow(row) {
row = Dot.transform(row)
calleeData = _.omit(row, calleeDataIgnore)
calleeData = row
// If there are :M associations included we need to see if the main result of the row has already been identified
existingResult = options.checkExisting && _.find(results, function (result) {
// If we can, detect equality on the singular primary key
if (options.checkExisting) {
if (primaryKeyAttribute) {
return result[primaryKeyAttribute] === calleeData[primaryKeyAttribute]
}
// If we can, detect equality on the singular primary key
existingResult = primaryKeyMap[calleeData[primaryKeyAttribute]]
} else {
// If we can't identify on a singular primary key, do a full row equality check
existingResult = _.find(results, function (result) {
return Utils._.isEqual(_.omit(result, calleeDataIgnore), calleeData)
})
}
} else {
existingResult = null
}
if (!existingResult) {
results.push(existingResult = calleeData)
if (options.checkExisting && primaryKeyAttribute) {
primaryKeyMap[existingResult[primaryKeyAttribute]] = existingResult
}
}
for (var attrName in row) {
......@@ -398,6 +402,9 @@ module.exports = (function() {
}
existingResult.__children[attrName].push(row[attrName])
// Remove from main
delete existingResult[attrName]
}
}
}
......@@ -406,6 +413,7 @@ module.exports = (function() {
if (!options.checkExisting) {
parseChildren(existingResult)
}
})
// parseChildren after row parsing if duplicate values are possible
......
......@@ -46,7 +46,7 @@
"lingo": "~0.0.5",
"validator": "~3.2.0",
"moment": "~2.5.0",
"dottie": "0.2.0",
"dottie": "0.2.1",
"toposort-class": "~0.3.0",
"generic-pool": "2.0.4",
"sql": "~0.35.0",
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!