Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions lib/helpers/model/castBulkWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ module.exports = function castBulkWrite(originalModel, op, options) {
if (model.schema.$timestamps != null && op['updateOne'].timestamps !== false) {
const createdAt = model.schema.$timestamps.createdAt;
const updatedAt = model.schema.$timestamps.updatedAt;
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateOne']['update'], {});
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateOne']['update'], {
timestamps: op['updateOne'].timestamps
});
}

if (op['updateOne'].timestamps !== false) {
Expand Down Expand Up @@ -100,7 +102,8 @@ module.exports = function castBulkWrite(originalModel, op, options) {
op['updateOne']['update'] = castUpdate(model.schema, op['updateOne']['update'], {
strict: strict,
overwrite: false,
upsert: op['updateOne'].upsert
upsert: op['updateOne'].upsert,
overwriteImmutable: op['updateOne'].overwriteImmutable
}, model, op['updateOne']['filter']);
} catch (error) {
return callback(error, null);
Expand Down Expand Up @@ -136,7 +139,9 @@ module.exports = function castBulkWrite(originalModel, op, options) {
if (model.schema.$timestamps != null && op['updateMany'].timestamps !== false) {
const createdAt = model.schema.$timestamps.createdAt;
const updatedAt = model.schema.$timestamps.updatedAt;
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateMany']['update'], {});
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateMany']['update'], {
timestamps: op['updateMany'].timestamps
});
}
if (op['updateMany'].timestamps !== false) {
applyTimestampsToChildren(now, op['updateMany']['update'], model.schema);
Expand All @@ -158,7 +163,8 @@ module.exports = function castBulkWrite(originalModel, op, options) {
op['updateMany']['update'] = castUpdate(model.schema, op['updateMany']['update'], {
strict: strict,
overwrite: false,
upsert: op['updateMany'].upsert
upsert: op['updateMany'].upsert,
overwriteImmutable: op['updateMany'].overwriteImmutable
}, model, op['updateMany']['filter']);
} catch (error) {
return callback(error, null);
Expand Down
4 changes: 2 additions & 2 deletions lib/helpers/query/castUpdate.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {

if (op !== '$setOnInsert' &&
!options.overwrite &&
handleImmutable(schematype, strict, obj, key, prefix + key, context)) {
handleImmutable(schematype, strict, obj, key, prefix + key, options, context)) {
continue;
}

Expand Down Expand Up @@ -335,7 +335,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
// You can use `$setOnInsert` with immutable keys
if (op !== '$setOnInsert' &&
!options.overwrite &&
handleImmutable(schematype, strict, obj, key, prefix + key, context)) {
handleImmutable(schematype, strict, obj, key, prefix + key, options, context)) {
continue;
}

Expand Down
6 changes: 5 additions & 1 deletion lib/helpers/query/handleImmutable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const StrictModeError = require('../../error/strict');

module.exports = function handleImmutable(schematype, strict, obj, key, fullPath, ctx) {
module.exports = function handleImmutable(schematype, strict, obj, key, fullPath, options, ctx) {
if (schematype == null || !schematype.options || !schematype.options.immutable) {
return false;
}
Expand All @@ -15,6 +15,10 @@ module.exports = function handleImmutable(schematype, strict, obj, key, fullPath
return false;
}

if (options && options.overwriteImmutable) {
return false;
}

if (strict === false) {
return false;
}
Expand Down
30 changes: 30 additions & 0 deletions test/model.updateOne.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2707,6 +2707,36 @@ describe('model: updateOne: ', function() {
assert.equal(doc.age, 20);
});

it('overwriting immutable createdAt with bulkWrite (gh-15781)', async function() {
const start = new Date().valueOf();
const schema = Schema({
createdAt: {
type: mongoose.Schema.Types.Date,
immutable: true
},
name: String
}, { timestamps: true });

const Model = db.model('Test', schema);

await Model.create({ name: 'gh-15781' });
let doc = await Model.collection.findOne({ name: 'gh-15781' });
assert.ok(doc.createdAt.valueOf() >= start);

const createdAt = new Date('2011-06-01');
assert.ok(createdAt.valueOf() < start.valueOf());
await Model.bulkWrite([{
updateOne: {
filter: { _id: doc._id },
update: { name: 'gh-15781 update', createdAt },
overwriteImmutable: true,
timestamps: false
}
}]);
doc = await Model.collection.findOne({ name: 'gh-15781 update' });
assert.equal(doc.createdAt.valueOf(), createdAt.valueOf());
});

it('updates buffers with `runValidators` successfully (gh-8580)', async function() {
const Test = db.model('Test', Schema({
data: { type: Buffer, required: true }
Expand Down
Loading