From e13d0ca1b0b3ae6366a90bc2ec9d41205642e84c Mon Sep 17 00:00:00 2001 From: Margaret Stephenson Date: Fri, 14 Aug 2015 10:44:38 -0400 Subject: [PATCH] SERVER-12856 Add createIndexes shell helper Signed-off-by: Adam Midvidy Closes #1008 --- .../create_indexes_shell_helper.js | 82 +++++++++++++++++++ src/mongo/shell/collection.js | 37 ++++++--- 2 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 jstests/noPassthrough/create_indexes_shell_helper.js diff --git a/jstests/noPassthrough/create_indexes_shell_helper.js b/jstests/noPassthrough/create_indexes_shell_helper.js new file mode 100644 index 0000000000000..8aa0c79b5a6b2 --- /dev/null +++ b/jstests/noPassthrough/create_indexes_shell_helper.js @@ -0,0 +1,82 @@ +(function() { + "use strict"; + var t = db.create_indexes_shell_helper; + t.drop(); + + var mongo = db.getMongo(); + + try { + var commandsRan = []; + var insertsRan = []; + var mockMongo = { + forceWriteMode: function(mode) { + _writeMode = mode; + }, + writeMode: function() { + return _writeMode; + }, + getSlaveOk: function() { return true; }, + runCommand: function(db, cmd, opts) { + commandsRan.push({db: db, cmd: cmd, opts: opts}); + return {ok: 1.0}; + }, + insert: function(db, indexSpecs, opts) { + insertsRan.push({db: db, indexSpecs: indexSpecs, opts: opts}); + return {ok: 1.0}; + }, + getWriteConcern: function() { + return null; + }, + useWriteCommands: function() { + return true; + }, + hasWriteCommands: function() { + return true; + } + }; + + db._mongo = mockMongo; + + mockMongo.forceWriteMode("commands"); + + t.createIndexes([{x: 1}]); + assert.eq(commandsRan.length, 1); + assert(commandsRan[0].cmd.hasOwnProperty("createIndexes")); + assert.eq(commandsRan[0].cmd["indexes"][0], + {ns: "test.create_indexes_shell_helper", key: {x:1}, name: "x_1"}); + + commandsRan = []; + + t.createIndexes([{y: 1}, {z: -1}]); + assert.eq(commandsRan.length, 1); + assert( commandsRan[0].cmd.hasOwnProperty("createIndexes")); + assert.eq(commandsRan[0].cmd["indexes"][0], + {ns: "test.create_indexes_shell_helper", key: {y:1}, name: "y_1"}); + assert.eq(commandsRan[0].cmd["indexes"][1], + {ns: "test.create_indexes_shell_helper", key: {z:-1}, name: "z_-1"}); + + commandsRan = []; + + t.createIndex({a: 1}); + assert.eq(commandsRan.length, 1); + assert( commandsRan[0].cmd.hasOwnProperty("createIndexes")); + assert.eq(commandsRan[0].cmd["indexes"][0], + {ns: "test.create_indexes_shell_helper", key: {a:1}, name: "a_1"}); + + db.getMongo().forceWriteMode("compatibility"); + + commandsRan = []; + assert.eq(commandsRan.length, 0); + t.createIndex({b: 1}); + assert.eq(insertsRan.length, 1); + assert.eq(insertsRan[0]["indexSpecs"]["ns"], "test.create_indexes_shell_helper"); + assert.eq(insertsRan[0]["indexSpecs"]["key"], {b:1}); + assert.eq(insertsRan[0]["indexSpecs"]["name"], "b_1"); + //getLastError is called in the course of the bulk insert + assert.eq(commandsRan.length, 1); + assert(commandsRan[0].cmd.hasOwnProperty("getlasterror")); + } + finally { + db._mongo = mongo; + } +}()); diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index 53e2a63239fb4..b93e6dd753f3e 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -37,6 +37,7 @@ DBCollection.prototype.help = function () { print("\tdb." + shortName + ".copyTo(newColl) - duplicates collection by copying all documents to newColl; no indexes are copied."); print("\tdb." + shortName + ".convertToCapped(maxBytes) - calls {convertToCapped:'" + shortName + "', size:maxBytes}} command"); print("\tdb." + shortName + ".createIndex(keypattern[,options])"); + print("\tdb." + shortName + ".createIndexes([keypatterns], )"); print("\tdb." + shortName + ".dataSize()"); print("\tdb." + shortName + ".deleteOne( filter, ) - delete first matching document, optional parameters are: w, wtimeout, j"); print("\tdb." + shortName + ".deleteMany( filter, ) - delete all matching documents, optional parameters are: w, wtimeout, j"); @@ -577,29 +578,39 @@ DBCollection.prototype._indexSpec = function( keys, options ) { return ret; } -DBCollection.prototype.createIndex = function( keys , options ){ - var o = this._indexSpec( keys, options ); +DBCollection.prototype.createIndex = function(keys , options) { + return this.createIndexes([keys], options); +} + +DBCollection.prototype.createIndexes = function(keys, options) { + var indexSpecs = Array(keys.length); + for (var i = 0; i < indexSpecs.length; i++) { + indexSpecs[i] = this._indexSpec(keys[i], options); + } - if ( this.getMongo().writeMode() == "commands" ) { - delete o.ns; // ns is passed to the first element in the command. - return this._db.runCommand({ createIndexes: this.getName(), indexes: [o] }); + if (this.getMongo().writeMode() == "commands") { + for (i = 0; i++; i < indexSpecs.length) { + delete (indexSpecs[i].ns); // ns is passed to the first element in the command. + } + return this._db.runCommand({createIndexes: this.getName(), indexes: indexSpecs}); } - else if( this.getMongo().writeMode() == "compatibility" ) { + else if(this.getMongo().writeMode() == "compatibility") { // Use the downconversion machinery of the bulk api to do a safe write, report response as a // command response - var result = this._db.getCollection( "system.indexes" ).insert( o , 0, true ); + var result = this._db.getCollection("system.indexes").insert(indexSpecs , 0, true); - if (result.hasWriteError() || result.hasWriteConcernError()) { - var error = result.hasWriteError() ? result.getWriteError() : - result.getWriteConcernError(); - return { ok : 0.0, code : error.code, errmsg : error.errmsg }; + if (result.hasWriteErrors() || result.hasWriteConcernError()) { + // Return the first error + var error = result.hasWriteErrors() ? result.getWriteErrors()[0] : + result.getWriteConcernError(); + return {ok : 0.0, code : error.code, errmsg : error.errmsg}; } else { - return { ok : 1.0 }; + return {ok : 1.0}; } } else { - this._db.getCollection( "system.indexes" ).insert( o , 0, true ); + this._db.getCollection("system.indexes").insert(indexSpecs, 0, true); } }