1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com
.google
.appengine
.api
.datastore
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Iterator
;
9 * Describes the limit, offset, and chunk size to be applied when
10 * executing a {@link PreparedQuery}.
12 * {@code limit} is the maximum number of results the query will return.
14 * {@code offset} is the number of results to skip before returning any
15 * results. Results that are skipped due to offset do not count against
18 * {@code startCursor} and {@code endCursor} are previously generated cursors
19 * that point to locations in a result set. If specified queries will start
20 * and end at these locations.
22 * {@code prefetchSize} is the number of results retrieved on the first call
25 * {@code chunkSize} determines the internal chunking strategy of the
26 * {@link Iterator} returned by {@link PreparedQuery#asIterator(FetchOptions)}
27 * and the {@link Iterable} returned by
28 * {@link PreparedQuery#asIterable(FetchOptions)}.
30 * Note that unlike {@code limit}, {@code offset} and {@code cursor},
31 * {@code prefetchSize} and {@code chunkSize} have no impact on the result of
32 * the {@link PreparedQuery}, but rather only the performance of the
33 * {@link PreparedQuery}.
36 * The recommended way to instantiate a {@code FetchOptions} object is to
37 * statically import {@link Builder}.* and invoke a static
38 * creation method followed by an instance mutator (if needed):
41 * import static com.google.appengine.api.datastore.FetchOptions.Builder.*;
46 * datastoreService.prepare(query).asList(withLimit(10));
48 * // limit 10, offset 5
49 * datastoreService.prepare(query).asList(withLimit(10).offset(5));
53 public final class FetchOptions
{
55 /** @deprecated Instead of using DEFAULT_CHUNK_SIZE, do not specify a chunk size. */
57 public static final int DEFAULT_CHUNK_SIZE
= 20;
59 private Integer limit
;
60 private Integer offset
;
61 private Integer prefetchSize
;
62 private Integer chunkSize
;
63 private Cursor startCursor
;
64 private Cursor endCursor
;
65 private Boolean compile
;
67 private FetchOptions() {
70 FetchOptions(FetchOptions original
) {
71 this.limit
= original
.limit
;
72 this.offset
= original
.offset
;
73 this.prefetchSize
= original
.prefetchSize
;
74 this.chunkSize
= original
.chunkSize
;
75 this.startCursor
= original
.startCursor
;
76 this.endCursor
= original
.endCursor
;
77 this.compile
= original
.compile
;
81 * Sets the limit. Please read the class javadoc for an explanation of how
83 * @param limit The limit to set. Must be non-negative.
84 * @return {@code this} (for chaining)
86 public FetchOptions
limit(int limit
) {
88 throw new IllegalArgumentException("Limit must be non-negative.");
94 FetchOptions
clearLimit() {
100 * Sets the offset. Please read the class javadoc for an explanation of how
102 * @param offset The offset to set. Must be 0 or greater.
103 * @return {@code this} (for chaining)
105 public FetchOptions
offset(int offset
) {
107 throw new IllegalArgumentException("Offset must be 0 or greater.");
109 this.offset
= offset
;
113 FetchOptions
clearOffset() {
119 * Sets the chunk size. Please read the class javadoc for an explanation of
120 * how chunk size is used.
121 * @param chunkSize The chunk size to set. Must be greater than 0.
122 * @return {@code this} (for chaining)
124 public FetchOptions
chunkSize(int chunkSize
) {
126 throw new IllegalArgumentException("Chunk size must be greater than 0.");
128 this.chunkSize
= chunkSize
;
132 FetchOptions
clearChunkSize() {
138 * Sets the number of entities to prefetch.
139 * @param prefetchSize The prefetch size to set. Must be {@literal >= 0}.
140 * @return {@code this} (for chaining)
142 public FetchOptions
prefetchSize(int prefetchSize
) {
143 if (prefetchSize
< 0) {
144 throw new IllegalArgumentException("Prefetch size must be 0 or greater.");
146 this.prefetchSize
= prefetchSize
;
150 FetchOptions
clearPrefetchSize() {
156 * Sets the cursor to start the query from.
157 * @param cursor the cursor to set
158 * @return {@code this} (for chaining)
159 * @deprecated use {@link #startCursor} instead.
162 public FetchOptions
cursor(Cursor cursor
) {
163 return startCursor(cursor
);
167 * Sets the cursor at which to start the query.
169 * @param startCursor the cursor to set
170 * @return {@code this} (for chaining)
172 public FetchOptions
startCursor(Cursor startCursor
) {
173 if (startCursor
== null) {
174 throw new NullPointerException("start cursor cannot be null.");
176 this.startCursor
= startCursor
;
181 * Sets the cursor at which to end the query.
183 * @param endCursor the cursor to set
184 * @return {@code this} (for chaining)
186 public FetchOptions
endCursor(Cursor endCursor
) {
187 if (endCursor
== null) {
188 throw new NullPointerException("end cursor cannot be null.");
190 this.endCursor
= endCursor
;
194 FetchOptions
clearStartCursor() {
199 FetchOptions
clearEndCursor() {
204 FetchOptions
compile(boolean compile
) {
205 this.compile
= compile
;
209 FetchOptions
clearCompile() {
215 * @return The limit, or {@code null} if no limit was provided.
217 public Integer
getLimit() {
222 * @return The offset, or {@code null} if no offset was provided.
224 public Integer
getOffset() {
229 * @return The chunk size, or {@code null} if no chunk size was provided.
231 public Integer
getChunkSize() {
236 * @return The prefetch size, or {@code null} if no prefetch size was
239 public Integer
getPrefetchSize() {
244 * @return The start cursor, or {@code null} if no cursor was provided.
245 * @deprecated use {@link #getStartCursor()} instead
248 public Cursor
getCursor() {
249 return getStartCursor();
253 * @return The start cursor, or {@code null} if no start cursor was provided.
255 public Cursor
getStartCursor() {
260 * @return The end cursor, or {@code null} if no end cursor was provided.
262 public Cursor
getEndCursor() {
266 Boolean
getCompile() {
271 public int hashCode() {
274 if (prefetchSize
!= null) {
275 result
= result
* 31 + prefetchSize
.hashCode();
278 if (chunkSize
!= null) {
279 result
= result
* 31 + chunkSize
.hashCode();
283 result
= result
* 31 + limit
.hashCode();
286 if (offset
!= null) {
287 result
= result
* 31 + offset
.hashCode();
290 if (startCursor
!= null) {
291 result
= result
* 31 + startCursor
.hashCode();
294 if (endCursor
!= null) {
295 result
= result
* 31 + endCursor
.hashCode();
298 if (compile
!= null) {
299 result
= result
* 31 + compile
.hashCode();
306 public boolean equals(Object obj
) {
311 if (obj
.getClass() != this.getClass()) {
315 FetchOptions that
= (FetchOptions
) obj
;
317 if (prefetchSize
!= null) {
318 if (!prefetchSize
.equals(that
.prefetchSize
)) {
321 } else if (that
.prefetchSize
!= null) {
325 if (chunkSize
!= null) {
326 if (!chunkSize
.equals(that
.chunkSize
)) {
329 } else if (that
.chunkSize
!= null) {
334 if (!limit
.equals(that
.limit
)) {
337 } else if (that
.limit
!= null) {
341 if (offset
!= null) {
342 if (!offset
.equals(that
.offset
)) {
345 } else if (that
.offset
!= null) {
349 if (startCursor
!= null) {
350 if (!startCursor
.equals(that
.startCursor
)) {
353 } else if (that
.startCursor
!= null) {
357 if (endCursor
!= null) {
358 if (!endCursor
.equals(that
.endCursor
)) {
361 } else if (that
.endCursor
!= null) {
365 if (compile
!= null) {
366 if (!compile
.equals(that
.compile
)) {
369 } else if (that
.compile
!= null) {
377 public String
toString() {
378 List
<String
> result
= new ArrayList
<String
>();
380 if (prefetchSize
!= null) {
381 result
.add("prefetchSize=" + prefetchSize
);
384 if (chunkSize
!= null) {
385 result
.add("chunkSize=" + chunkSize
);
389 result
.add("limit=" + limit
);
392 if (offset
!= null) {
393 result
.add("offset=" + offset
);
396 if (startCursor
!= null) {
397 result
.add("startCursor=" + startCursor
);
400 if (endCursor
!= null) {
401 result
.add("endCursor=" + endCursor
);
404 if (compile
!= null) {
405 result
.add("compile=" + compile
);
407 return "FetchOptions" + result
;
411 * Contains static creation methods for {@link FetchOptions}.
413 public static final class Builder
{
416 * Create a {@link FetchOptions} with the given limit. Shorthand for
417 * <code>FetchOptions.withDefaults().limit(...);</code> Please read the
418 * {@link FetchOptions} class javadoc for an explanation of how limit
420 * @param limit the limit to set.
421 * @return The newly created FetchOptions instance.
423 public static FetchOptions
withLimit(int limit
) {
424 return withDefaults().limit(limit
);
428 * Create a {@link FetchOptions} with the given offset. Shorthand for
429 * <code>FetchOptions.withDefaults().offset(...);</code> Please read the
430 * {@link FetchOptions} class javadoc for an explanation of how offset
432 * @param offset the offset to set.
433 * @return The newly created FetchOptions instance.
435 public static FetchOptions
withOffset(int offset
) {
436 return withDefaults().offset(offset
);
440 * Create a {@link FetchOptions} with the given chunk size. Shorthand for
441 * <code>FetchOptions.withDefaults().chunkSize(...);</code> Please read the
442 * {@link FetchOptions} class javadoc for an explanation of how chunk size
444 * @param chunkSize the chunkSize to set.
445 * @return The newly created FetchOptions instance.
447 public static FetchOptions
withChunkSize(int chunkSize
) {
448 return withDefaults().chunkSize(chunkSize
);
452 * Create a {@link FetchOptions} with the given prefetch size.
453 * Shorthand for <code>FetchOptions.withDefaults().prefetchSize(...);</code>.
454 * Please read the {@link FetchOptions} class javadoc for an explanation of
455 * how prefetch size is used.
456 * @param prefetchSize the prefetchSize to set.
457 * @return The newly created FetchOptions instance.
459 public static FetchOptions
withPrefetchSize(int prefetchSize
) {
460 return withDefaults().prefetchSize(prefetchSize
);
464 * Create a {@link FetchOptions} with the given cursor.
465 * Shorthand for <code>FetchOptions.withDefaults().cursor(cursor);</code>.
466 * Please read the {@link FetchOptions} class javadoc for an explanation of
467 * how cursors are used.
468 * @param cursor the cursor to set.
469 * @return The newly created FetchOptions instance.
470 * @deprecated use {@link #withStartCursor} instead.
473 public static FetchOptions
withCursor(Cursor cursor
) {
474 return withStartCursor(cursor
);
478 * Create a {@link FetchOptions} with the given start cursor.
479 * Shorthand for <code>FetchOptions.withDefaults().startCursor(cursor);</code>.
480 * Please read the {@link FetchOptions} class javadoc for an explanation of
481 * how cursors are used.
482 * @param startCursor the cursor to set.
483 * @return The newly created FetchOptions instance.
485 public static FetchOptions
withStartCursor(Cursor startCursor
) {
486 return withDefaults().startCursor(startCursor
);
490 * Create a {@link FetchOptions} with the given end cursor.
491 * Shorthand for <code>FetchOptions.withDefaults().endCursor(cursor);</code>.
492 * Please read the {@link FetchOptions} class javadoc for an explanation of
493 * how cursors are used.
494 * @param endCursor the cursor to set.
495 * @return The newly created FetchOptions instance.
497 public static FetchOptions
withEndCursor(Cursor endCursor
) {
498 return withDefaults().endCursor(endCursor
);
502 * Helper method for creating a {@link FetchOptions} instance with
503 * default values. The defaults are {@code null} for all values.
505 public static FetchOptions
withDefaults() {
506 return new FetchOptions();