More clean up for the scope processing

This commit is contained in:
Raymond Feng 2014-06-19 12:00:49 -07:00
parent 177752e144
commit 1833352238
2 changed files with 45 additions and 50 deletions

View File

@ -38,7 +38,7 @@ ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefres
if (!self.__cachedRelations || self.__cachedRelations[name] === undefined
|| actualRefresh) {
// It either doesn't hit the cache or refresh is required
var params = mergeParams(actualCond, scopeParams);
var params = mergeQuery(actualCond, scopeParams);
return this.targetModel.find(params, function (err, data) {
if (!err && saveOnCache) {
defineCachedRelations(self);
@ -134,7 +134,7 @@ function defineScope(cls, targetClass, name, params, methods) {
Object.defineProperty(f, name, {
enumerable: false,
get: function () {
mergeParams(f._scope, targetClass._scopeMeta[name]);
mergeQuery(f._scope, targetClass._scopeMeta[name]);
return f;
}
});
@ -183,15 +183,40 @@ function defineScope(cls, targetClass, name, params, methods) {
cls['__delete__' + name] = fn_delete;
/*
* Extracting fixed property values for the scope from the where clause into
* the data object
*
* @param {Object} The data object
* @param {Object} The where clause
*/
function setScopeValuesFromWhere(data, where) {
for (var i in where) {
if (i === 'and') {
// Find fixed property values from each subclauses
for (var w = 0, n = where[i].length; w < n; w++) {
setScopeValuesFromWhere(data, where[i][w]);
}
continue;
}
var prop = targetClass.definition.properties[i];
if (prop) {
var val = where[i];
if (typeof val !== 'object' || val instanceof prop.type) {
// Only pick the {propertyName: propertyValue}
data[i] = where[i];
}
}
}
}
// and it should have create/build methods with binded thisModelNameId param
function build(data) {
data = data || {};
var params = mergeParams(this._scope, {where: data}).where;
delete params['and'];
delete params['or'];
delete params['nor'];
return new targetClass(params);
// Find all fixed property values for the scope
var where = (this._scope && this._scope.where) || {};
setScopeValuesFromWhere(data, where);
return new targetClass(data);
}
function create(data, cb) {
@ -209,58 +234,28 @@ function defineScope(cls, targetClass, name, params, methods) {
- If fetching the Elements on which destroyAll is called results in an error
*/
function destroyAll(cb) {
targetClass.find(this._scope, function (err, data) {
if (err) {
cb(err);
} else {
(function loopOfDestruction(data) {
if (data.length > 0) {
data.shift().destroy(function (err) {
if (err && cb) cb(err);
loopOfDestruction(data);
});
} else {
if (cb) cb();
targetClass.destroyAll(this._scope, cb);
}
}(data));
}
});
}
}
/*!
* Merge `base` and `update` params
* @param {Object} base - base object (updating this object)
* @param {Object} update - object with new data to update base
* @returns {Object} `base`
* @private
*/
function mergeWhere(base, update) {
base = base || {};
if (update) {
var keys = Object.keys(update);
for (var k = 0; k < keys.length; k++) {
var key = keys[k];
base[key] = update[key];
}
}
return base;
}
/*!
* Merge query parameters
* @param base
* @param update
* @returns {*|{}}
* @param {Object} base The base object to contain the merged results
* @param {Object} update The object containing updates to be merged
* @returns {*|Object} The base object
* @private
*/
function mergeParams(base, update) {
function mergeQuery(base, update) {
if (!update) {
return;
}
base = base || {};
if (update.where) {
base.where = mergeWhere(base.where, update.where);
if (update.where && Object.keys(update.where).length > 0) {
if (base.where && Object.keys(base.where).length > 0) {
base.where = {and: [base.where, update.where]};
} else {
base.where = update.where;
}
}
// Overwrite inclusion

View File

@ -3,7 +3,7 @@ var should = require('./init.js');
var db, Railway, Station;
describe('sc0pe', function () {
describe('scope', function () {
before(function () {
db = getSchema();