| 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 | } |