3 var modifiedPaths = require('./common').modifiedPaths;
6 * Applies defaults to update and findOneAndUpdate operations.
9 * @param {Schema} schema
10 * @param {Object} castedDoc
11 * @param {Object} options
12 * @method setDefaultsOnInsert
16 module.exports = function(query, schema, castedDoc, options) {
17 var keys = Object.keys(castedDoc || {});
19 var updatedValues = {};
20 var numKeys = keys.length;
21 var hasDollarUpdate = false;
24 if (options && options.upsert) {
25 for (var i = 0; i < numKeys; ++i) {
26 if (keys[i].charAt(0) === '$') {
27 modifiedPaths(castedDoc[keys[i]], '', modified);
28 hasDollarUpdate = true;
32 if (!hasDollarUpdate) {
33 modifiedPaths(castedDoc, '', modified);
36 var paths = Object.keys(query._conditions);
37 var numPaths = keys.length;
38 for (i = 0; i < numPaths; ++i) {
40 var condition = query._conditions[path];
41 if (condition && typeof condition === 'object') {
42 var conditionKeys = Object.keys(condition);
43 var numConditionKeys = conditionKeys.length;
44 var hasDollarKey = false;
45 for (var j = 0; j < numConditionKeys; ++j) {
46 if (conditionKeys[j].charAt(0) === '$') {
55 updatedKeys[path] = true;
56 modified[path] = true;
59 if (options.setDefaultsOnInsert) {
60 schema.eachPath(function(path, schemaType) {
62 // Ignore _id for now because it causes bugs in 2.4
65 if (schemaType.$isSingleNested) {
66 // Only handle nested schemas 1-level deep to avoid infinite
67 // recursion re: https://github.com/mongodb-js/mongoose-autopopulate/issues/11
68 schemaType.schema.eachPath(function(_path, _schemaType) {
70 // Ignore _id for now because it causes bugs in 2.4
74 var def = _schemaType.getDefault(null, true);
75 if (!modified[path + '.' + _path] && typeof def !== 'undefined') {
76 castedDoc = castedDoc || {};
77 castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
78 castedDoc.$setOnInsert[path + '.' + _path] = def;
79 updatedValues[path + '.' + _path] = def;
83 var def = schemaType.getDefault(null, true);
84 if (!modified[path] && typeof def !== 'undefined') {
85 castedDoc = castedDoc || {};
86 castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
87 castedDoc.$setOnInsert[path] = def;
88 updatedValues[path] = def;