summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2016-04-25 17:55:54 -0400
committerDavid Storch <david.storch@10gen.com>2016-05-10 09:16:34 -0400
commit6218a59683bf97c6cb7f198f9d9eccc0371f8bb7 (patch)
treeea0558dec72853193d406a0eb2942fff850c4f57 /src
parente381d56bfe3a805e44678566437ef4a732d3fa1a (diff)
downloadmongo-6218a59683bf97c6cb7f198f9d9eccc0371f8bb7.tar.gz
SERVER-23791 extend shell helpers to pass collation parameter to server
Includes changes to the following: - Bulk API - CRUD API - DBCollection CRUD methods (e.g. DBCollection.prototype.remove()) - New DBQuery.prototype.collation() method to use with find().
Diffstat (limited to 'src')
-rw-r--r--src/mongo/shell/bulk_api.js37
-rw-r--r--src/mongo/shell/collection.js44
-rw-r--r--src/mongo/shell/crud_api.js86
-rw-r--r--src/mongo/shell/explain_query.js2
-rw-r--r--src/mongo/shell/explainable.js18
-rw-r--r--src/mongo/shell/query.js16
6 files changed, 185 insertions, 18 deletions
diff --git a/src/mongo/shell/bulk_api.js b/src/mongo/shell/bulk_api.js
index 84dc583b1ea..8ef10b5c976 100644
--- a/src/mongo/shell/bulk_api.js
+++ b/src/mongo/shell/bulk_api.js
@@ -674,6 +674,11 @@ var _bulk_api_module = (function() {
upsert: upsert
};
+ // Copy over the collation, if we have one.
+ if (currentOp.hasOwnProperty('collation')) {
+ document.collation = currentOp.collation;
+ }
+
// Clear out current Op
currentOp = null;
// Add the update document to the list
@@ -693,6 +698,11 @@ var _bulk_api_module = (function() {
upsert: upsert
};
+ // Copy over the collation, if we have one.
+ if (currentOp.hasOwnProperty('collation')) {
+ document.collation = currentOp.collation;
+ }
+
// Clear out current Op
currentOp = null;
// Add the update document to the list
@@ -718,6 +728,11 @@ var _bulk_api_module = (function() {
limit: 1
};
+ // Copy over the collation, if we have one.
+ if (currentOp.hasOwnProperty('collation')) {
+ document.collation = currentOp.collation;
+ }
+
// Clear out current Op
currentOp = null;
// Add the remove document to the list
@@ -733,11 +748,31 @@ var _bulk_api_module = (function() {
limit: 0
};
+ // Copy over the collation, if we have one.
+ if (currentOp.hasOwnProperty('collation')) {
+ document.collation = currentOp.collation;
+ }
+
// Clear out current Op
currentOp = null;
// Add the remove document to the list
return addToOperationsList(REMOVE, document);
- }
+ },
+
+ collation: function(collationSpec) {
+ if (!collection.getMongo().hasWriteCommands()) {
+ throw new Error(
+ "cannot use collation if server does not support write commands");
+ }
+
+ if (collection.getMongo().writeMode() !== "commands") {
+ throw new Error("write mode must be 'commands' in order to use collation, " +
+ "but found write mode: " + collection.getMongo().writeMode());
+ }
+
+ currentOp.collation = collationSpec;
+ return findOperations;
+ },
};
//
diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js
index c066648be4a..72efdbaaf97 100644
--- a/src/mongo/shell/collection.js
+++ b/src/mongo/shell/collection.js
@@ -279,13 +279,17 @@ DBCollection.prototype.find = function(query, fields, limit, skip, batchSize, op
return cursor;
};
-DBCollection.prototype.findOne = function(query, fields, options, readConcern) {
+DBCollection.prototype.findOne = function(query, fields, options, readConcern, collation) {
var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/, 0 /* batchSize */, options);
if (readConcern) {
cursor = cursor.readConcern(readConcern);
}
+ if (collation) {
+ cursor = cursor.collation(collation);
+ }
+
if (!cursor.hasNext())
return null;
var ret = cursor.next();
@@ -408,10 +412,12 @@ DBCollection.prototype._parseRemove = function(t, justOne) {
var query = this._massageObject(t);
var wc = undefined;
+ var collation = undefined;
if (typeof(justOne) === "object") {
var opts = justOne;
wc = opts.writeConcern;
justOne = opts.justOne;
+ collation = opts.collation;
}
// Normalize "justOne" to a bool.
@@ -425,7 +431,8 @@ DBCollection.prototype._parseRemove = function(t, justOne) {
return {
"query": query,
"justOne": justOne,
- "wc": wc
+ "wc": wc,
+ "collation": collation
};
};
@@ -434,6 +441,7 @@ DBCollection.prototype.remove = function(t, justOne) {
var query = parsed.query;
var justOne = parsed.justOne;
var wc = parsed.wc;
+ var collation = parsed.collation;
var result = undefined;
var startTime =
@@ -443,6 +451,10 @@ DBCollection.prototype.remove = function(t, justOne) {
var bulk = this.initializeOrderedBulkOp();
var removeOp = bulk.find(query);
+ if (collation) {
+ removeOp.collation(collation);
+ }
+
if (justOne) {
removeOp.removeOne();
} else {
@@ -460,6 +472,10 @@ DBCollection.prototype.remove = function(t, justOne) {
}
}
} else {
+ if (collation) {
+ throw new Error("collation requires use of write commands");
+ }
+
this._validateRemoveDoc(t);
this.getMongo().remove(this._fullName, query, justOne);
@@ -505,6 +521,7 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) {
throw Error("need an object");
var wc = undefined;
+ var collation = undefined;
// can pass options via object for improved readability
if (typeof(upsert) === "object") {
if (multi) {
@@ -516,6 +533,7 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) {
multi = opts.multi;
wc = opts.writeConcern;
upsert = opts.upsert;
+ collation = opts.collation;
}
// Normalize 'upsert' and 'multi' to booleans.
@@ -531,7 +549,8 @@ DBCollection.prototype._parseUpdate = function(query, obj, upsert, multi) {
"obj": obj,
"upsert": upsert,
"multi": multi,
- "wc": wc
+ "wc": wc,
+ "collation": collation
};
};
@@ -542,6 +561,7 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) {
var upsert = parsed.upsert;
var multi = parsed.multi;
var wc = parsed.wc;
+ var collation = parsed.collation;
var result = undefined;
var startTime =
@@ -555,6 +575,10 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) {
updateOp = updateOp.upsert();
}
+ if (collation) {
+ updateOp.collation(collation);
+ }
+
if (multi) {
updateOp.update(obj);
} else {
@@ -572,6 +596,10 @@ DBCollection.prototype.update = function(query, obj, upsert, multi) {
}
}
} else {
+ if (collation) {
+ throw new Error("collation requires use of write commands");
+ }
+
this._validateUpdateDoc(obj);
this.getMongo().update(this._fullName, query, obj, upsert, multi);
@@ -1684,6 +1712,8 @@ DBCollection.prototype.unsetWriteConcern = function() {
* @param {string|object} [options.hint=null] An index name hint or specification for the query.
* @param {number} [options.maxTimeMS=null] The maximum amount of time to allow the query to run.
* @param {string} [options.readConcern=null] The level of readConcern passed to the count command
+* @param {object} [options.collation=null] The collation that should be used for string comparisons
+* for this count op.
* @return {number}
*/
DBCollection.prototype.count = function(query, options) {
@@ -1710,6 +1740,10 @@ DBCollection.prototype.count = function(query, options) {
query.readConcern(opts.readConcern);
}
+ if (typeof opts.collation == 'object') {
+ query.collation(opts.collation);
+ }
+
// Return the result of the find
return query.count(true);
};
@@ -1753,6 +1787,10 @@ DBCollection.prototype.distinct = function(keyString, query, options) {
cmd.maxTimeMS = opts.maxTimeMS;
}
+ if (opts.collation) {
+ cmd.collation = opts.collation;
+ }
+
// Execute distinct command
var res = this.runReadCommand(cmd);
if (!res.ok) {
diff --git a/src/mongo/shell/crud_api.js b/src/mongo/shell/crud_api.js
index 7c83b5093aa..9a2d74ab62c 100644
--- a/src/mongo/shell/crud_api.js
+++ b/src/mongo/shell/crud_api.js
@@ -48,15 +48,15 @@ DBCollection.prototype.addIdIfNeeded = function(obj) {
*
* { insertOne: { document: { a: 1 } } }
*
-* { updateOne: { filter: {a:2}, update: {$set: {a:2}}, upsert:true } }
+* { updateOne: { filter: {a:2}, update: {$set: {a:2}}, upsert:true, collation: {locale: "fr"} } }
*
-* { updateMany: { filter: {a:2}, update: {$set: {a:2}}, upsert:true } }
+* { updateMany: { filter: {a:2}, update: {$set: {a:2}}, upsert:true collation: {locale: "fr"} } }
*
-* { deleteOne: { filter: {c:1} } }
+* { deleteOne: { filter: {c:1}, collation: {locale: "fr"} } }
*
-* { deleteMany: { filter: {c:1} } }
+* { deleteMany: { filter: {c:1}, collation: {locale: "fr"} } }
*
-* { replaceOne: { filter: {c:3}, replacement: {c:4}, upsert:true}}
+* { replaceOne: { filter: {c:3}, replacement: {c:4}, upsert:true, collation: {locale: "fr"} } }
*
* @method
* @param {object[]} operations Bulk operations to perform.
@@ -112,6 +112,10 @@ DBCollection.prototype.bulkWrite = function(operations, options) {
operation = operation.upsert();
}
+ if (op.updateOne.collation) {
+ operation.collation(op.updateOne.collation);
+ }
+
operation.updateOne(op.updateOne.update);
} else if (op.updateMany) {
if (!op.updateMany.filter) {
@@ -128,6 +132,10 @@ DBCollection.prototype.bulkWrite = function(operations, options) {
operation = operation.upsert();
}
+ if (op.updateMany.collation) {
+ operation.collation(op.updateMany.collation);
+ }
+
operation.update(op.updateMany.update);
} else if (op.replaceOne) {
if (!op.replaceOne.filter) {
@@ -144,21 +152,37 @@ DBCollection.prototype.bulkWrite = function(operations, options) {
operation = operation.upsert();
}
+ if (op.replaceOne.collation) {
+ operation.collation(op.replaceOne.collation);
+ }
+
operation.replaceOne(op.replaceOne.replacement);
} else if (op.deleteOne) {
if (!op.deleteOne.filter) {
throw new Error('deleteOne bulkWrite operation expects the filter field');
}
- // Translate operation to bulkOp operation
- bulkOp.find(op.deleteOne.filter).removeOne();
+ // Translate operation to bulkOp operation.
+ var deleteOp = bulkOp.find(op.deleteOne.filter);
+
+ if (op.deleteOne.collation) {
+ deleteOp.collation(op.deleteOne.collation);
+ }
+
+ deleteOp.removeOne();
} else if (op.deleteMany) {
if (!op.deleteMany.filter) {
throw new Error('deleteMany bulkWrite operation expects the filter field');
}
- // Translate operation to bulkOp operation
- bulkOp.find(op.deleteMany.filter).remove();
+ // Translate operation to bulkOp operation.
+ var deleteOp = bulkOp.find(op.deleteMany.filter);
+
+ if (op.deleteMany.collation) {
+ deleteOp.collation(op.deleteMany.collation);
+ }
+
+ deleteOp.remove();
}
}, this);
@@ -317,9 +341,15 @@ DBCollection.prototype.deleteOne = function(filter, options) {
// Use bulk operation API already in the shell
var bulk = this.initializeOrderedBulkOp();
+ var removeOp = bulk.find(filter);
- // Add the deleteOne operation
- bulk.find(filter).removeOne();
+ // Add the collation, if there is one.
+ if (opts.collation) {
+ removeOp.collation(opts.collation);
+ }
+
+ // Add the deleteOne operation.
+ removeOp.removeOne();
try {
// Remove the first document that matches the selector
@@ -368,9 +398,15 @@ DBCollection.prototype.deleteMany = function(filter, options) {
// Use bulk operation API already in the shell
var bulk = this.initializeOrderedBulkOp();
+ var removeOp = bulk.find(filter);
- // Add the deleteOne operation
- bulk.find(filter).remove();
+ // Add the collation, if there is one.
+ if (opts.collation) {
+ removeOp.collation(opts.collation);
+ }
+
+ // Add the deleteOne operation.
+ removeOp.remove();
try {
// Remove all documents that matche the selector
@@ -435,6 +471,10 @@ DBCollection.prototype.replaceOne = function(filter, replacement, options) {
op = op.upsert();
}
+ if (opts.collation) {
+ op.collation(opts.collation);
+ }
+
op.replaceOne(replacement);
try {
@@ -510,6 +550,10 @@ DBCollection.prototype.updateOne = function(filter, update, options) {
op = op.upsert();
}
+ if (opts.collation) {
+ op.collation(opts.collation);
+ }
+
op.updateOne(update);
try {
@@ -585,6 +629,10 @@ DBCollection.prototype.updateMany = function(filter, update, options) {
op = op.upsert();
}
+ if (opts.collation) {
+ op.collation(opts.collation);
+ }
+
op.update(update);
try {
@@ -649,6 +697,10 @@ DBCollection.prototype.findOneAndDelete = function(filter, options) {
cmd.maxTimeMS = opts.maxTimeMS;
}
+ if (opts.collation) {
+ cmd.collation = opts.collation;
+ }
+
// Get the write concern
var writeConcern = this._createWriteConcern(opts);
@@ -705,6 +757,10 @@ DBCollection.prototype.findOneAndReplace = function(filter, replacement, options
cmd.maxTimeMS = opts.maxTimeMS;
}
+ if (opts.collation) {
+ cmd.collation = opts.collation;
+ }
+
// Set flags
cmd.upsert = (typeof opts.upsert == 'boolean') ? opts.upsert : false;
cmd.new = (typeof opts.returnNewDocument == 'boolean') ? opts.returnNewDocument : false;
@@ -769,6 +825,10 @@ DBCollection.prototype.findOneAndUpdate = function(filter, update, options) {
cmd.maxTimeMS = opts.maxTimeMS;
}
+ if (opts.collation) {
+ cmd.collation = opts.collation;
+ }
+
// Set flags
cmd.upsert = (typeof opts.upsert == 'boolean') ? opts.upsert : false;
cmd.new = (typeof opts.returnNewDocument == 'boolean') ? opts.returnNewDocument : false;
diff --git a/src/mongo/shell/explain_query.js b/src/mongo/shell/explain_query.js
index 3a90e17d4eb..cb14b71f0cf 100644
--- a/src/mongo/shell/explain_query.js
+++ b/src/mongo/shell/explain_query.js
@@ -96,6 +96,7 @@ var DBExplainQuery = (function() {
var delegationFuncNames = [
"addOption",
"batchSize",
+ "collation",
"comment",
"hint",
"limit",
@@ -226,6 +227,7 @@ var DBExplainQuery = (function() {
print("\t.addOption(n)");
print("\t.batchSize(n)");
print("\t.comment(comment)");
+ print("\t.collation(collationSpec)");
print("\t.count()");
print("\t.hint(hintSpec)");
print("\t.limit(n)");
diff --git a/src/mongo/shell/explainable.js b/src/mongo/shell/explainable.js
index 5a6d4932c40..4f54694acd3 100644
--- a/src/mongo/shell/explainable.js
+++ b/src/mongo/shell/explainable.js
@@ -147,12 +147,17 @@ var Explainable = (function() {
return throwOrReturn(explainResult);
};
- this.distinct = function(keyString, query) {
+ this.distinct = function(keyString, query, options) {
var distinctCmd = {
distinct: this._collection.getName(),
key: keyString,
query: query || {}
};
+
+ if (options && options.hasOwnProperty("collation")) {
+ distinctCmd.collation = options.collation;
+ }
+
var explainCmd = {
explain: distinctCmd,
verbosity: this._verbosity
@@ -165,9 +170,15 @@ var Explainable = (function() {
var parsed = this._collection._parseRemove.apply(this._collection, arguments);
var query = parsed.query;
var justOne = parsed.justOne;
+ var collation = parsed.collation;
var bulk = this._collection.initializeOrderedBulkOp();
var removeOp = bulk.find(query);
+
+ if (collation) {
+ removeOp.collation(collation);
+ }
+
if (justOne) {
removeOp.removeOne();
} else {
@@ -185,6 +196,7 @@ var Explainable = (function() {
var obj = parsed.obj;
var upsert = parsed.upsert;
var multi = parsed.multi;
+ var collation = parsed.collation;
var bulk = this._collection.initializeOrderedBulkOp();
var updateOp = bulk.find(query);
@@ -193,6 +205,10 @@ var Explainable = (function() {
updateOp = updateOp.upsert();
}
+ if (collation) {
+ updateOp.collation(collation);
+ }
+
if (multi) {
updateOp.update(obj);
} else {
diff --git a/src/mongo/shell/query.js b/src/mongo/shell/query.js
index b92f3b1f318..813d9be9e59 100644
--- a/src/mongo/shell/query.js
+++ b/src/mongo/shell/query.js
@@ -29,6 +29,7 @@ DBQuery.prototype.help = function() {
print("\t.limit(<n>)");
print("\t.skip(<n>)");
print("\t.batchSize(<n>) - sets the number of docs to return per getMore");
+ print("\t.collation({...})");
print("\t.hint({...})");
print("\t.readConcern(<level>)");
print("\t.readPref(<mode>, <tagset>)");
@@ -121,6 +122,10 @@ DBQuery.prototype._exec = function() {
throw new Error("readConcern requires use of read commands");
}
+ if (this._special && this._query.collation) {
+ throw new Error("collation requires use of read commands");
+ }
+
this._cursor = this._mongo.find(this._ns,
this._query,
this._fields,
@@ -223,6 +228,10 @@ DBQuery.prototype._convertToCommand = function(canAttachReadPref) {
cmd["readConcern"] = this._query.readConcern;
}
+ if ("collation" in this._query) {
+ cmd["collation"] = this._query.collation;
+ }
+
if ((this._options & DBQuery.Option.tailable) != 0) {
cmd["tailable"] = true;
}
@@ -350,6 +359,9 @@ DBQuery.prototype._convertToCountCmd = function(applySkipLimit) {
if (this._query.readConcern) {
cmd.readConcern = this._query.readConcern;
}
+ if (this._query.collation) {
+ cmd.collation = this._query.collation;
+ }
} else {
cmd.query = this._query;
}
@@ -467,6 +479,10 @@ DBQuery.prototype.readConcern = function(level) {
return this._addSpecial("readConcern", readConcernObj);
};
+DBQuery.prototype.collation = function(collationSpec) {
+ return this._addSpecial("collation", collationSpec);
+};
+
/**
* Sets the read preference for this cursor.
*