Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / datastore / PreparedQueryImpl.java
blob099330a8878534298acdc86eea838be28a409e7a
1 // Copyright 2007 Google Inc. All rights reserved.
3 package com.google.appengine.api.datastore;
5 import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit;
6 import static com.google.common.base.Preconditions.checkArgument;
8 import java.util.Iterator;
9 import java.util.List;
11 /**
12 * Implements PreparedQuery.
15 class PreparedQueryImpl extends BasePreparedQuery {
16 private final Query query;
17 private final Transaction txn;
18 private final QueryRunner queryRunner;
20 public PreparedQueryImpl(Query query, Transaction txn, QueryRunner queryRunner) {
21 this.query = query;
22 this.txn = txn;
23 this.queryRunner = queryRunner;
25 checkArgument(txn == null || query.getAncestor() != null,
26 "Only ancestor queries are allowed inside transactions.");
27 TransactionImpl.ensureTxnActive(txn);
30 private QueryResultIteratorImpl runQuery(FetchOptions fetchOptions) {
31 return new QueryResultIteratorImpl(this, queryRunner.runQuery(fetchOptions, query, txn),
32 fetchOptions, txn);
35 @Override
36 public List<Entity> asList(FetchOptions fetchOptions) {
37 return new LazyList(runQuery(fetchOptions));
40 @Override
41 public QueryResultList<Entity> asQueryResultList(FetchOptions fetchOptions) {
42 FetchOptions override = new FetchOptions(fetchOptions);
43 if (override.getCompile() == null) {
44 override.compile(true);
46 LazyList lazyList = new LazyList(runQuery(override));
47 return lazyList;
50 @Override
51 public Iterator<Entity> asIterator(FetchOptions fetchOptions) {
52 return runQuery(fetchOptions);
55 @Override
56 public QueryResultIterator<Entity> asQueryResultIterator(FetchOptions fetchOptions) {
57 if (fetchOptions.getCompile() == null) {
58 fetchOptions = new FetchOptions(fetchOptions).compile(true);
60 return runQuery(fetchOptions);
63 @Override
64 public Entity asSingleEntity() throws TooManyResultsException {
65 List<Entity> entities = asList(withLimit(2));
66 if (entities.isEmpty()) {
67 return null;
68 } else if (entities.size() != 1) {
69 throw new TooManyResultsException();
71 return entities.get(0);
74 @Override
75 /**
76 * Counts the number of entities in the result set.
78 * This method will run a query that will offset past all results and return
79 * the number of results that have been skipped in the process.
81 * (offset, limit) is converted to (offset + limit, 0) so that no results are
82 * actually returned. The resulting count is max(0, skipped - offset). This
83 * is the number of entities in the range [offset, offset + limit) which is
84 * the count.
86 public int countEntities(FetchOptions fetchOptions) {
87 FetchOptions overrideOptions = new FetchOptions(fetchOptions);
89 overrideOptions.limit(0);
90 if (fetchOptions.getLimit() != null) {
91 if (fetchOptions.getOffset() != null) {
92 int offset = fetchOptions.getLimit() + fetchOptions.getOffset();
93 overrideOptions.offset(offset >= 0 ? offset : Integer.MAX_VALUE);
94 } else {
95 overrideOptions.offset(fetchOptions.getLimit());
97 } else {
98 overrideOptions.offset(Integer.MAX_VALUE);
101 int count = runQuery(overrideOptions).getNumSkipped();
102 if (fetchOptions.getOffset() != null) {
103 if (count < fetchOptions.getOffset()) {
104 count = 0;
105 } else {
106 count = count - fetchOptions.getOffset();
109 return count;
112 @Override
113 public String toString() {
114 return query + (txn != null ? " IN " + txn : "");