Factorization of the modifiers

pull/2/head
Louis Chatriot 12 years ago
parent 671539a614
commit d5b990e776
  1. 98
      lib/model.js
  2. 2
      test/model.test.js

@ -214,90 +214,62 @@ function compareThings (a, b) {
// Updating documents // Updating documents
// ============================================================== // ==============================================================
lastStepModifierFunctions.$set = function (obj, field, value) {
obj[field] = value;
};
function findLastModificationStep (modifier, obj, field, value) {
var fieldParts = typeof field === 'string' ? field.split('.') : field;
if (fieldParts.length === 1) {
lastStepModifierFunctions[modifier](obj, field, value);
} else {
obj[fieldParts[0]] = obj[fieldParts[0]] || {};
modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value);
}
}
/** /**
* Set field to value in a model * The signature of modifier functions is as follows
* Create it if it doesn't exist * Their structure is always the same: recursively follow the dot notation while creating
* @param {Object} obj The model to set a field for * the nested documents if needed, then apply the "last step modifier"
* @param {Object} obj The model to modify
* @param {String} field Can contain dots, in that case that means we will set a subfield recursively * @param {String} field Can contain dots, in that case that means we will set a subfield recursively
* @param {Model} value * @param {Model} value
*/ */
modifierFunctions.$set = function (obj, field, value) {
var fieldParts = typeof field === 'string' ? field.split('.') : field;
if (fieldParts.length === 1) { // Set a field to a new value
obj[fieldParts[0]] = value; lastStepModifierFunctions.$set = function (obj, field, value) {
} else { obj[field] = value;
obj[fieldParts[0]] = obj[fieldParts[0]] || {};
modifierFunctions.$set(obj[fieldParts[0]], fieldParts.slice(1), value);
}
}; };
// Push an element to the end of an array field
/** lastStepModifierFunctions.$push = function (obj, field, value) {
* Push an element at the last place of an array
* @param {Object} obj The model to set a field for
* @param {String} field Can contain dots, in that case that means we will set a subfield recursively
* @param {Model} value
*/
modifierFunctions.$push = function (obj, field, value) {
var fieldParts = typeof field === 'string' ? field.split('.') : field;
if (fieldParts.length === 1) {
// Create the array if it doesn't exist // Create the array if it doesn't exist
if (!obj.hasOwnProperty(fieldParts[0])) { obj[fieldParts[0]] = []; } if (!obj.hasOwnProperty(field)) { obj[field] = []; }
if (!util.isArray(obj[fieldParts[0]])) { throw "Can't $push an element on non-array values"; } if (!util.isArray(obj[field])) { throw "Can't $push an element on non-array values"; }
obj[fieldParts[0]].push(value); obj[field].push(value);
} else {
obj[fieldParts[0]] = obj[fieldParts[0]] || {};
modifierFunctions.$push(obj[fieldParts[0]], fieldParts.slice(1), value);
}
}; };
// Increment a numeric field's value
/** lastStepModifierFunctions.$inc = function (obj, field, value) {
* Increase (or decrease) a 'number' field
* Create and initialize it if needed
* @param {Object} obj The model to set a field for
* @param {String} field Can contain dots, in that case that means we will set a subfield recursively
* @param {Model} value
*/
modifierFunctions.$inc = function (obj, field, value) {
var fieldParts = typeof field === 'string' ? field.split('.') : field;
if (typeof value !== 'number') { throw value + " must be a number"; } if (typeof value !== 'number') { throw value + " must be a number"; }
if (fieldParts.length === 1) { if (typeof obj[field] !== 'number') {
if (typeof obj[fieldParts[0]] !== 'number') { if (!_.has(obj, field)) {
if (!_.has(obj, fieldParts[0])) { obj[field] = value;
obj[fieldParts[0]] = value;
} else { } else {
throw "Don't use the $inc modifier on non-number fields"; throw "Don't use the $inc modifier on non-number fields";
} }
} else { } else {
obj[fieldParts[0]] += value; obj[field] += value;
} }
};
// Given its name, create the complete modifier function
function createModifierFunction (modifier) {
return function (obj, field, value) {
var fieldParts = typeof field === 'string' ? field.split('.') : field;
if (fieldParts.length === 1) {
lastStepModifierFunctions[modifier](obj, field, value);
} else { } else {
obj[fieldParts[0]] = obj[fieldParts[0]] || {}; obj[fieldParts[0]] = obj[fieldParts[0]] || {};
modifierFunctions.$inc(obj[fieldParts[0]], fieldParts.slice(1), value); modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value);
} }
}; };
}
// Actually create all modifier functions
Object.keys(lastStepModifierFunctions).forEach(function (modifier) {
modifierFunctions[modifier] = createModifierFunction(modifier);
});
/** /**

@ -201,7 +201,7 @@ describe('Model', function () {
}); // ==== End of 'Deep copying' ==== // }); // ==== End of 'Deep copying' ==== //
describe.only('Modifying documents', function () { describe('Modifying documents', function () {
it('Queries not containing any modifier just replace the document by the contents of the query but keep its _id', function () { it('Queries not containing any modifier just replace the document by the contents of the query but keep its _id', function () {
var obj = { some: 'thing', _id: 'keepit' } var obj = { some: 'thing', _id: 'keepit' }

Loading…
Cancel
Save