From 42e8a61ba940424f880720b5f26bb183731f8e44 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 09:09:36 -0700
Subject: [PATCH 01/31] Added license and serialVersionUID
---
src/main/com/mongodb/CommandResult.java | 26 ++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/main/com/mongodb/CommandResult.java b/src/main/com/mongodb/CommandResult.java
index df13f80b2a3..e6b18c6dda9 100644
--- a/src/main/com/mongodb/CommandResult.java
+++ b/src/main/com/mongodb/CommandResult.java
@@ -1,10 +1,27 @@
// CommandResult.java
+/**
+ * Copyright (C) 2008 10gen Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.mongodb;
+/** A simple wrapper for the result of getLastError() calls, and network (socket) errors. */
public class CommandResult extends BasicDBObject {
- CommandResult(){
+ CommandResult(){
}
public boolean ok(){
@@ -47,9 +64,12 @@ public void throwOnError()
DBObject _cmd;
+ private static final long serialVersionUID = 1L;
+
+ static class CommandFailure extends MongoException {
+ private static final long serialVersionUID = 1L;
- static class CommandFailure extends MongoException {
- CommandFailure( CommandResult res , String msg ){
+ CommandFailure( CommandResult res , String msg ){
super( ServerError.getCode( res ) , msg );
}
}
From d93f2aef50231499f3740215f5815cb70c877ecd Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 09:26:05 -0700
Subject: [PATCH 02/31] general cleanup
---
src/main/com/mongodb/DB.java | 2 ++
src/main/com/mongodb/DBConnector.java | 4 ----
src/main/com/mongodb/DBCursor.java | 1 -
src/main/com/mongodb/DBTCPConnector.java | 2 --
src/main/com/mongodb/WriteConcern.java | 6 ++++--
src/main/org/bson/types/ObjectId.java | 2 +-
6 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/src/main/com/mongodb/DB.java b/src/main/com/mongodb/DB.java
index 518e5d8e6d7..f97dd90c30c 100644
--- a/src/main/com/mongodb/DB.java
+++ b/src/main/com/mongodb/DB.java
@@ -34,6 +34,7 @@ public abstract class DB {
* updates, and removes).
* @deprecated
*/
+ @Deprecated
public static class WriteConcern {
/**
* Don't check for or report any errors on writes.
@@ -301,6 +302,7 @@ public CommandResult getLastError( int w , int wtimeout , boolean fsync )
* @param concern write concern to use
*/
public void setWriteConcern( com.mongodb.WriteConcern concern ){
+ if (concern == null) throw new IllegalArgumentException();
_concern = concern;
}
diff --git a/src/main/com/mongodb/DBConnector.java b/src/main/com/mongodb/DBConnector.java
index 765223b5353..23b0f66f7e5 100644
--- a/src/main/com/mongodb/DBConnector.java
+++ b/src/main/com/mongodb/DBConnector.java
@@ -18,10 +18,6 @@
package com.mongodb;
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.util.*;
public interface DBConnector {
diff --git a/src/main/com/mongodb/DBCursor.java b/src/main/com/mongodb/DBCursor.java
index 746c69da13d..000227f3c47 100644
--- a/src/main/com/mongodb/DBCursor.java
+++ b/src/main/com/mongodb/DBCursor.java
@@ -332,7 +332,6 @@ private DBObject _next()
_cur = null;
_cur = _it.next();
- _collection.apply( _cur , false );
_num++;
if ( _keysWanted != null && _keysWanted.keySet().size() > 0 ){
diff --git a/src/main/com/mongodb/DBTCPConnector.java b/src/main/com/mongodb/DBTCPConnector.java
index 7cc2e4a38a7..11a4faf240e 100644
--- a/src/main/com/mongodb/DBTCPConnector.java
+++ b/src/main/com/mongodb/DBTCPConnector.java
@@ -20,7 +20,6 @@
import java.io.*;
import java.net.*;
-import java.nio.*;
import java.util.*;
import java.util.logging.*;
@@ -268,7 +267,6 @@ DBPort get( boolean keep ){
void done( DBPort p ){
if ( _internalStack <= 0 ){
- int prev = _internalStack;
_reset();
throw new IllegalStateException( "done called and _internalStack was: " + _internalStack );
}
diff --git a/src/main/com/mongodb/WriteConcern.java b/src/main/com/mongodb/WriteConcern.java
index 5c456323f8a..711b532b3ca 100644
--- a/src/main/com/mongodb/WriteConcern.java
+++ b/src/main/com/mongodb/WriteConcern.java
@@ -40,9 +40,11 @@ public class WriteConcern {
public final static WriteConcern NONE = new WriteConcern(-1);
public final static WriteConcern NORMAL = new WriteConcern(0);
- public final static WriteConcern STRICT = new WriteConcern(1); // STRICT is deprecated should use SAFE
-
public final static WriteConcern SAFE = new WriteConcern(1);
+
+ @Deprecated /** use SAFE */
+ public final static WriteConcern STRICT = SAFE;
+
public final static WriteConcern FSYNC_SAFE = new WriteConcern(1,0,true);
public final static WriteConcern REPLICAS_SAFE = new WriteConcern(2);
diff --git a/src/main/org/bson/types/ObjectId.java b/src/main/org/bson/types/ObjectId.java
index 701c7e1f3e1..d9d8b95dc80 100644
--- a/src/main/org/bson/types/ObjectId.java
+++ b/src/main/org/bson/types/ObjectId.java
@@ -80,7 +80,7 @@ public static boolean isValid( String s ){
* @param o the object to convert
* @return an ObjectId
if it can be massaged, null otherwise
*/
- public static ObjectId massageToObjectId( Object o ){
+ protected static ObjectId massageToObjectId( Object o ){
if ( o == null )
return null;
From 720c6e13790a1f942fc03f8be65fd31fd064cd51 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 09:26:42 -0700
Subject: [PATCH 03/31] WriteResult.getLastError(concern) changes
---
src/main/com/mongodb/DBPort.java | 16 ++++-----
src/main/com/mongodb/WriteResult.java | 41 ++++++++++++++++--------
src/test/com/mongodb/JavaClientTest.java | 41 +++++++++++++++++++++++-
3 files changed, 75 insertions(+), 23 deletions(-)
diff --git a/src/main/com/mongodb/DBPort.java b/src/main/com/mongodb/DBPort.java
index 583e4139deb..054f18ec129 100644
--- a/src/main/com/mongodb/DBPort.java
+++ b/src/main/com/mongodb/DBPort.java
@@ -20,7 +20,6 @@
import java.io.*;
import java.net.*;
-import java.nio.*;
import java.util.*;
import java.util.logging.*;
@@ -91,7 +90,12 @@ private synchronized Response go( OutMessage msg , DBCollection coll )
}
}
- synchronized CommandResult runCommand( DB db , DBObject cmd ){
+ synchronized CommandResult getLastError( DB db , WriteConcern concern){
+ DBApiLayer dbAL = (DBApiLayer) db;
+ return runCommand( dbAL , concern.getCommand() );
+ }
+
+ synchronized CommandResult runCommand( DB db , DBObject cmd ) {
OutMessage msg = OutMessage.query( 0 , db.getName() + ".$cmd" , 0 , -1 , cmd , null );
try {
@@ -106,15 +110,11 @@ synchronized CommandResult runCommand( DB db , DBObject cmd ){
}
- synchronized CommandResult getLastError( DB db ){
- return runCommand( db , new BasicDBObject( "getlasterror" , 1 ) );
- }
-
- synchronized CommandResult tryGetLastError( DB db , long last ){
+ synchronized CommandResult tryGetLastError( DB db , long last, WriteConcern concern){
if ( last != _calls )
return null;
- return getLastError( db );
+ return getLastError( db , concern );
}
public synchronized void ensureOpen()
diff --git a/src/main/com/mongodb/WriteResult.java b/src/main/com/mongodb/WriteResult.java
index 473ddecc3db..25f68a7d2bf 100644
--- a/src/main/com/mongodb/WriteResult.java
+++ b/src/main/com/mongodb/WriteResult.java
@@ -21,7 +21,7 @@
/**
- * This class lets you access the results of the previous write
+ * This class lets you access the results of the previous write.
* if you have STRICT mode on, this just stores the result of that getLastError call
* if you don't, then this will actually to the getlasterror call.
* if another op has been done on this connection in the interim, this will fail
@@ -32,6 +32,8 @@ public class WriteResult {
_lastErrorResult = o;
_lastConcern = concern;
_lazy = false;
+ _port = null;
+ _db = null;
}
WriteResult( DB db , DBPort p , WriteConcern concern ){
@@ -53,19 +55,32 @@ public WriteConcern getLastConcern(){
}
+ /**
+ * Calling this will either return the cache result if getLastError has been called,
+ * or execute a new getLastError command on the sever.
+ * @throws MongoInternalException if the connection has been used since the last write operation.
+ * @return {@link CommandResult} from the last write operation.
+ */
public synchronized CommandResult getLastError(){
+ return getLastError(null);
+
+ }
+
+ public synchronized CommandResult getLastError(WriteConcern concern){
+ //if the concern hasn't changed and it is cached.
if ( _lastErrorResult != null )
- return _lastErrorResult;
+ if ( ( _lastConcern != null && _lastConcern.equals( concern ) ) || ( concern != null && concern.equals( _lastConcern ) ) )
+ return _lastErrorResult;
if ( _port != null ){
- _lastErrorResult = _port.tryGetLastError( _db , _lastCall );
- _port = null;
- _db = null;
+ _lastErrorResult = _port.tryGetLastError( _db , _lastCall , (concern == null) ? new WriteConcern() : concern );
+ _lastConcern = concern;
}
if ( _lastErrorResult == null )
- throw new IllegalStateException( "this port has been used since the last call, can't call getLastError anymore" );
+ throw new IllegalStateException( "The connection has been used since the last call, can't call getLastError anymore" );
+ _lastCall++;
return _lastErrorResult;
}
@@ -93,12 +108,10 @@ public String toString(){
return getLastError().toString();
}
- DB _db;
- DBPort _port;
- long _lastCall;
- WriteConcern _lastConcern;
-
- CommandResult _lastErrorResult;
-
- final boolean _lazy;
+ private long _lastCall;
+ private WriteConcern _lastConcern;
+ private CommandResult _lastErrorResult;
+ final private DB _db;
+ final private DBPort _port;
+ final private boolean _lazy;
}
diff --git a/src/test/com/mongodb/JavaClientTest.java b/src/test/com/mongodb/JavaClientTest.java
index 3e855bd9554..281a805890b 100644
--- a/src/test/com/mongodb/JavaClientTest.java
+++ b/src/test/com/mongodb/JavaClientTest.java
@@ -304,7 +304,7 @@ public void testTimestamp()
}
@Test
- public void testStrictWrite(){
+ public void testStrictWriteSetInCollection(){
DBCollection c = _db.getCollection( "write1" );
c.drop();
c.setWriteConcern( WriteConcern.STRICT );
@@ -321,6 +321,23 @@ public void testStrictWrite(){
assertEquals( 1 , c.find().count() );
}
+ @Test
+ public void testStrictWriteSetInMethod(){
+ DBCollection c = _db.getCollection( "write1" );
+ c.drop();
+ c.insert( new BasicDBObject( "_id" , 1 ));
+ boolean gotError = false;
+ try {
+ c.insert( new BasicDBObject( "_id" , 1 ) , WriteConcern.STRICT);
+ }
+ catch ( MongoException.DuplicateKey e ){
+ gotError = true;
+ }
+ assertEquals( true , gotError );
+
+ assertEquals( 1 , c.find().count() );
+ }
+
@Test
public void testPattern(){
DBCollection c = _db.getCollection( "jp1" );
@@ -554,6 +571,28 @@ public void testIn(){
assertEquals( 2 , a.size() );
}
+ @Test
+ public void testWriteResultWithGetLastErrorWithDifferentConcerns(){
+ DBCollection c = _db.getCollection( "writeresultwfle1" );
+ c.drop();
+
+ WriteResult res = c.insert( new BasicDBObject( "_id" , 1 ) );
+ res = c.update( new BasicDBObject( "_id" , 1 ) , new BasicDBObject( "$inc" , new BasicDBObject( "x" , 1 ) ) );
+ assertEquals( 1 , res.getN() );
+ assertTrue( res.isLazy() );
+
+ CommandResult cr = res.getLastError( WriteConcern.FSYNC_SAFE );
+ assertEquals( 1 , cr.getInt( "n" ) );
+ assertTrue( cr.containsField( "fsyncFiles" ));
+
+ CommandResult cr2 = res.getLastError( WriteConcern.FSYNC_SAFE );
+ assertTrue( cr == cr2 );
+
+ CommandResult cr3 = res.getLastError( WriteConcern.NONE );
+ assertTrue( cr != cr3 && cr2 != cr3 );
+
+ }
+
@Test
public void testWriteResult(){
DBCollection c = _db.getCollection( "writeresult1" );
From 1ab87f5af63b63406a53ff80f40524227f3a29e0 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 09:35:07 -0700
Subject: [PATCH 04/31] inc version for release
---
src/main/com/mongodb/Mongo.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/com/mongodb/Mongo.java b/src/main/com/mongodb/Mongo.java
index 0878ccd090b..5f4dd9c496c 100644
--- a/src/main/com/mongodb/Mongo.java
+++ b/src/main/com/mongodb/Mongo.java
@@ -68,7 +68,7 @@
public class Mongo {
public static final int MAJOR_VERSION = 2;
- public static final int MINOR_VERSION = 0;
+ public static final int MINOR_VERSION = 1;
public static DB connect( DBAddress addr ){
return new Mongo( addr ).getDB( addr.getDBName() );
From dbd099231c41560653335d313987f16c0f6a598f Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 09:39:27 -0700
Subject: [PATCH 05/31] added upsert to findAndModify
---
src/main/com/mongodb/DBCollection.java | 11 +++++++----
src/test/com/mongodb/JavaClientTest.java | 2 +-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index 4547b7c790f..a5d589d9a74 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -241,13 +241,14 @@ public final DBObject findOne( Object obj, DBObject fields ) {
* You can also specify the fields to return in the document, optionally.
* @return the found document (before, or after the update)
*/
- public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort, boolean remove, DBObject update, boolean returnNew) {
+ public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort, boolean remove, DBObject update, boolean returnNew, boolean upsert) {
if ( DEBUG ) System.out.println( "findAndModify: " + _fullName +
" query:" + JSON.serialize( query ) +
" sort:" + JSON.serialize( sort )+
" remove:" + remove +
" update: " + JSON.serialize( update )+
+ " upsert: " + upsert+
" returnNew:" + returnNew);
BasicDBObject cmd = new BasicDBObject( "findandmodify", _name);
@@ -265,6 +266,8 @@ public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort, bo
cmd.append( "update", update );
if (returnNew)
cmd.append( "new", returnNew );
+ if (upsert)
+ cmd.append( "upsert", returnNew );
}
if (remove && !(update == null || update.keySet().isEmpty() || returnNew))
@@ -279,7 +282,7 @@ public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort, bo
* @return the old document
*/
public DBObject findAndModify( DBObject query , DBObject sort , DBObject update){
- return findAndModify( query, null, null, false, update, false );
+ return findAndModify( query, null, null, false, update, false, false);
}
/**
@@ -287,7 +290,7 @@ public DBObject findAndModify( DBObject query , DBObject sort , DBObject update)
* @return the old document
*/
public DBObject findAndModify( DBObject query , DBObject update ) {
- return findAndModify( query, null, null, false, update, false );
+ return findAndModify( query, null, null, false, update, false, false );
}
/**
@@ -295,7 +298,7 @@ public DBObject findAndModify( DBObject query , DBObject update ) {
* @return the removed document
*/
public DBObject findAndRemove( DBObject query ) {
- return findAndModify( query, null, null, true, null, false );
+ return findAndModify( query, null, null, true, null, false, false );
}
// --- START INDEX CODE ---
diff --git a/src/test/com/mongodb/JavaClientTest.java b/src/test/com/mongodb/JavaClientTest.java
index 281a805890b..789f9d66129 100644
--- a/src/test/com/mongodb/JavaClientTest.java
+++ b/src/test/com/mongodb/JavaClientTest.java
@@ -636,7 +636,7 @@ public void testFindAndModify(){
assertEquals( 1 , c.findOne(new BasicDBObject( "_id" , 1 ) ).get( "x" ));
//return new one
- dbObj = c.findAndModify( new BasicDBObject( "_id" , 1 ) , null, null, false, new BasicDBObject( "x", 5), true);
+ dbObj = c.findAndModify( new BasicDBObject( "_id" , 1 ) , null, null, false, new BasicDBObject( "x", 5), true, false);
assertEquals( 2 , dbObj.keySet().size());
assertEquals( 5 , dbObj.get( "x" ));
assertEquals( 5 , c.findOne(new BasicDBObject( "_id" , 1 ) ).get( "x" ));
From 7a6beb1efe8941e109099556347e9570bb05d8fe Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 11:52:06 -0700
Subject: [PATCH 06/31] added missing WriteConcern optoin on save
---
src/main/com/mongodb/DBCollection.java | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index a5d589d9a74..1094d61a0cc 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -519,7 +519,15 @@ public final Object apply( DBObject jo , boolean ensureID ){
* @param jo the DBObject
to save
* will add _id
field to jo if needed
*/
- public final WriteResult save( DBObject jo )
+ public final WriteResult save( DBObject jo ) {
+ return save(jo, null);
+ }
+
+ /** Saves an object to this collection.
+ * @param jo the DBObject
to save
+ * will add _id
field to jo if needed
+ */
+ public final WriteResult save( DBObject jo, WriteConcern concern )
throws MongoException {
if ( checkReadOnly( true ) )
return null;
@@ -535,13 +543,20 @@ public final WriteResult save( DBObject jo )
if ( DEBUG ) System.out.println( "saving new object" );
if ( id != null && id instanceof ObjectId )
((ObjectId)id).notNew();
- return insert( jo );
+ if ( concern == null )
+ return insert( jo );
+ else
+ return insert( jo, concern );
}
if ( DEBUG ) System.out.println( "doing implicit upsert : " + jo.get( "_id" ) );
DBObject q = new BasicDBObject();
q.put( "_id" , id );
- return update( q , jo , true , false );
+ if ( concern == null )
+ return update( q , jo , true , false );
+ else
+ return update( q , jo , true , false , concern );
+
}
// ---- DB COMMANDS ----
From bb1ee01befcae35a0b66cce8cc7af30a723d5591 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 19 Aug 2010 11:53:50 -0700
Subject: [PATCH 07/31] removed comment about old method
---
src/main/com/mongodb/DBCollection.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index 1094d61a0cc..c118bcc7f2b 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -534,8 +534,6 @@ public final WriteResult save( DBObject jo, WriteConcern concern )
_checkObject( jo , false , false );
- //_findSubObject( s , jo , null );
-
Object id = jo.get( "_id" );
if ( DEBUG ) System.out.println( "id : " + id );
From 171ad66ce158565a98664b427573b70b56763923 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Tue, 24 Aug 2010 10:38:58 -0700
Subject: [PATCH 08/31] better javadocs
---
src/main/com/mongodb/WriteConcern.java | 58 +++++++++++++++++++-------
1 file changed, 44 insertions(+), 14 deletions(-)
diff --git a/src/main/com/mongodb/WriteConcern.java b/src/main/com/mongodb/WriteConcern.java
index 711b532b3ca..39f98b7638a 100644
--- a/src/main/com/mongodb/WriteConcern.java
+++ b/src/main/com/mongodb/WriteConcern.java
@@ -20,46 +20,76 @@
/**
* WriteConcern control the write behavior for with various options, as well as exception raising on error conditions.
*
- * w
- * -1 = don't even report network errors
- * 0 = default, don't call getLastError by default
- * 1 = basic, call getLastError, but don't wait for slaves
- * 2+= wait for slaves
- *
- * wtimeout
- * how long to wait for slaves before failing
- * 0 = indefinite
- * > 0 = ms to wait
- *
- * fsync
- * force fsync to disk
+ *
+ * w
+ *
+ * - -1 = don't even report network errors
+ * - 0 = default, don't call getLastError by default
+ * - 1 = basic, call getLastError, but don't wait for slaves
+ * - 2+= wait for slaves
+ *
+ * wtimeout how long to wait for slaves before failing
+ *
+ * - 0 = indefinite
+ * - > 0 = ms to wait
+ *
+ *
+ * fsync force fsync to disk
+ *
* @dochub databases
*/
public class WriteConcern {
+ /** No exceptions are raised, even for network issues */
public final static WriteConcern NONE = new WriteConcern(-1);
+ /** Exceptions are raised for network issues, but not server errors */
public final static WriteConcern NORMAL = new WriteConcern(0);
+ /** Exceptions are raised for network issues, and server errors; waits on a server for the write operation */
public final static WriteConcern SAFE = new WriteConcern(1);
@Deprecated /** use SAFE */
public final static WriteConcern STRICT = SAFE;
- public final static WriteConcern FSYNC_SAFE = new WriteConcern(1,0,true);
+ /** Exceptions are raised for network issues, and server errors and the write operation waits for the server to flush the data to disk*/
+ public final static WriteConcern FSYNC_SAFE = new WriteConcern(true);
+ /** Exceptions are raised for network issues, and server errors; waits for at least 2 servers for the write operation*/
public final static WriteConcern REPLICAS_SAFE = new WriteConcern(2);
public WriteConcern(){
this(0);
}
+ /** Specifies the number of servers to wait for on the write operation, and exception raising behavior
+ * w represents # of servers:
+ *
+ * - {@code w=-1} None, no checking is done
+ * - {@code w=0} None, network socket errors raised
+ * - {@code w=1} Checks server for errors as well as network socket errors raised
+ * - {@code w>1} Checks servers (w) for errors as well as network socket errors raised
+ *
+ *
+ *
+ **/
public WriteConcern( int w ){
this( w , 0 , false );
}
+ /** Specifies the number of servers to wait for on the write operation, and the amount of time (ms) to wait.
+ * Note: w should be > 1
+ *
+ **/
public WriteConcern( int w , int wtimeout ){
this( w , wtimeout , false );
}
+ public WriteConcern( boolean fsync ){
+ this( 1 , 0 , fsync);
+ }
+
+ /** Specifies the number of servers to wait for on the write operation, and the amount of time (ms) to wait.
+ * Note: w should be > 1
+ **/
public WriteConcern( int w , int wtimeout , boolean fsync ){
_w = w;
_wtimeout = wtimeout;
From ce35ed2c27d74a06ced8dbd711febab94bdb6283 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Tue, 24 Aug 2010 11:16:28 -0700
Subject: [PATCH 09/31] BSONEncoder map optimization JAVA-153
---
src/main/org/bson/BSONEncoder.java | 41 ++++++++++++++++++++----------
1 file changed, 28 insertions(+), 13 deletions(-)
diff --git a/src/main/org/bson/BSONEncoder.java b/src/main/org/bson/BSONEncoder.java
index eb576a11a7e..d578dd66ca7 100644
--- a/src/main/org/bson/BSONEncoder.java
+++ b/src/main/org/bson/BSONEncoder.java
@@ -7,6 +7,7 @@
import java.nio.*;
import java.nio.charset.*;
import java.util.*;
+import java.util.Map.Entry;
import java.util.concurrent.atomic.*;
import java.util.regex.*;
@@ -105,19 +106,33 @@ int putObject( String name , BSONObject o ){
}
}
-
- for ( String s : o.keySet() ){
-
- if ( rewriteID && s.equals( "_id" ) )
- continue;
-
- if ( transientFields != null && transientFields.contains( s ) )
- continue;
-
- Object val = o.get( s );
-
- _putObjectField( s , val );
-
+ //TODO: reduce repeated code below.
+ if ( o instanceof Map ){
+ for ( Entry e : ((Map)o).entrySet() ){
+
+ if ( rewriteID && e.getKey().equals( "_id" ) )
+ continue;
+
+ if ( transientFields != null && transientFields.contains( e.getKey() ) )
+ continue;
+
+ _putObjectField( e.getKey() , e.getValue() );
+
+ }
+ } else {
+ for ( String s : o.keySet() ){
+
+ if ( rewriteID && s.equals( "_id" ) )
+ continue;
+
+ if ( transientFields != null && transientFields.contains( s ) )
+ continue;
+
+ Object val = o.get( s );
+
+ _putObjectField( s , val );
+
+ }
}
_buf.write( EOO );
From 7f1ba21e301c2a6803100c7311fa42461f3af7b5 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 1 Sep 2010 12:14:45 -0700
Subject: [PATCH 10/31] more general support for Iterable in JSON.serialize -
JAVA-161
---
src/main/com/mongodb/util/JSON.java | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/main/com/mongodb/util/JSON.java b/src/main/com/mongodb/util/JSON.java
index c17e0fad977..c07a5666d71 100644
--- a/src/main/com/mongodb/util/JSON.java
+++ b/src/main/com/mongodb/util/JSON.java
@@ -2,14 +2,15 @@
package com.mongodb.util;
-import com.mongodb.*;
-import org.bson.*;
-import org.bson.types.*;
-
import java.text.*;
import java.util.*;
import java.util.regex.*;
+import org.bson.*;
+import org.bson.types.*;
+
+import com.mongodb.*;
+
/**
* Helper methods for JSON serialization and de-serialization
*/
@@ -69,12 +70,12 @@ public static void serialize( Object o , StringBuilder buf ){
return;
}
- if ( o instanceof Collection){
+ if ( o instanceof Iterable){
boolean first = true;
buf.append( "[ " );
- for ( Object n : (Collection)o ){
+ for ( Object n : (Iterable)o ){
if ( first ) first = false;
else buf.append( " , " );
From 6ad17bd0251134674595ff188593efc4f1624363 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Sat, 11 Sep 2010 06:35:00 -0700
Subject: [PATCH 11/31] fixed stale collection cache JAVA-164
---
src/main/com/mongodb/DB.java | 52 +++++++++++++++++++++++-
src/main/com/mongodb/DBCollection.java | 20 +++------
src/test/com/mongodb/JavaClientTest.java | 10 +++++
3 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/src/main/com/mongodb/DB.java b/src/main/com/mongodb/DB.java
index ce15798bb69..1187511e94b 100644
--- a/src/main/com/mongodb/DB.java
+++ b/src/main/com/mongodb/DB.java
@@ -72,6 +72,55 @@ public DB( Mongo mongo , String name ){
*/
protected abstract DBCollection doGetCollection( String name );
+ DBCollection renameCollection ( String name, String newName )
+ throws MongoException {
+
+ String fullName = _name + "." + name;
+
+ CommandResult ret =
+ getSisterDB( "admin" )
+ .command( BasicDBObjectBuilder.start()
+ .add( "renameCollection" , fullName )
+ .add( "to" , _name + "." + newName )
+ .get() );
+ ret.throwOnError();
+
+ removeFromCollectionCache( name , newName );
+
+ return getCollection( newName );
+ }
+
+ void dropCollection( String name )
+ throws MongoException {
+
+ CommandResult res = command( new BasicDBObjectBuilder().add( "drop" , name ).get() );
+ if ( res.ok() || res.getErrorMessage().equals( "ns not found" ) ) {
+ removeFromCollectionCache( name );
+ return;
+ }
+ throw new MongoException( "error dropping : " + res );
+
+ }
+
+ public void removeFromCollectionCache( String...names )
+ throws MongoException {
+
+ if (names == null || names.length == 0) return;
+
+ for ( String name : names ) {
+ String fullName = _name + "." + name;
+ //remove collection from cache
+ DBCollection collToRemove = null;
+ for (DBCollection coll : _seenCollections)
+ if (coll.getFullName().equals( fullName )) {
+ collToRemove = coll;
+ break;
+ }
+ if (collToRemove != null)
+ _seenCollections.remove( collToRemove );
+ }
+ }
+
/** Gets a collection with a given name.
* If the collection does not exist, a new collection is created.
* @param name the name of the collection to return
@@ -84,7 +133,8 @@ public final DBCollection getCollection( String name ){
}
return c;
}
-
+
+
/** Creates a collection with a given name and options.
* If the collection does not exist, a new collection is created.
* Possible options:
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index b4f7c7e0382..f0a96779c62 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -33,7 +33,7 @@
*
* @dochub collections
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings({"unchecked", "rawtypes"})
public abstract class DBCollection {
final static boolean DEBUG = Boolean.getBoolean( "DEBUG.DB" );
@@ -584,12 +584,9 @@ public void dropIndexes( String name )
/** Drops (deletes) this collection
*/
- public void drop()
+ public void drop()
throws MongoException {
- CommandResult res =_db.command( BasicDBObjectBuilder.start().add( "drop" , getName() ).get() );
- if ( res.ok() || res.getErrorMessage().equals( "ns not found" ) )
- return;
- throw new MongoException( "error dropping : " + res );
+ _db.dropCollection( _name );
}
public long count()
@@ -685,14 +682,7 @@ public long getCount(DBObject query, DBObject fields, long limit, long skip )
public DBCollection rename( String newName )
throws MongoException {
- CommandResult ret =
- _db.getSisterDB( "admin" )
- .command( BasicDBObjectBuilder.start()
- .add( "renameCollection" , _fullName )
- .add( "to" , _db._name + "." + newName )
- .get() );
- ret.throwOnError();
- return _db.getCollection( newName );
+ return _db.renameCollection( _name , newName );
}
/**
@@ -987,7 +977,7 @@ public WriteConcern getWriteConcern(){
final DB _db;
- final protected String _name;
+ final protected String _name;
final protected String _fullName;
protected List _hintFields;
diff --git a/src/test/com/mongodb/JavaClientTest.java b/src/test/com/mongodb/JavaClientTest.java
index 8285eac8991..e84650069a3 100644
--- a/src/test/com/mongodb/JavaClientTest.java
+++ b/src/test/com/mongodb/JavaClientTest.java
@@ -303,6 +303,16 @@ public void testTimestamp()
assert( t.getInc() > 0 );
}
+ @Test
+ public void testDrop(){
+ DBCollection c = _db.getCollection( "drop1" );
+ c.drop();
+ c.insert( new BasicDBObject( "_id" , 1 ) );
+ assertEquals( 1 , c.find().count() );
+ c.drop();
+ assertEquals( 0 , c.find().count() );
+ }
+
@Test
public void testStrictWriteSetInCollection(){
DBCollection c = _db.getCollection( "write1" );
From 66952e18ea560a4befbd07e0a48c852ec9040084 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 15 Sep 2010 07:59:04 -0700
Subject: [PATCH 12/31] fixes JAVA-155
---
src/main/com/mongodb/DBApiLayer.java | 4 ++
src/main/com/mongodb/Response.java | 6 +--
src/test/com/mongodb/DBCursorTest.java | 51 +++++++++++++++++++++++++-
3 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/src/main/com/mongodb/DBApiLayer.java b/src/main/com/mongodb/DBApiLayer.java
index 7d10557c74f..83e0dcdbd61 100644
--- a/src/main/com/mongodb/DBApiLayer.java
+++ b/src/main/com/mongodb/DBApiLayer.java
@@ -309,6 +309,10 @@ public boolean hasNext(){
return false;
_advance();
+
+ if ( ( _options & Bytes.QUERYOPTION_TAILABLE ) == Bytes.QUERYOPTION_TAILABLE && !_cur.hasNext())
+ return false;
+
return hasNext();
}
diff --git a/src/main/com/mongodb/Response.java b/src/main/com/mongodb/Response.java
index 8f833ed968b..85c8d60964a 100644
--- a/src/main/com/mongodb/Response.java
+++ b/src/main/com/mongodb/Response.java
@@ -22,7 +22,7 @@
import java.util.*;
import org.bson.*;
-import org.bson.io.*;
+import org.bson.io.Bits;
class Response {
@@ -90,8 +90,8 @@ public boolean hasGetMore( int queryOptions ){
if ( _num > 0 )
return true;
- if ( ( queryOptions & Bytes.QUERYOPTION_TAILABLE ) == 0 )
- return false;
+// if ( ( queryOptions & Bytes.QUERYOPTION_TAILABLE ) == Bytes.QUERYOPTION_TAILABLE )
+// return false;
// have a tailable cursor
if ( ( _flags & Bytes.RESULTFLAG_AWAITCAPABLE ) > 0 )
diff --git a/src/test/com/mongodb/DBCursorTest.java b/src/test/com/mongodb/DBCursorTest.java
index b16a7d159ca..77028286749 100644
--- a/src/test/com/mongodb/DBCursorTest.java
+++ b/src/test/com/mongodb/DBCursorTest.java
@@ -19,7 +19,7 @@
import java.io.*;
import java.util.*;
-import org.testng.annotations.Test;
+import org.testng.annotations.*;
import com.mongodb.util.*;
@@ -66,6 +66,55 @@ public void testSnapshot() {
assertEquals( 50 , c.find().snapshot().limit(50).toArray().size() );
}
+ @Test//(enabled = false)
+ public void testTailable() {
+ DBCollection c = _db.getCollection("tail1");
+ c.drop();
+ _db.createCollection( "tail1", new BasicDBObject("capped", true).append( "size", 10000 ) );
+ for ( int i=0; i<10; i++ )
+ c.save( new BasicDBObject( "x" , i ) );
+
+
+ DBCursor cur = c.find().sort( new BasicDBObject( "$natural" , 1 ) )
+ .addOption( Bytes.QUERYOPTION_TAILABLE );
+
+ while ( cur.hasNext() ) {
+ cur.next();
+ //do nothing...
+ }
+
+ assert( !cur.hasNext() );
+ c.save( new BasicDBObject( "x" , 12 ) );
+ assert( cur.hasNext() );
+ assertNotNull( cur.next() );
+ assert( !cur.hasNext() );
+
+ }
+
+ @Test//(enabled = false)
+ public void testTailableAwait() {
+ DBCollection c = _db.getCollection("tail1");
+ c.drop();
+ _db.createCollection( "tail1", new BasicDBObject("capped", true).append( "size", 10000 ) );
+ for ( int i=0; i<10; i++ )
+ c.save( new BasicDBObject( "x" , i ) );
+
+
+ DBCursor cur = c.find().sort( new BasicDBObject( "$natural" , 1 ) )
+ .addOption( Bytes.QUERYOPTION_TAILABLE | Bytes.QUERYOPTION_AWAITDATA );
+
+ while ( cur.hasNext() ) {
+ cur.next();
+ //do nothing...
+ }
+
+ assert( !cur.hasNext() );
+ c.save( new BasicDBObject( "x" , 12 ) );
+ assert( cur.hasNext() );
+ assertNotNull( cur.next() );
+ assert( !cur.hasNext() );
+ }
+
@Test
public void testBig(){
DBCollection c = _db.getCollection("big1");
From efb91dbc42cff1d9c138bf27eda4062d27458741 Mon Sep 17 00:00:00 2001
From: hmeiser
Date: Mon, 27 Sep 2010 15:02:29 +0200
Subject: [PATCH 13/31] improved version von BSONDecoder
---
src/main/org/bson/BSONDecoder.java | 404 ++++++++++++++++++++++++-----
1 file changed, 346 insertions(+), 58 deletions(-)
diff --git a/src/main/org/bson/BSONDecoder.java b/src/main/org/bson/BSONDecoder.java
index fb1fcac13ce..f90826ff919 100644
--- a/src/main/org/bson/BSONDecoder.java
+++ b/src/main/org/bson/BSONDecoder.java
@@ -2,12 +2,37 @@
package org.bson;
-import static org.bson.BSON.*;
-
-import java.io.*;
-
-import org.bson.io.*;
-import org.bson.types.*;
+import static org.bson.BSON.ARRAY;
+import static org.bson.BSON.BINARY;
+import static org.bson.BSON.BOOLEAN;
+import static org.bson.BSON.B_BINARY;
+import static org.bson.BSON.B_GENERAL;
+import static org.bson.BSON.B_UUID;
+import static org.bson.BSON.CODE;
+import static org.bson.BSON.CODE_W_SCOPE;
+import static org.bson.BSON.DATE;
+import static org.bson.BSON.EOO;
+import static org.bson.BSON.MAXKEY;
+import static org.bson.BSON.MINKEY;
+import static org.bson.BSON.NULL;
+import static org.bson.BSON.NUMBER;
+import static org.bson.BSON.NUMBER_INT;
+import static org.bson.BSON.NUMBER_LONG;
+import static org.bson.BSON.OBJECT;
+import static org.bson.BSON.OID;
+import static org.bson.BSON.REF;
+import static org.bson.BSON.REGEX;
+import static org.bson.BSON.STRING;
+import static org.bson.BSON.SYMBOL;
+import static org.bson.BSON.TIMESTAMP;
+import static org.bson.BSON.UNDEFINED;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+
+import org.bson.types.ObjectId;
public class BSONDecoder {
@@ -63,7 +88,7 @@ public int decode( Input in , BSONCallback callback )
int decode()
throws IOException {
- final int start = _in._read;
+ final int start = _in.getBytesRead();
final int len = _in.readInt();
@@ -71,7 +96,7 @@ int decode()
while ( decodeElement() );
_callback.objectDone();
- final int read = _in._read - start;
+ final int read = _in.getBytesRead() - start;
if ( read != len ){
//throw new IllegalArgumentException( "bad data. lengths don't match " + read + " != " + len );
@@ -251,32 +276,148 @@ Object _readBasicObject()
}
class Input {
- Input( InputStream in ){
+ /**
+ * Maximum size of readahead. This ensures that we copy in memory at most
+ * readahead bytes if the buffer does not contain enough continuous bytes.
+ * Must be lower or equal than size of _charBuffer to prevent a buffer overflow.
+ */
+ final private static int MAX_READAHEADSIZE = 512;
+
+ Input( final InputStream in ){
_in = in;
_read = 0;
}
-
- int readInt()
- throws IOException {
- _read += 4;
- return Bits.readInt( _in );
+ /**
+ * Ensures that a continuous block of bytes is loaded to the buffer. Its responsibility to consume
+ * the complete block.
+ *
+ * @param blockSize
+ * @throws IOException
+ */
+ void ensureContinuousBlock(int blockSize) throws IOException {
+ //
+ // Enough bytes already loaded?
+ if(_o + blockSize <= _l)
+ return;
+
+ final int remaining = _l - _o;
+ //
+ // Is buffer large enough for block?
+ if(blockSize < _random.length)
+ {
+ //
+ // copy the rest in the buffer to the front
+ System.arraycopy(_random, _o, _random, 0, remaining);
+ }
+ else
+ {
+ //
+ // Allocate a larger buffer
+ final byte largerBuffer[] = new byte[blockSize + MAX_READAHEADSIZE];
+ //
+ // copy the rest of the old buffer to the front of the new
+ System.arraycopy(_random, _o, largerBuffer, 0, remaining);
+ //
+ // swap the buffers
+ _random = largerBuffer;
+ }
+ //
+ // Increase the numbers of bytes by all processed bytes (offset with current buffer)
+ // Buffer is now aligned with the front
+ _read += _o;
+
+ _o = 0;
+ _l = remaining;
+ //
+ //
+ final int readahead = Math.min(MAX_READAHEADSIZE, _random.length - remaining);
+ int wanted = Math.max(readahead, blockSize - remaining);
+
+ while(wanted > 0 && _l < blockSize) {
+ //
+ // Read as much as we wanted at the end of the buffer
+ int rd = _in.read(_random, _l, wanted);
+ //
+ // EOS reached?
+ if(rd < 0)
+ break;
+ //
+ // Increase end and reduced wanted by bytes read from InputStream
+ _l = _l + rd;
+ wanted -=rd;
+ }
+ //
+ // Ups, we were not able to read enough bytes from stream
+ if(_l < blockSize) {
+ System.out.println("ups");
+ }
}
- long readLong()
+ /**
+ * Reads an integer.
+ *
+ * @return
+ * @throws IOException
+ */
+ final int readInt()
throws IOException {
- _read += 8;
- return Bits.readLong( _in );
+ //
+ // All integers are 4 bytes
+ ensureContinuousBlock(4);
+ //
+ // Code copied from java.io.Bits
+ return
+ ((_random[_o++] & 0xFF) << 0) +
+ ((_random[_o++] & 0xFF) << 8) +
+ ((_random[_o++] & 0xFF) << 16) +
+ ((_random[_o++]) << 24);
}
-
+ /**
+ * Reads a long.
+ *
+ * @return
+ * @throws IOException
+ */
+ long readLong()
+ throws IOException {
+ //
+ // All longs are 8 bytes
+ ensureContinuousBlock(8);
+ //
+ // Code copied from java.io.Bits
+ return ((_random[_o++] & 0xFFL) << 0) +
+ ((_random[_o++] & 0xFFL) << 8) +
+ ((_random[_o++] & 0xFFL) << 16) +
+ ((_random[_o++] & 0xFFL) << 24) +
+ ((_random[_o++] & 0xFFL) << 32) +
+ ((_random[_o++] & 0xFFL) << 40) +
+ ((_random[_o++] & 0xFFL) << 48) +
+ (((long) _random[_o++]) << 56);
+ }
+ /**
+ * Simply read a double
+ *
+ * @return
+ * @throws IOException
+ */
double readDouble()
throws IOException {
return Double.longBitsToDouble( readLong() );
}
-
+ /**
+ * Read the next byte from stream.
+ *
+ * @return
+ * @throws IOException
+ */
byte read()
- throws IOException {
- _read++;
- return (byte)(_in.read() & 0xFF);
+ throws IOException {
+ //
+ // Ensure that one byte can be read
+ ensureContinuousBlock(1);
+ //
+ // Simply return the byte
+ return _random[_o++];
}
void fill( byte b[] )
@@ -285,64 +426,211 @@ void fill( byte b[] )
}
void fill( byte b[] , int len )
- throws IOException {
- int off = 0;
- while ( len > 0 ){
- int x = _in.read( b , off , len );
- _read += x;
- off += x;
- len -= x;
+ throws IOException {
+ //
+ // Take the remaining bytes from the buffer
+ int outputOffset = _l - _o;
+
+ if(outputOffset > 0)
+ {
+ System.arraycopy(_random, _o, b, 0, outputOffset);
+ //
+ // Reduced needed bytes
+ len -= outputOffset;
+ //
+ // leave it up to the next ensure a continuous block
+ _o = _l;
+ }
+ //
+ // Read the rest direct from the InputStream
+ while ( len > 0 ) {
+ final int bytesRead = _in.read( b , outputOffset , len );
+ //
+ // Reduced needed bytes
+ len -= bytesRead;
+ //
+ // Increase the number of read bytes because we reading directly from _in
+ _read += bytesRead;
+
+ outputOffset += bytesRead;
+ }
+ }
+ /**
+ * Read a multibyte character with the first given as parameter c1
.
+ *
+ * @param c1
+ * @return
+ * @throws IOException
+ */
+ char readMultiByte(int c1) throws IOException
+ {
+ switch (c1 >> 4) {
+ case 12:
+ case 13: {
+ //
+ // We need at least one byte for the character and one for the null to terminate
+ ensureContinuousBlock(2);
+ //
+ // Read next byte and check for correctness
+ final int c2 = _random[_o++];
+
+ if ((c2 & 0xC0) != 0x80)
+ return '\uFFFD';
+
+ return (char)(((c1 & 0x1F) << 6) | (c2 & 0x3F));
+ }
+ case 14: {
+ //
+ // We need at least two bytes for the character and one for the null to terminate
+ ensureContinuousBlock(3);
+ //
+ // Read next bytes and check for correctness
+ final int c2 = _random[_o++];
+ final int c3 = _random[_o++];
+
+ if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
+ return '\uFFFD';
+
+ return (char)(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | ((c3 & 0x3F) << 0));
+ }
+ default:
+ return '\uFFFD';
}
}
+ /**
+ * Read an null terminated string in UTF8 from {@link InputStream}.
+ * We assume that null terminated strings have small lengths and are mostly ascii.
+ *
+ * @return
+ * @throws IOException
+ */
String readCStr()
- throws IOException {
-
- _stringBuffer.reset();
-
- while ( true ){
- byte b = read();
- if ( b == 0 )
- break;
- _stringBuffer.write( b );
- }
-
- String out = null;
- try {
- out = _stringBuffer.asString( "UTF-8" );
- }
- catch ( UnsupportedOperationException e ){
- throw new RuntimeException( "impossible" , e );
- }
- _stringBuffer.reset();
- return out;
+ throws IOException {
+ //
+ // Position within _charBuffer
+ int charBufferPosition = 0;
+ //
+ // Claim a StringBuilder for bulding strings longer than charBuffer
+ StringBuilder stringBuilder = _stringBuilder.get();
+
+ if(stringBuilder == null) {
+ stringBuilder = new StringBuilder(_charBuffer.length * 2);
+ _stringBuilder = new SoftReference(stringBuilder);
+ }
+ else
+ stringBuilder.setLength(0);
+ //
+ // Fille the buffer with the first byte
+ ensureContinuousBlock(1);
+
+ outer:
+ while ( true ) {
+ //
+ // This is the fast inner loop where every character is completely located in the buffer
+ // Since we read at maximum MAX_READAHEADSIZE and _charBuffer.length is greater than MAX_READAHEADSIZE
+ // there is no need to check for a buffer overflow in _charBuffer.
+ assert(_l - _o < _charBuffer.length - charBufferPosition);
+
+ while(_o < _l) {
+ //
+ // Read next byte from buffer
+ final int b = _random[_o++];
+ //
+ // Normal ascii character? Its the most common case
+ if( b > 0) {
+ //
+ // Append it to the end of our buffer
+ assert charBufferPosition < _charBuffer.length;
+ _charBuffer[charBufferPosition++] = (char)b;
+ }
+ else if( b == 0) {
+ break outer;
+ }
+ else {
+ //
+ // Read a multibyte. Its currently not optimized because this case is infrequent
+ assert charBufferPosition < _charBuffer.length;
+ _charBuffer[charBufferPosition++] = readMultiByte(b & 0xff);
+ }
+ }
+ //
+ // We need more bytes in the buffer, at least one byte
+ ensureContinuousBlock(1);
+ //
+ // If there are to much characters in the buffer, then append _charBuffer to StringBuilder
+ // and reset the _charBuffer. This ensures that the byteBuffer does not rise a char buffer overflow
+ if(_l - _o > _charBuffer.length - charBufferPosition)
+ {
+ stringBuilder.append(_charBuffer, 0, charBufferPosition);
+ charBufferPosition = 0;
+ }
+ }
+ //
+ // Some characters in _charBuffer
+ if(charBufferPosition > 0) {
+ //
+ // if string is empty then create the string direct from _charBuffer
+ if(stringBuilder.length() == 0)
+ return new String(_charBuffer, 0, charBufferPosition);
+ //
+ // Append _charBuffer to final string
+ stringBuilder.append(_charBuffer, 0, charBufferPosition);
+ }
+
+ return stringBuilder.toString();
}
-
+ /**
+ * Read an UTF8-String from {@link InputStream}.
+ *
+ * @return
+ * @throws IOException
+ */
String readUTF8String()
throws IOException {
- int size = readInt();
+ //
+ // Read size and ensure that the complete string is in the buffer
+ final int size = readInt();
if ( size < 0 || size > ( 3 * 1024 * 1024 ) )
throw new RuntimeException( "bad string size: " + size );
- byte[] b = size < _random.length ? _random : new byte[size];
-
- fill( b , size );
+ ensureContinuousBlock(size);
+ //
+ // Start of the string is the current pointer in buffer
+ final int startOfString = _o;
+ //
+ // Increase offset by size of string
+ _o += size;
+
try {
- return new String( b , 0 , size - 1 , "UTF-8" );
+ return new String( _random, startOfString , size - 1 , "UTF-8" );
}
catch ( java.io.UnsupportedEncodingException uee ){
throw new RuntimeException( "impossible" , uee );
}
}
+ /**
+ * Returns the number of bytes read so far.
+ *
+ * @return
+ */
+ int getBytesRead() {
+ return _read + _o;
+ }
+ int _o;
+ int _l;
int _read;
+
final InputStream _in;
}
-
private Input _in;
private BSONCallback _callback;
private byte[] _random = new byte[1024];
-
- private PoolOutputBuffer _stringBuffer = new PoolOutputBuffer();
+ private char _charBuffer[] = new char[1024];
+ /**
+ * {@link SoftReference} to {@link StringBuilder} to allow reclaiming of memory by GC
+ */
+ private SoftReference _stringBuilder = new SoftReference(null);
}
From fbd97ea04f196e09e68d71877ca68e7c72474d17 Mon Sep 17 00:00:00 2001
From: hmeiser
Date: Wed, 29 Sep 2010 09:31:32 +0200
Subject: [PATCH 14/31] coding conventions
---
src/main/org/bson/BSONDecoder.java | 58 ++++++++----------------------
1 file changed, 15 insertions(+), 43 deletions(-)
diff --git a/src/main/org/bson/BSONDecoder.java b/src/main/org/bson/BSONDecoder.java
index f90826ff919..67b8a8220db 100644
--- a/src/main/org/bson/BSONDecoder.java
+++ b/src/main/org/bson/BSONDecoder.java
@@ -2,37 +2,12 @@
package org.bson;
-import static org.bson.BSON.ARRAY;
-import static org.bson.BSON.BINARY;
-import static org.bson.BSON.BOOLEAN;
-import static org.bson.BSON.B_BINARY;
-import static org.bson.BSON.B_GENERAL;
-import static org.bson.BSON.B_UUID;
-import static org.bson.BSON.CODE;
-import static org.bson.BSON.CODE_W_SCOPE;
-import static org.bson.BSON.DATE;
-import static org.bson.BSON.EOO;
-import static org.bson.BSON.MAXKEY;
-import static org.bson.BSON.MINKEY;
-import static org.bson.BSON.NULL;
-import static org.bson.BSON.NUMBER;
-import static org.bson.BSON.NUMBER_INT;
-import static org.bson.BSON.NUMBER_LONG;
-import static org.bson.BSON.OBJECT;
-import static org.bson.BSON.OID;
-import static org.bson.BSON.REF;
-import static org.bson.BSON.REGEX;
-import static org.bson.BSON.STRING;
-import static org.bson.BSON.SYMBOL;
-import static org.bson.BSON.TIMESTAMP;
-import static org.bson.BSON.UNDEFINED;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.SoftReference;
-
-import org.bson.types.ObjectId;
+import static org.bson.BSON.*;
+
+import java.io.*;
+import java.lang.ref.*;
+
+import org.bson.types.*;
public class BSONDecoder {
@@ -294,7 +269,8 @@ class Input {
* @param blockSize
* @throws IOException
*/
- void ensureContinuousBlock(int blockSize) throws IOException {
+ void ensureContinuousBlock(int blockSize)
+ throws IOException {
//
// Enough bytes already loaded?
if(_o + blockSize <= _l)
@@ -303,14 +279,12 @@ void ensureContinuousBlock(int blockSize) throws IOException {
final int remaining = _l - _o;
//
// Is buffer large enough for block?
- if(blockSize < _random.length)
- {
+ if(blockSize < _random.length) {
//
// copy the rest in the buffer to the front
System.arraycopy(_random, _o, _random, 0, remaining);
}
- else
- {
+ else {
//
// Allocate a larger buffer
final byte largerBuffer[] = new byte[blockSize + MAX_READAHEADSIZE];
@@ -426,13 +400,12 @@ void fill( byte b[] )
}
void fill( byte b[] , int len )
- throws IOException {
+ throws IOException {
//
// Take the remaining bytes from the buffer
int outputOffset = _l - _o;
- if(outputOffset > 0)
- {
+ if(outputOffset > 0) {
System.arraycopy(_random, _o, b, 0, outputOffset);
//
// Reduced needed bytes
@@ -462,8 +435,8 @@ void fill( byte b[] , int len )
* @return
* @throws IOException
*/
- char readMultiByte(int c1) throws IOException
- {
+ char readMultiByte(int c1)
+ throws IOException {
switch (c1 >> 4) {
case 12:
case 13: {
@@ -560,8 +533,7 @@ else if( b == 0) {
//
// If there are to much characters in the buffer, then append _charBuffer to StringBuilder
// and reset the _charBuffer. This ensures that the byteBuffer does not rise a char buffer overflow
- if(_l - _o > _charBuffer.length - charBufferPosition)
- {
+ if(_l - _o > _charBuffer.length - charBufferPosition) {
stringBuilder.append(_charBuffer, 0, charBufferPosition);
charBufferPosition = 0;
}
From e6e164c6fcadfcf9a50b4b4723ba516afeb49c85 Mon Sep 17 00:00:00 2001
From: hmeiser
Date: Wed, 29 Sep 2010 10:12:37 +0200
Subject: [PATCH 15/31] BSONEncoder now can handle primitive arrays JAVA-103
---
src/main/org/bson/BSONEncoder.java | 16 +++++++++++++++-
src/test/org/bson/BSONTest.java | 20 +++++++++++---------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/main/org/bson/BSONEncoder.java b/src/main/org/bson/BSONEncoder.java
index d578dd66ca7..62b305296d8 100644
--- a/src/main/org/bson/BSONEncoder.java
+++ b/src/main/org/bson/BSONEncoder.java
@@ -4,6 +4,7 @@
import static org.bson.BSON.*;
+import java.lang.reflect.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.*;
@@ -182,7 +183,7 @@ else if ( val instanceof Binary )
else if ( val instanceof UUID )
putUUID( name , (UUID)val );
else if ( val.getClass().isArray() )
- putIterable( name , Arrays.asList( (Object[])val ) );
+ putArray( name , val );
else if (val instanceof Symbol) {
putSymbol(name, (Symbol) val);
@@ -204,7 +205,20 @@ else if ( putSpecial( name , val ) ){
}
}
+
+ private void putArray( String name , Object array ) {
+ _put( ARRAY , name );
+ final int sizePos = _buf.getPosition();
+ _buf.writeInt( 0 );
+
+ int size = Array.getLength(array);
+ for ( int i = 0; i < size; i++ )
+ _putObjectField( String.valueOf( i ) , Array.get( array, i ) );
+ _buf.write( EOO );
+ _buf.writeInt( sizePos , _buf.getPosition() - sizePos );
+ }
+
private void putIterable( String name , Iterable l ){
_put( ARRAY , name );
final int sizePos = _buf.getPosition();
diff --git a/src/test/org/bson/BSONTest.java b/src/test/org/bson/BSONTest.java
index afddc273afd..c1c7cafa7b6 100644
--- a/src/test/org/bson/BSONTest.java
+++ b/src/test/org/bson/BSONTest.java
@@ -19,17 +19,13 @@
package org.bson;
import java.io.*;
-import java.nio.*;
import java.util.*;
-import java.util.zip.*;
-import com.mongodb.*;
-import com.mongodb.util.*;
-
-import org.testng.annotations.Test;
-
-import org.bson.types.*;
import org.bson.io.*;
+import org.bson.types.*;
+import org.testng.annotations.*;
+
+import com.mongodb.util.*;
public class BSONTest extends TestCase {
@@ -70,7 +66,7 @@ void _test( BSONObject o , int size , String hash )
@Test
public void testBasic1()
throws IOException {
- BSONObject o = new BasicBSONObject();
+// BSONObject o = new BasicBSONObject();
_test( new BasicBSONObject( "x" , true ) , 9 , "6fe24623e4efc5cf07f027f9c66b5456" );
_test( new BasicBSONObject( "x" , null ) , 8 , "12d43430ff6729af501faf0638e68888" );
@@ -85,6 +81,12 @@ public void testBasic1()
_test( new BasicBSONObject( "x" , 4 ) , 12 , "d1ed8dbf79b78fa215e2ded74548d89d" );
}
+
+ @Test
+ public void testArray()
+ throws IOException {
+ _test( new BasicBSONObject( "x" , new int[]{ 1 , 2 , 3 , 4} ) , 41 , "e63397fe37de1349c50e1e4377a45e2d" );
+ }
@Test
public void testOB1(){
From 2722cbf36c66fcae0609561881805157ebf5c2ff Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 30 Sep 2010 17:36:54 -0700
Subject: [PATCH 16/31] eclipse formatting files (v3.5)
---
eclipse-java-code-formatters.xml | 279 +++++++++++++++++++++++++++++++
eclipse-java.importorder | 6 +
2 files changed, 285 insertions(+)
create mode 100755 eclipse-java-code-formatters.xml
create mode 100755 eclipse-java.importorder
diff --git a/eclipse-java-code-formatters.xml b/eclipse-java-code-formatters.xml
new file mode 100755
index 00000000000..dc6b047b014
--- /dev/null
+++ b/eclipse-java-code-formatters.xml
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eclipse-java.importorder b/eclipse-java.importorder
new file mode 100755
index 00000000000..30c47df0ea6
--- /dev/null
+++ b/eclipse-java.importorder
@@ -0,0 +1,6 @@
+#Organize Import Order
+#Fri Sep 24 11:18:51 PDT 2010
+3=com
+2=org
+1=javax
+0=java
From ac11b1ce697838117cf8a6bf6d1cb6be9f00d46b Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Tue, 5 Oct 2010 11:28:42 -0700
Subject: [PATCH 17/31] javadoc cleanup
---
src/main/com/mongodb/DB.java | 2 +-
src/main/com/mongodb/DBCollection.java | 2 +-
src/main/com/mongodb/DBCursor.java | 2 +-
src/main/com/mongodb/Mongo.java | 3 +--
src/main/com/mongodb/MongoOptions.java | 14 ++++++++------
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/main/com/mongodb/DB.java b/src/main/com/mongodb/DB.java
index b5431145bbe..b60322c31a1 100644
--- a/src/main/com/mongodb/DB.java
+++ b/src/main/com/mongodb/DB.java
@@ -481,7 +481,7 @@ public DB getSisterDB( String name ){
}
/**
- * makes thisq query ok to run on a slave node
+ * makes this query ok to run on a slave node
*/
public void slaveOk(){
addOption( Bytes.QUERYOPTION_SLAVEOK );
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index 3dbc9fa4520..d52cc77accd 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -965,7 +965,7 @@ public WriteConcern getWriteConcern(){
}
/**
- * makes thisq query ok to run on a slave node
+ * makes this query ok to run on a slave node
*/
public void slaveOk(){
addOption( Bytes.QUERYOPTION_SLAVEOK );
diff --git a/src/main/com/mongodb/DBCursor.java b/src/main/com/mongodb/DBCursor.java
index 898ef84b161..e8be3188b1e 100644
--- a/src/main/com/mongodb/DBCursor.java
+++ b/src/main/com/mongodb/DBCursor.java
@@ -230,7 +230,7 @@ public DBCursor skip( int n ){
}
/**
- * makes thisq query ok to run on a slave node
+ * makes this query ok to run on a slave node
*/
public void slaveOk(){
addOption( Bytes.QUERYOPTION_SLAVEOK );
diff --git a/src/main/com/mongodb/Mongo.java b/src/main/com/mongodb/Mongo.java
index 0600d5b6b2d..76fc899f325 100644
--- a/src/main/com/mongodb/Mongo.java
+++ b/src/main/com/mongodb/Mongo.java
@@ -22,7 +22,6 @@
import java.util.*;
import java.util.concurrent.*;
-import org.bson.util.*;
import org.bson.io.*;
/**
@@ -316,7 +315,7 @@ public WriteConcern getWriteConcern(){
}
/**
- * makes thisq query ok to run on a slave node
+ * makes this query ok to run on a slave node
*/
public void slaveOk(){
addOption( Bytes.QUERYOPTION_SLAVEOK );
diff --git a/src/main/com/mongodb/MongoOptions.java b/src/main/com/mongodb/MongoOptions.java
index e293d23dc92..b8a0d3da9a5 100644
--- a/src/main/com/mongodb/MongoOptions.java
+++ b/src/main/com/mongodb/MongoOptions.java
@@ -18,6 +18,8 @@
package com.mongodb;
+import java.net.*;
+
/**
* Various settings for the driver
*/
@@ -37,8 +39,8 @@ public void reset(){
}
/**
- number of connections allowed per host
- will block if run out
+ The number of connections allowed per host (the pool size, per host)
+ Once the pool is exhausted, this will block. See {@linkplain MongoOptions.threadsAllowedToBlockForConnectionMultiplier}
*/
public int connectionsPerHost;
@@ -51,22 +53,22 @@ public void reset(){
public int threadsAllowedToBlockForConnectionMultiplier;
/**
- * max wait time of a blocking thread for a connection
+ * The max wait time for a blocking thread for a connection from the pool
*/
public int maxWaitTime;
/**
- connect timeout in milliseconds. 0 is default and infinite
+ The connection timeout in milliseconds; this is for establishing the socket connections (open). 0 is default and infinite
*/
public int connectTimeout;
/**
- socket timeout. 0 is default and infinite
+ The socket timeout; this value is passed to {@link Socket.setSoTimeout}. 0 is default and infinite
*/
public int socketTimeout;
/**
- this controls whether or not on a connect, the system retries automatically. defaults to false
+ This controls whether the system retries automatically on connection errors. defaults to false
*/
public boolean autoConnectRetry;
From 483b0372d37a3f699cacee7af852cfb809e08cbc Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 6 Oct 2010 13:28:13 -0700
Subject: [PATCH 18/31] Use weakrefs.
---
src/main/com/mongodb/Mongo.java | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/main/com/mongodb/Mongo.java b/src/main/com/mongodb/Mongo.java
index 76fc899f325..70aea98babd 100644
--- a/src/main/com/mongodb/Mongo.java
+++ b/src/main/com/mongodb/Mongo.java
@@ -18,6 +18,7 @@
package com.mongodb;
+import java.lang.ref.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
@@ -76,6 +77,12 @@ public static DB connect( DBAddress addr ){
return new Mongo( addr ).getDB( addr.getDBName() );
}
+ /** Returns the count of mongo instances used by static methods**/
+ public static int getStaticInstanceCount () {
+ return _mongos.size();
+ }
+
+ /** returns a mongo instance based on the host **/
public static Mongo getStaticMongo( String host )
throws UnknownHostException , MongoException {
return getStaticMongo( host , null );
@@ -83,17 +90,19 @@ public static Mongo getStaticMongo( String host )
private static final MongoOptions _defaultOptions = new MongoOptions();
+ /** Returns a Mongo instance based on the host + options. **/
public static Mongo getStaticMongo( String host , MongoOptions options )
throws UnknownHostException , MongoException {
final String key = host + "-" + options;
- Mongo m = _mongos.get( key );
+ WeakReference mRef = _mongos.get( key );
+ Mongo m = mRef.get();
if ( m != null )
return m;
m = new Mongo( host , options == null ? _defaultOptions : options );
- Mongo temp = _mongos.putIfAbsent( key , m );
+ Mongo temp = _mongos.putIfAbsent( key , new WeakReference(m) ).get();
if ( temp != null ){
m.close();
return temp;
@@ -355,6 +364,5 @@ protected PoolOutputBuffer createNew(){
};
-
- private static final ConcurrentMap _mongos = new ConcurrentHashMap();
+ private static final ConcurrentMap> _mongos = new ConcurrentHashMap>();
}
From 8bdc38782b444a942d07e5b64942d44538fd5f46 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 7 Oct 2010 18:01:37 -0700
Subject: [PATCH 19/31] Add constructor with size.
---
src/main/com/mongodb/BasicDBObject.java | 8 ++++++--
src/main/org/bson/BasicBSONObject.java | 6 ++++--
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/main/com/mongodb/BasicDBObject.java b/src/main/com/mongodb/BasicDBObject.java
index fdc6087fb60..9fca85331de 100644
--- a/src/main/com/mongodb/BasicDBObject.java
+++ b/src/main/com/mongodb/BasicDBObject.java
@@ -20,10 +20,10 @@
import java.util.*;
-import com.mongodb.util.*;
-
import org.bson.*;
+import com.mongodb.util.*;
+
/**
* A simple implementation of DBObject
.
* A DBObject
can be created as follows, using this class:
@@ -39,6 +39,10 @@ public class BasicDBObject extends BasicBSONObject implements DBObject {
*/
public BasicDBObject(){
}
+
+ public BasicDBObject(int size){
+ super(size);
+ }
/**
* Convenience CTOR
diff --git a/src/main/org/bson/BasicBSONObject.java b/src/main/org/bson/BasicBSONObject.java
index 257285ca506..eca918fca32 100644
--- a/src/main/org/bson/BasicBSONObject.java
+++ b/src/main/org/bson/BasicBSONObject.java
@@ -20,8 +20,6 @@
import java.util.*;
-import org.bson.*;
-
/**
* A simple implementation of DBObject
.
* A DBObject
can be created as follows, using this class:
@@ -38,6 +36,10 @@ public class BasicBSONObject extends LinkedHashMap implements BSO
public BasicBSONObject(){
}
+ public BasicBSONObject(int size){
+ super(size);
+ }
+
/**
* Convenience CTOR
* @param key key under which to store
From 22d8edf7d157b7f75a57e9afa3fdc437a27f7769 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Fri, 8 Oct 2010 19:01:03 -0700
Subject: [PATCH 20/31] expose cursorId/kill() for JAVA-178
---
src/main/com/mongodb/DBCursor.java | 31 ++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/main/com/mongodb/DBCursor.java b/src/main/com/mongodb/DBCursor.java
index e8be3188b1e..b6f2b82080d 100644
--- a/src/main/com/mongodb/DBCursor.java
+++ b/src/main/com/mongodb/DBCursor.java
@@ -20,6 +20,9 @@
import java.util.*;
+import com.mongodb.DBApiLayer.MyCollection;
+import com.mongodb.DBApiLayer.Result;
+
/** An iterator over database results.
* Doing a find()
query on a collection returns a
@@ -229,6 +232,34 @@ public DBCursor skip( int n ){
return this;
}
+ /** The cursor (id) on the server; 0 = no cursor */
+ public long getCursorId() {
+ if (_it instanceof Result) {
+ Response curRes = ((Result)_it)._curResult;
+ if ( curRes != null )
+ return curRes._cursor;
+ }
+
+ return 0;
+ }
+
+ /** kill the current cursor on the server. */
+ public boolean kill() {
+ long cursorId = getCursorId();
+ if ( cursorId > 0 ) {
+ if ( _it instanceof Result ) {
+ Result res = (Result)_it;
+ ((MyCollection) res._collection).killCursors( Arrays.asList( cursorId ) );
+
+ //null the current results so it doesn't get killed again.
+ res._curResult = null;
+ }
+ }
+
+ //TODO: how can we tell if it was successful? getLastError?
+ return true;
+ }
+
/**
* makes this query ok to run on a slave node
*/
From c30892cc06baef0a7df1877f1d2efc941ec15142 Mon Sep 17 00:00:00 2001
From: unknown
Date: Mon, 11 Oct 2010 14:30:51 +0200
Subject: [PATCH 21/31] corrected BSONDecoder to prevent from reading beyond
object boundary
---
src/main/org/bson/BSONDecoder.java | 55 +++++++++++++++++++-----------
1 file changed, 36 insertions(+), 19 deletions(-)
diff --git a/src/main/org/bson/BSONDecoder.java b/src/main/org/bson/BSONDecoder.java
index 67b8a8220db..d66afba8c55 100644
--- a/src/main/org/bson/BSONDecoder.java
+++ b/src/main/org/bson/BSONDecoder.java
@@ -7,6 +7,7 @@
import java.io.*;
import java.lang.ref.*;
+import org.bson.io.*;
import org.bson.types.*;
public class BSONDecoder {
@@ -42,7 +43,7 @@ public int decode( InputStream in , BSONCallback callback )
return decode( new Input( in ) , callback );
}
- public int decode( Input in , BSONCallback callback )
+ int decode( Input in , BSONCallback callback )
throws IOException {
if ( _in != null || _callback != null )
@@ -62,22 +63,21 @@ public int decode( Input in , BSONCallback callback )
int decode()
throws IOException {
-
- final int start = _in.getBytesRead();
+ //
+ // We already read four bytes for length
+ final int start = _in.getBytesRead() - 4;
- final int len = _in.readInt();
-
_callback.objectStart();
while ( decodeElement() );
_callback.objectDone();
final int read = _in.getBytesRead() - start;
- if ( read != len ){
+ if ( read != _in._length ) {
//throw new IllegalArgumentException( "bad data. lengths don't match " + read + " != " + len );
}
- return len;
+ return _in._length;
}
boolean decodeElement()
@@ -258,9 +258,14 @@ class Input {
*/
final private static int MAX_READAHEADSIZE = 512;
- Input( final InputStream in ){
+ Input( final InputStream in )
+ throws IOException {
_in = in;
_read = 0;
+ //
+ // Limit Buffer to only read 4 bytes for the real length
+ _length = 4;
+ _length = readInt();
}
/**
* Ensures that a continuous block of bytes is loaded to the buffer. Its responsibility to consume
@@ -303,8 +308,10 @@ void ensureContinuousBlock(int blockSize)
_o = 0;
_l = remaining;
//
- //
- final int readahead = Math.min(MAX_READAHEADSIZE, _random.length - remaining);
+ // Calculate possible readahead. It is not allowed to read beyond the end of the current object (_length)
+ final int bytesTillEnd = _length - _read - _l;
+ final int readahead = Math.min(Math.min(MAX_READAHEADSIZE, _random.length - remaining), bytesTillEnd);
+
int wanted = Math.max(readahead, blockSize - remaining);
while(wanted > 0 && _l < blockSize) {
@@ -323,7 +330,7 @@ void ensureContinuousBlock(int blockSize)
//
// Ups, we were not able to read enough bytes from stream
if(_l < blockSize) {
- System.out.println("ups");
+ throw new RuntimeException("end of stream reached");
}
}
@@ -403,13 +410,22 @@ void fill( byte b[] , int len )
throws IOException {
//
// Take the remaining bytes from the buffer
- int outputOffset = _l - _o;
-
- if(outputOffset > 0) {
- System.arraycopy(_random, _o, b, 0, outputOffset);
+ int remaining = _l - _o;
+ //
+ // Did we alread read enough bytes?
+ if(remaining >= len) {
+ System.arraycopy(_random, _o, b, 0, len);
+ _o += len;
+
+ return;
+ }
+ //
+ // Take the complete remaining bytes from buffer
+ if(remaining > 0) {
+ System.arraycopy(_random, _o, b, 0, remaining);
//
// Reduced needed bytes
- len -= outputOffset;
+ len -= remaining;
//
// leave it up to the next ensure a continuous block
_o = _l;
@@ -417,7 +433,7 @@ void fill( byte b[] , int len )
//
// Read the rest direct from the InputStream
while ( len > 0 ) {
- final int bytesRead = _in.read( b , outputOffset , len );
+ final int bytesRead = _in.read( b , remaining , len );
//
// Reduced needed bytes
len -= bytesRead;
@@ -425,7 +441,7 @@ void fill( byte b[] , int len )
// Increase the number of read bytes because we reading directly from _in
_read += bytesRead;
- outputOffset += bytesRead;
+ remaining += bytesRead;
}
}
/**
@@ -494,7 +510,7 @@ String readCStr()
else
stringBuilder.setLength(0);
//
- // Fille the buffer with the first byte
+ // Fill the buffer with the first byte
ensureContinuousBlock(1);
outer:
@@ -595,6 +611,7 @@ int getBytesRead() {
int _read;
final InputStream _in;
+ int _length;
}
private Input _in;
From 1557f5723d1b5fff05174177d2bb110e881404f3 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Mon, 18 Oct 2010 17:32:51 -0700
Subject: [PATCH 22/31] add valueOf for issue JAVA-175
---
src/main/com/mongodb/WriteConcern.java | 27 ++++++++++++++++++++++++
src/test/com/mongodb/JavaClientTest.java | 10 +++++++++
2 files changed, 37 insertions(+)
diff --git a/src/main/com/mongodb/WriteConcern.java b/src/main/com/mongodb/WriteConcern.java
index 39f98b7638a..86ced5eefaa 100644
--- a/src/main/com/mongodb/WriteConcern.java
+++ b/src/main/com/mongodb/WriteConcern.java
@@ -17,6 +17,10 @@
*/
package com.mongodb;
+
+import java.lang.reflect.*;
+import java.util.*;
+
/**
* WriteConcern control the write behavior for with various options, as well as exception raising on error conditions.
*
@@ -56,6 +60,29 @@ public class WriteConcern {
/** Exceptions are raised for network issues, and server errors; waits for at least 2 servers for the write operation*/
public final static WriteConcern REPLICAS_SAFE = new WriteConcern(2);
+ //map of the constants from above for use by fromString
+ private static Map _namedConcerns = null;
+
+ /** Get the WriteConcern constants by name: NONE, NORMAL, SAFE, FSYNC_SAFE, REPLICA_SAFE. (matching is done case insensitively)*/
+ public static WriteConcern valueOf(String name) {
+ if (_namedConcerns == null) {
+ HashMap newMap = new HashMap( 8 , 1 );
+ for (Field f : WriteConcern.class.getFields())
+ if (Modifier.isStatic( f.getModifiers() ) && f.getType().equals( WriteConcern.class )) {
+ try {
+ newMap.put( f.getName().toLowerCase(), (WriteConcern) f.get( null ) );
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ //Thought about doing a synchronize but this seems just as safe and I don't care about race conditions.
+ _namedConcerns = newMap;
+ }
+
+ return _namedConcerns.get(name.toLowerCase());
+ }
+
public WriteConcern(){
this(0);
}
diff --git a/src/test/com/mongodb/JavaClientTest.java b/src/test/com/mongodb/JavaClientTest.java
index e84650069a3..465534995b8 100644
--- a/src/test/com/mongodb/JavaClientTest.java
+++ b/src/test/com/mongodb/JavaClientTest.java
@@ -634,6 +634,16 @@ public void testWriteResultMethodLevelWriteConcern(){
assertFalse( res.isLazy() );
}
+ @Test
+ public void testWriteConcernValueOf(){
+ WriteConcern wc1 = WriteConcern.NORMAL;
+ WriteConcern wc2 = WriteConcern.valueOf( "normal" );
+ WriteConcern wc3 = WriteConcern.valueOf( "NORMAL" );
+
+ assertEquals( wc1._w , wc2._w );
+ assertEquals( wc1._w , wc3._w );
+ }
+
@Test
public void testFindAndModify(){
DBCollection c = _db.getCollection( "findandmodify" );
From df95f02cedbbdd0c596c4eaaff493bcd94ba7c74 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Mon, 18 Oct 2010 17:33:09 -0700
Subject: [PATCH 23/31] disable broken tests
---
src/test/com/mongodb/DBCursorTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/test/com/mongodb/DBCursorTest.java b/src/test/com/mongodb/DBCursorTest.java
index ee8f7c1cf71..1d9ba25d136 100644
--- a/src/test/com/mongodb/DBCursorTest.java
+++ b/src/test/com/mongodb/DBCursorTest.java
@@ -66,7 +66,7 @@ public void testSnapshot() {
assertEquals( 50 , c.find().snapshot().limit(50).toArray().size() );
}
- @Test//(enabled = false)
+ @Test(enabled = false)
public void testTailable() {
DBCollection c = _db.getCollection("tail1");
c.drop();
@@ -91,7 +91,7 @@ public void testTailable() {
}
- @Test//(enabled = false)
+ @Test(enabled = false)
public void testTailableAwait() {
DBCollection c = _db.getCollection("tail1");
c.drop();
From 3d12dd96661f2d8dc6f6e993bb08f66d963ced1a Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 20 Oct 2010 12:10:20 -0700
Subject: [PATCH 24/31] added BasicDBObjectBuilder.isEmpty() and more tests
---
.../com/mongodb/BasicDBObjectBuilder.java | 6 +++--
src/test/com/mongodb/BasicDBObjectTest.java | 25 +++++++++++++++----
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/src/main/com/mongodb/BasicDBObjectBuilder.java b/src/main/com/mongodb/BasicDBObjectBuilder.java
index 5dcf92dd59b..d152e7b5f3f 100644
--- a/src/main/com/mongodb/BasicDBObjectBuilder.java
+++ b/src/main/com/mongodb/BasicDBObjectBuilder.java
@@ -68,8 +68,7 @@ public BasicDBObjectBuilder append( String key , Object val ){
* @return returns itself so you can chain .add( "a" , 1 ).add( "b" , 1 )
*/
public BasicDBObjectBuilder add( String key , Object val ){
- _cur().put( key , val );
- return this;
+ return append( key, val );
}
public BasicDBObjectBuilder push( String key ){
@@ -90,6 +89,9 @@ public DBObject get(){
return _stack.getFirst();
}
+ public boolean isEmpty(){
+ return ((BasicDBObject) _stack.getFirst()).size() == 0;
+ }
private DBObject _cur(){
return _stack.getLast();
}
diff --git a/src/test/com/mongodb/BasicDBObjectTest.java b/src/test/com/mongodb/BasicDBObjectTest.java
index c6e235912b9..6acc7118edd 100644
--- a/src/test/com/mongodb/BasicDBObjectTest.java
+++ b/src/test/com/mongodb/BasicDBObjectTest.java
@@ -18,11 +18,7 @@
package com.mongodb;
-import java.util.*;
-import java.util.regex.*;
-import java.io.IOException;
-
-import org.testng.annotations.Test;
+import org.testng.annotations.*;
import com.mongodb.util.*;
@@ -48,6 +44,25 @@ public void testBasic2(){
assert( ! a.equals( JSON.parse( "{ 'x' : 2 }" ) ) );
}
+
+ @Test(groups = {"basic"})
+ public void testBuilderIsEmpty(){
+ BasicDBObjectBuilder b = BasicDBObjectBuilder.start();
+ assert( b.isEmpty() );
+ b.append( "a" , 1 );
+ assert( !b.isEmpty() );
+ assert( b.get().equals( JSON.parse( "{ 'a' : 1 }" ) ) );
+ }
+
+ @Test(groups = {"basic"})
+ public void testBuilderNested(){
+ BasicDBObjectBuilder b = BasicDBObjectBuilder.start();
+ b.add( "a", 1 );
+ b.push( "b" ).append( "c", 2 ).pop();
+ DBObject a = b.get();
+ assert( a.equals( JSON.parse( "{ 'a' : 1, 'b' : { 'c' : 2 } }" ) ) );
+ }
+
@Test(groups = {"basic"})
public void testDown1(){
BasicDBObjectBuilder b = BasicDBObjectBuilder.start();
From 07dd5519c48a82f09e999348374cc720be41753b Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 20 Oct 2010 18:35:24 -0700
Subject: [PATCH 25/31] formatting changes for previous commit
---
src/main/com/mongodb/WriteConcern.java | 44 +++++++++++++-----------
src/test/com/mongodb/JavaClientTest.java | 16 ++++-----
2 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/src/main/com/mongodb/WriteConcern.java b/src/main/com/mongodb/WriteConcern.java
index 86ced5eefaa..8bd5287c2e9 100644
--- a/src/main/com/mongodb/WriteConcern.java
+++ b/src/main/com/mongodb/WriteConcern.java
@@ -59,30 +59,34 @@ public class WriteConcern {
public final static WriteConcern FSYNC_SAFE = new WriteConcern(true);
/** Exceptions are raised for network issues, and server errors; waits for at least 2 servers for the write operation*/
public final static WriteConcern REPLICAS_SAFE = new WriteConcern(2);
-
- //map of the constants from above for use by fromString
+
+ // map of the constants from above for use by fromString
private static Map _namedConcerns = null;
- /** Get the WriteConcern constants by name: NONE, NORMAL, SAFE, FSYNC_SAFE, REPLICA_SAFE. (matching is done case insensitively)*/
+ /**
+ * Get the WriteConcern constants by name: NONE, NORMAL, SAFE, FSYNC_SAFE,
+ * REPLICA_SAFE. (matching is done case insensitively)
+ */
public static WriteConcern valueOf(String name) {
- if (_namedConcerns == null) {
- HashMap newMap = new HashMap( 8 , 1 );
- for (Field f : WriteConcern.class.getFields())
- if (Modifier.isStatic( f.getModifiers() ) && f.getType().equals( WriteConcern.class )) {
- try {
- newMap.put( f.getName().toLowerCase(), (WriteConcern) f.get( null ) );
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- //Thought about doing a synchronize but this seems just as safe and I don't care about race conditions.
- _namedConcerns = newMap;
- }
-
- return _namedConcerns.get(name.toLowerCase());
+ if (_namedConcerns == null) {
+ HashMap newMap = new HashMap( 8 , 1 );
+ for (Field f : WriteConcern.class.getFields())
+ if (Modifier.isStatic( f.getModifiers() ) && f.getType().equals( WriteConcern.class )) {
+ try {
+ newMap.put( f.getName().toLowerCase(), (WriteConcern) f.get( null ) );
+ } catch (Exception e) {
+ throw new RuntimeException( e );
+ }
+ }
+
+ // Thought about doing a synchronize but this seems just as safe and
+ // I don't care about race conditions.
+ _namedConcerns = newMap;
+ }
+
+ return _namedConcerns.get( name.toLowerCase() );
}
-
+
public WriteConcern(){
this(0);
}
diff --git a/src/test/com/mongodb/JavaClientTest.java b/src/test/com/mongodb/JavaClientTest.java
index 465534995b8..7612fbefc50 100644
--- a/src/test/com/mongodb/JavaClientTest.java
+++ b/src/test/com/mongodb/JavaClientTest.java
@@ -635,15 +635,15 @@ public void testWriteResultMethodLevelWriteConcern(){
}
@Test
- public void testWriteConcernValueOf(){
- WriteConcern wc1 = WriteConcern.NORMAL;
- WriteConcern wc2 = WriteConcern.valueOf( "normal" );
- WriteConcern wc3 = WriteConcern.valueOf( "NORMAL" );
-
- assertEquals( wc1._w , wc2._w );
- assertEquals( wc1._w , wc3._w );
+ public void testWriteConcernValueOf() {
+ WriteConcern wc1 = WriteConcern.NORMAL;
+ WriteConcern wc2 = WriteConcern.valueOf( "normal" );
+ WriteConcern wc3 = WriteConcern.valueOf( "NORMAL" );
+
+ assertEquals( wc1._w, wc2._w );
+ assertEquals( wc1._w, wc3._w );
}
-
+
@Test
public void testFindAndModify(){
DBCollection c = _db.getCollection( "findandmodify" );
From 26acc0bd386ec5d023d5a91526b55805244cec18 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 20 Oct 2010 18:55:55 -0700
Subject: [PATCH 26/31] tab -> spaces
---
eclipse-java-code-formatters.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/eclipse-java-code-formatters.xml b/eclipse-java-code-formatters.xml
index dc6b047b014..382925cf11b 100755
--- a/eclipse-java-code-formatters.xml
+++ b/eclipse-java-code-formatters.xml
@@ -88,7 +88,7 @@
-
+
From e9939e283fcb0765f2ebd4893a9420c688108161 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Wed, 27 Oct 2010 14:32:31 -0700
Subject: [PATCH 27/31] updated mongo constructor javadocs
---
src/main/com/mongodb/Mongo.java | 64 ++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 20 deletions(-)
diff --git a/src/main/com/mongodb/Mongo.java b/src/main/com/mongodb/Mongo.java
index b9ebc92e903..cf89475bb29 100644
--- a/src/main/com/mongodb/Mongo.java
+++ b/src/main/com/mongodb/Mongo.java
@@ -82,7 +82,7 @@ public Mongo()
}
/**
- * Connects to the local mongo instance on default port.
+ * Connects to a (single) mongodb node (default port)
*
* @param host server to connect to
* @throws UnknownHostException if the database host cannot be resolved
@@ -93,11 +93,10 @@ public Mongo( String host )
}
/**
- * Connects to the local mongo instance on default port.
- *
- * @param host server to connect to
- * @param options options to use
- * @throws UnknownHostException if the database host cannot be resolved
+ * Connects to a (single) mongodb node (default port)
+ * @param host server to connect to
+ * @param options options to use
+ * @throws UnknownHostException if the database host cannot be resolved
*/
public Mongo( String host , MongoOptions options )
throws UnknownHostException , MongoException {
@@ -105,7 +104,7 @@ public Mongo( String host , MongoOptions options )
}
/**
- * Connects to Mongo using a given host, port, and database.
+ * Connects to a (single) mongodb node
* @param host the database's host address
* @param port the port on which the database is running
* @throws UnknownHostException if the database host cannot be resolved
@@ -116,8 +115,8 @@ public Mongo( String host , int port )
}
/**
- * Connects to Mongo using a given DBAddress
- * @see com.mongodb.DBAddress
+ * Connects to a (single) mongodb node
+ * @see com.mongodb.ServerAddress
* @param addr the database address
*/
public Mongo( ServerAddress addr )
@@ -127,8 +126,8 @@ public Mongo( ServerAddress addr )
/**
- * Connects to Mongo using a given DBAddress
- * @see com.mongodb.DBAddress
+ * Connects to a (single) mongo node using a given ServerAddress
+ * @see com.mongodb.ServerAddress
* @param addr the database address
*/
public Mongo( ServerAddress addr , MongoOptions options )
@@ -142,9 +141,13 @@ public Mongo( ServerAddress addr , MongoOptions options )
}
/**
- creates a Mongo connection in paired mode
- * @param left left side of the pair
- * @param right right side of the pair
+ * Creates a Mongo connection in paired mode.
This will also work for
+ * a replica set and will find all members (the master will be used by
+ * default).
+ *
+ * @see com.mongodb.ServerAddress
+ * @param left left side of the pair
+ * @param right right side of the pair
*/
public Mongo( ServerAddress left , ServerAddress right )
throws MongoException {
@@ -152,9 +155,13 @@ public Mongo( ServerAddress left , ServerAddress right )
}
/**
- creates a Mongo connection in paired mode
- * @param left left side of the pair
- * @param right right side of the pair
+ * Creates a Mongo connection in paired mode.
This will also work for
+ * a replica set and will find all members (the master will be used by
+ * default).
+ *
+ * @see com.mongodb.ServerAddress
+ * @param left left side of the pair
+ * @param right right side of the pair
*/
public Mongo( ServerAddress left , ServerAddress right , MongoOptions options )
throws MongoException {
@@ -167,7 +174,11 @@ public Mongo( ServerAddress left , ServerAddress right , MongoOptions options )
}
/**
- * creates a Mongo connection to a replica set
+ * Creates a Mongo connection.
This will work for
+ * a replica set, or pair, and will find all members (the master will be used by
+ * default).
+ *
+ * @see com.mongodb.ServerAddress
* @pair replicaSetSeeds put as many servers as you can in the list.
* the system will figure the rest out
*/
@@ -177,8 +188,12 @@ public Mongo( List replicaSetSeeds )
}
/**
- * creates a Mongo connection to a replica set
- * @pair replicaSetSeeds put as many servers as you can in the list.
+ * Creates a Mongo connection.
This will work for
+ * a replica set, or pair, and will find all members (the master will be used by
+ * default).
+ *
+ * @see com.mongodb.ServerAddress
+ * @param replicaSetSeeds put as many servers as you can in the list.
* the system will figure the rest out
*/
public Mongo( List replicaSetSeeds , MongoOptions options )
@@ -191,6 +206,15 @@ public Mongo( List replicaSetSeeds , MongoOptions options )
_connector.checkMaster( true , false );
}
+ /**
+ * Creates a Mongo connection. If only one address is used it will only connect to that node, otherwise it will discover all nodes.
+ * @see MongoURI
+ * examples:
+ *
mongodb://localhost
+ * mongodb://fred:foobar@localhost/
+ *
+ * @dochub connections
+ */
public Mongo( MongoURI uri )
throws MongoException , UnknownHostException {
From 2b1e3c598abe15ad3438e943df6cb24cf4d545c3 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Fri, 29 Oct 2010 10:30:31 -0700
Subject: [PATCH 28/31] DBCollection.setObjectClass bug; JAVA-206
---
src/main/com/mongodb/DBCollection.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index 84bcc99ea69..3b0cceb3c51 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -908,11 +908,14 @@ public String toString(){
return _name;
}
- /** Set a default class for objects in this collection
+ /** Set a default class for objects in this collection; null resets the class to nothing.
* @param c the class
* @throws IllegalArgumentException if c
is not a DBObject
*/
public void setObjectClass( Class c ){
+ if ( c == null )
+ _wrapper = null;
+
if ( ! DBObject.class.isAssignableFrom( c ) )
throw new IllegalArgumentException( c.getName() + " is not a DBObject" );
_objectClass = c;
From 019b26532bc8f643da6ec0a6cdb8386e02682dc6 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Sun, 28 Nov 2010 20:03:17 -0800
Subject: [PATCH 29/31] helper methods
---
src/main/com/mongodb/BasicDBObject.java | 4 ++++
src/main/org/bson/BasicBSONObject.java | 10 ++++++++++
2 files changed, 14 insertions(+)
diff --git a/src/main/com/mongodb/BasicDBObject.java b/src/main/com/mongodb/BasicDBObject.java
index 9fca85331de..6100429bc74 100644
--- a/src/main/com/mongodb/BasicDBObject.java
+++ b/src/main/com/mongodb/BasicDBObject.java
@@ -90,4 +90,8 @@ public BasicDBObject append( String key , Object val ){
private boolean _isPartialObject = false;
+
+ public BasicDBObject getObj(String key) {
+ return (BasicDBObject) super.getObj( key );
+ }
}
diff --git a/src/main/org/bson/BasicBSONObject.java b/src/main/org/bson/BasicBSONObject.java
index eca918fca32..44d5475b47a 100644
--- a/src/main/org/bson/BasicBSONObject.java
+++ b/src/main/org/bson/BasicBSONObject.java
@@ -108,6 +108,16 @@ public int getInt( String key ){
return BSON.toInt( o );
}
+ /** Returns the value of a field as a BSONObject
.
+ * @param key the field to look for
+ * @return the field value cast to a BSONObject
.
+ */
+ public BSONObject getObj( String key ){
+ Object foo = get( key );
+ return (BSONObject) foo ;
+ }
+
+
/** Returns the value of a field as an int
.
* @param key the field to look for
* @param def the default to return
From 66fee89b78214add73f0b94cd6495fc2afac0a58 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Tue, 30 Nov 2010 15:09:00 -0800
Subject: [PATCH 30/31] now handles primitive arrays as well
---
src/main/com/mongodb/util/JSON.java | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/main/com/mongodb/util/JSON.java b/src/main/com/mongodb/util/JSON.java
index ea831119aea..0674a3b039c 100644
--- a/src/main/com/mongodb/util/JSON.java
+++ b/src/main/com/mongodb/util/JSON.java
@@ -2,6 +2,7 @@
package com.mongodb.util;
+import java.lang.reflect.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;
@@ -166,13 +167,11 @@ public static void serialize( Object o , StringBuilder buf ){
}
if ( o.getClass().isArray() ){
- Object[] arr = (Object[])o;
-
buf.append( "[ " );
- for ( int i=0; i 0 ) buf.append( " , " );
- serialize( arr[i] , buf );
+ serialize( Array.get( o , i ) , buf );
}
buf.append( "]" );
From cbbf165c83f3df4577ddefb637b11face65fb855 Mon Sep 17 00:00:00 2001
From: Scott Hernandez
Date: Thu, 3 Feb 2011 14:16:06 -0800
Subject: [PATCH 31/31] Deprecate getCount methods JAVA-264
---
src/main/com/mongodb/DBCollection.java | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/src/main/com/mongodb/DBCollection.java b/src/main/com/mongodb/DBCollection.java
index 2ddfe643261..ae447bacb88 100644
--- a/src/main/com/mongodb/DBCollection.java
+++ b/src/main/com/mongodb/DBCollection.java
@@ -700,9 +700,27 @@ public long count()
* @return
* @throws MongoException
*/
- public long count(DBObject query)
+ public long count(DBObject query)
throws MongoException {
- return getCount(query, null);
+ BasicDBObject cmd = new BasicDBObject();
+ cmd.put( "count", getName() );
+ cmd.put( "query", query );
+
+ CommandResult res = _db.command( cmd, getOptions() );
+
+ if ( ! res.ok() ){
+ String errmsg = res.getErrorMessage();
+
+ if ( errmsg.equals("ns does not exist") ||
+ errmsg.equals("ns missing" ) ){
+ // for now, return 0 - lets pretend it does exist
+ return 0;
+ }
+
+ throw new MongoException( "error counting : " + res );
+ }
+
+ return res.getLong("n");
}
@@ -711,6 +729,7 @@ public long count(DBObject query)
* @return number of documents that match query
* @throws MongoException
*/
+ @Deprecated
public long getCount()
throws MongoException {
return getCount(new BasicDBObject(), null);
@@ -722,6 +741,7 @@ public long getCount()
* @return
* @throws MongoException
*/
+ @Deprecated
public long getCount(DBObject query)
throws MongoException {
return getCount(query, null);
@@ -734,6 +754,7 @@ public long getCount(DBObject query)
* @return
* @throws MongoException
*/
+ @Deprecated
public long getCount(DBObject query, DBObject fields)
throws MongoException {
return getCount( query , fields , 0 , 0 );
@@ -750,6 +771,7 @@ public long getCount(DBObject query, DBObject fields)
* @return number of documents that match query and fields
* @throws MongoException
*/
+ @Deprecated
public long getCount(DBObject query, DBObject fields, long limit, long skip )
throws MongoException {