diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java new file mode 100644 index 000000000..79abd57cc --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2011 the original author or authors. + * + * 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 org.springframework.data.mongodb.core; + +public class FindAndModifyOptions { + + boolean returnNew; + + boolean upsert; + + boolean remove; + + /** + * Static factory method to create a FindAndModifyOptions instance + * + * @return a new instance + */ + public static FindAndModifyOptions options() { + return new FindAndModifyOptions(); + } + + public FindAndModifyOptions returnNew(boolean returnNew) { + this.returnNew = returnNew; + return this; + } + + public FindAndModifyOptions upsert(boolean upsert) { + this.upsert = upsert; + return this; + } + + public FindAndModifyOptions remove(boolean remove) { + this.remove = remove; + return this; + } + + public boolean isReturnNew() { + return returnNew; + } + + public boolean isUpsert() { + return upsert; + } + + public boolean isRemove() { + return remove; + } + + + +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index f991b65b1..a13ef6350 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -495,6 +495,13 @@ public interface MongoOperations { */ T findById(Object id, Class entityClass, String collectionName); + T findAndModify(Query query, Update update, Class entityClass); + + T findAndModify(Query query, Update update, Class entityClass, String collectionName); + + T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass); + + T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass, String collectionName); /** * Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the * specified type. The first document that matches the query is returned and also removed from the collection in the diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index d23b1152c..a6dbed911 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -522,6 +522,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return new GeoResults(result, new Distance(averageDistance, near.getMetric())); } + public T findAndModify(Query query, Update update, Class entityClass) { + // TODO Auto-generated method stub + return null; + } + + public T findAndModify(Query query, Update update, Class entityClass, String collectionName) { + // TODO Auto-generated method stub + return null; + } + + public T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass) { + // TODO Auto-generated method stub + return null; + } + + public T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass, + String collectionName) { + return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(), + entityClass, update, options); + } + // Find methods that take a Query to express the query and that return a single object that is also removed from the // collection in the database. @@ -1276,6 +1297,29 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return executeFindOneInternal(new FindAndRemoveCallback(mapper.getMappedObject(query, entity), fields, sort), new ReadDbObjectCallback(readerToUse, entityClass), collectionName); } + + protected T doFindAndModify(String collectionName, DBObject query, DBObject fields, DBObject sort, + Class entityClass, Update update, FindAndModifyOptions options ) { + + EntityReader readerToUse = this.mongoConverter; + + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); + + DBObject updateObj = update.getUpdateObject(); + for (String key : updateObj.keySet()) { + updateObj.put(key, mongoConverter.convertToMongoType(updateObj.get(key))); + } + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("findAndModify using query: " + query + " fields: " + fields + " sort: " + sort + " for class: " + + entityClass + " and update: " + updateObj + " in collection: " + collectionName); + } + + + return executeFindOneInternal(new FindAndModifyCallback(mapper.getMappedObject(query, entity), fields, sort, updateObj, options), + new ReadDbObjectCallback(readerToUse, entityClass), collectionName); + } + /** * Populates the id property of the saved object, if it's not set already. @@ -1566,6 +1610,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return collection.findAndModify(query, fields, sort, true, null, false, false); } } + + private static class FindAndModifyCallback implements CollectionCallback { + + private final DBObject query; + private final DBObject fields; + private final DBObject sort; + private final DBObject update; + private final FindAndModifyOptions options; + + public FindAndModifyCallback(DBObject query, DBObject fields, DBObject sort, DBObject update, FindAndModifyOptions options) { + this.query = query; + this.fields = fields; + this.sort = sort; + this.update = update; + this.options = options; + } + + public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException { + return collection.findAndModify(query, fields, sort, options.isRemove(), update, options.isReturnNew(), options.isUpsert()); + } + } /** * Simple internal callback to allow operations on a {@link DBObject}. @@ -1649,4 +1714,5 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return new GeoResult(doWith, new Distance(distance, metric)); } } + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java index 92b099224..ac736fbc9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapreduce/MapReduceOptions.java @@ -44,10 +44,9 @@ public class MapReduceOptions { /** - * Static factory method to create a Criteria using the provided key + * Static factory method to create a MapReduceOptions instance * - * @param key - * @return + * @return a new instance */ public static MapReduceOptions options() { return new MapReduceOptions();