Skip to content

Commit

Permalink
Supports the keepGoing bulk insert property for 1.9.1 or higher, igno…
Browse files Browse the repository at this point in the history
…red in earlier db versions
  • Loading branch information
christkv committed Aug 10, 2011
1 parent e88d4a4 commit d869d25
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 17 deletions.
24 changes: 18 additions & 6 deletions lib/mongodb/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ Collection.prototype.insert = function insert (docs, options, callback) {
if(!('function' === typeof callback)) callback = null;

this.insertAll(Array.isArray(docs) ? docs : [docs], options, callback);

return this;
};

Expand Down Expand Up @@ -242,10 +241,20 @@ Collection.prototype.insertAll = function insertAll (docs, options, callback) {
if('function' === typeof options) callback = options, options = {};
if(options == null) options = {};
if(!('function' === typeof callback)) callback = null;


// Insert options (flags for insert)
var insertFlags = {};
// If we have a mongodb version >= 1.9.1 support keepGoing attribute
if(this.db.versionAsNumber >= 191) {
if(options['keepGoing'] != null) {
insertFlags['keepGoing'] = options['keepGoing'];
}
}

// Pass in options
var insertCommand = new InsertCommand(
this.db
, this.db.databaseName + "." + this.collectionName);
, this.db.databaseName + "." + this.collectionName, true, insertFlags);

// Add the documents and decorate them with id's if they have none
for (var index = 0, len = docs.length; index < len; ++index) {
Expand All @@ -264,11 +273,14 @@ Collection.prototype.insertAll = function insertAll (docs, options, callback) {
errorOptions = errorOptions == null && this.opts.safe != null ? this.opts.safe : errorOptions;
errorOptions = errorOptions == null && this.db.strict != null ? this.db.strict : errorOptions;

// Default command options
var commandOptions = {};

// If safe is defined check for error message
// if(options != null && (options.safe == true || this.db.strict == true || this.opts.safe == true)) {
if(errorOptions) {
// Insert options
var commandOptions = {read:false};
commandOptions['read'] = false;
// If we have safe set set async to false
if(errorOptions == null) commandOptions['async'] = true;
// Set safe option
Expand All @@ -280,7 +292,7 @@ Collection.prototype.insertAll = function insertAll (docs, options, callback) {
commandOptions[keys[i]] = errorOptions[keys[i]];
}
}

// Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
this.db.executeCommand(insertCommand, commandOptions, function (err, error) {
error = error && error.documents;
Expand All @@ -295,7 +307,7 @@ Collection.prototype.insertAll = function insertAll (docs, options, callback) {
}
});
} else {
var result = this.db.executeCommand(insertCommand);
var result = this.db.executeCommand(insertCommand, commandOptions);
// If no callback just return
if(!callback) return;
// If error return error
Expand Down
24 changes: 18 additions & 6 deletions lib/mongodb/commands/insert_command.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ var BaseCommand = require('./base_command').BaseCommand,
/**
Insert Document Command
**/
var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys) {
var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) {
BaseCommand.call(this);

this.collectionName = collectionName;
this.documents = [];
this.checkKeys = checkKeys == null ? true : checkKeys;
this.db = db;
this.flags = 0;

// Ensure valid options hash
options = options == null ? {} : options;

// Check if we have keepGoing set -> set flag if it's the case
if(options['keepGoing'] != null && options['keepGoing']) {
// This will finish inserting all non-index violating documents even if it returns an error
this.flags = 1;
}
};

inherits(InsertCommand, BaseCommand);
Expand Down Expand Up @@ -71,11 +81,13 @@ InsertCommand.prototype.toBinary = function() {
_command[_index] = InsertCommand.OP_INSERT & 0xff;
// Adjust index
_index = _index + 4;
// Write zero
_command[_index++] = 0;
_command[_index++] = 0;
_command[_index++] = 0;
_command[_index++] = 0;
// Write flags if any
_command[_index + 3] = (this.flags >> 24) & 0xff;
_command[_index + 2] = (this.flags >> 16) & 0xff;
_command[_index + 1] = (this.flags >> 8) & 0xff;
_command[_index] = this.flags & 0xff;
// Adjust index
_index = _index + 4;
// Write the collection name to the command
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
_command[_index - 1] = 0;
Expand Down
1 change: 1 addition & 0 deletions lib/mongodb/connections/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Server.prototype.connect = function(parent, callback) {
if(err != null) return callback(err, null);
// Store the db version
parent.version = doc.version;
parent.versionAsNumber = parseInt(doc.version.replace(/\./g, ""));
callback(null, parent);
});
} else {
Expand Down
4 changes: 1 addition & 3 deletions lib/mongodb/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,7 @@ Db.prototype.wrap = function(error) {
var keys = Object.keys(error);
// Populate error object with properties
for(var i = 0; i < keys.length; i++) {
if(error.hasOwnProperty(keys[i])) {
e[keys[i]] = error[keys[i]];
}
e[keys[i]] = error[keys[i]];
}

return e;
Expand Down
2 changes: 1 addition & 1 deletion test/find_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ var tests = testCase({
client.createCollection('AttemptToFindAndModifyNonExistingDocument', function(err, collection) {
// Let's modify the document in place
collection.findAndModify({name: 'test1'}, [], {$set: {name: 'test2'}}, {}, function(err, updated_doc) {
if(parseInt(client.version.replace(/./, '')) < 191) {
if(parseInt(client.version.replace(/\./g, '')) < 191) {
test.equal(null, updated_doc);
test.ok(err != null);
} else {
Expand Down
22 changes: 21 additions & 1 deletion test/index_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ var tests = testCase({
collection.find({title:{$ne:null}}).sort({title:1}).toArray(function(err, items) {
test.equal(1, items.length);
test.equal("Sarah", items[0].name);

// Fetch the info for the indexes
collection.indexInformation({full:true}, function(err, indexInfo) {
test.equal(null, err);
Expand All @@ -245,6 +245,26 @@ var tests = testCase({
})
})
},

"Should correctly execute insert with keepGoing option on mongod >= 1.9.1" : function(test) {
if(parseInt((client.version.replace(/\./g, ''))) >= 191) {
client.createCollection('shouldCorrectlyExecuteKeepGoingWithMongodb191OrHigher', function(err, collection) {
collection.ensureIndex({title:1}, {unique:true}, function(err, indexName) {
collection.insert([{name:"Jim"}, {name:"Sarah", title:"Princess"}], {safe:true}, function(err, result) {
// Force keep going flag, ignoring unique index issue
collection.insert([{name:"Jim"}, {name:"Sarah", title:"Princess"}, {name:'Gump', title:"Gump"}], {safe:true, keepGoing:true}, function(err, result) {
collection.count(function(err, count) {
test.equal(3, count);
test.done();
})
});
});
});
});
} else {
test.done();
}
}
})

// Stupid freaking workaround due to there being no way to run setup once for each suite
Expand Down

0 comments on commit d869d25

Please sign in to comment.