|
|
|
@ -899,35 +899,130 @@ class MongoClientInterface {
|
|
|
|
|
return cb(errors.InternalError);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Put object when versioning is not enabled
|
|
|
|
|
* @param {Object} c bucket collection
|
|
|
|
|
* @param {String} bucketName bucket name
|
|
|
|
|
* @param {String} objName object name
|
|
|
|
|
* @param {Object} objVal object metadata
|
|
|
|
|
* @param {Object} params params
|
|
|
|
|
* @param {Object} log logger
|
|
|
|
|
* @param {Function} cb callback
|
|
|
|
|
* @return {undefined}
|
|
|
|
|
* Puts an object into a MongoDB collection.
|
|
|
|
|
* Depending on the parameters, the object is either directly put into the collection
|
|
|
|
|
* or the existing object is marked as deleted and a new object is inserted.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} collection - The MongoDB collection to put the object into.
|
|
|
|
|
* @param {string} bucketName - The name of the bucket the object belongs to.
|
|
|
|
|
* @param {string} objName - The name of the object.
|
|
|
|
|
* @param {Object} value - The value of the object.
|
|
|
|
|
* @param {Object} params - Additional parameters.
|
|
|
|
|
* @param {string} params.vFormat - object key format.
|
|
|
|
|
* @param {boolean} params.needOplogUpdate - If true, the object is directly put into the collection
|
|
|
|
|
* with updating the operation log.
|
|
|
|
|
* @param {Object} log - The logger to use.
|
|
|
|
|
* @param {Function} cb - The callback function to call when the operation is complete. It is called with an error
|
|
|
|
|
* if there is an issue with the operation.
|
|
|
|
|
* @returns {Promise} A promise that resolves when the operation is complete. The promise is rejected with an error
|
|
|
|
|
* if there is an issue with the operation.
|
|
|
|
|
*/
|
|
|
|
|
putObjectNoVer(c, bucketName, objName, objVal, params, log, cb) {
|
|
|
|
|
const masterKey = formatMasterKey(objName, params.vFormat);
|
|
|
|
|
c.updateOne({
|
|
|
|
|
_id: masterKey,
|
|
|
|
|
}, {
|
|
|
|
|
putObjectNoVer(collection, bucketName, objName, value, params, log, cb) {
|
|
|
|
|
if (params?.needOplogUpdate) {
|
|
|
|
|
return this.putObjectNoVerWithOplogUpdate(collection, bucketName, objName, value, params, log, cb);
|
|
|
|
|
}
|
|
|
|
|
const key = formatMasterKey(objName, params.vFormat);
|
|
|
|
|
const putFilter = { _id: key };
|
|
|
|
|
return collection.updateOne(putFilter, {
|
|
|
|
|
$set: {
|
|
|
|
|
_id: masterKey,
|
|
|
|
|
value: objVal,
|
|
|
|
|
_id: key,
|
|
|
|
|
value,
|
|
|
|
|
},
|
|
|
|
|
}, {
|
|
|
|
|
upsert: true,
|
|
|
|
|
}).then(() => cb()).catch((err) => {
|
|
|
|
|
}).then(() => cb()).catch(err => {
|
|
|
|
|
log.error('putObjectNoVer: error putting obect with no versioning', { error: err.message });
|
|
|
|
|
return cb(errors.InternalError);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Updates an object in a MongoDB collection without changing its version.
|
|
|
|
|
* If the object doesn't exist, it will be created (upsert is true for the second update operation).
|
|
|
|
|
* The operation is logged in the oplog.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} collection - The MongoDB collection to update the object in.
|
|
|
|
|
* @param {string} bucketName - The name of the bucket the object belongs to.
|
|
|
|
|
* @param {string} objName - The name of the object.
|
|
|
|
|
* @param {Object} value - The new value of the object.
|
|
|
|
|
* @param {Object} params - Additional parameters.
|
|
|
|
|
* @param {string} params.vFormat - object key format
|
|
|
|
|
* @param {string} params.originOp - origin operation
|
|
|
|
|
* @param {Object} log - The logger to use.
|
|
|
|
|
* @param {Function} cb - The callback function to call when the operation is complete.
|
|
|
|
|
* It is called with an error if there is an issue with the operation.
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
putObjectNoVerWithOplogUpdate(collection, bucketName, objName, value, params, log, cb) {
|
|
|
|
|
const key = formatMasterKey(objName, params.vFormat);
|
|
|
|
|
const putFilter = { _id: key };
|
|
|
|
|
// filter used when finding and updating object
|
|
|
|
|
const findFilter = {
|
|
|
|
|
...putFilter,
|
|
|
|
|
$or: [
|
|
|
|
|
{ 'value.deleted': { $exists: false } },
|
|
|
|
|
{ 'value.deleted': { $eq: false } },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
const updateDeleteFilter = {
|
|
|
|
|
...putFilter,
|
|
|
|
|
'value.deleted': true,
|
|
|
|
|
};
|
|
|
|
|
return async.waterfall([
|
|
|
|
|
// Adding delete flag when getting the object
|
|
|
|
|
// to avoid having race conditions.
|
|
|
|
|
next => collection.findOneAndUpdate(findFilter, {
|
|
|
|
|
$set: updateDeleteFilter,
|
|
|
|
|
}, {
|
|
|
|
|
upsert: false,
|
|
|
|
|
}).then(doc => {
|
|
|
|
|
if (!doc.value) {
|
|
|
|
|
log.error('internalPutObject: unable to find target object to update',
|
|
|
|
|
{ bucket: bucketName, object: key });
|
|
|
|
|
return next(errors.NoSuchKey);
|
|
|
|
|
}
|
|
|
|
|
const obj = doc.value;
|
|
|
|
|
const objMetadata = new ObjectMD(obj.value);
|
|
|
|
|
objMetadata.setOriginOp(params.originOp);
|
|
|
|
|
objMetadata.setDeleted(true);
|
|
|
|
|
return next(null, objMetadata.getValue());
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
log.error('internalPutObject: error getting object',
|
|
|
|
|
{ bucket: bucketName, object: key, error: err.message });
|
|
|
|
|
return next(errors.InternalError);
|
|
|
|
|
}),
|
|
|
|
|
// We update the full object to get the whole object metadata
|
|
|
|
|
// in the oplog update event
|
|
|
|
|
(objMetadata, next) => collection.bulkWrite([
|
|
|
|
|
{
|
|
|
|
|
updateOne: {
|
|
|
|
|
filter: updateDeleteFilter,
|
|
|
|
|
update: {
|
|
|
|
|
$set: { _id: key, value: objMetadata },
|
|
|
|
|
},
|
|
|
|
|
upsert: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
updateOne: {
|
|
|
|
|
filter: putFilter,
|
|
|
|
|
update: {
|
|
|
|
|
$set: { _id: key, value },
|
|
|
|
|
},
|
|
|
|
|
upsert: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
], { ordered: true }).then(() => next(null)).catch(next),
|
|
|
|
|
], (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
log.error('internalPutObject: error updating object',
|
|
|
|
|
{ bucket: bucketName, object: key, error: err.message });
|
|
|
|
|
return cb(errors.InternalError);
|
|
|
|
|
}
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Returns the putObjectVerCase function to use
|
|
|
|
|
* depending on params
|
|
|
|
@ -973,8 +1068,7 @@ class MongoClientInterface {
|
|
|
|
|
return putObjectVer(c, bucketName, objName, objVal, _params, log,
|
|
|
|
|
cb);
|
|
|
|
|
}
|
|
|
|
|
return this.putObjectNoVer(c, bucketName, objName, objVal,
|
|
|
|
|
_params, log, cb);
|
|
|
|
|
return this.putObjectNoVer(c, bucketName, objName, objVal, _params, log, cb);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|