/*
* Copyright 2011 VZ Netzwerke Ltd
*
* 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 net.vz.mongodb.jackson;
import java.util.ArrayList;
import java.util.List;
import com.mongodb.CommandResult;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import net.vz.mongodb.jackson.internal.stream.JacksonDBObject;
/**
* 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 do the getlasterror call.
* if another operation has been done on this connection in the interim, calls will fail
*
* This class also gives you access to the saved objects, for the purposes of finding out the objects ids, if they were
* generated by MongoDB.
*
* @author James Roper
* @since 1.0
*/
public class WriteResult<T, K> {
private final JacksonDBCollection<T, K> jacksonDBCollection;
private final DBObject[] dbObjects;
private final com.mongodb.WriteResult writeResult;
private List<T> objects;
protected WriteResult(JacksonDBCollection<T, K> jacksonDBCollection, com.mongodb.WriteResult writeResult, DBObject... dbObjects) {
this.jacksonDBCollection = jacksonDBCollection;
this.writeResult = writeResult;
this.dbObjects = dbObjects;
}
/**
* Get the object that was saved. This will contain the updated ID if the ID was generated.
* <p/>
* Note, this operation is a little expensive because it has to deserialise the object. If you just want the ID,
* call getSavedId() instead.
*
* @return The saved object
* @throws MongoException If no objects were saved
*/
public T getSavedObject() {
if (dbObjects.length == 0) {
throw new MongoException("No objects to return");
}
return getSavedObjects().get(0);
}
/**
* Get the objects that were saved. These will contain the updated IDs if the IDs were generated.
* <p/>
* This operation only works if object serialization is used. If stream serialization is used, the IDs are
* generated by the database, and cannot be known.
* <p/>
* Note, this operation is a little expensive because it has to deserialise the objects. If you just want the IDs,
* call getSavedIds() instead.
*
* @return The saved objects
*/
public List<T> getSavedObjects() {
// Lazily generate the object, in case it's not needed.
if (objects == null) {
if (dbObjects.length > 0) {
if (dbObjects[0] instanceof JacksonDBObject) {
throw new UnsupportedOperationException("Saved object retrieval not supported when using stream serialization");
}
}
objects = jacksonDBCollection.convertFromDbObjects(dbObjects);
}
return objects;
}
/**
* Get the saved ID. This may be useful for finding out the ID that was generated by MongoDB if no ID was supplied.
*
* @return The saved ID
* @throws MongoException If no objects were saved
*/
public K getSavedId() {
if (dbObjects.length == 0) {
throw new MongoException("No objects to return");
}
if (dbObjects[0] instanceof JacksonDBObject) {
throw new UnsupportedOperationException("Generated _id retrieval not supported when using stream serialization");
}
return jacksonDBCollection.convertFromDbId(dbObjects[0].get("_id"));
}
/**
* Get the saved IDs. This may be useful for finding out the IDs that were generated by MongoDB if no IDs were
* supplied.
*
* @return The saved IDs
*/
public List<K> getSavedIds() {
if (dbObjects.length > 0 && dbObjects[0] instanceof JacksonDBObject) {
throw new UnsupportedOperationException("Generated _id retrieval not supported when using stream serialization");
}
List<K> ids = new ArrayList<K>();
for (int i = 0; i < dbObjects.length; i++) {
ids.add((K) jacksonDBCollection.convertFromDbId(dbObjects[i].get("_id")));
}
return ids;
}
/**
* Get the underlying DBObject that was serialised before it was saved. This will contain the updated ID if an
* ID was generated.
*
* @return The underlying DBObject
* @throws MongoException If no objects were saved
*/
public DBObject getDbObject() {
if (dbObjects.length == 0) {
throw new MongoException("No objects to return");
}
return dbObjects[0];
}
/**
* Get the underlying DBObjects that were serialised before they were saved. These will contain the updated IDs if
* IDs were generated.
*
* @return The underlying DBObjects
*/
public DBObject[] getDbObjects() {
return dbObjects;
}
/**
* The underlying write result
*
* @return Get the underlying MongoDB write result
*/
public com.mongodb.WriteResult getWriteResult() {
return writeResult;
}
/**
* Gets the last result from getLastError()
*
* @return The last error
*/
public CommandResult getCachedLastError() {
return writeResult.getCachedLastError();
}
/**
* Gets the last {@link com.mongodb.WriteConcern} used when calling getLastError()
*
* @return The last write concern.
*/
public WriteConcern getLastConcern() {
return writeResult.getLastConcern();
}
/**
* calls {@link WriteResult#getLastError(com.mongodb.WriteConcern)} with concern=null
*
* @return The last error
*/
public synchronized CommandResult getLastError() {
return writeResult.getLastError();
}
/**
* This method does following:
* - returns the existing CommandResult if concern is null or less strict than the concern it was obtained with
* - otherwise attempts to obtain a CommandResult by calling getLastError with the concern
*
* @param concern the concern
* @return The last error for the concern
*/
public synchronized CommandResult getLastError(WriteConcern concern) {
return writeResult.getLastError(concern);
}
/**
* Gets the error String ("err" field)
*
* @return The error string
*/
public String getError() {
return writeResult.getError();
}
/**
* Gets the "n" field, which contains the number of documents
* affected in the write operation.
*
* @return The n field
*/
public int getN() {
return writeResult.getN();
}
/**
* Gets a field
*
* @param name field name
* @return The value
*/
public Object getField(String name) {
return writeResult.getField(name);
}
/**
* Returns whether or not the result is lazy, meaning that getLastError was not called automatically
*
* @return if it's lazy
*/
public boolean isLazy() {
return writeResult.isLazy();
}
@Override
public String toString() {
return writeResult.toString();
}
}