Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow usage of schema reserved keywords #10414

Merged
merged 56 commits into from
Aug 20, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
be27aec
chore: use ecmaVersion 2018 in 6.0 branch to allow async/await
AbdelrahmanHafez Jul 2, 2021
a1d862e
test(document): assert possibility of using `validate` as a document …
AbdelrahmanHafez Jul 2, 2021
5722d05
fix(document): use Document#$validate internally instead of Document#…
AbdelrahmanHafez Jul 2, 2021
03cdcc7
lint: remove dangling commas
AbdelrahmanHafez Jul 2, 2021
67bf197
test(document): assert possibility of using `save` as a document prop…
AbdelrahmanHafez Jul 2, 2021
0270b51
fix(document): prefer $save over save internally
AbdelrahmanHafez Jul 2, 2021
c8af05b
remove schema reserved keys from #8869 in favor of #9010
AbdelrahmanHafez Jul 9, 2021
6969966
Merge branch '6.0' into gh-9010
AbdelrahmanHafez Jul 9, 2021
b403e72
test: assert ability of using isModified as a schema path re #9010
AbdelrahmanHafez Jul 9, 2021
11a7315
fix(document): allow using isModified as a schema path re #9010
AbdelrahmanHafez Jul 9, 2021
c861c7f
test(document): add tests asserting isNew can be used as a schema pat…
AbdelrahmanHafez Jul 9, 2021
980d6b0
test(document): assert that `populated` can be used as a schema path …
AbdelrahmanHafez Jul 9, 2021
6f352b4
fix(document): allow using `populated` as a schema path re #9010
AbdelrahmanHafez Jul 9, 2021
5d3eb79
revert schema reserved keys starting with $ changes to docs
AbdelrahmanHafez Jul 9, 2021
85ade36
revert schema reserved keys changes in docs
AbdelrahmanHafez Jul 9, 2021
e2a343b
test: assert toObject is usable as a schema path re #9010
AbdelrahmanHafez Jul 9, 2021
3deb806
fix: allow `toObject` as a path in documents, and use `$toObject` int…
AbdelrahmanHafez Jul 11, 2021
e925e2b
more converting toObject => $toObject re #9010
AbdelrahmanHafez Jul 11, 2021
965ef83
fix clone test cases
AbdelrahmanHafez Jul 11, 2021
9fe1409
fix typo causing infinite loop
AbdelrahmanHafez Jul 11, 2021
713909e
revert $toObject preference for internal usage
AbdelrahmanHafez Jul 11, 2021
a6a0a84
remove $toObject from clone test
AbdelrahmanHafez Jul 11, 2021
44b9910
prefer method.apply(this, arguments); over method()
AbdelrahmanHafez Jul 11, 2021
2746ba4
test(document): assert ability of using init as a schema path
AbdelrahmanHafez Jul 11, 2021
65587fa
prefer Document#$init over Document#init
AbdelrahmanHafez Jul 11, 2021
13d4096
fix model.$init re #9010
AbdelrahmanHafez Jul 11, 2021
d4641ce
fix failing tests
AbdelrahmanHafez Jul 11, 2021
7b4fa6d
add $collection to model prototype
AbdelrahmanHafez Jul 27, 2021
d403d85
test(document): assert ability of using `isNew` as a document property
AbdelrahmanHafez Jul 27, 2021
8360dd2
fix(document): allow using `isNew` as a schema path
AbdelrahmanHafez Jul 27, 2021
f814ff8
Merge branch '6.0' into gh-9010
AbdelrahmanHafez Jul 27, 2021
6500068
fix failing test re: #5078 #9010
AbdelrahmanHafez Jul 27, 2021
359f935
test(document): assert Document#errors can be used as a schema path
AbdelrahmanHafez Jul 27, 2021
f722c1d
fix(document): allow using `errors` as a schema path re #9010
AbdelrahmanHafez Jul 27, 2021
7452cc2
test(document): add test asserting ability to use `collection` as a s…
AbdelrahmanHafez Jul 27, 2021
c37f17b
dummy commit to trigger CI tests
AbdelrahmanHafez Jul 27, 2021
9f2809e
refactor tests re #9010
AbdelrahmanHafez Aug 4, 2021
4ca268c
fix failing tests
AbdelrahmanHafez Aug 4, 2021
8ed12a1
fix lint
AbdelrahmanHafez Aug 4, 2021
28595a1
Merge branch '6.0' into gh-9010
AbdelrahmanHafez Aug 4, 2021
254a610
test(document): assert ability to use `removeListener` as a schema path
AbdelrahmanHafez Aug 4, 2021
2d46fff
fix(document): allow using removeListener as a schema path re #9010
AbdelrahmanHafez Aug 4, 2021
c134994
test(document): assert ability of using `listeners` as a schema path
AbdelrahmanHafez Aug 4, 2021
f596418
fix(document): allow using `listeners` as a schema path re #9010
AbdelrahmanHafez Aug 4, 2021
7cba2dd
fix failing tests
AbdelrahmanHafez Aug 4, 2021
b655b27
test(document): assert ability of using `on` as a schema path
AbdelrahmanHafez Aug 4, 2021
51e2e7c
fix(document): allow using `on` as a schema path
AbdelrahmanHafez Aug 4, 2021
312d5c2
test(document): assert ability of using emit as a schema path
AbdelrahmanHafez Aug 4, 2021
e47936e
fix(document): allow using `emit` as a schema path re #9010
AbdelrahmanHafez Aug 4, 2021
22e3ec8
fix failing test
AbdelrahmanHafez Aug 4, 2021
984adb7
fix(document): allow using `get` as a schema path
AbdelrahmanHafez Aug 4, 2021
33bdb7c
fix(document): allow using `document` as a schema path re #9010
AbdelrahmanHafez Aug 4, 2021
30c4415
fix failing tests
AbdelrahmanHafez Aug 4, 2021
3a5189b
feat(schema): add warning when using a schema reserved path, and an o…
AbdelrahmanHafez Aug 4, 2021
41273a8
fix failing tests re #9010
AbdelrahmanHafez Aug 5, 2021
05bbdf1
run tests on all reserved properties
AbdelrahmanHafez Aug 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions benchmarks/benchjs/multiop.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
res.author = 'soemthing new';
res.comments.push(commentData);
res.title = 'something newerrrr';
res.save(function(err) {
res.$save(function(err) {
if (err) {
throw err;
}
Expand Down Expand Up @@ -413,7 +413,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
bp.author = 'soemthing new';
bp.comments.push(commentData);
bp.title = 'something newerrrr';
blogpost.save(bp, function(err) {
blogpost.$save(bp, function(err) {
if (err) {
throw err;
}
Expand Down
8 changes: 4 additions & 4 deletions benchmarks/benchjs/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
// The driver will send the full document, while mongoose will check
// and only update fields that have been changed. This is meant to
// illustrate that difference between the two
bp.save(function(err) {
bp.$save(function(err) {
if (err) {
throw err;
}
Expand All @@ -225,7 +225,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
bp.comments[3].title = 'this is a new title';
bp.comments[0].date = new Date();
bp.comments.push(commentData);
blogpost.save(bp, function(err) {
blogpost.$save(bp, function(err) {
if (err) {
throw err;
}
Expand Down Expand Up @@ -266,7 +266,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
fn: function(deferred) {
testBp.comments.push(commentData);
testBp.comments.$shift();
testBp.save(function(err) {
testBp.$save(function(err) {
if (err) {
throw err;
}
Expand Down Expand Up @@ -340,7 +340,7 @@ mongoose.connect('mongodb://localhost/mongoose-bench', function(err) {
for (let i = 0; i < 100; i++) {
testBp.comments.push(commentData);
}
testBp.save(function(err) {
testBp.$save(function(err) {
if (err) {
throw err;
}
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/mem.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function cycle() {
docs: [{title: 'yo'}, {title: 'nowafasdi0fas asjkdfla fa'}]
});

a.save(function() {
a.$save(function() {
methods[Math.random() * methods.length | 0](a, function() {
a = null;
process.nextTick(cycle);
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/populate.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mongoose.connect('localhost', 'benchmark-populate', function(err) {
as: [a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a],
a: a,
nested: [{a: a}, {a: a}, {a: a}, {a: a}, {a: a}, {a: a}]
}).save(function(err) {
}).$save(function(err) {
if (err) {
return done(err);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async function run() {

await Content.deleteMany({});
for (const content of contents) {
await content.save();
await content.$save();
}

const results = await Content.
Expand Down
2 changes: 1 addition & 1 deletion examples/redis-todo/db/models/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ userSchema.methods.genAuthToken = function() {
// password hasing
userPasswordSchema.pre('save', async function(next) {
try {
if (this.isModified('password')) {
if (this.$isModified('password')) {
this.password = await bcrypt.hashSync(this.password, 8);
return next();
}
Expand Down
4 changes: 2 additions & 2 deletions examples/redis-todo/routers/todoRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Router.get('/all', auth, async function({ userId }, res) {
Router.post('/create', auth, clearCache, async function({ userId, body }, res) {
try {
const todo = new Todo({ ...body, userId });
await todo.save();
await todo.$save();
res.status(201).json({ todo });
} catch (err) {
res.status(501).send('Server Error: ' + err);
Expand All @@ -46,7 +46,7 @@ Router.post('/update', auth, async function({ userId, body }, res) {
);
if (!updatedTodo) return res.status(404).send({ msg: 'Todo not found' });

await updatedTodo.save();
await updatedTodo.$save();
res.status(200).json({ todo: updatedTodo });
} catch (err) {
res.status(501).send('Server Error: ' + err);
Expand Down
6 changes: 3 additions & 3 deletions examples/redis-todo/routers/userRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Router.post('/create', async function({ body }, res) {
const token = await user.genAuthToken();

// hashing password
await password.save();
await user.save();
await password.$save();
await user.$save();
res.status(201).json({ token });
} catch (err) {
console.log(err);
Expand Down Expand Up @@ -68,7 +68,7 @@ Router.post('/update', auth, async function({ userId, body }, res) {
if (body.password) {
const password = await Password.findById({ _id: updatedUser.passwordId });
password.password = body.password;
password.save(); // hashing password
password.$save(); // hashing password
}

res.status(200).json({ user: updatedUser });
Expand Down
2 changes: 1 addition & 1 deletion lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ Connection.prototype.startSession = _wrapConnHelper(function startSession(option
* const doc = new Person({ name: 'Will Riker' });
* await db.transaction(async function setRank(session) {
* doc.rank = 'Captain';
* await doc.save({ session });
* await doc.$save({ session });
* doc.isNew; // false
*
* // Throw an error to abort the transaction
Expand Down
2 changes: 1 addition & 1 deletion lib/cursor/QueryCursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ QueryCursor.prototype.next = function(callback) {
* cursor().
* eachAsync(async function (doc, i) {
* doc.foo = doc.bar + i;
* await doc.save();
* await doc.$save();
* })
*
* @param {Function} fn
Expand Down
42 changes: 23 additions & 19 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ Document.prototype.errors;
* const doc = new Model({ name: 'test' });
* doc.$op; // null
*
* const promise = doc.save();
* const promise = doc.$save();
* doc.$op; // 'save'
*
* await promise;
Expand Down Expand Up @@ -708,7 +708,7 @@ function init(self, obj, doc, opts, prefix) {
}
}
// mark as hydrated
if (!self.isModified(path)) {
if (!self.$isModified(path)) {
self.$__.activePaths.init(path);
}
}
Expand Down Expand Up @@ -1686,7 +1686,7 @@ Document.prototype.$__path = function(path) {
*
* doc.mixed.type = 'changed';
* doc.markModified('mixed.type');
* doc.save() // changes to mixed.type are now persisted
* doc.$save() // changes to mixed.type are now persisted
*
* @param {String} path the path to mark modified
* @param {Document} [scope] the scope to run validators with
Expand All @@ -1707,7 +1707,7 @@ Document.prototype.markModified = function(path, scope) {
*
* doc.foo = 'bar';
* doc.unmarkModified('foo');
* doc.save(); // changes to foo will not be persisted
* doc.$save(); // changes to foo will not be persisted
*
* @param {String} path the path to unmark modified
* @api public
Expand All @@ -1725,7 +1725,7 @@ Document.prototype.unmarkModified = function(path) {
*
* doc.foo = null;
* doc.$ignore('foo');
* doc.save(); // changes to foo will not be persisted and validators won't be run
* doc.$save(); // changes to foo will not be persisted and validators won't be run
*
* @memberOf Document
* @instance
Expand Down Expand Up @@ -1896,10 +1896,10 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
* ####Example
*
* doc.set('documents.0.title', 'changed');
* doc.isModified() // true
* doc.isModified('documents') // true
* doc.isModified('documents.0.title') // true
* doc.isModified('documents otherProp') // true
* doc.$isModified() // true
* doc.$isModified('documents') // true
* doc.$isModified('documents.0.title') // true
* doc.$isModified('documents otherProp') // true
* doc.isDirectModified('documents') // false
*
* @param {String} [path] optional
Expand Down Expand Up @@ -1928,6 +1928,8 @@ Document.prototype.isModified = function(paths, modifiedPaths) {
return this.$__.activePaths.some('modify');
};

Document.prototype.$isModified = Document.prototype.isModified;

Document.prototype[documentIsModified] = Document.prototype.isModified;

/**
Expand Down Expand Up @@ -2201,7 +2203,7 @@ Document.prototype.isDirectSelected = function isDirectSelected(path) {
*
* ####Example:
*
* doc.validate(function (err) {
* doc.$validate(function (err) {
* if (err) handleError(err);
* else // validation passed
* });
Expand Down Expand Up @@ -2266,6 +2268,8 @@ Document.prototype.validate = function(pathsToValidate, options, callback) {
}, this.constructor.events);
};

Document.prototype.$validate = Document.prototype.validate;

/*!
* ignore
*/
Expand All @@ -2290,7 +2294,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) {
if (!doc.$__isSelected(path) && !doc.isModified(path)) {
if (!doc.$__isSelected(path) && !doc.$isModified(path)) {
return false;
}
if (path in doc.$__.cachedRequired) {
Expand All @@ -2317,7 +2321,7 @@ function _getPathsToValidate(doc) {
}
}

if (doc.isModified(subdoc.$basePath, modifiedPaths) &&
if (doc.$isModified(subdoc.$basePath, modifiedPaths) &&
!doc.isDirectModified(subdoc.$basePath) &&
!doc.$isDefault(subdoc.$basePath)) {
paths.add(subdoc.$basePath);
Expand Down Expand Up @@ -2433,7 +2437,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
// Remove any validation errors that aren't from modified paths
const errors = Object.keys(validationError.errors);
for (const errPath of errors) {
if (!this.isModified(errPath)) {
if (!this.$isModified(errPath)) {
delete validationError.errors[errPath];
}
}
Expand Down Expand Up @@ -2463,7 +2467,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
// only validate required fields when necessary
const pathDetails = _getPathsToValidate(this);
let paths = shouldValidateModifiedOnly ?
pathDetails[0].filter((path) => this.isModified(path)) :
pathDetails[0].filter((path) => this.$isModified(path)) :
pathDetails[0];
const skipSchemaValidators = pathDetails[1];
if (typeof pathsToValidate === 'string') {
Expand Down Expand Up @@ -2662,7 +2666,7 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
// only validate required fields when necessary
const pathDetails = _getPathsToValidate(this);
let paths = shouldValidateModifiedOnly ?
pathDetails[0].filter((path) => this.isModified(path)) :
pathDetails[0].filter((path) => this.$isModified(path)) :
pathDetails[0];
const skipSchemaValidators = pathDetails[1];

Expand Down Expand Up @@ -2731,7 +2735,7 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
*
* doc.invalidate('size', 'must be less than 20', 14);

* doc.validate(function (err) {
* doc.$validate(function (err) {
* console.log(err)
* // prints
* { message: 'Validation failed',
Expand Down Expand Up @@ -2850,14 +2854,14 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
* ####Example:
*
* product.sold = Date.now();
* product = await product.save();
* product = await product.$save();
*
* If save is successful, the returned promise will fulfill with the document
* saved.
*
* ####Example:
*
* const newProduct = await product.save();
* const newProduct = await product.$save();
* newProduct === product; // true
*
* @param {Object} [options] options optional options
Expand Down Expand Up @@ -4163,7 +4167,7 @@ Document.prototype.$__fullPath = function(path) {
*
* user.getChanges(); // { $set: { age: 26 }, { $unset: { country: 1 } } }
*
* await user.save();
* await user.$save();
*
* user.getChanges(); // { }
*
Expand Down
2 changes: 1 addition & 1 deletion lib/error/divergentArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DivergentArrayError extends MongooseError {
* @param {Array<String>} paths
*/
constructor(paths) {
const msg = 'For your own good, using `document.save()` to update an array '
const msg = 'For your own good, using `document.$save()` to update an array '
+ 'which was selected using an $elemMatch projection OR '
+ 'populated using skip, limit, query conditions, or exclusion of '
+ 'the _id field when the operation results in a $pop or $set of '
Expand Down
4 changes: 2 additions & 2 deletions lib/helpers/model/castBulkWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
doc.$session(options.session);
}
op['insertOne']['document'] = doc;
op['insertOne']['document'].validate({ __noPromise: true }, function(error) {
op['insertOne']['document'].$validate({ __noPromise: true }, function(error) {
if (error) {
return callback(error, null);
}
Expand Down Expand Up @@ -154,7 +154,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
}
op['replaceOne']['replacement'] = doc;

op['replaceOne']['replacement'].validate({ __noPromise: true }, function(error) {
op['replaceOne']['replacement'].$validate({ __noPromise: true }, function(error) {
if (error) {
return callback(error, null);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/helpers/timestamps/setupTimestamps.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
this.$set(createdAt, auto_id ? this._id.getTimestamp() : defaultTimestamp);
}

if (!skipUpdatedAt && updatedAt && (this.isNew || this.isModified())) {
if (!skipUpdatedAt && updatedAt && (this.isNew || this.$isModified())) {
let ts = defaultTimestamp;
if (this.isNew) {
if (createdAt != null) {
Expand Down
3 changes: 1 addition & 2 deletions lib/helpers/updateValidators.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const modifiedPaths = require('./common').modifiedPaths;
*/

module.exports = function(query, schema, castedDoc, options, callback) {
let _keys;
const keys = Object.keys(castedDoc || {});
let updatedKeys = {};
let updatedValues = {};
Expand All @@ -39,7 +38,7 @@ module.exports = function(query, schema, castedDoc, options, callback) {
if (keys[i].startsWith('$')) {
hasDollarUpdate = true;
if (keys[i] === '$push' || keys[i] === '$addToSet') {
_keys = Object.keys(castedDoc[keys[i]]);
const _keys = Object.keys(castedDoc[keys[i]]);
for (let ii = 0; ii < _keys.length; ++ii) {
currentUpdate = castedDoc[keys[i]][_keys[ii]];
if (currentUpdate && currentUpdate.$each) {
Expand Down