Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: loopbackio/loopback-connector-mongodb
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ef0d97cdec9e724885c4e36fb4ea9b7df545890b
Choose a base ref
..
head repository: loopbackio/loopback-connector-mongodb
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 65ad9a5dfbd8b5710f849967944152c2a42f7581
Choose a head ref
Showing with 90 additions and 89 deletions.
  1. +90 −89 lib/mongodb.js
179 changes: 90 additions & 89 deletions lib/mongodb.js
Original file line number Diff line number Diff line change
@@ -197,8 +197,9 @@ function MongoDB(settings, dataSource) {
this.settings.enableOptimizedfindOrCreate === true ||
this.settings.enableOptimizedFindOrCreate === true
) {
MongoDB.prototype.findOrCreate = optimizedFindOrCreate;
debug('Optimized findOrCreate is enabled by default, and the enableOptimizedFindOrCreate setting is ignored since v7.0.0.')

Check failure on line 200 in lib/mongodb.js

GitHub Actions / Code Lint

This line has a length of 129. Maximum allowed is 120

Check failure on line 200 in lib/mongodb.js

GitHub Actions / Code Lint

Expected indentation of 4 spaces but found 6

Check failure on line 200 in lib/mongodb.js

GitHub Actions / Code Lint

Missing semicolon
}

if (this.settings.enableGeoIndexing === true) {
MongoDB.prototype.buildNearFilter = buildNearFilter;
} else {
@@ -1509,6 +1510,94 @@ MongoDB.prototype.all = function all(modelName, filter, options, callback) {
}
};

/**
* Find a matching model instances by the filter or create a new instance
*
* Only supported on mongodb 2.6+
*
* @param {String} modelName The model name
* @param {Object} data The model instance data
* @param {Object} filter The filter
* @param {Function} [callback] The callback function
*/
MongoDB.prototype.findOrCreate = function findOrCreate(modelName, filter, data, options, callback) {
const self = this;
if (self.debug) {
debug('findOrCreate', modelName, filter, data);
}

if (!callback) callback = options;

const idValue = self.getIdValue(modelName, data);
const idName = self.idName(modelName);

if (idValue == null) {
delete data[idName]; // Allow MongoDB to generate the id
} else {
const oid = self.coerceId(modelName, idValue, options); // Is it an Object ID?
data._id = oid; // Set it to _id
if (idName !== '_id') {
delete data[idName];
}
}

filter = filter || {};
let query = {};
if (filter.where) {
if (filter.where[idName]) {
let id = filter.where[idName];
delete filter.where[idName];
id = self.coerceId(modelName, id, options);
filter.where._id = id;
}
query = self.buildWhere(modelName, filter.where, options);
}

const sort = self.buildSort(modelName, filter.order, options);

const projection = fieldsArrayToObj(filter.fields);

this.collection(modelName).findOneAndUpdate(
query,
{$setOnInsert: data},
{projection: projection, sort: sort, upsert: true},
function(err, result) {
if (self.debug) {
debug('findOrCreate.callback', modelName, filter, err, result);
}
if (err) {
return callback(err);
}

let value = result.value;
const created = !!result.lastErrorObject.upserted;

if (created && (value == null || Object.keys(value).length === 0)) {
value = data;
self.setIdValue(modelName, value, result.lastErrorObject.upserted);
} else {
value = self.fromDatabase(modelName, value);
self.setIdValue(modelName, value, value._id);
}

if (value && idName !== '_id') {
delete value._id;
}

if (filter && filter.include) {
self._models[modelName].model.include([value], filter.include, function(
err,
data,
) {
callback(err, data[0], created);
});
} else {
callback(null, value, created);
}
},
);
}

Check failure on line 1599 in lib/mongodb.js

GitHub Actions / Code Lint

Missing semicolon

/**
* Transform db data to model entity
*
@@ -2265,94 +2354,6 @@ function sanitizeFilter(filter, options) {

exports.sanitizeFilter = sanitizeFilter;

/**
* Find a matching model instances by the filter or create a new instance
*
* Only supported on mongodb 2.6+
*
* @param {String} modelName The model name
* @param {Object} data The model instance data
* @param {Object} filter The filter
* @param {Function} [callback] The callback function
*/
function optimizedFindOrCreate(modelName, filter, data, options, callback) {
const self = this;
if (self.debug) {
debug('findOrCreate', modelName, filter, data);
}

if (!callback) callback = options;

const idValue = self.getIdValue(modelName, data);
const idName = self.idName(modelName);

if (idValue == null) {
delete data[idName]; // Allow MongoDB to generate the id
} else {
const oid = self.coerceId(modelName, idValue, options); // Is it an Object ID?
data._id = oid; // Set it to _id
if (idName !== '_id') {
delete data[idName];
}
}

filter = filter || {};
let query = {};
if (filter.where) {
if (filter.where[idName]) {
let id = filter.where[idName];
delete filter.where[idName];
id = self.coerceId(modelName, id, options);
filter.where._id = id;
}
query = self.buildWhere(modelName, filter.where, options);
}

const sort = self.buildSort(modelName, filter.order, options);

const projection = fieldsArrayToObj(filter.fields);

this.collection(modelName).findOneAndUpdate(
query,
{$setOnInsert: data},
{projection: projection, sort: sort, upsert: true},
function(err, result) {
if (self.debug) {
debug('findOrCreate.callback', modelName, filter, err, result);
}
if (err) {
return callback(err);
}

let value = result.value;
const created = !!result.lastErrorObject.upserted;

if (created && (value == null || Object.keys(value).length === 0)) {
value = data;
self.setIdValue(modelName, value, result.lastErrorObject.upserted);
} else {
value = self.fromDatabase(modelName, value);
self.setIdValue(modelName, value, value._id);
}

if (value && idName !== '_id') {
delete value._id;
}

if (filter && filter.include) {
self._models[modelName].model.include([value], filter.include, function(
err,
data,
) {
callback(err, data[0], created);
});
} else {
callback(null, value, created);
}
},
);
}

/**
* @param {*} data Plain Data Object for the matching property definition(s)
* @param {*} modelCtor Model constructor