Skip to content

Commit e33ca0c

Browse files
committed
JAVA-2254: Change toCollection methods to asynchronous AggregateIterable and MapReduceIterable interfaces to throw IllegalStateException instead of IllegalArgumentExce
Useful for clients who just want to write the results to a collection but do not need to iterate over them.
1 parent 2ffc7c8 commit e33ca0c

12 files changed

+124
-35
lines changed

driver-async/src/main/com/mongodb/async/client/AggregateIterable.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public interface AggregateIterable<TResult> extends MongoIterable<TResult> {
6363
* Aggregates documents according to the specified aggregation pipeline, which must end with a $out stage.
6464
*
6565
* @param callback the callback, which is called when the aggregation completes
66+
* @throws IllegalStateException if the pipeline does not end with a $out stage
6667
* @mongodb.driver.manual aggregation/ Aggregation
6768
*/
6869
void toCollection(SingleResultCallback<Void> callback);

driver-async/src/main/com/mongodb/async/client/AggregateIterableImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void toCollection(final SingleResultCallback<Void> callback) {
107107
BsonValue outCollection = getAggregateOutCollection(aggregateList);
108108

109109
if (outCollection == null) {
110-
throw new IllegalArgumentException("The last stage of the aggregation pipeline must be $out");
110+
throw new IllegalStateException("The last stage of the aggregation pipeline must be $out");
111111
}
112112

113113
executor.execute(new AggregateToCollectionOperation(namespace, aggregateList, writeConcern)

driver-async/src/main/com/mongodb/async/client/MapReduceIterable.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ public interface MapReduceIterable<TResult> extends MongoIterable<TResult> {
190190
* non-inline result.
191191
*
192192
* @param callback the callback, which is called when the aggregation completes
193+
* @throws IllegalStateException if a collection name to write the results to has not been specified
194+
* @see #collectionName(String)
193195
* @mongodb.driver.manual aggregation/ Aggregation
194196
*/
195197
void toCollection(SingleResultCallback<Void> callback);

driver-async/src/main/com/mongodb/async/client/MapReduceIterableImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public MapReduceIterable<TResult> collation(final Collation collation) {
192192
public void toCollection(final SingleResultCallback<Void> callback) {
193193
notNull("callback", callback);
194194
if (inline) {
195-
throw new IllegalArgumentException("The options must specify a non-inline result");
195+
throw new IllegalStateException("The options must specify a non-inline result");
196196
}
197197
executor.execute(createMapReduceToCollectionOperation(),
198198
new SingleResultCallback<MapReduceStatistics>() {

driver-async/src/test/unit/com/mongodb/async/client/AggregateIterableSpecification.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,11 @@ class AggregateIterableSpecification extends Specification {
164164
then: 'the future should handle the exception'
165165
thrown(MongoException)
166166

167-
when: 'toCollection should throw IllegalArgumentException when last state is not $out'
167+
when: 'toCollection should throw IllegalStateException when last state is not $out'
168168
aggregationIterable.toCollection(new FutureResultCallback())
169169

170170
then:
171-
thrown(IllegalArgumentException)
171+
thrown(IllegalStateException)
172172

173173
when: 'a codec is missing'
174174
futureResultCallback = new FutureResultCallback<List<BsonDocument>>()

driver-async/src/test/unit/com/mongodb/async/client/MapReduceIterableSpecification.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,11 @@ class MapReduceIterableSpecification extends Specification {
193193
then: 'the future should handle the exception'
194194
thrown(MongoException)
195195

196-
when: 'toCollection should throw IllegalArgumentException its inline'
196+
when: 'toCollection should throw IllegalStateException its inline'
197197
mapReduceIterable.toCollection(new FutureResultCallback())
198198

199199
then:
200-
thrown(IllegalArgumentException)
200+
thrown(IllegalStateException)
201201

202202
when: 'a codec is missing'
203203
futureResultCallback = new FutureResultCallback<List<BsonDocument>>()

driver/src/main/com/mongodb/AggregateIterableImpl.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ class AggregateIterableImpl<TDocument, TResult> implements AggregateIterable<TRe
7070
this.pipeline = notNull("pipeline", pipeline);
7171
}
7272

73+
@Override
74+
public void toCollection() {
75+
List<BsonDocument> aggregateList = createBsonDocumentList(pipeline);
76+
77+
if (getOutCollection(aggregateList) == null) {
78+
throw new IllegalStateException("The last stage of the aggregation pipeline must be $out");
79+
}
80+
81+
executor.execute(createAggregateToCollectionOperation(aggregateList));
82+
}
83+
7384
@Override
7485
public AggregateIterable<TResult> allowDiskUse(final Boolean allowDiskUse) {
7586
this.allowDiskUse = allowDiskUse;
@@ -135,15 +146,10 @@ public <A extends Collection<? super TResult>> A into(final A target) {
135146
private MongoIterable<TResult> execute() {
136147
List<BsonDocument> aggregateList = createBsonDocumentList(pipeline);
137148

138-
BsonValue outCollection = aggregateList.size() == 0 ? null : aggregateList.get(aggregateList.size() - 1).get("$out");
149+
BsonValue outCollection = getOutCollection(aggregateList);
139150

140151
if (outCollection != null) {
141-
AggregateToCollectionOperation operation = new AggregateToCollectionOperation(namespace, aggregateList, writeConcern)
142-
.maxTime(maxTimeMS, MILLISECONDS)
143-
.allowDiskUse(allowDiskUse)
144-
.bypassDocumentValidation(bypassDocumentValidation)
145-
.collation(collation);
146-
executor.execute(operation);
152+
executor.execute(createAggregateToCollectionOperation(aggregateList));
147153
FindIterable<TResult> findOperation = new FindIterableImpl<TDocument, TResult>(new MongoNamespace(namespace.getDatabaseName(),
148154
outCollection.asString().getValue()), documentClass, resultClass, codecRegistry, readPreference, readConcern, executor,
149155
new BsonDocument(), new FindOptions().collation(collation));
@@ -163,6 +169,19 @@ private MongoIterable<TResult> execute() {
163169
}
164170
}
165171

172+
173+
private BsonValue getOutCollection(final List<BsonDocument> aggregateList) {
174+
return aggregateList.size() == 0 ? null : aggregateList.get(aggregateList.size() - 1).get("$out");
175+
}
176+
177+
private AggregateToCollectionOperation createAggregateToCollectionOperation(final List<BsonDocument> aggregateList) {
178+
return new AggregateToCollectionOperation(namespace, aggregateList, writeConcern)
179+
.maxTime(maxTimeMS, MILLISECONDS)
180+
.allowDiskUse(allowDiskUse)
181+
.bypassDocumentValidation(bypassDocumentValidation)
182+
.collation(collation);
183+
}
184+
166185
private List<BsonDocument> createBsonDocumentList(final List<? extends Bson> pipeline) {
167186
List<BsonDocument> aggregateList = new ArrayList<BsonDocument>(pipeline.size());
168187
for (Bson obj : pipeline) {

driver/src/main/com/mongodb/MapReduceIterableImpl.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ class MapReduceIterableImpl<TDocument, TResult> implements MapReduceIterable<TRe
8383
this.reduceFunction = notNull("reduceFunction", reduceFunction);
8484
}
8585

86+
@Override
87+
public void toCollection() {
88+
if (inline) {
89+
throw new IllegalStateException("The options must specify a non-inline result");
90+
}
91+
92+
executor.execute(createMapReduceToCollectionOperation());
93+
}
94+
8695
@Override
8796
public MapReduceIterable<TResult> collectionName(final String collectionName) {
8897
this.collectionName = notNull("collectionName", collectionName);
@@ -227,27 +236,7 @@ MongoIterable<TResult> execute() {
227236
}
228237
return new OperationIterable<TResult>(operation, readPreference, executor);
229238
} else {
230-
MapReduceToCollectionOperation operation =
231-
new MapReduceToCollectionOperation(namespace, new BsonJavaScript(mapFunction), new BsonJavaScript(reduceFunction),
232-
collectionName, writeConcern)
233-
.filter(toBsonDocument(filter))
234-
.limit(limit)
235-
.maxTime(maxTimeMS, MILLISECONDS)
236-
.jsMode(jsMode)
237-
.scope(toBsonDocument(scope))
238-
.sort(toBsonDocument(sort))
239-
.verbose(verbose)
240-
.action(action.getValue())
241-
.nonAtomic(nonAtomic)
242-
.sharded(sharded)
243-
.databaseName(databaseName)
244-
.bypassDocumentValidation(bypassDocumentValidation)
245-
.collation(collation);
246-
247-
if (finalizeFunction != null) {
248-
operation.finalizeFunction(new BsonJavaScript(finalizeFunction));
249-
}
250-
executor.execute(operation);
239+
executor.execute(createMapReduceToCollectionOperation());
251240

252241
String dbName = databaseName != null ? databaseName : namespace.getDatabaseName();
253242
return new FindIterableImpl<TDocument, TResult>(new MongoNamespace(dbName, collectionName), documentClass, resultClass,
@@ -256,6 +245,30 @@ codecRegistry, primary(), readConcern, executor, new BsonDocument(),
256245
}
257246
}
258247

248+
private MapReduceToCollectionOperation createMapReduceToCollectionOperation() {
249+
MapReduceToCollectionOperation operation =
250+
new MapReduceToCollectionOperation(namespace, new BsonJavaScript(mapFunction), new BsonJavaScript(reduceFunction),
251+
collectionName, writeConcern)
252+
.filter(toBsonDocument(filter))
253+
.limit(limit)
254+
.maxTime(maxTimeMS, MILLISECONDS)
255+
.jsMode(jsMode)
256+
.scope(toBsonDocument(scope))
257+
.sort(toBsonDocument(sort))
258+
.verbose(verbose)
259+
.action(action.getValue())
260+
.nonAtomic(nonAtomic)
261+
.sharded(sharded)
262+
.databaseName(databaseName)
263+
.bypassDocumentValidation(bypassDocumentValidation)
264+
.collation(collation);
265+
266+
if (finalizeFunction != null) {
267+
operation.finalizeFunction(new BsonJavaScript(finalizeFunction));
268+
}
269+
return operation;
270+
}
271+
259272
private BsonDocument toBsonDocument(final Bson document) {
260273
return document == null ? null : document.toBsonDocument(documentClass, codecRegistry);
261274
}

driver/src/main/com/mongodb/client/AggregateIterable.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,20 @@
2424
* Iterable for aggregate.
2525
*
2626
* @param <TResult> The type of the result.
27+
* @mongodb.driver.manual reference/command/aggregate/ Aggregation
2728
* @since 3.0
2829
*/
2930
public interface AggregateIterable<TResult> extends MongoIterable<TResult> {
3031

32+
/**
33+
* Aggregates documents according to the specified aggregation pipeline, which must end with a $out stage.
34+
*
35+
* @throws IllegalStateException if the pipeline does not end with a $out stage
36+
* @mongodb.driver.manual reference/operator/aggregation/out/ $out stage
37+
* @since 3.4
38+
*/
39+
void toCollection();
40+
3141
/**
3242
* Enables writing to temporary files. A null value indicates that it's unspecified.
3343
*

driver/src/main/com/mongodb/client/MapReduceIterable.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@
3333
*/
3434
public interface MapReduceIterable<TResult> extends MongoIterable<TResult> {
3535

36+
/**
37+
* Aggregates documents to a collection according to the specified map-reduce function with the given options, which must specify a
38+
* non-inline result.
39+
*
40+
* @throws IllegalStateException if a collection name to write the results to has not been specified
41+
* @see #collectionName(String)
42+
* @since 3.4
43+
*/
44+
void toCollection();
45+
3646
/**
3747
* Sets the collectionName for the output of the MapReduce
3848
*

0 commit comments

Comments
 (0)