DATAMONGO-471 - Add support for $each when using $addToSet.

Additionally to Update.addToSet(String, Object) the method 'addToSet(String)' has been introduced, returning a builder to allow the creation of $addToSet command for either single value, or multiple values using $each.

Using value:
new Update().addToSet("key").value("spring");

Using each:
new Update().addToSet("key").each("spring", "data", "mongodb");

Original Pull Request: #157.
This commit is contained in:
Christoph Strobl
2014-03-27 09:51:15 +01:00
committed by Oliver Gierke
parent 2cfd4781bc
commit 5e43f5846a
3 changed files with 115 additions and 1 deletions

View File

@@ -196,6 +196,18 @@ public class Update {
return this;
}
/**
* Update using {@code $addToSet} modifier. <br/>
* Allows creation of {@code $push} command for single or multiple (using {@code $each}) values
*
* @param key
* @return
* @since 1.5
*/
public AddToSetBuilder addToSet(String key) {
return new AddToSetBuilder(key);
}
/**
* Update using the {@literal $addToSet} update modifier
*
@@ -408,7 +420,7 @@ public class Update {
/**
* Builder for creating {@code $push} modifiers
*
* @author Christop Strobl
* @author Christoph Strobl
*/
public class PushOperatorBuilder {
@@ -442,4 +454,41 @@ public class Update {
return Update.this.push(key, value);
}
}
/**
* Builder for creating {@code $addToSet} modifier.
*
* @author Christoph Strobl
* @since 1.5
*/
public class AddToSetBuilder {
private final String key;
public AddToSetBuilder(String key) {
this.key = key;
}
/**
* Propagates {@code $each} to {@code $addToSet}
*
* @param values
* @return
*/
public Update each(Object... values) {
return Update.this.addToSet(this.key, new Each(values));
}
/**
* Propagates {@link #value(Object)} to {@code $addToSet}
*
* @param values
* @return
*/
public Update value(Object value) {
return Update.this.addToSet(this.key, value);
}
}
}

View File

@@ -2580,6 +2580,25 @@ public class MongoTemplateTests {
assertThat(savedTmpl.getContent().getText(), is(nullValue()));
}
/**
* @see DATAMONGO-471
*/
@Test
public void updateMultiShouldAddValuesCorrectlyWhenUsingAddToSetWithEach() {
DocumentWithCollectionOfSimpleType document = new DocumentWithCollectionOfSimpleType();
document.values = Arrays.asList("spring");
template.save(document);
Query query = query(where("id").is(document.id));
assumeThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(1));
Update update = new Update().addToSet("values").each("data", "mongodb");
template.updateMulti(query, update, DocumentWithCollectionOfSimpleType.class);
assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3));
}
static class DocumentWithDBRefCollection {
@Id public String id;

View File

@@ -412,6 +412,46 @@ public class UpdateMapperUnitTests {
assertThat(inClause, IsIterableContainingInOrder.<Object> contains(1L, 2L));
}
/**
* @see DATAMONG0-471
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testUpdateShouldApply$addToSetCorrectlyWhenUsedWith$each() {
Update update = new Update().addToSet("values").each("spring", "data", "mongodb");
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
context.getPersistentEntity(ListModel.class));
DBObject addToSet = getAsDBObject(mappedObject, "$addToSet");
DBObject values = getAsDBObject(addToSet, "values");
BasicDBList each = getAsDBList(values, "$each");
assertThat(each.toMap(), (Matcher) allOf(hasValue("spring"), hasValue("data"), hasValue("mongodb")));
}
/**
* @see DATAMONG0-471
*/
@Test
public void testUpdateShouldRetainClassTypeInformationWhenUsing$addToSetWith$eachForCustomTypes() {
Update update = new Update().addToSet("models").each(new ModelImpl(2014), new ModelImpl(1), new ModelImpl(28));
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
context.getPersistentEntity(ModelWrapper.class));
DBObject addToSet = getAsDBObject(mappedObject, "$addToSet");
DBObject values = getAsDBObject(addToSet, "models");
BasicDBList each = getAsDBList(values, "$each");
for (Object updateValue : each) {
assertThat(((DBObject) updateValue).get("_class").toString(),
equalTo("org.springframework.data.mongodb.core.convert.UpdateMapperUnitTests$ModelImpl"));
}
}
static interface Model {}
static class ModelImpl implements Model {
@@ -425,6 +465,12 @@ public class UpdateMapperUnitTests {
public class ModelWrapper {
Model model;
public ModelWrapper() {}
public ModelWrapper(Model model) {
this.model = model;
}
}
static class ListModelWrapper {