Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
GroupBy |
|
| 1.0689655172413792;1.069 | ||||
GroupBy$Builder |
|
| 1.0689655172413792;1.069 |
1 | /* | |
2 | * #%L | |
3 | * GroupBy.java - mongodb-async-driver - Allanbank Consulting, Inc. | |
4 | * %% | |
5 | * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc. | |
6 | * %% | |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
8 | * you may not use this file except in compliance with the License. | |
9 | * You may obtain a copy of the License at | |
10 | * | |
11 | * http://www.apache.org/licenses/LICENSE-2.0 | |
12 | * | |
13 | * Unless required by applicable law or agreed to in writing, software | |
14 | * distributed under the License is distributed on an "AS IS" BASIS, | |
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
16 | * See the License for the specific language governing permissions and | |
17 | * limitations under the License. | |
18 | * #L% | |
19 | */ | |
20 | ||
21 | package com.allanbank.mongodb.builder; | |
22 | ||
23 | import static com.allanbank.mongodb.util.Assertions.assertThat; | |
24 | ||
25 | import java.util.Collections; | |
26 | import java.util.HashSet; | |
27 | import java.util.Set; | |
28 | import java.util.concurrent.TimeUnit; | |
29 | ||
30 | import com.allanbank.mongodb.MongoCollection; | |
31 | import com.allanbank.mongodb.ReadPreference; | |
32 | import com.allanbank.mongodb.Version; | |
33 | import com.allanbank.mongodb.bson.Document; | |
34 | import com.allanbank.mongodb.bson.DocumentAssignable; | |
35 | ||
36 | /** | |
37 | * Group provides a container for all of the options to a <tt>group</tt> | |
38 | * command. A {@link Builder} is provided to assist in creating a | |
39 | * {@link GroupBy}. | |
40 | * | |
41 | * @api.yes This class is part of the driver's API. Public and protected members | |
42 | * will be deprecated for at least 1 non-bugfix release (version | |
43 | * numbers are <major>.<minor>.<bugfix>) before being | |
44 | * removed or modified. | |
45 | * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved | |
46 | */ | |
47 | public class GroupBy { | |
48 | /** | |
49 | * The first version of MongoDB to support the {@code group} command with | |
50 | * the ability to limit the execution time on the server. | |
51 | */ | |
52 | 1 | public static final Version MAX_TIMEOUT_VERSION = Find.MAX_TIMEOUT_VERSION; |
53 | ||
54 | /** | |
55 | * Creates a new builder for a {@link GroupBy}. | |
56 | * | |
57 | * @return The builder to construct a {@link GroupBy}. | |
58 | */ | |
59 | public static Builder builder() { | |
60 | 4 | return new Builder(); |
61 | } | |
62 | ||
63 | /** The finalizer function to run for each group. */ | |
64 | private final String myFinalizeFunction; | |
65 | ||
66 | /** The initial value for each group. */ | |
67 | private final Document myInitialValue; | |
68 | ||
69 | /** | |
70 | * Function to return the key for a document. Used instead of the | |
71 | * {@link #getKeys} to dynamically determine the group for each document. | |
72 | */ | |
73 | private final String myKeyFunction; | |
74 | ||
75 | /** The fields to group by. */ | |
76 | private final Set<String> myKeys; | |
77 | ||
78 | /** The maximum amount of time to allow the command to run. */ | |
79 | private final long myMaximumTimeMilliseconds; | |
80 | ||
81 | /** The query to select the documents to run the group against. */ | |
82 | private final Document myQuery; | |
83 | ||
84 | /** The read preference to use. */ | |
85 | private final ReadPreference myReadPreference; | |
86 | ||
87 | /** | |
88 | * The reduce function taking the previous value and the current value and | |
89 | * returning the new reduced value. | |
90 | */ | |
91 | private final String myReduceFunction; | |
92 | ||
93 | /** | |
94 | * Creates a new GroupBy. | |
95 | * | |
96 | * @param builder | |
97 | * The builder to copy the state from. | |
98 | * @throws IllegalArgumentException | |
99 | * If neither the {@link #getKeys() keys} nor | |
100 | * {@link #getKeyFunction() key function} have been set. | |
101 | */ | |
102 | 19 | protected GroupBy(final Builder builder) throws IllegalArgumentException { |
103 | 19 | assertThat( |
104 | !builder.myKeys.isEmpty() || (builder.myKeyFunction != null), | |
105 | "Must specify either a set of keys for the groupBy or a key function."); | |
106 | ||
107 | 17 | myKeys = Collections |
108 | .unmodifiableSet(new HashSet<String>(builder.myKeys)); | |
109 | 17 | myReduceFunction = builder.myReduceFunction; |
110 | 17 | myInitialValue = builder.myInitialValue; |
111 | 17 | myKeyFunction = builder.myKeyFunction; |
112 | 17 | myQuery = builder.myQuery; |
113 | 17 | myFinalizeFunction = builder.myFinalizeFunction; |
114 | 17 | myReadPreference = builder.myReadPreference; |
115 | 17 | myMaximumTimeMilliseconds = builder.myMaximumTimeMilliseconds; |
116 | 17 | } |
117 | ||
118 | /** | |
119 | * Returns the finalizer function to run for each group. | |
120 | * | |
121 | * @return The finalizer function to run for each group. | |
122 | */ | |
123 | public String getFinalizeFunction() { | |
124 | 16 | return myFinalizeFunction; |
125 | } | |
126 | ||
127 | /** | |
128 | * Returns the initial value for each group. | |
129 | * | |
130 | * @return The initial value for each group. | |
131 | */ | |
132 | public Document getInitialValue() { | |
133 | 16 | return myInitialValue; |
134 | } | |
135 | ||
136 | /** | |
137 | * Returns the function to return the key for a document. Used instead of | |
138 | * the {@link #getKeys} to dynamically determine the group for each | |
139 | * document. | |
140 | * | |
141 | * @return The function to return the key for a document. Used instead of | |
142 | * the {@link #getKeys} to dynamically determine the group for each | |
143 | * document. | |
144 | */ | |
145 | public String getKeyFunction() { | |
146 | 16 | return myKeyFunction; |
147 | } | |
148 | ||
149 | /** | |
150 | * Returns the fields to group by. | |
151 | * | |
152 | * @return The fields to group by. | |
153 | */ | |
154 | public Set<String> getKeys() { | |
155 | 21 | return myKeys; |
156 | } | |
157 | ||
158 | /** | |
159 | * Returns the maximum amount of time to allow the command to run on the | |
160 | * Server before it is aborted. | |
161 | * | |
162 | * @return The maximum amount of time to allow the command to run on the | |
163 | * Server before it is aborted. | |
164 | * | |
165 | * @since MongoDB 2.6 | |
166 | */ | |
167 | public long getMaximumTimeMilliseconds() { | |
168 | 12 | return myMaximumTimeMilliseconds; |
169 | } | |
170 | ||
171 | /** | |
172 | * Returns the query to select the documents to run the group against. | |
173 | * | |
174 | * @return The query to select the documents to run the group against. | |
175 | */ | |
176 | public Document getQuery() { | |
177 | 16 | return myQuery; |
178 | } | |
179 | ||
180 | /** | |
181 | * Returns the {@link ReadPreference} specifying which servers may be used | |
182 | * to execute the {@link GroupBy} command. | |
183 | * <p> | |
184 | * If <code>null</code> then the {@link MongoCollection} instance's | |
185 | * {@link ReadPreference} will be used. | |
186 | * </p> | |
187 | * | |
188 | * @return The read preference to use. | |
189 | * | |
190 | * @see MongoCollection#getReadPreference() | |
191 | */ | |
192 | public ReadPreference getReadPreference() { | |
193 | 9 | return myReadPreference; |
194 | } | |
195 | ||
196 | /** | |
197 | * Returns the reduce function taking the previous value and the current | |
198 | * value and returning the new reduced value. | |
199 | * | |
200 | * @return The reduce function taking the previous value and the current | |
201 | * value and returning the new reduced value. | |
202 | */ | |
203 | public String getReduceFunction() { | |
204 | 16 | return myReduceFunction; |
205 | } | |
206 | ||
207 | /** | |
208 | * Builder provides a builder for Group commands. | |
209 | * | |
210 | * @api.yes This class is part of the driver's API. Public and protected | |
211 | * members will be deprecated for at least 1 non-bugfix release | |
212 | * (version numbers are <major>.<minor>.<bugfix>) | |
213 | * before being removed or modified. | |
214 | * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved | |
215 | */ | |
216 | public static class Builder { | |
217 | ||
218 | /** The finalizer function to run for each group. */ | |
219 | protected String myFinalizeFunction; | |
220 | ||
221 | /** The initial value for the group. */ | |
222 | protected Document myInitialValue; | |
223 | ||
224 | /** | |
225 | * Function to return the key for a document. Used instead of the | |
226 | * {@link #setKeys} to dynamically determine the group for each | |
227 | * document. | |
228 | */ | |
229 | protected String myKeyFunction; | |
230 | ||
231 | /** The fields to group by. */ | |
232 | protected final Set<String> myKeys; | |
233 | ||
234 | /** The maximum amount of time to allow the command to run. */ | |
235 | protected long myMaximumTimeMilliseconds; | |
236 | ||
237 | /** The query to select the documents to run the group against. */ | |
238 | protected Document myQuery; | |
239 | ||
240 | /** The read preference to use. */ | |
241 | protected ReadPreference myReadPreference; | |
242 | ||
243 | /** | |
244 | * The reduce function taking the previous value and the current value | |
245 | * and returning the new reduced value. | |
246 | */ | |
247 | protected String myReduceFunction; | |
248 | ||
249 | /** | |
250 | * Creates a new Builder. | |
251 | */ | |
252 | 16 | public Builder() { |
253 | 16 | myKeys = new HashSet<String>(); |
254 | ||
255 | 16 | reset(); |
256 | 16 | } |
257 | ||
258 | /** | |
259 | * Creates a new {@link GroupBy} based on the current state of the | |
260 | * builder. | |
261 | * | |
262 | * @return A new {@link GroupBy} based on the current state of the | |
263 | * builder. | |
264 | * @throws IllegalArgumentException | |
265 | * If neither the {@link #getKeys() keys} nor | |
266 | * {@link #getKeyFunction() key function} have been set. | |
267 | */ | |
268 | public GroupBy build() throws IllegalArgumentException { | |
269 | 19 | return new GroupBy(this); |
270 | } | |
271 | ||
272 | /** | |
273 | * Sets the value of the finalizer function to run for each group. | |
274 | * <p> | |
275 | * This method delegates to {@link #setFinalizeFunction(String)}. | |
276 | * </p> | |
277 | * | |
278 | * @param finalizeFunction | |
279 | * The new value for the finalizer function to run for each | |
280 | * group. | |
281 | * @return This {@link Builder} for method call chaining. | |
282 | */ | |
283 | public Builder finalize(final String finalizeFunction) { | |
284 | 1 | return setFinalizeFunction(finalizeFunction); |
285 | } | |
286 | ||
287 | /** | |
288 | * Sets the value of the initial value for the group. | |
289 | * <p> | |
290 | * This method delegates to {@link #setInitialValue(DocumentAssignable)} | |
291 | * . | |
292 | * </p> | |
293 | * | |
294 | * @param initialValue | |
295 | * The new value for the initial value for the group. | |
296 | * @return This {@link Builder} for method call chaining. | |
297 | */ | |
298 | public Builder initialValue(final DocumentAssignable initialValue) { | |
299 | 1 | return setInitialValue(initialValue); |
300 | } | |
301 | ||
302 | /** | |
303 | * Sets the value of the function to return the key for a document. Used | |
304 | * instead of the {@link #setKeys} to dynamically determine the group | |
305 | * for each document. | |
306 | * <p> | |
307 | * This method delegates to {@link #setKeyFunction(String)}. | |
308 | * </p> | |
309 | * | |
310 | * @param keyFunction | |
311 | * The new value for the function to return the key for a | |
312 | * document. Used instead of the {@link #setKeys} to | |
313 | * dynamically determine the group for each document. | |
314 | * @return This {@link Builder} for method call chaining. | |
315 | */ | |
316 | public Builder key(final String keyFunction) { | |
317 | 1 | return setKeyFunction(keyFunction); |
318 | } | |
319 | ||
320 | /** | |
321 | * Sets the fields to group by | |
322 | * <p> | |
323 | * This method delegates to {@link #setKeys(Set)}. | |
324 | * </p> | |
325 | * | |
326 | * @param keys | |
327 | * The new fields to group by | |
328 | * @return This {@link Builder} for method call chaining. | |
329 | */ | |
330 | public Builder keys(final Set<String> keys) { | |
331 | 7 | return setKeys(keys); |
332 | } | |
333 | ||
334 | /** | |
335 | * Sets the maximum number of milliseconds to allow the command to run | |
336 | * before aborting the request on the server. | |
337 | * <p> | |
338 | * This method equivalent to {@link #setMaximumTimeMilliseconds(long) | |
339 | * setMaximumTimeMilliseconds(timeLimitUnits.toMillis(timeLimit)}. | |
340 | * </p> | |
341 | * | |
342 | * @param timeLimit | |
343 | * The new maximum amount of time to allow the command to | |
344 | * run. | |
345 | * @param timeLimitUnits | |
346 | * The units for the maximum amount of time to allow the | |
347 | * command to run. | |
348 | * | |
349 | * @return This {@link Builder} for method call chaining. | |
350 | * | |
351 | * @since MongoDB 2.6 | |
352 | */ | |
353 | public Builder maximumTime(final long timeLimit, | |
354 | final TimeUnit timeLimitUnits) { | |
355 | 1 | return setMaximumTimeMilliseconds(timeLimitUnits |
356 | .toMillis(timeLimit)); | |
357 | } | |
358 | ||
359 | /** | |
360 | * Sets the value of the query to select the documents to run the group | |
361 | * against. | |
362 | * <p> | |
363 | * This method delegates to {@link #setQuery(DocumentAssignable)}. | |
364 | * </p> | |
365 | * | |
366 | * @param query | |
367 | * The new value for the query to select the documents to run | |
368 | * the group against. | |
369 | * @return This {@link Builder} for method call chaining. | |
370 | */ | |
371 | public Builder query(final DocumentAssignable query) { | |
372 | 1 | return setQuery(query); |
373 | } | |
374 | ||
375 | /** | |
376 | * Sets the {@link ReadPreference} specifying which servers may be used | |
377 | * to execute the {@link GroupBy} command. | |
378 | * <p> | |
379 | * If not set or set to <code>null</code> then the | |
380 | * {@link MongoCollection} instance's {@link ReadPreference} will be | |
381 | * used. | |
382 | * </p> | |
383 | * <p> | |
384 | * This method delegates to {@link #setReadPreference(ReadPreference)}. | |
385 | * </p> | |
386 | * | |
387 | * @param readPreference | |
388 | * The read preferences specifying which servers may be used. | |
389 | * @return This builder for chaining method calls. | |
390 | * | |
391 | * @see MongoCollection#getReadPreference() | |
392 | */ | |
393 | public Builder readPreference(final ReadPreference readPreference) { | |
394 | 1 | return setReadPreference(readPreference); |
395 | } | |
396 | ||
397 | /** | |
398 | * Sets the value of the reduce function taking the previous value and | |
399 | * the current value and returning the new reduced value. | |
400 | * <p> | |
401 | * This method delegates to {@link #setReduceFunction(String)}. | |
402 | * </p> | |
403 | * | |
404 | * @param reduceFunction | |
405 | * The new value for the reduce function taking the previous | |
406 | * value and the current value and returning the new reduced | |
407 | * value. | |
408 | * @return This {@link Builder} for method call chaining. | |
409 | */ | |
410 | public Builder reduce(final String reduceFunction) { | |
411 | 1 | return setReduceFunction(reduceFunction); |
412 | } | |
413 | ||
414 | /** | |
415 | * Resets the builder back to its initial state. | |
416 | * | |
417 | * @return This {@link Builder} for method call chaining. | |
418 | */ | |
419 | public Builder reset() { | |
420 | 17 | myFinalizeFunction = null; |
421 | 17 | myInitialValue = null; |
422 | 17 | myKeyFunction = null; |
423 | 17 | myKeys.clear(); |
424 | 17 | myQuery = null; |
425 | 17 | myReadPreference = null; |
426 | 17 | myReduceFunction = null; |
427 | 17 | myMaximumTimeMilliseconds = 0; |
428 | ||
429 | 17 | return this; |
430 | } | |
431 | ||
432 | /** | |
433 | * Sets the value of the finalizer function to run for each group. | |
434 | * | |
435 | * @param finalizeFunction | |
436 | * The new value for the finalizer function to run for each | |
437 | * group. | |
438 | * @return This {@link Builder} for method call chaining. | |
439 | */ | |
440 | public Builder setFinalizeFunction(final String finalizeFunction) { | |
441 | 3 | myFinalizeFunction = finalizeFunction; |
442 | 3 | return this; |
443 | } | |
444 | ||
445 | /** | |
446 | * Sets the value of the initial value for the group. | |
447 | * | |
448 | * @param initialValue | |
449 | * The new value for the initial value for the group. | |
450 | * @return This {@link Builder} for method call chaining. | |
451 | */ | |
452 | public Builder setInitialValue(final DocumentAssignable initialValue) { | |
453 | 3 | myInitialValue = initialValue.asDocument(); |
454 | 3 | return this; |
455 | } | |
456 | ||
457 | /** | |
458 | * Sets the value of the function to return the key for a document. Used | |
459 | * instead of the {@link #setKeys} to dynamically determine the group | |
460 | * for each document. | |
461 | * | |
462 | * @param keyFunction | |
463 | * The new value for the function to return the key for a | |
464 | * document. Used instead of the {@link #setKeys} to | |
465 | * dynamically determine the group for each document. | |
466 | * @return This {@link Builder} for method call chaining. | |
467 | */ | |
468 | public Builder setKeyFunction(final String keyFunction) { | |
469 | 3 | myKeyFunction = keyFunction; |
470 | 3 | return this; |
471 | } | |
472 | ||
473 | /** | |
474 | * Sets the fields to group by | |
475 | * | |
476 | * @param keys | |
477 | * The new fields to group by | |
478 | * @return This {@link Builder} for method call chaining. | |
479 | */ | |
480 | public Builder setKeys(final Set<String> keys) { | |
481 | 15 | myKeys.clear(); |
482 | 15 | if (keys != null) { |
483 | 14 | myKeys.addAll(keys); |
484 | } | |
485 | 15 | return this; |
486 | } | |
487 | ||
488 | /** | |
489 | * Sets the maximum number of milliseconds to allow the command to run | |
490 | * before aborting the request on the server. | |
491 | * | |
492 | * @param maximumTimeMilliseconds | |
493 | * The new maximum number of milliseconds to allow the | |
494 | * command to run. | |
495 | * @return This {@link Builder} for method call chaining. | |
496 | * | |
497 | * @since MongoDB 2.6 | |
498 | */ | |
499 | public Builder setMaximumTimeMilliseconds( | |
500 | final long maximumTimeMilliseconds) { | |
501 | 3 | myMaximumTimeMilliseconds = maximumTimeMilliseconds; |
502 | 3 | return this; |
503 | } | |
504 | ||
505 | /** | |
506 | * Sets the value of the query to select the documents to run the group | |
507 | * against. | |
508 | * | |
509 | * @param query | |
510 | * The new value for the query to select the documents to run | |
511 | * the group against. | |
512 | * @return This {@link Builder} for method call chaining. | |
513 | */ | |
514 | public Builder setQuery(final DocumentAssignable query) { | |
515 | 3 | myQuery = query.asDocument(); |
516 | 3 | return this; |
517 | } | |
518 | ||
519 | /** | |
520 | * Sets the {@link ReadPreference} specifying which servers may be used | |
521 | * to execute the {@link GroupBy} command. | |
522 | * <p> | |
523 | * If not set or set to <code>null</code> then the | |
524 | * {@link MongoCollection} instance's {@link ReadPreference} will be | |
525 | * used. | |
526 | * </p> | |
527 | * | |
528 | * @param readPreference | |
529 | * The read preferences specifying which servers may be used. | |
530 | * @return This builder for chaining method calls. | |
531 | * | |
532 | * @see MongoCollection#getReadPreference() | |
533 | */ | |
534 | public Builder setReadPreference(final ReadPreference readPreference) { | |
535 | 3 | myReadPreference = readPreference; |
536 | 3 | return this; |
537 | } | |
538 | ||
539 | /** | |
540 | * Sets the value of the reduce function taking the previous value and | |
541 | * the current value and returning the new reduced value. | |
542 | * | |
543 | * @param reduceFunction | |
544 | * The new value for the reduce function taking the previous | |
545 | * value and the current value and returning the new reduced | |
546 | * value. | |
547 | * @return This {@link Builder} for method call chaining. | |
548 | */ | |
549 | public Builder setReduceFunction(final String reduceFunction) { | |
550 | 3 | myReduceFunction = reduceFunction; |
551 | 3 | return this; |
552 | } | |
553 | } | |
554 | } |