PageRenderTime 45ms CodeModel.GetById 22ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/appengine/datanucleus/query/StreamingQueryResult.java

http://datanucleus-appengine.googlecode.com/
Java | 157 lines | 88 code | 26 blank | 43 comment | 11 complexity | b1d075aa942f8df4d916ded60bdb2793 MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus.query;
 17
 18import com.google.appengine.api.datastore.Cursor;
 19import com.google.appengine.api.datastore.Entity;
 20
 21import org.datanucleus.exceptions.NucleusUserException;
 22
 23import com.google.appengine.datanucleus.Utils.Function;
 24
 25import org.datanucleus.store.query.AbstractQueryResult;
 26import org.datanucleus.store.query.Query;
 27import org.datanucleus.util.NucleusLogger;
 28
 29import java.util.Iterator;
 30import java.util.ListIterator;
 31import java.util.NoSuchElementException;
 32
 33import javax.jdo.JDOUserException;
 34
 35/**
 36 * An {@link AbstractQueryResult} implementation that streams results, converting
 37 * from {@link Entity Entities} to POJOs as clients access the data.
 38 *
 39 * @author Max Ross <maxr@google.com>
 40 */
 41class StreamingQueryResult extends AbstractQueryResult {
 42
 43  /** Delegate for lazy loading of results. */
 44  private final LazyResult<Object> lazyResult;
 45
 46  private boolean loadResultsAtCommit = true;
 47
 48  private final Cursor endCursor;
 49
 50  private boolean hasError;
 51
 52  private RuntimeExceptionWrappingIterable inputIterable;
 53
 54  /**
 55   * Constructs a StreamingQueryResult.
 56   * @param query The query which yields the results.
 57   * @param lazyEntities The result of the query.
 58   * @param entityToPojoFunc A function that can convert a {@link Entity} into a pojo.
 59   * @param endCursor Provides a cursor that points to the end of the result set. Can be null.
 60   */
 61  public StreamingQueryResult(Query query, Iterable<Entity> lazyEntities,
 62      Function<Entity, Object> entityToPojoFunc, Cursor endCursor) {
 63    super(query);
 64    if (lazyEntities instanceof RuntimeExceptionWrappingIterable) {
 65      this.inputIterable = (RuntimeExceptionWrappingIterable) lazyEntities;
 66    }
 67    this.lazyResult = new LazyResult<Object>(lazyEntities, entityToPojoFunc, query.useResultsCaching());
 68    this.endCursor = endCursor;
 69  }
 70
 71  @Override
 72  public void disconnect() {
 73    if (inputIterable != null) {
 74      // Relay the iterable error out
 75      this.hasError = inputIterable.hasError();
 76    }
 77
 78    super.disconnect();
 79  }
 80
 81  @Override
 82  protected void closingConnection() {
 83    // Connection is being closed so last chance to grab any results not yet loaded
 84    if (loadResultsAtCommit && isOpen()) {
 85      if (hasError) {
 86        NucleusLogger.QUERY.info("Skipping resolution of remaining results due to earlier error.");
 87      } else {
 88        try {
 89          // If we are still open, force consumption of the rest of the results
 90          lazyResult.resolveAll();
 91          // TODO Get rid of this selective exception swallowing. Makes no sense
 92        } catch (NucleusUserException jpue) {
 93          // Log any exception - can get exceptions when maybe the user has specified an invalid result class etc
 94          NucleusLogger.QUERY.warn("Exception thrown while loading remaining rows of query : " + jpue.getMessage());
 95        } catch (JDOUserException ue) {
 96          // Log any exception - can get exceptions when maybe the user has specified an invalid result class etc
 97          NucleusLogger.QUERY.warn("Exception thrown while loading remaining rows of query : " + ue.getMessage());
 98        }
 99      }
100
101      // Cache the query results (if required)
102      cacheQueryResults();
103    }
104  }
105
106  @Override
107  protected void closeResults() {
108    // Cache the query results (if required)
109    cacheQueryResults();
110  }
111
112  /**
113   * Method to cache the results (List of the Entity keys) if it has been requested. 
114   */
115  protected void cacheQueryResults() {
116    if (query != null && query.useResultsCaching()) {
117      lazyResult.resolveAll();
118      query.getQueryManager().addDatastoreQueryResult(query, query.getInputParameters(), lazyResult.getEntityKeys());
119    }
120  }
121
122  @Override
123  public boolean equals(Object o) {
124    return this == o;
125  }
126
127  @Override
128  public Object get(int index) {
129    return lazyResult.get(index);
130  }
131
132  /**
133   * @throws NoSuchElementException if there are no more elements to resolve.
134   */
135  void resolveNext() {
136    lazyResult.resolveNext();
137  }
138
139  @Override
140  public Iterator<Object> iterator() {
141    return lazyResult.listIterator();
142  }
143
144  @Override
145  public ListIterator<Object> listIterator() {
146    return lazyResult.listIterator();
147  }
148
149  @Override
150  public int size() {
151    return lazyResult.size();
152  }
153
154  Cursor getEndCursor() {
155    return endCursor;
156  }
157}