Skip to content

Commit

Permalink
JAVA-706: Wrap command in $query field if sending to mongos and read …
Browse files Browse the repository at this point in the history
…preference is not primary or secondaryPreferred (primary is the default and

secondaryPreferred is already covered by slaveOk bit).
  • Loading branch information
jyemin committed Nov 30, 2012
1 parent 5993975 commit b925dee
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/main/com/mongodb/DB.java
Expand Up @@ -269,11 +269,7 @@ public CommandResult command( DBObject cmd , int options, ReadPreference readPre
*/
public CommandResult command( DBObject cmd , int options, ReadPreference readPrefs, DBEncoder encoder ){
readPrefs = getCommandReadPreference(cmd, readPrefs);

// TODO: automate an integration test for this condition
if (getMongo().isMongosConnection()) {
cmd.put(QueryOpBuilder.READ_PREFERENCE_META_OPERATOR, readPrefs.toDBObject());
}
cmd = wrapCommand(cmd, readPrefs);

Iterator<DBObject> i =
getCollection("$cmd").__find(cmd, new BasicDBObject(), 0, -1, 0, options, readPrefs ,
Expand All @@ -288,6 +284,22 @@ public CommandResult command( DBObject cmd , int options, ReadPreference readPre
return cr;
}

// Only append $readPreference meta-operator if connected to a mongos, read preference is not primary
// or secondary preferred,
// and command is an instance of BasicDBObject. The last condition is unfortunate, but necessary in case
// the encoder is not capable of encoding a BasicDBObject
// Due to issues with compatibility between different versions of mongos, also wrap the command in a
// $query field, so that the $readPreference is not rejected
private DBObject wrapCommand(DBObject cmd, final ReadPreference readPrefs) {
if (getMongo().isMongosConnection() &&
!(ReadPreference.primary().equals(readPrefs) || ReadPreference.secondaryPreferred().equals(readPrefs)) &&
cmd instanceof BasicDBObject) {
cmd = new BasicDBObject("$query", cmd)
.append(QueryOpBuilder.READ_PREFERENCE_META_OPERATOR, readPrefs.toDBObject());
}
return cmd;
}

/**
* Executes a database command.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
Expand Down

0 comments on commit b925dee

Please sign in to comment.