Skip to content

Commit

Permalink
Improved timestamps option handling in bulkWrite
Browse files Browse the repository at this point in the history
  • Loading branch information
sderrow committed Apr 28, 2024
1 parent 3072c41 commit 1111ae2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
33 changes: 27 additions & 6 deletions lib/helpers/model/castBulkWrite.js
Expand Up @@ -29,7 +29,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 && options.timestamps !== false) {
if (model.schema.options.timestamps && getTimestampsOpt(op['insertOne'], options)) {
doc.initializeTimestamps();
}
if (options.session != null) {
Expand Down Expand Up @@ -69,13 +69,15 @@ module.exports = function castBulkWrite(originalModel, op, options) {

_addDiscriminatorToObject(schema, op['updateOne']['filter']);

if (model.schema.$timestamps != null && op['updateOne'].timestamps !== false) {
const doInitTimestamps = getTimestampsOpt(op['updateOne'], options);

Check failure on line 73 in lib/helpers/model/castBulkWrite.js

View workflow job for this annotation

GitHub Actions / Lint JS-Files

Trailing spaces not allowed
if (model.schema.$timestamps != null && doInitTimestamps) {
const createdAt = model.schema.$timestamps.createdAt;
const updatedAt = model.schema.$timestamps.updatedAt;
applyTimestampsToUpdate(now, createdAt, updatedAt, update, {});
}

if (op['updateOne'].timestamps !== false) {
if (doInitTimestamps) {
applyTimestampsToChildren(now, update, model.schema);
}

Expand Down Expand Up @@ -134,12 +136,14 @@ module.exports = function castBulkWrite(originalModel, op, options) {
});
}

if (model.schema.$timestamps != null && op['updateMany'].timestamps !== false) {
const doInitTimestamps = getTimestampsOpt(op['updateMany'], options);

if (model.schema.$timestamps != null && doInitTimestamps) {
const createdAt = model.schema.$timestamps.createdAt;
const updatedAt = model.schema.$timestamps.updatedAt;
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateMany']['update'], {});
}
if (op['updateMany'].timestamps !== false) {
if (doInitTimestamps) {
applyTimestampsToChildren(now, op['updateMany']['update'], model.schema);
}

Expand Down Expand Up @@ -184,7 +188,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {

// set `skipId`, otherwise we get "_id field cannot be changed"
const doc = new model(op['replaceOne']['replacement'], strict, true);
if (model.schema.options.timestamps) {
if (model.schema.options.timestamps && getTimestampsOpt(op['replaceOne'], options)) {
doc.initializeTimestamps();
}
if (options.session != null) {
Expand Down Expand Up @@ -273,3 +277,20 @@ function decideModelByObject(model, object) {
}
return model;
}


/**
* gets timestamps option for a given operation. If the option is set within an individual operation, use it. Otherwise, use the global timestamps option configured in the `bulkWrite` options. Overall default is `true`.
* @api private
*/

function getTimestampsOpt(opCommand, options) {
const opLevelOpt = opCommand.timestamps;
const bulkLevelOpt = options.timestamps;
if (opLevelOpt != null) {
return opLevelOpt;
} else if (bulkLevelOpt != null) {
return bulkLevelOpt;
}
return true;
}
3 changes: 3 additions & 0 deletions lib/model.js
Expand Up @@ -3467,6 +3467,7 @@ function _setIsNew(doc, val) {
*
* @param {Array} ops
* @param {Object} [ops.insertOne.document] The document to insert
* @param {Object} [ops.insertOne.timestamps=true] If false, do not apply [timestamps](https://mongoosejs.com/docs/guide.html#timestamps) to the operation
* @param {Object} [ops.updateOne.filter] Update the first document that matches this filter
* @param {Object} [ops.updateOne.update] An object containing [update operators](https://www.mongodb.com/docs/manual/reference/operator/update/)
* @param {Boolean} [ops.updateOne.upsert=false] If true, insert a doc if none match
Expand All @@ -3484,8 +3485,10 @@ function _setIsNew(doc, val) {
* @param {Object} [ops.replaceOne.filter] Replace the first document that matches this filter
* @param {Object} [ops.replaceOne.replacement] The replacement document
* @param {Boolean} [ops.replaceOne.upsert=false] If true, insert a doc if no documents match `filter`
* @param {Object} [ops.replaceOne.timestamps=true] If false, do not apply [timestamps](https://mongoosejs.com/docs/guide.html#timestamps) to the operation
* @param {Object} [options]
* @param {Boolean} [options.ordered=true] If true, execute writes in order and stop at the first error. If false, execute writes in parallel and continue until all writes have either succeeded or errored.
* @param {Boolean} [options.timestamps=true] If false, do not apply [timestamps](https://mongoosejs.com/docs/guide.html#timestamps) to any operations. Can be overridden at the operation-level.
* @param {ClientSession} [options.session=null] The session associated with this bulk write. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
* @param {String|number} [options.w=1] The [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/). See [`Query#w()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.w()) for more information.
* @param {number} [options.wtimeout=null] The [write concern timeout](https://www.mongodb.com/docs/manual/reference/write-concern/#wtimeout).
Expand Down
12 changes: 9 additions & 3 deletions types/models.d.ts
Expand Up @@ -28,6 +28,8 @@ declare module 'mongoose' {
skipValidation?: boolean;
throwOnValidationError?: boolean;
strict?: boolean | 'throw';
/** When false, do not add timestamps to documents. Can be overridden at the operation level. */
timestamps?: boolean;
}

interface MongooseBulkSaveOptions extends mongodb.BulkWriteOptions {
Expand Down Expand Up @@ -179,7 +181,9 @@ declare module 'mongoose' {
};

export interface InsertOneModel<TSchema> {
document: mongodb.OptionalId<TSchema>
document: mongodb.OptionalId<TSchema>;
/** When false, do not add timestamps. When true, overrides the `timestamps` option set in the `bulkWrite` options. */
timestamps?: boolean;
}

export interface ReplaceOneModel<TSchema = AnyObject> {
Expand All @@ -193,6 +197,8 @@ declare module 'mongoose' {
hint?: mongodb.Hint;
/** When true, creates a new document if no document matches the query. */
upsert?: boolean;
/** When false, do not add timestamps. When true, overrides the `timestamps` option set in the `bulkWrite` options. */
timestamps?: boolean;
}

export interface UpdateOneModel<TSchema = AnyObject> {
Expand All @@ -208,7 +214,7 @@ declare module 'mongoose' {
hint?: mongodb.Hint;
/** When true, creates a new document if no document matches the query. */
upsert?: boolean;
/** When false, do not add timestamps. */
/** When false, do not add timestamps. When true, overrides the `timestamps` option set in the `bulkWrite` options. */
timestamps?: boolean;
}

Expand All @@ -225,7 +231,7 @@ declare module 'mongoose' {
hint?: mongodb.Hint;
/** When true, creates a new document if no document matches the query. */
upsert?: boolean;
/** When false, do not add timestamps. */
/** When false, do not add timestamps. When true, overrides the `timestamps` option set in the `bulkWrite` options. */
timestamps?: boolean;
}

Expand Down

0 comments on commit 1111ae2

Please sign in to comment.