1.9.30 sync.
[gae.git] / java / src / main / com / google / appengine / api / datastore / FetchOptions.java
blob8b576f8784518fd703c73c092f930d6b9f28dc64
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;
6 import java.util.List;
8 /**
9 * Describes the limit, offset, and chunk size to be applied when
10 * executing a {@link PreparedQuery}.
11 * <p>
12 * {@code limit} is the maximum number of results the query will return.
13 * <p>
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
16 * {@code limit}.<br>
17 * <b>Note:</b> Using {@code offset} still retrieves skipped entities internally.
18 * This affects the latency of the query, and <b>your application is billed for the
19 * operations</b> required to retrieve them. Using cursors lets you avoid these costs.
20 * <p>
21 * {@code startCursor} and {@code endCursor} are previously generated cursors
22 * that point to locations in a result set. If specified queries will start
23 * and end at these locations.
24 * <p>
25 * {@code prefetchSize} is the number of results retrieved on the first call
26 * to the datastore.
27 * <p>
28 * {@code chunkSize} determines the internal chunking strategy of the
29 * {@link Iterator} returned by {@link PreparedQuery#asIterator(FetchOptions)}
30 * and the {@link Iterable} returned by
31 * {@link PreparedQuery#asIterable(FetchOptions)}.
32 * <p>
33 * Note that unlike {@code limit}, {@code offset} and {@code cursor},
34 * {@code prefetchSize} and {@code chunkSize} have no impact on the result of
35 * the {@link PreparedQuery}, but rather only the performance of the
36 * {@link PreparedQuery}.
37 * <p>
38 * Notes on usage:<br>
39 * The recommended way to instantiate a {@code FetchOptions} object is to
40 * statically import {@link Builder}.* and invoke a static
41 * creation method followed by an instance mutator (if needed):
43 * <pre>
44 * import static com.google.appengine.api.datastore.FetchOptions.Builder.*;
46 * Cursor cursor = ...
48 * ...
50 * // limit 10
51 * datastoreService.prepare(query).asList(withLimit(10));
53 * // limit 10, start cursor
54 * datastoreService.prepare(query).asList(withLimit(10).startCursor(cursor);
55 * </pre>
58 public final class FetchOptions {
60 /** @deprecated Instead of using DEFAULT_CHUNK_SIZE, do not specify a chunk size. */
61 @Deprecated
62 public static final int DEFAULT_CHUNK_SIZE = 20;
64 private Integer limit;
65 private Integer offset;
66 private Integer prefetchSize;
67 private Integer chunkSize;
68 private Cursor startCursor;
69 private Cursor endCursor;
70 private Boolean compile;
72 private FetchOptions() {
75 FetchOptions(FetchOptions original) {
76 this.limit = original.limit;
77 this.offset = original.offset;
78 this.prefetchSize = original.prefetchSize;
79 this.chunkSize = original.chunkSize;
80 this.startCursor = original.startCursor;
81 this.endCursor = original.endCursor;
82 this.compile = original.compile;
85 /**
86 * Sets the limit. Please read the class javadoc for an explanation of how
87 * limit is used.
88 * @param limit The limit to set. Must be non-negative.
89 * @return {@code this} (for chaining)
91 public FetchOptions limit(int limit) {
92 if (limit < 0) {
93 throw new IllegalArgumentException("Limit must be non-negative.");
95 this.limit = limit;
96 return this;
99 FetchOptions clearLimit() {
100 limit = null;
101 return this;
105 * Sets the offset. Please read the class javadoc for an explanation of how
106 * offset is used.
107 * @param offset The offset to set. Must be 0 or greater.
108 * @return {@code this} (for chaining)
110 public FetchOptions offset(int offset) {
111 if (offset < 0) {
112 throw new IllegalArgumentException("Offset must be 0 or greater.");
114 this.offset = offset;
115 return this;
118 FetchOptions clearOffset() {
119 offset = null;
120 return this;
124 * Sets the chunk size. Please read the class javadoc for an explanation of
125 * how chunk size is used.
126 * @param chunkSize The chunk size to set. Must be greater than 0.
127 * @return {@code this} (for chaining)
129 public FetchOptions chunkSize(int chunkSize) {
130 if (chunkSize < 1) {
131 throw new IllegalArgumentException("Chunk size must be greater than 0.");
133 this.chunkSize = chunkSize;
134 return this;
137 FetchOptions clearChunkSize() {
138 chunkSize = null;
139 return this;
143 * Sets the number of entities to prefetch.
144 * @param prefetchSize The prefetch size to set. Must be {@literal >= 0}.
145 * @return {@code this} (for chaining)
147 public FetchOptions prefetchSize(int prefetchSize) {
148 if (prefetchSize < 0) {
149 throw new IllegalArgumentException("Prefetch size must be 0 or greater.");
151 this.prefetchSize = prefetchSize;
152 return this;
155 FetchOptions clearPrefetchSize() {
156 prefetchSize = null;
157 return this;
161 * Sets the cursor to start the query from.
162 * @param cursor the cursor to set
163 * @return {@code this} (for chaining)
164 * @deprecated use {@link #startCursor} instead.
166 @Deprecated
167 public FetchOptions cursor(Cursor cursor) {
168 return startCursor(cursor);
172 * Sets the cursor at which to start the query.
174 * @param startCursor the cursor to set
175 * @return {@code this} (for chaining)
177 public FetchOptions startCursor(Cursor startCursor) {
178 if (startCursor == null) {
179 throw new NullPointerException("start cursor cannot be null.");
181 this.startCursor = startCursor;
182 return this;
186 * Sets the cursor at which to end the query.
188 * @param endCursor the cursor to set
189 * @return {@code this} (for chaining)
191 public FetchOptions endCursor(Cursor endCursor) {
192 if (endCursor == null) {
193 throw new NullPointerException("end cursor cannot be null.");
195 this.endCursor = endCursor;
196 return this;
199 FetchOptions clearStartCursor() {
200 startCursor = null;
201 return this;
204 FetchOptions clearEndCursor() {
205 endCursor = null;
206 return this;
209 FetchOptions compile(boolean compile) {
210 this.compile = compile;
211 return this;
214 FetchOptions clearCompile() {
215 compile = null;
216 return this;
220 * @return The limit, or {@code null} if no limit was provided.
222 public Integer getLimit() {
223 return limit;
227 * @return The offset, or {@code null} if no offset was provided.
229 public Integer getOffset() {
230 return offset;
234 * @return The chunk size, or {@code null} if no chunk size was provided.
236 public Integer getChunkSize() {
237 return chunkSize;
241 * @return The prefetch size, or {@code null} if no prefetch size was
242 * provided.
244 public Integer getPrefetchSize() {
245 return prefetchSize;
249 * @return The start cursor, or {@code null} if no cursor was provided.
250 * @deprecated use {@link #getStartCursor()} instead
252 @Deprecated
253 public Cursor getCursor() {
254 return getStartCursor();
258 * @return The start cursor, or {@code null} if no start cursor was provided.
260 public Cursor getStartCursor() {
261 return startCursor;
265 * @return The end cursor, or {@code null} if no end cursor was provided.
267 public Cursor getEndCursor() {
268 return endCursor;
271 Boolean getCompile() {
272 return compile;
275 @Override
276 public int hashCode() {
277 int result = 0;
279 if (prefetchSize != null) {
280 result = result * 31 + prefetchSize.hashCode();
283 if (chunkSize != null) {
284 result = result * 31 + chunkSize.hashCode();
287 if (limit != null) {
288 result = result * 31 + limit.hashCode();
291 if (offset != null) {
292 result = result * 31 + offset.hashCode();
295 if (startCursor != null) {
296 result = result * 31 + startCursor.hashCode();
299 if (endCursor != null) {
300 result = result * 31 + endCursor.hashCode();
303 if (compile != null) {
304 result = result * 31 + compile.hashCode();
307 return result;
310 @Override
311 public boolean equals(Object obj) {
312 if (obj == null) {
313 return false;
316 if (obj.getClass() != this.getClass()) {
317 return false;
320 FetchOptions that = (FetchOptions) obj;
322 if (prefetchSize != null) {
323 if (!prefetchSize.equals(that.prefetchSize)) {
324 return false;
326 } else if (that.prefetchSize != null) {
327 return false;
330 if (chunkSize != null) {
331 if (!chunkSize.equals(that.chunkSize)) {
332 return false;
334 } else if (that.chunkSize != null) {
335 return false;
338 if (limit != null) {
339 if (!limit.equals(that.limit)) {
340 return false;
342 } else if (that.limit != null) {
343 return false;
346 if (offset != null) {
347 if (!offset.equals(that.offset)) {
348 return false;
350 } else if (that.offset != null) {
351 return false;
354 if (startCursor != null) {
355 if (!startCursor.equals(that.startCursor)) {
356 return false;
358 } else if (that.startCursor != null) {
359 return false;
362 if (endCursor != null) {
363 if (!endCursor.equals(that.endCursor)) {
364 return false;
366 } else if (that.endCursor != null) {
367 return false;
370 if (compile != null) {
371 if (!compile.equals(that.compile)) {
372 return false;
374 } else if (that.compile != null) {
375 return false;
378 return true;
381 @Override
382 public String toString() {
383 List<String> result = new ArrayList<String>();
385 if (prefetchSize != null) {
386 result.add("prefetchSize=" + prefetchSize);
389 if (chunkSize != null) {
390 result.add("chunkSize=" + chunkSize);
393 if (limit != null) {
394 result.add("limit=" + limit);
397 if (offset != null) {
398 result.add("offset=" + offset);
401 if (startCursor != null) {
402 result.add("startCursor=" + startCursor);
405 if (endCursor != null) {
406 result.add("endCursor=" + endCursor);
409 if (compile != null) {
410 result.add("compile=" + compile);
412 return "FetchOptions" + result;
416 * Contains static creation methods for {@link FetchOptions}.
418 public static final class Builder {
421 * Create a {@link FetchOptions} with the given limit. Shorthand for
422 * <code>FetchOptions.withDefaults().limit(...);</code> Please read the
423 * {@link FetchOptions} class javadoc for an explanation of how limit
424 * is used.
425 * @param limit the limit to set.
426 * @return The newly created FetchOptions instance.
428 public static FetchOptions withLimit(int limit) {
429 return withDefaults().limit(limit);
433 * Create a {@link FetchOptions} with the given offset. Shorthand for
434 * <code>FetchOptions.withDefaults().offset(...);</code> Please read the
435 * {@link FetchOptions} class javadoc for an explanation of how offset
436 * is used.
437 * @param offset the offset to set.
438 * @return The newly created FetchOptions instance.
440 public static FetchOptions withOffset(int offset) {
441 return withDefaults().offset(offset);
445 * Create a {@link FetchOptions} with the given chunk size. Shorthand for
446 * <code>FetchOptions.withDefaults().chunkSize(...);</code> Please read the
447 * {@link FetchOptions} class javadoc for an explanation of how chunk size
448 * is used.
449 * @param chunkSize the chunkSize to set.
450 * @return The newly created FetchOptions instance.
452 public static FetchOptions withChunkSize(int chunkSize) {
453 return withDefaults().chunkSize(chunkSize);
457 * Create a {@link FetchOptions} with the given prefetch size.
458 * Shorthand for <code>FetchOptions.withDefaults().prefetchSize(...);</code>.
459 * Please read the {@link FetchOptions} class javadoc for an explanation of
460 * how prefetch size is used.
461 * @param prefetchSize the prefetchSize to set.
462 * @return The newly created FetchOptions instance.
464 public static FetchOptions withPrefetchSize(int prefetchSize) {
465 return withDefaults().prefetchSize(prefetchSize);
469 * Create a {@link FetchOptions} with the given cursor.
470 * Shorthand for <code>FetchOptions.withDefaults().cursor(cursor);</code>.
471 * Please read the {@link FetchOptions} class javadoc for an explanation of
472 * how cursors are used.
473 * @param cursor the cursor to set.
474 * @return The newly created FetchOptions instance.
475 * @deprecated use {@link #withStartCursor} instead.
477 @Deprecated
478 public static FetchOptions withCursor(Cursor cursor) {
479 return withStartCursor(cursor);
483 * Create a {@link FetchOptions} with the given start cursor.
484 * Shorthand for <code>FetchOptions.withDefaults().startCursor(cursor);</code>.
485 * Please read the {@link FetchOptions} class javadoc for an explanation of
486 * how cursors are used.
487 * @param startCursor the cursor to set.
488 * @return The newly created FetchOptions instance.
490 public static FetchOptions withStartCursor(Cursor startCursor) {
491 return withDefaults().startCursor(startCursor);
495 * Create a {@link FetchOptions} with the given end cursor.
496 * Shorthand for <code>FetchOptions.withDefaults().endCursor(cursor);</code>.
497 * Please read the {@link FetchOptions} class javadoc for an explanation of
498 * how cursors are used.
499 * @param endCursor the cursor to set.
500 * @return The newly created FetchOptions instance.
502 public static FetchOptions withEndCursor(Cursor endCursor) {
503 return withDefaults().endCursor(endCursor);
507 * Helper method for creating a {@link FetchOptions} instance with
508 * default values. The defaults are {@code null} for all values.
510 public static FetchOptions withDefaults() {
511 return new FetchOptions();
514 private Builder() {}