Skip to content

Commit

Permalink
Merge branch '6.5' into vkarpov15/gh-11945
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jul 18, 2022
2 parents e62d0ff + 871a121 commit b165936
Show file tree
Hide file tree
Showing 19 changed files with 394 additions and 110 deletions.
3 changes: 3 additions & 0 deletions lib/connection.js
Expand Up @@ -491,6 +491,9 @@ Connection.prototype.transaction = function transaction(fn, options) {
doc.set(doc.schema.options.versionKey, state.versionKey);
}

if (state.modifiedPaths.length > 0 && doc.$__.activePaths.states.modify == null) {
doc.$__.activePaths.states.modify = {};
}
for (const path of state.modifiedPaths) {
doc.$__.activePaths.paths[path] = 'modify';
doc.$__.activePaths.states.modify[path] = true;
Expand Down
69 changes: 40 additions & 29 deletions lib/document.js
Expand Up @@ -94,7 +94,11 @@ function Document(obj, fields, skipId, options) {
}

this.$__ = new InternalCache();
this.$isNew = 'isNew' in options ? options.isNew : true;

// Avoid setting `isNew` to `true`, because it is `true` by default
if (options.isNew != null && options.isNew !== true) {
this.$isNew = options.isNew;
}

if (options.priorDoc != null) {
this.$__.priorDoc = options.priorDoc;
Expand All @@ -117,13 +121,12 @@ function Document(obj, fields, skipId, options) {
const schema = this.$__schema;

if (typeof fields === 'boolean' || fields === 'throw') {
this.$__.strictMode = fields;
if (fields !== true) {
this.$__.strictMode = fields;
}
fields = undefined;
} else {
} else if (schema.options.strict !== true) {
this.$__.strictMode = schema.options.strict;
if (fields != null) {
this.$__.selected = fields;
}
}

const requiredPaths = schema.requiredPaths(true);
Expand All @@ -135,9 +138,9 @@ function Document(obj, fields, skipId, options) {

// determine if this doc is a result of a query with
// excluded fields
if (utils.isPOJO(fields)) {
if (utils.isPOJO(fields) && Object.keys(fields).length > 0) {
exclude = isExclusive(fields);
this.$__.fields = fields;
this.$__.selected = fields;
this.$__.exclude = exclude;
}

Expand Down Expand Up @@ -211,6 +214,13 @@ Object.defineProperty(Document.prototype, 'errors', {
this.$errors = value;
}
});

/*!
* ignore
*/

Document.prototype.$isNew = true;

/*!
* Document exposes the NodeJS event emitter API, so you can use
* `on`, `once`, etc.
Expand Down Expand Up @@ -658,10 +668,11 @@ Document.prototype.$__init = function(doc, opts) {
this.$emit('init', this);
this.constructor.emit('init', this);

const hasIncludedChildren = this.$__.exclude === false && this.$__.fields ?
$__hasIncludedChildren(this.$__.fields) :
const hasIncludedChildren = this.$__.exclude === false && this.$__.selected ?
$__hasIncludedChildren(this.$__.selected) :
null;
applyDefaults(this, this.$__.fields, this.$__.exclude, hasIncludedChildren, false, this.$__.skipDefaults);

applyDefaults(this, this.$__.selected, this.$__.exclude, hasIncludedChildren, false, this.$__.skipDefaults);

return this;
};
Expand Down Expand Up @@ -1505,7 +1516,7 @@ Document.prototype.$__shouldModify = function(pathToMark, path, options, constru
return true;
}

if (val === void 0 && path in this.$__.activePaths.states.default) {
if (val === void 0 && path in this.$__.activePaths.getStatePaths('default')) {
// we're just unsetting the default value which was never saved
return false;
}
Expand All @@ -1525,7 +1536,7 @@ Document.prototype.$__shouldModify = function(pathToMark, path, options, constru
if (!constructing &&
val !== null &&
val !== undefined &&
path in this.$__.activePaths.states.default &&
path in this.$__.activePaths.getStatePaths('default') &&
deepEqual(val, schema.getDefault(this, constructing))) {
// a path with a default was $unset on the server
// and the user is setting it to the same value again
Expand Down Expand Up @@ -1823,7 +1834,7 @@ Document.prototype.$ignore = function(path) {
*/

Document.prototype.directModifiedPaths = function() {
return Object.keys(this.$__.activePaths.states.modify);
return Object.keys(this.$__.activePaths.getStatePaths('modify'));
};

/**
Expand Down Expand Up @@ -1901,7 +1912,7 @@ function _isEmpty(v) {
Document.prototype.modifiedPaths = function(options) {
options = options || {};

const directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
const directModifiedPaths = Object.keys(this.$__.activePaths.getStatePaths('modify'));
const result = new Set();

let i = 0;
Expand Down Expand Up @@ -1980,7 +1991,7 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;

Document.prototype.isModified = function(paths, modifiedPaths) {
if (paths) {
const directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
const directModifiedPaths = Object.keys(this.$__.activePaths.getStatePaths('modify'));
if (directModifiedPaths.length === 0) {
return false;
}
Expand Down Expand Up @@ -2030,15 +2041,15 @@ Document.prototype.$isDefault = function(path) {
}

if (typeof path === 'string' && path.indexOf(' ') === -1) {
return this.$__.activePaths.states.default.hasOwnProperty(path);
return this.$__.activePaths.getStatePaths('default').hasOwnProperty(path);
}

let paths = path;
if (!Array.isArray(paths)) {
paths = paths.split(' ');
}

return paths.some(path => this.$__.activePaths.states.default.hasOwnProperty(path));
return paths.some(path => this.$__.activePaths.getStatePaths('default').hasOwnProperty(path));
};

/**
Expand Down Expand Up @@ -2091,15 +2102,15 @@ Document.prototype.isDirectModified = function(path) {
}

if (typeof path === 'string' && path.indexOf(' ') === -1) {
return this.$__.activePaths.states.modify.hasOwnProperty(path);
return this.$__.activePaths.getStatePaths('modify').hasOwnProperty(path);
}

let paths = path;
if (!Array.isArray(paths)) {
paths = paths.split(' ');
}

return paths.some(path => this.$__.activePaths.states.modify.hasOwnProperty(path));
return paths.some(path => this.$__.activePaths.getStatePaths('modify').hasOwnProperty(path));
};

/**
Expand All @@ -2116,15 +2127,15 @@ Document.prototype.isInit = function(path) {
}

if (typeof path === 'string' && path.indexOf(' ') === -1) {
return this.$__.activePaths.states.init.hasOwnProperty(path);
return this.$__.activePaths.getStatePaths('init').hasOwnProperty(path);
}

let paths = path;
if (!Array.isArray(paths)) {
paths = paths.split(' ');
}

return paths.some(path => this.$__.activePaths.states.init.hasOwnProperty(path));
return paths.some(path => this.$__.activePaths.getStatePaths('init').hasOwnProperty(path));
};

/**
Expand Down Expand Up @@ -2352,7 +2363,7 @@ Document.prototype.$validate = Document.prototype.validate;
*/

function _evaluateRequiredFunctions(doc) {
const requiredFields = Object.keys(doc.$__.activePaths.states.require);
const requiredFields = Object.keys(doc.$__.activePaths.getStatePaths('require'));
let i = 0;
const len = requiredFields.length;
for (i = 0; i < len; ++i) {
Expand Down Expand Up @@ -2380,7 +2391,7 @@ function _getPathsToValidate(doc) {

_evaluateRequiredFunctions(doc);
// only validate required fields when necessary
let paths = new Set(Object.keys(doc.$__.activePaths.states.require).filter(function(path) {
let paths = new Set(Object.keys(doc.$__.activePaths.getStatePaths('require')).filter(function(path) {
if (!doc.$__isSelected(path) && !doc.$isModified(path)) {
return false;
}
Expand All @@ -2390,9 +2401,9 @@ function _getPathsToValidate(doc) {
return true;
}));

Object.keys(doc.$__.activePaths.states.init).forEach(addToPaths);
Object.keys(doc.$__.activePaths.states.modify).forEach(addToPaths);
Object.keys(doc.$__.activePaths.states.default).forEach(addToPaths);
Object.keys(doc.$__.activePaths.getStatePaths('init')).forEach(addToPaths);
Object.keys(doc.$__.activePaths.getStatePaths('modify')).forEach(addToPaths);
Object.keys(doc.$__.activePaths.getStatePaths('default')).forEach(addToPaths);
function addToPaths(p) { paths.add(p); }

const subdocs = doc.$getAllSubdocs();
Expand Down Expand Up @@ -3114,8 +3125,8 @@ Document.prototype.$__reset = function reset() {

this.$__.backup = {};
this.$__.backup.activePaths = {
modify: Object.assign({}, this.$__.activePaths.states.modify),
default: Object.assign({}, this.$__.activePaths.states.default)
modify: Object.assign({}, this.$__.activePaths.getStatePaths('modify')),
default: Object.assign({}, this.$__.activePaths.getStatePaths('default'))
};
this.$__.backup.validationError = this.$__.validationError;
this.$__.backup.errors = this.$errors;
Expand Down
6 changes: 3 additions & 3 deletions lib/helpers/document/cleanModifiedSubpaths.js
Expand Up @@ -13,21 +13,21 @@ module.exports = function cleanModifiedSubpaths(doc, path, options) {
return deleted;
}

for (const modifiedPath of Object.keys(doc.$__.activePaths.states.modify)) {
for (const modifiedPath of Object.keys(doc.$__.activePaths.getStatePaths('modify'))) {
if (skipDocArrays) {
const schemaType = doc.$__schema.path(modifiedPath);
if (schemaType && schemaType.$isMongooseDocumentArray) {
continue;
}
}
if (modifiedPath.startsWith(path + '.')) {
delete doc.$__.activePaths.states.modify[modifiedPath];
doc.$__.activePaths.clearPath(modifiedPath);
++deleted;

if (doc.$isSubdocument) {
const owner = doc.ownerDocument();
const fullPath = doc.$__fullPath(modifiedPath);
delete owner.$__.activePaths.states.modify[fullPath];
owner.$__.activePaths.clearPath(fullPath);
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions lib/helpers/document/compile.js
Expand Up @@ -17,6 +17,13 @@ const isPOJO = utils.isPOJO;
exports.compile = compile;
exports.defineKey = defineKey;

const _isEmptyOptions = Object.freeze({
minimize: true,
virtuals: false,
getters: false,
transform: false
});

/*!
* Compiles schemas.
*/
Expand Down Expand Up @@ -130,12 +137,6 @@ function defineKey({ prop, subprops, prototype, prefix, options }) {
value: true
});

const _isEmptyOptions = Object.freeze({
minimize: true,
virtuals: false,
getters: false,
transform: false
});
Object.defineProperty(nested, '$isEmpty', {
enumerable: false,
configurable: true,
Expand Down
2 changes: 1 addition & 1 deletion lib/helpers/model/castBulkWrite.js
Expand Up @@ -20,7 +20,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
const model = decideModelByObject(originalModel, op['insertOne']['document']);

const doc = new model(op['insertOne']['document']);
if (model.schema.options.timestamps) {
if (model.schema.options.timestamps && options.timestamps !== false) {
doc.initializeTimestamps();
}
if (options.session != null) {
Expand Down
3 changes: 2 additions & 1 deletion lib/internal.js
Expand Up @@ -13,8 +13,9 @@ function InternalCache() {
this.activePaths = new ActiveRoster();
}

InternalCache.prototype.strictMode = true;

InternalCache.prototype.fullPath = undefined;
InternalCache.prototype.strictMode = undefined;
InternalCache.prototype.selected = undefined;
InternalCache.prototype.shardval = undefined;
InternalCache.prototype.saveError = undefined;
Expand Down

0 comments on commit b165936

Please sign in to comment.