From 9e25f381ce7847e5df29ff82f97626786d213a0f Mon Sep 17 00:00:00 2001 From: "Brendan W. McAdams" Date: Thu, 8 Sep 2011 16:21:28 +0200 Subject: [PATCH] JAVA-428 - Support new ReadPreference semantics, deprecate SlaveOK * Like WriteConcern, each read method now takes an optional ReadPreference arg, defaulting to default otherwise --- src/main/com/mongodb/DB.java | 2 + src/main/com/mongodb/DBApiLayer.java | 2 +- src/main/com/mongodb/DBCollection.java | 125 +++++++++++++++++++++++-- src/main/com/mongodb/DBCursor.java | 28 +++++- 4 files changed, 146 insertions(+), 11 deletions(-) diff --git a/src/main/com/mongodb/DB.java b/src/main/com/mongodb/DB.java index af8b515c1d8..5e82d0cb647 100644 --- a/src/main/com/mongodb/DB.java +++ b/src/main/com/mongodb/DB.java @@ -156,6 +156,7 @@ public CommandResult command( DBObject cmd ) public CommandResult command( DBObject cmd , int options ) throws MongoException { + // TODO - Is ReadPreference OK for commands? Iterator i = getCollection("$cmd").__find(cmd, new BasicDBObject(), 0, -1, 0, options); if ( i == null || ! i.hasNext() ) return null; @@ -263,6 +264,7 @@ public Set getCollectionNames() if (namespaces == null) throw new RuntimeException("this is impossible"); + // TODO - Is ReadPreference OK for collection Names? Iterator i = namespaces.__find(new BasicDBObject(), null, 0, 0, 0, getOptions()); if (i == null) return new HashSet(); diff --git a/src/main/com/mongodb/DBApiLayer.java b/src/main/com/mongodb/DBApiLayer.java index b603516a023..a6f65a4789a 100644 --- a/src/main/com/mongodb/DBApiLayer.java +++ b/src/main/com/mongodb/DBApiLayer.java @@ -290,7 +290,7 @@ public WriteResult remove( DBObject o , com.mongodb.WriteConcern concern ) } @Override - Iterator __find( DBObject ref , DBObject fields , int numToSkip , int batchSize, int limit , int options ) + Iterator __find( DBObject ref , DBObject fields , int numToSkip , int batchSize, int limit , int options, ReadPreference readPref ) throws MongoException { if ( ref == null ) diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java index 05c365bdb88..798aaa27475 100644 --- a/src/main/com/mongodb/DBCollection.java +++ b/src/main/com/mongodb/DBCollection.java @@ -291,7 +291,11 @@ public WriteResult remove( DBObject o ) /** * Finds objects */ - abstract Iterator __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options ) throws MongoException ; + Iterator __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options ) throws MongoException { + return __find( ref, fields, numToSkip, batchSize, limit, options, _readPref ); + } + + abstract Iterator __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options, ReadPreference readPref ) throws MongoException ; /** * Calls {@link DBCollection#find(com.mongodb.DBObject, com.mongodb.DBObject, int, int)} and applies the query options @@ -340,7 +344,20 @@ public final DBCursor find( DBObject query , DBObject fields , int numToSkip , i */ public final DBObject findOne( Object obj ) throws MongoException { - return findOne(obj, null); + return findOne(obj, null, _readPref); + } + + /** + * Finds an object by its id. + * This compares the passed in value to the _id field of the document + * + * @param obj any valid object + * @return the object, if found, otherwise null + * @throws MongoException + */ + public final DBObject findOne( Object obj , ReadPreference readPref ) + throws MongoException { + return findOne(obj, null, readPref); } /** @@ -353,7 +370,20 @@ public final DBObject findOne( Object obj ) * @dochub find */ public final DBObject findOne( Object obj, DBObject fields ) { - Iterator iterator = __find(new BasicDBObject("_id", obj), fields, 0, -1, 0, getOptions() ); + return findOne( obj, fields, _readPref ); + } + + /** + * Finds an object by its id. + * This compares the passed in value to the _id field of the document + * + * @param obj any valid object + * @param fields fields to return + * @return the object, if found, otherwise null + * @dochub find + */ + public final DBObject findOne( Object obj, DBObject fields, ReadPreference readPref ) { + Iterator iterator = __find(new BasicDBObject("_id", obj), fields, 0, -1, 0, getOptions(), readPref ); return (iterator != null ? iterator.next() : null); } @@ -578,7 +608,18 @@ public void setHintFields( List lst ){ * @dochub find */ public final DBCursor find( DBObject ref ){ - return new DBCursor( this, ref, null ); + return find( ref, _readPref ); + } + + /** + * Queries for an object in this collection. + * @param ref object for which to search + * @param preference Read Preference for this write + * @return an iterator over the results + * @dochub find + */ + public final DBCursor find( DBObject ref, ReadPreference preference ){ + return new DBCursor( this, ref, null, preference ); } /** @@ -605,7 +646,34 @@ public final DBCursor find( DBObject ref ){ * @dochub find */ public final DBCursor find( DBObject ref , DBObject keys ){ - return new DBCursor( this, ref, keys ); + return find( ref, keys, _readPref ); + } + + /** + * Queries for an object in this collection. + * + *

+ * An empty DBObject will match every document in the collection. + * Regardless of fields specified, the _id fields are always returned. + *

+ *

+ * An example that returns the "x" and "_id" fields for every document + * in the collection that has an "x" field: + *

+ *
+     * BasicDBObject keys = new BasicDBObject();
+     * keys.put("x", 1);
+     *
+     * DBCursor cursor = collection.find(new BasicDBObject(), keys);
+     * 
+ * + * @param ref object for which to search + * @param keys fields to return + * @return a cursor to iterate over results + * @dochub find + */ + public final DBCursor find( DBObject ref , DBObject keys, ReadPreference readPref ){ + return new DBCursor( this, ref, keys, readPref ); } /** @@ -614,7 +682,16 @@ public final DBCursor find( DBObject ref , DBObject keys ){ * @dochub find */ public final DBCursor find(){ - return new DBCursor( this, new BasicDBObject(), null ); + return find( _readPref ); + } + + /** + * Queries for all objects in this collection. + * @return a cursor which will iterate over every object + * @dochub find + */ + public final DBCursor find( ReadPreference readPref ){ + return new DBCursor( this, new BasicDBObject(), null, readPref ); } /** @@ -627,6 +704,16 @@ public final DBObject findOne() return findOne( new BasicDBObject() ); } + /** + * Returns a single object from this collection. + * @return the object found, or null if the collection is empty + * @throws MongoException + */ + public final DBObject findOne( ReadPreference readPref ) + throws MongoException { + return findOne( new BasicDBObject(), readPref ); + } + /** * Returns a single object from this collection matching the query. * @param o the query object @@ -635,7 +722,18 @@ public final DBObject findOne() */ public final DBObject findOne( DBObject o ) throws MongoException { - return findOne(o, null); + return findOne( o, null, _readPref ); + } + + /** + * Returns a single object from this collection matching the query. + * @param o the query object + * @return the object found, or null if no such object exists + * @throws MongoException + */ + public final DBObject findOne( DBObject o, ReadPreference readPref ) + throws MongoException { + return findOne( o, null, readPref ); } /** @@ -646,7 +744,17 @@ public final DBObject findOne( DBObject o ) * @dochub find */ public final DBObject findOne( DBObject o, DBObject fields ) { - Iterator i = __find( o , fields , 0 , -1 , 0, getOptions() ); + return findOne( o, fields, _readPref ); + } + /** + * Returns a single object from this collection matching the query. + * @param o the query object + * @param fields fields to return + * @return the object found, or null if no such object exists + * @dochub find + */ + public final DBObject findOne( DBObject o, DBObject fields, ReadPreference readPref ) { + Iterator i = __find( o , fields , 0 , -1 , 0, getOptions(), readPref ); DBObject obj = (i == null ? null : i.next()); if ( obj != null && ( fields != null && fields.keySet().size() > 0 ) ){ obj.markAsPartialObject(); @@ -654,6 +762,7 @@ public final DBObject findOne( DBObject o, DBObject fields ) { return obj; } + /** * calls {@link DBCollection#apply(com.mongodb.DBObject, boolean)} with ensureID=true * @param o DBObject to which to add fields diff --git a/src/main/com/mongodb/DBCursor.java b/src/main/com/mongodb/DBCursor.java index 09ce8b31702..dd54e8f908e 100644 --- a/src/main/com/mongodb/DBCursor.java +++ b/src/main/com/mongodb/DBCursor.java @@ -59,14 +59,16 @@ public class DBCursor implements Iterator , Iterable { * @param collection collection to use * @param q query to perform * @param k keys to return from the query + * @param preference the Read Preference for this query */ - public DBCursor( DBCollection collection , DBObject q , DBObject k ){ + public DBCursor( DBCollection collection , DBObject q , DBObject k, ReadPreference preference ){ _collection = collection; _query = q == null ? new BasicDBObject() : q; _keysWanted = k; if ( _collection != null ){ _options = _collection.getOptions(); } + _readPref = preference; } /** @@ -82,7 +84,7 @@ static enum CursorType { ITERATOR , ARRAY }; * @return the new cursor */ public DBCursor copy() { - DBCursor c = new DBCursor(_collection, _query, _keysWanted); + DBCursor c = new DBCursor(_collection, _query, _keysWanted, _readPref); c._orderBy = _orderBy; c._hint = _hint; c._hintDBObj = _hintDBObj; @@ -685,6 +687,25 @@ public ServerAddress getServerAddress() { return null; } + /** + * Sets the read preference for this cursor. + * See the * documentation for {@link ReadPreference} + * for more information. + * + * @param preference Read Preference to use + */ + public void setReadPreference( ReadPreference preference ){ + _readPref = preference; + } + + /** + * Gets the default read preference + * @return + */ + public ReadPreference getReadPreference(){ + return _readPref; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -704,6 +725,8 @@ public String toString() { ServerAddress addr = getServerAddress(); if (addr != null) sb.append(", addr=").append(addr); + + sb.append(", readPreference=").append( _readPref.toString() ); return sb.toString(); } @@ -721,6 +744,7 @@ public String toString() { private int _skip = 0; private boolean _snapshot = false; private int _options = 0; + private ReadPreference _readPref; private DBObject _specialFields;