Skip to content

Commit

Permalink
Merge pull request #5072 from sjorssnoeren/gh-5068
Browse files Browse the repository at this point in the history
InsertMany behaves as expected for validation errors while ordered op…
  • Loading branch information
vkarpov15 authored Mar 15, 2017
2 parents 0a88085 + d2eaff0 commit 91866a8
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 7 deletions.
27 changes: 21 additions & 6 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1976,6 +1976,12 @@ Model.insertMany = function(arr, options, callback) {
doc = new _this(doc);
doc.validate({ __noPromise: true }, function(error) {
if (error) {
// Option `ordered` signals that insert should be continued after reaching
// a failing insert. Therefore we delegate "null", meaning the validation
// failed. It's up to the next function to filter out all failed models
if (options != null && typeof options === 'object' && options['ordered'] === false) {
return callback(null, null);
}
return callback(error);
}
callback(null, doc);
Expand All @@ -1988,7 +1994,16 @@ Model.insertMany = function(arr, options, callback) {
callback && callback(error);
return;
}
var docObjects = docs.map(function(doc) {
// We filter all failed pre-validations by removing nulls
var docAttributes = docs.filter(function(doc) {
return doc != null;
});
// Quickly escape while there aren't any valid docAttributes
if (docAttributes.length < 1) {
callback && callback(null, []);
return;
}
var docObjects = docAttributes.map(function(doc) {
if (doc.schema.options.versionKey) {
doc[doc.schema.options.versionKey] = 0;
}
Expand All @@ -2002,12 +2017,12 @@ Model.insertMany = function(arr, options, callback) {
callback && callback(error);
return;
}
for (var i = 0; i < docs.length; ++i) {
docs[i].isNew = false;
docs[i].emit('isNew', false);
docs[i].constructor.emit('isNew', false);
for (var i = 0; i < docAttributes.length; ++i) {
docAttributes[i].isNew = false;
docAttributes[i].emit('isNew', false);
docAttributes[i].constructor.emit('isNew', false);
}
callback && callback(null, docs);
callback && callback(null, docAttributes);
});
});
};
Expand Down
76 changes: 75 additions & 1 deletion test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5222,7 +5222,7 @@ describe('Model', function() {
});
});

it('insertMany() ordered option (gh-3893)', function(done) {
it('insertMany() ordered option for constraint errors (gh-3893)', function(done) {
start.mongodVersion(function(err, version) {
if (err) {
done(err);
Expand Down Expand Up @@ -5264,6 +5264,80 @@ describe('Model', function() {
}
});

it('insertMany() ordered option for validation errors (gh-5068)', function(done) {
start.mongodVersion(function(err, version) {
if (err) {
done(err);
return;
}
var mongo34 = version[0] > 3 || (version[0] === 3 && version[1] >= 4);
if (!mongo34) {
done();
return;
}

test();
});

function test() {
var schema = new Schema({
name: { type: String, required: true }
});
var Movie = db.model('gh5068', schema);

var arr = [
{ name: 'Star Wars' },
{ foo: 'Star Wars' },
{ name: 'The Empire Strikes Back' }
];
Movie.insertMany(arr, { ordered: false }, function(error) {
assert.ifError(error);
Movie.find({}).sort({ name: 1 }).exec(function(error, docs) {
assert.ifError(error);
assert.equal(docs.length, 2);
assert.equal(docs[0].name, 'Star Wars');
assert.equal(docs[1].name, 'The Empire Strikes Back');
done();
});
});
}
});

it('insertMany() ordered option for single validation error', function(done) {
start.mongodVersion(function(err, version) {
if (err) {
done(err);
return;
}
var mongo34 = version[0] > 3 || (version[0] === 3 && version[1] >= 4);
if (!mongo34) {
done();
return;
}

test();
});

function test() {
var schema = new Schema({
name: { type: String, required: true }
});
var Movie = db.model('gh5068-2', schema);

var arr = [
{ foo: 'Star Wars' },
{ foo: 'The Fast and the Furious' }
];
Movie.insertMany(arr, { ordered: false }, function(error) {
assert.ifError(error);
Movie.find({}).sort({ name: 1 }).exec(function(error, docs) {
assert.equal(docs.length, 0);
done();
});
});
}
});

it('insertMany() hooks (gh-3846)', function(done) {
var schema = new Schema({
name: String
Expand Down

0 comments on commit 91866a8

Please sign in to comment.