You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP →

loopback-connector-mongodb

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

loopback-connector-mongodb - npm Package Compare versions

Comparing version

to
3.5.0

@@ -6,2 +6,4 @@ // Copyright IBM Corp. 2015,2016. All Rights Reserved.

'use strict';
var DataSource = require('loopback-datasource-juggler').DataSource;

@@ -17,3 +19,3 @@ var connector = require('..');

var Todo = ds.define('Todo', {
content: { type: String },
content: {type: String},
});

@@ -30,3 +32,3 @@

var suite = new Benchmark.Suite;
var suite = new Benchmark.Suite();
suite

@@ -39,3 +41,3 @@ .on('start', function() {

fn: function(deferred) {
Todo.create({ content: 'Buy eggs, ' + (uniqVal++) }, function() {
Todo.create({content: 'Buy eggs, ' + uniqVal++}, function() {
deferred.resolve();

@@ -55,5 +57,5 @@ });

Todo.create([
{ content: 'Buy eggs' },
{ content: 'Buy milk' },
{ content: 'Buy cheese' },
{content: 'Buy eggs'},
{content: 'Buy milk'},
{content: 'Buy cheese'},
]);

@@ -66,3 +68,3 @@ },

fn: function(deferred) {
Todo.find({ where: { content: 'Buy milk' }}, function() {
Todo.find({where: {content: 'Buy milk'}}, function() {
deferred.resolve();

@@ -73,5 +75,5 @@ });

Todo.create([
{ content: 'Buy eggs' },
{ content: 'Buy milk' },
{ content: 'Buy cheese' },
{content: 'Buy eggs'},
{content: 'Buy milk'},
{content: 'Buy cheese'},
]);

@@ -89,2 +91,2 @@ },

})
.run({ async: true });
.run({async: true});

@@ -0,1 +1,9 @@

2018-07-24, Version 3.5.0
=========================
* chore: drop node 4 and update deps (Taranveer Virk)
* [WebFM] cs/pl/ru translation (candytangnb)
2018-06-05, Version 3.4.4

@@ -2,0 +10,0 @@ =========================

@@ -6,2 +6,4 @@ // Copyright IBM Corp. 2013,2016. All Rights Reserved.

'use strict';
var g = require('strong-globalize')();

@@ -11,39 +13,52 @@

var config = require('rc')('loopback', { dev: { mongodb: {}}}).dev.mongodb;
var config = require('rc')('loopback', {dev: {mongodb: {}}}).dev.mongodb;
var ds = new DataSource(require('../'), config);
var Customer = ds.createModel('customer', { seq: { type: Number, id: true }, name: String, emails: [
{ label: String, email: String },
], age: Number });
var Customer = ds.createModel('customer', {
seq: {type: Number, id: true},
name: String,
emails: [{label: String, email: String}],
age: Number,
});
Customer.destroyAll(function(err) {
Customer.create({
seq: 1,
name: 'John1',
emails: [
{ label: 'work', email: 'john@x.com' },
{ label: 'home', email: 'john@y.com' },
],
age: 30,
}, function(err, customer1) {
console.log(customer1.toObject());
Customer.create({
seq: 2,
name: 'John2',
Customer.create(
{
seq: 1,
name: 'John1',
emails: [
{ label: 'work', email: 'john2@x.com' },
{ label: 'home', email: 'john2@y.com' },
{label: 'work', email: 'john@x.com'},
{label: 'home', email: 'john@y.com'},
],
age: 35,
}, function(err, customer2) {
Customer.find({ where: { 'emails.email': 'john@x.com' }}, function(err, customers) {
g.log('{{Customers}} matched by {{emails.email}} %s', customers);
});
age: 30,
},
function(err, customer1) {
console.log(customer1.toObject());
Customer.find({ where: { 'emails.0.label': 'work' }}, function(err, customers) {
g.log('{{Customers}} matched by {{emails.0.label}} %s', customers);
});
/*
Customer.create(
{
seq: 2,
name: 'John2',
emails: [
{label: 'work', email: 'john2@x.com'},
{label: 'home', email: 'john2@y.com'},
],
age: 35,
},
function(err, customer2) {
Customer.find({where: {'emails.email': 'john@x.com'}}, function(
err,
customers
) {
g.log('{{Customers}} matched by {{emails.email}} %s', customers);
});
Customer.find({where: {'emails.0.label': 'work'}}, function(
err,
customers
) {
g.log('{{Customers}} matched by {{emails.0.label}} %s', customers);
});
/*
customer1.updateAttributes({name: 'John'}, function(err, result) {

@@ -53,3 +68,2 @@ console.log(err, result);

customer1.delete(function(err, result) {

@@ -63,15 +77,15 @@ customer1.updateAttributes({name: 'JohnX'}, function(err, result) {

Customer.findById(customer1.seq, function(err, customer1) {
console.log(customer1.toObject());
Customer.findById(customer1.seq, function(err, customer1) {
console.log(customer1.toObject());
customer1.name = 'John';
customer1.save(function(err, customer1) {
console.log(customer1.toObject());
ds.disconnect();
});
});
});
});
customer1.name = 'John';
customer1.save(function(err, customer1) {
console.log(customer1.toObject());
ds.disconnect();
});
});
}
);
}
);
});

@@ -6,2 +6,4 @@ // Copyright IBM Corp. 2012. All Rights Reserved.

'use strict';
var SG = require('strong-globalize');

@@ -8,0 +10,0 @@ SG.SetRootDir(__dirname);

@@ -6,2 +6,4 @@ // Copyright IBM Corp. 2015,2016. All Rights Reserved.

'use strict';
var DataSource = require('loopback-datasource-juggler').DataSource;

@@ -16,5 +18,5 @@ var connector = require('../..');

var Todo = db.define('Todo', {
content: { type: String },
content: {type: String},
});
module.exports = Todo;

@@ -6,4 +6,5 @@ // Copyright IBM Corp. 2015. All Rights Reserved.

global.sinon = require('sinon');
'use strict';
global.ITERATIONS = process.env.ITERATIONS || 100;
require('should');

@@ -6,3 +6,6 @@ // Copyright IBM Corp. 2015. All Rights Reserved.

'use strict';
var memwatch = require('memwatch-next');
var sinon = require('sinon');

@@ -20,4 +23,4 @@ describe('leak detector', function() {

var interval = setInterval(function() {
if (test.iterations >= ITERATIONS || test.spy.called) {
test.spy.called.should.be.true;
if (test.iterations >= global.ITERATIONS || test.spy.called) {
test.spy.called.should.be.True();
clearInterval(interval);

@@ -24,0 +27,0 @@ return done();

@@ -6,3 +6,6 @@ // Copyright IBM Corp. 2015,2016. All Rights Reserved.

'use strict';
var memwatch = require('memwatch-next');
var sinon = require('sinon');
var Todo = require('./fixtures/todo');

@@ -33,4 +36,4 @@

var interval = setInterval(function() {
if (ctx.iterations >= ITERATIONS || ctx.spy.called) {
ctx.spy.called.should.be.false;
if (ctx.iterations >= global.ITERATIONS || ctx.spy.called) {
ctx.spy.called.should.be.False();
clearInterval(interval);

@@ -40,2 +43,3 @@ return done();

ctx.iterations++;
// eslint-disable-next-line
hasOptions ? Todo[func](options) : Todo[func];

@@ -51,11 +55,14 @@ }, 0);

beforeEach(function createFixtures(done) {
Todo.create([
{ content: 'Buy eggs' },
{ content: 'Buy milk' },
{ content: 'Buy cheese' },
], done);
Todo.create(
[
{content: 'Buy eggs'},
{content: 'Buy milk'},
{content: 'Buy cheese'},
],
done
);
});
it('should not leak when retrieving a specific item', function(done) {
execute(this, 'find', { where: { content: 'Buy eggs' }}, done);
execute(this, 'find', {where: {content: 'Buy eggs'}}, done);
});

@@ -74,13 +81,18 @@

it('should not leak when creating an item', function(done) {
execute(this, 'create', { content: 'Buy eggs' }, done);
execute(this, 'create', {content: 'Buy eggs'}, done);
});
it('should not leak when creating multiple items', function(done) {
execute(this, 'create', [
{ content: 'Buy eggs' },
{ content: 'Buy milk' },
{ content: 'Buy cheese' },
], done);
execute(
this,
'create',
[
{content: 'Buy eggs'},
{content: 'Buy milk'},
{content: 'Buy cheese'},
],
done
);
});
});
});

@@ -6,2 +6,4 @@ // Copyright IBM Corp. 2012,2016. All Rights Reserved.

'use strict';
/*!

@@ -51,10 +53,28 @@ * Module dependencies

function generateMongoDBURL(options) {
options.hostname = (options.hostname || options.host || '127.0.0.1');
options.port = (options.port || 27017);
options.database = (options.database || options.db || 'test');
options.hostname = options.hostname || options.host || '127.0.0.1';
options.port = options.port || 27017;
options.database = options.database || options.db || 'test';
var username = options.username || options.user;
if (username && options.password) {
return 'mongodb://' + username + ':' + options.password + '@' + options.hostname + ':' + options.port + '/' + options.database;
return (
'mongodb://' +
username +
':' +
options.password +
'@' +
options.hostname +
':' +
options.port +
'/' +
options.database
);
} else {
return 'mongodb://' + options.hostname + ':' + options.port + '/' + options.database;
return (
'mongodb://' +
options.hostname +
':' +
options.port +
'/' +
options.database
);
}

@@ -75,3 +95,3 @@ }

s.safe = (s.safe !== false);
s.safe = s.safe !== false;
s.w = s.w || 1;

@@ -95,3 +115,3 @@ s.url = s.url || generateMongoDBURL(s);

/**
/**
* The constructor for MongoDB connector

@@ -112,6 +132,8 @@ * @param {Object} settings The settings object

this.dataSource = dataSource;
if (this.settings.enableOptimisedfindOrCreate === true ||
if (
this.settings.enableOptimisedfindOrCreate === true ||
this.settings.enableOptimisedFindOrCreate === true ||
this.settings.enableOptimizedfindOrCreate === true ||
this.settings.enableOptimizedFindOrCreate === true) {
this.settings.enableOptimizedFindOrCreate === true
) {
MongoDB.prototype.findOrCreate = optimizedFindOrCreate;

@@ -140,3 +162,3 @@ }

process.nextTick(function() {
callback && callback(null, self.db);
if (callback) callback(null, self.db);
});

@@ -146,3 +168,3 @@ } else if (self.dataSource.connecting) {

process.nextTick(function() {
callback && callback(null, self.db);
if (callback) callback(null, self.db);
});

@@ -227,3 +249,6 @@ });

debug('Valid options: %j', validOptions);
new mongodb.MongoClient(self.settings.url, validOptions).connect(function(err, client) {
new mongodb.MongoClient(self.settings.url, validOptions).connect(function(
err,
client
) {
if (!err) {

@@ -236,10 +261,17 @@ if (self.debug) {

return urlParser(self.settings.url, self.settings, function(err, url) {
self.db = client.db(url.dbName || self.settings.database, url.db_options || self.settings);
callback && callback(err, self.db);
self.db = client.db(
url.dbName || self.settings.database,
url.db_options || self.settings
);
if (callback) callback(err, self.db);
});
} else {
if (self.debug || !callback) {
g.error('{{MongoDB}} connection is failed: %s %s', self.settings.url, err);
g.error(
'{{MongoDB}} connection is failed: %s %s',
self.settings.url,
err
);
}
callback && callback(err, self.db);
if (callback) callback(err, self.db);
}

@@ -307,4 +339,9 @@ });

}
} else if (data[p] && prop && prop.type && prop.type.name === 'GeoPoint' &&
this.settings.enableGeoIndexing === true) {
} else if (
data[p] &&
prop &&
prop.type &&
prop.type.name === 'GeoPoint' &&
this.settings.enableGeoIndexing === true
) {
data[p] = {

@@ -376,3 +413,8 @@ lat: data[p].coordinates[1],

if (err) {
debug('Connection not established - MongoDB: model=%s command=%s -- error=%s', model, command, err);
debug(
'Connection not established - MongoDB: model=%s command=%s -- error=%s',
model,
command,
err
);
}

@@ -387,3 +429,4 @@ doExecute();

model: model,
collection: collection, req: {
collection: collection,
req: {
command: command,

@@ -395,3 +438,3 @@ params: args,

try {
var collection = self.collection(model);
collection = self.collection(model);
} catch (err) {

@@ -403,15 +446,20 @@ debug('Error: ', err);

self.notifyObserversAround('execute', context, function(context, done) {
args[args.length - 1] = function(err, result) {
if (err) {
debug('Error: ', err);
} else {
context.res = result;
debug('Result: ', result);
}
done(err, result);
};
debug('MongoDB: model=%s command=%s', model, command, args);
return collection[command].apply(collection, args);
}, callback);
self.notifyObserversAround(
'execute',
context,
function(context, done) {
args[args.length - 1] = function(err, result) {
if (err) {
debug('Error: ', err);
} else {
context.res = result;
debug('Result: ', result);
}
done(err, result);
};
debug('MongoDB: model=%s command=%s', model, command, args);
return collection[command].apply(collection, args);
},
callback
);
}

@@ -464,3 +512,5 @@ };

data._id = oid; // Set it to _id
idName !== '_id' && delete data[idName];
if (idName !== '_id') {
delete data[idName];
}
}

@@ -470,3 +520,3 @@

this.execute(model, 'insert', data, { safe: true }, function(err, result) {
this.execute(model, 'insert', data, {safe: true}, function(err, result) {
if (self.debug) {

@@ -507,3 +557,5 @@ debug('create.callback', model, err, result);

data._id = oid;
idName !== '_id' && delete data[idName];
if (idName !== '_id') {
delete data[idName];
}

@@ -515,3 +567,5 @@ data = self.toDatabase(model, data);

self.setIdValue(model, data, idValue);
idName !== '_id' && delete data._id;
if (idName !== '_id') {
delete data._id;
}
}

@@ -538,3 +592,5 @@ if (self.debug) {

callback && callback(err, result && result.ops, info);
if (callback) {
callback(err, result && result.ops, info);
}
});

@@ -556,3 +612,3 @@ };

id = self.coerceId(model, id);
this.execute(model, 'findOne', { _id: id }, function(err, data) {
this.execute(model, 'findOne', {_id: id}, function(err, data) {
if (self.debug) {

@@ -578,3 +634,3 @@ debug('exists.callback', model, id, err, data);

var oid = self.coerceId(model, id);
this.execute(model, 'findOne', { _id: oid }, function(err, data) {
this.execute(model, 'findOne', {_id: oid}, function(err, data) {
if (self.debug) {

@@ -585,9 +641,12 @@ debug('find.callback', model, id, err, data);

data = self.fromDatabase(model, data);
data && idName !== '_id' && delete data._id;
callback && callback(err, data);
if (data && idName !== '_id') {
delete data._id;
}
if (callback) {
callback(err, data);
}
});
};
Connector.defineAliases(MongoDB.prototype, 'find',
'findById');
Connector.defineAliases(MongoDB.prototype, 'find', 'findById');

@@ -610,5 +669,9 @@ /**

allowExtendedOperators = options.allowExtendedOperators === true;
} else if (allowExtendedOperators !== false && modelClass.settings.mongodb &&
modelClass.settings.mongodb.hasOwnProperty('allowExtendedOperators')) {
allowExtendedOperators = modelClass.settings.mongodb.allowExtendedOperators === true;
} else if (
allowExtendedOperators !== false &&
modelClass.settings.mongodb &&
modelClass.settings.mongodb.hasOwnProperty('allowExtendedOperators')
) {
allowExtendedOperators =
modelClass.settings.mongodb.allowExtendedOperators === true;
} else if (allowExtendedOperators === true) {

@@ -622,5 +685,18 @@ allowExtendedOperators = true;

// Field operators
'$currentDate', '$inc', '$max', '$min', '$mul', '$rename', '$setOnInsert', '$set', '$unset',
'$currentDate',
'$inc',
'$max',
'$min',
'$mul',
'$rename',
'$setOnInsert',
'$set',
'$unset',
// Array operators
'$addToSet', '$pop', '$pullAll', '$pull', '$pushAll', '$push',
'$addToSet',
'$pop',
'$pullAll',
'$pull',
'$pushAll',
'$push',
// Bitwise operator

@@ -658,3 +734,8 @@ '$bit',

*/
MongoDB.prototype.updateOrCreate = function updateOrCreate(model, data, options, callback) {
MongoDB.prototype.updateOrCreate = function updateOrCreate(
model,
data,
options,
callback
) {
var self = this;

@@ -675,29 +756,39 @@ if (self.debug) {

this.execute(model, 'findAndModify', {
_id: oid,
}, [
['_id', 'asc'],
], data, { upsert: true, new: true }, function(err, result) {
if (self.debug) {
debug('updateOrCreate.callback', model, id, err, result);
}
var object = result && result.value;
if (!err && !object) {
// No result
err = 'No ' + model + ' found for id ' + id;
}
if (!err) {
self.setIdValue(model, object, oid);
object && idName !== '_id' && delete object._id;
}
this.execute(
model,
'findAndModify',
{
_id: oid,
},
[['_id', 'asc']],
data,
{upsert: true, new: true},
function(err, result) {
if (self.debug) {
debug('updateOrCreate.callback', model, id, err, result);
}
var object = result && result.value;
if (!err && !object) {
// No result
err = 'No ' + model + ' found for id ' + id;
}
if (!err) {
self.setIdValue(model, object, oid);
if (object && idName !== '_id') {
delete object._id;
}
}
var info;
if (result && result.lastErrorObject) {
info = { isNewInstance: !result.lastErrorObject.updatedExisting };
} else {
debug('updateOrCreate result format not recognized: %j', result);
var info;
if (result && result.lastErrorObject) {
info = {isNewInstance: !result.lastErrorObject.updatedExisting};
} else {
debug('updateOrCreate result format not recognized: %j', result);
}
if (callback) {
callback(err, object, info);
}
}
callback && callback(err, object, info);
});
);
};

@@ -721,3 +812,3 @@

delete data[idName];
this.replaceWithOptions(model, oid, data, { upsert: true }, cb);
this.replaceWithOptions(model, oid, data, {upsert: true}, cb);
};

@@ -737,3 +828,3 @@

id = self.coerceId(model, id);
this.execute(model, 'remove', { _id: id }, function(err, result) {
this.execute(model, 'remove', {_id: id}, function(err, result) {
if (self.debug) {

@@ -744,5 +835,7 @@ debug('delete.callback', model, id, err, result);

if (res) {
res = { count: res.n };
res = {count: res.n};
}
callback && callback(err, res);
if (callback) {
callback(err, res);
}
});

@@ -768,3 +861,3 @@ };

}
if ((idName in fields) && !fields[idName]) {
if (idName in fields && !fields[idName]) {
// Excluded

@@ -782,3 +875,3 @@ return false;

var query = {};
if (where === null || (typeof where !== 'object')) {
if (where === null || typeof where !== 'object') {
return query;

@@ -821,3 +914,3 @@ }

if (spec === 'between') {
query[k] = { $gte: cond[0], $lte: cond[1] };
query[k] = {$gte: cond[0], $lte: cond[1]};
} else if (spec === 'inq') {

@@ -841,14 +934,14 @@ cond = [].concat(cond || []);

if (cond instanceof RegExp) {
query[k] = { $regex: cond };
query[k] = {$regex: cond};
} else {
query[k] = { $regex: new RegExp(cond, options) };
query[k] = {$regex: new RegExp(cond, options)};
}
} else if (spec === 'nlike') {
if (cond instanceof RegExp) {
query[k] = { $not: cond };
query[k] = {$not: cond};
} else {
query[k] = { $not: new RegExp(cond, options) };
query[k] = {$not: new RegExp(cond, options)};
}
} else if (spec === 'neq') {
query[k] = { $ne: cond };
query[k] = {$ne: cond};
} else if (spec === 'regexp') {

@@ -858,3 +951,3 @@ if (cond.global)

query[k] = { $regex: cond };
query[k] = {$regex: cond};
} else {

@@ -868,3 +961,3 @@ query[k] = {};

// Null: 10
query[k] = { $type: 10 };
query[k] = {$type: 10};
} else {

@@ -913,3 +1006,3 @@ if (self.isObjectIDProperty(model, prop, cond)) {

// order by _id by default
sort = { _id: 1 };
sort = {_id: 1};
}

@@ -930,3 +1023,7 @@ return sort;

default:
console.warn('unsupported unit ' + unit + ', fallback to mongodb default unit \'meters\'');
console.warn(
'unsupported unit ' +
unit +
", fallback to mongodb default unit 'meters'"
);
return distance;

@@ -986,3 +1083,5 @@ }

if (!property.hasOwnProperty(subKey)) {
property[subKey] = Number.isInteger(near.mongoKey[i + 1]) ? [] : {};
property[subKey] = Number.isInteger(near.mongoKey[i + 1]) ?
[] :
{};
}

@@ -1001,3 +1100,3 @@

});
};
}

@@ -1064,5 +1163,10 @@ function hasNearFilter(where) {

if (prop.mongodb) {
propName = prop.mongodb.fieldName || prop.mongodb.field ||
prop.mongodb.columnName || prop.mongodb.column ||
prop.columnName || prop.column || propName;
propName =
prop.mongodb.fieldName ||
prop.mongodb.field ||
prop.mongodb.columnName ||
prop.mongodb.column ||
prop.columnName ||
prop.column ||
propName;
} else {

@@ -1150,3 +1254,3 @@ // Try top level overrides

// convert the array of fields into a projection object see http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#find
var findOpts = { projection: fields };
var findOpts = {projection: fields};
this.execute(model, 'find', query, findOpts, processResponse);

@@ -1200,3 +1304,8 @@ } else {

if (filter && filter.include) {
self._models[model].model.include(objs, filter.include, options, callback);
self._models[model].model.include(
objs,
filter.include,
options,
callback
);
} else {

@@ -1215,3 +1324,8 @@ callback(null, objs);

*/
MongoDB.prototype.destroyAll = function destroyAll(model, where, options, callback) {
MongoDB.prototype.destroyAll = function destroyAll(
model,
where,
options,
callback
) {
var self = this;

@@ -1229,8 +1343,9 @@ if (self.debug) {

if (self.debug)
debug('destroyAll.callback', model, where, err, info);
if (self.debug) debug('destroyAll.callback', model, where, err, info);
var affectedCount = info.result ? info.result.n : undefined;
callback && callback(err, { count: affectedCount });
if (callback) {
callback(err, {count: affectedCount});
}
});

@@ -1257,3 +1372,5 @@ };

}
callback && callback(err, count);
if (callback) {
callback(err, count);
}
});

@@ -1273,3 +1390,6 @@ };

var oid = this.coerceId(model, id);
this.replaceWithOptions(model, oid, data, { upsert: false }, function(err, data) {
this.replaceWithOptions(model, oid, data, {upsert: false}, function(
err,
data
) {
cb(err, data);

@@ -1298,5 +1418,8 @@ });

delete data[idName];
this.execute(model, 'update', { _id: id }, data, options, function(err, info) {
if (this.debug) debug('updateWithOptions.callback', model, { _id: id }, data, err, info);
if (err) return cb && cb(err);
this.execute(model, 'update', {_id: id}, data, options, function(
err,
info
) {
debug('updateWithOptions.callback', model, {_id: id}, data, err, info);
if (err) return cb && cb(err);
var result;

@@ -1322,3 +1445,5 @@ var cbInfo = {};

}
cb && cb(err, result, cbInfo);
if (cb) {
cb(err, result, cbInfo);
}
});

@@ -1333,3 +1458,9 @@ };

*/
MongoDB.prototype.updateAttributes = function updateAttrs(model, id, data, options, cb) {
MongoDB.prototype.updateAttributes = function updateAttrs(
model,
id,
data,
options,
cb
) {
var self = this;

@@ -1347,3 +1478,7 @@

if (Object.keys(data).length === 0) {
cb && process.nextTick(function() { cb(null, {}); });
if (cb) {
process.nextTick(function() {
cb(null, {});
});
}
return;

@@ -1355,17 +1490,27 @@ }

this.execute(model, 'findAndModify', { _id: oid }, [
['_id', 'asc'],
], data, {}, function(err, result) {
if (self.debug) {
debug('updateAttributes.callback', model, id, err, result);
this.execute(
model,
'findAndModify',
{_id: oid},
[['_id', 'asc']],
data,
{},
function(err, result) {
if (self.debug) {
debug('updateAttributes.callback', model, id, err, result);
}
var object = result && result.value;
if (!err && !object) {
// No result
err = errorIdNotFoundForUpdate(model, id);
}
self.setIdValue(model, object, id);
if (object && idName !== '_id') {
delete object._id;
}
if (cb) {
cb(err, object);
}
}
var object = result && result.value;
if (!err && !object) {
// No result
err = errorIdNotFoundForUpdate(model, id);
}
self.setIdValue(model, object, id);
object && idName !== '_id' && delete object._id;
cb && cb(err, object);
});
);
};

@@ -1387,30 +1532,43 @@

*/
MongoDB.prototype.update =
MongoDB.prototype.updateAll = function updateAll(model, where, data, options, cb) {
var self = this;
if (self.debug) {
debug('updateAll', model, where, data);
}
var idName = this.idName(model);
MongoDB.prototype.update = MongoDB.prototype.updateAll = function updateAll(
model,
where,
data,
options,
cb
) {
var self = this;
if (self.debug) {
debug('updateAll', model, where, data);
}
var idName = this.idName(model);
where = self.buildWhere(model, where);
delete data[idName];
where = self.buildWhere(model, where);
delete data[idName];
data = self.toDatabase(model, data);
data = self.toDatabase(model, data);
// Check for other operators and sanitize the data obj
data = self.parseUpdateData(model, data, options);
// Check for other operators and sanitize the data obj
data = self.parseUpdateData(model, data, options);
this.execute(model, 'update', where, data, { multi: true, upsert: false },
function(err, info) {
if (err) return cb && cb(err);
this.execute(
model,
'update',
where,
data,
{multi: true, upsert: false},
function(err, info) {
if (err) return cb && cb(err);
if (self.debug)
debug('updateAll.callback', model, where, data, err, info);
if (self.debug)
debug('updateAll.callback', model, where, data, err, info);
var affectedCount = info.result ? info.result.n : undefined;
var affectedCount = info.result ? info.result.n : undefined;
cb && cb(err, { count: affectedCount });
});
};
if (cb) {
cb(err, {count: affectedCount});
}
}
);
};

@@ -1447,3 +1605,3 @@ /**

}
if ((!cb) && ('function' === typeof models)) {
if (!cb && 'function' === typeof models) {
cb = models;

@@ -1461,85 +1619,105 @@ models = undefined;

async.each(models, function(model, modelCallback) {
var indexes = self._models[model].settings.indexes || [];
var indexList = [];
var index = {};
var options = {};
async.each(
models,
function(model, modelCallback) {
var indexes = self._models[model].settings.indexes || [];
var indexList = [];
var index = {};
var options = {};
if (typeof indexes === 'object') {
for (var indexName in indexes) {
index = indexes[indexName];
if (index.keys) {
// The index object has keys
options = index.options || {};
options.name = options.name || indexName;
index.options = options;
} else {
options = { name: indexName };
index = {
keys: index,
options: options,
};
if (typeof indexes === 'object') {
for (var indexName in indexes) {
index = indexes[indexName];
if (index.keys) {
// The index object has keys
options = index.options || {};
options.name = options.name || indexName;
index.options = options;
} else {
options = {name: indexName};
index = {
keys: index,
options: options,
};
}
indexList.push(index);
}
indexList.push(index);
} else if (Array.isArray(indexes)) {
indexList = indexList.concat(indexes);
}
} else if (Array.isArray(indexes)) {
indexList = indexList.concat(indexes);
}
var properties = self._models[model].properties;
/* eslint-disable one-var */
for (var p in properties) {
if (properties[p].index) {
index = {};
index[p] = 1; // Add the index key
if (typeof properties[p].index === 'object') {
// If there is a mongodb key for the index, use it
if (typeof properties[p].index.mongodb === 'object') {
options = properties[p].index.mongodb;
index[p] = options.kind || 1;
var properties = self._models[model].properties;
/* eslint-disable one-var */
for (var p in properties) {
if (properties[p].index) {
index = {};
index[p] = 1; // Add the index key
if (typeof properties[p].index === 'object') {
// If there is a mongodb key for the index, use it
if (typeof properties[p].index.mongodb === 'object') {
options = properties[p].index.mongodb;
index[p] = options.kind || 1;
// If 'kind' is set delete it so it isn't accidentally inserted as an index option
if (options.kind) {
delete options.kind;
// If 'kind' is set delete it so it isn't accidentally inserted as an index option
if (options.kind) {
delete options.kind;
}
// Backwards compatibility for former type of indexes
if (properties[p].index.unique === true) {
options.unique = true;
}
} else {
// If there isn't an properties[p].index.mongodb object, we read the properties from properties[p].index
options = properties[p].index;
}
// Backwards compatibility for former type of indexes
if (properties[p].index.unique === true) {
if (options.background === undefined) {
options.background = true;
}
} else if (
enableGeoIndexing &&
properties[p].type &&
properties[p].type.name === 'GeoPoint'
) {
var indexType =
typeof properties[p].index === 'string' ?
properties[p].index :
'2dsphere';
options = {name: 'index' + indexType + p};
index[p] = indexType;
} else {
options = {background: true};
if (properties[p].unique) {
options.unique = true;
}
} else {
// If there isn't an properties[p].index.mongodb object, we read the properties from properties[p].index
options = properties[p].index;
}
if (options.background === undefined) {
options.background = true;
}
} else if (enableGeoIndexing && properties[p].type && properties[p].type.name === 'GeoPoint') {
var indexType = typeof properties[p].index === 'string' ?
properties[p].index : '2dsphere';
options = { name: 'index' + indexType + p };
index[p] = indexType;
} else {
options = { background: true };
if (properties[p].unique) {
options.unique = true;
}
indexList.push({keys: index, options: options});
}
indexList.push({ keys: index, options: options });
}
}
/* eslint-enable one-var */
/* eslint-enable one-var */
if (self.debug) {
debug('create indexes: ', indexList);
}
async.each(indexList, function(index, indexCallback) {
if (self.debug) {
debug('createIndex: ', index);
debug('create indexes: ', indexList);
}
self.collection(model).createIndex(index.fields || index.keys, index.options, indexCallback);
}, modelCallback);
}, cb);
async.each(
indexList,
function(index, indexCallback) {
if (self.debug) {
debug('createIndex: ', index);
}
self
.collection(model)
.createIndex(
index.fields || index.keys,
index.options,
indexCallback
);
},
modelCallback
);
},
cb
);
} else {

@@ -1564,3 +1742,3 @@ self.dataSource.once('connected', function() {

}
if ((!cb) && ('function' === typeof models)) {
if (!cb && 'function' === typeof models) {
cb = models;

@@ -1577,29 +1755,43 @@ models = undefined;

// Make it serial as multiple models might map to the same collection
async.eachSeries(models, function(model, modelCallback) {
var collectionName = self.collectionName(model);
if (self.debug) {
debug('drop collection %s for model %s', collectionName, model);
}
async.eachSeries(
models,
function(model, modelCallback) {
var collectionName = self.collectionName(model);
if (self.debug) {
debug('drop collection %s for model %s', collectionName, model);
}
self.db.dropCollection(collectionName, function(err, collection) {
self.db.dropCollection(collectionName, function(err, collection) {
if (err) {
debug(
'Error dropping collection %s for model %s: ',
collectionName,
model,
err
);
if (
!(
err.name === 'MongoError' &&
err.ok === 0 &&
err.errmsg === 'ns not found'
)
) {
// For errors other than 'ns not found' (collection doesn't exist)
return modelCallback(err);
}
}
// Recreate the collection
if (self.debug) {
debug('create collection %s for model %s', collectionName, model);
}
self.db.createCollection(collectionName, modelCallback);
});
},
function(err) {
if (err) {
debug('Error dropping collection %s for model %s: ', collectionName, model, err);
if (!(err.name === 'MongoError' && err.ok === 0 &&
err.errmsg === 'ns not found')) {
// For errors other than 'ns not found' (collection doesn't exist)
return modelCallback(err);
}
return cb && cb(err);
}
// Recreate the collection
if (self.debug) {
debug('create collection %s for model %s', collectionName, model);
}
self.db.createCollection(collectionName, modelCallback);
});
}, function(err) {
if (err) {
return cb && cb(err);
self.autoupdate(models, cb);
}
self.autoupdate(models, cb);
});
);
} else {

@@ -1615,3 +1807,3 @@ self.dataSource.once('connected', function() {

if (self.db) {
this.db.collection('dummy').findOne({ _id: 1 }, cb);
this.db.collection('dummy').findOne({_id: 1}, cb);
} else {

@@ -1633,7 +1825,13 @@ self.dataSource.once('connected', function() {

MongoDB.prototype.isObjectIDProperty = function(model, prop, value) {
if (prop && ((prop.type === ObjectID) || (Array.isArray(prop.type) && prop.type[0] === ObjectID))) {
if (
prop &&
(prop.type === ObjectID ||
(Array.isArray(prop.type) && prop.type[0] === ObjectID))
) {
return true;
} else if ('string' === typeof value) {
var settings = this._models[model] && this._models[model].settings;
var strict = (settings && settings.strictObjectIDCoercion) || this.settings.strictObjectIDCoercion;
var strict =
(settings && settings.strictObjectIDCoercion) ||
this.settings.strictObjectIDCoercion;
if (strict) return false; // unless explicitly typed, don't coerce

@@ -1670,3 +1868,5 @@ return /^[0-9a-fA-F]{24}$/.test(value);

data._id = oid; // Set it to _id
idName !== '_id' && delete data[idName];
if (idName !== '_id') {
delete data[idName];
}
}

@@ -1690,4 +1890,4 @@

query,
{ $setOnInsert: data },
{ projection: filter.fields, sort: sort, upsert: true },
{$setOnInsert: data},
{projection: filter.fields, sort: sort, upsert: true},
function(err, result) {

@@ -1712,6 +1912,11 @@ if (self.debug) {

value && idName !== '_id' && delete value._id;
if (value && idName !== '_id') {
delete value._id;
}
if (filter && filter.include) {
self._models[model].model.include([value], filter.include, function(err, data) {
self._models[model].model.include([value], filter.include, function(
err,
data
) {
callback(err, data[0], created);

@@ -1722,3 +1927,4 @@ });

}
});
};
}
);
}

@@ -6,10 +6,17 @@ // Copyright IBM Corp. 2014. All Rights Reserved.

exports.getDistanceBetweenPoints = function getDistanceBetweenPoints(point1, point2) {
'use strict';
exports.getDistanceBetweenPoints = function getDistanceBetweenPoints(
point1,
point2
) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(point2.lat - point1.lat); // deg2rad below
var dLat = deg2rad(point2.lat - point1.lat); // deg2rad below
var dLon = deg2rad(point2.lng - point1.lng);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(point1.lat)) * Math.cos(deg2rad(point2.lat)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
Math.cos(deg2rad(point1.lat)) *
Math.cos(deg2rad(point2.lat)) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);

@@ -16,0 +23,0 @@ var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

{
"name": "loopback-connector-mongodb",
"version": "3.4.4",
"version": "3.5.0",
"description": "The official MongoDB connector for the LoopBack framework.",
"engines": {
"node": ">=4"
"node": ">=6"
},

@@ -12,3 +12,3 @@ "main": "index.js",

"leak-detection": "make leak-detection",
"test": "mocha -G --timeout 10000 --require test/init.js test/*.test.js",
"test": "mocha",
"lint": "eslint .",

@@ -33,5 +33,5 @@ "posttest": "npm run lint"

"debug": "^3.1.0",
"loopback-connector": "^4.0.0",
"loopback-connector": "^4.5.0",
"mongodb": "^3.0.1",
"strong-globalize": "^3.1.0"
"strong-globalize": "^4.1.1"
},

@@ -41,12 +41,12 @@ "devDependencies": {

"bluebird": "^3.5.1",
"eslint": "^2.7.0",
"eslint-config-loopback": "^1.0.0",
"eslint": "^5.1.0",
"eslint-config-loopback": "^10.0.0",
"loopback-datasource-juggler": "^3.0.0",
"memwatch-next": "^0.3.0",
"mocha": "^2.1.0",
"rc": "^1.0.0",
"mocha": "^5.2.0",
"rc": "^1.2.8",
"semver": "^5.5.0",
"should": "^8.0.2",
"sinon": "^1.15.4"
"should": "^13.2.1",
"sinon": "^6.1.3"
}
}