public List runQuery()

in api_dev/src/main/java/com/google/appengine/api/datastore/dev/KeyFilteredPseudoKind.java [55:128]


  public List<EntityProto> runQuery(Query query) {
    Key startKey = null;
    Key endKey = null;
    boolean startInclusive = false;
    boolean endInclusive = false;

    /* We could leave all the filters and orders to LocalDatastoreService, but that would force
     * queries to examine all entities even when filters are present, and wouldn't
     * report the invalid-query errors of the real datastore.
     *
     * Explicit code to handle range, as {@link com.google.appengine.api.datastore.FilterMatcher}
     * is somewhat specialized to deal with {@link PropertyValue} in {@link EntityProto}s.
     */
    for (Filter filter : query.filters()) {
      Operator op = filter.getOpEnum();

      // Report error for filters we can't handle
      checkRequest(
          filter.propertySize() == 1
              && filter.getProperty(0).getName().equals(Entity.KEY_RESERVED_PROPERTY)
              && (op == Operator.LESS_THAN
                  || op == Operator.LESS_THAN_OR_EQUAL
                  || op == Operator.GREATER_THAN
                  || op == Operator.GREATER_THAN_OR_EQUAL
                  || op == Operator.EQUAL),
          "Only comparison filters on " + Entity.KEY_RESERVED_PROPERTY + " supported");

      Object filterVal = DataTypeTranslator.getPropertyValue(filter.getProperty(0));
      // Redundant with {@link com.google.com.appengine.api.datastore.ValidatedQuery}
      checkRequest(
          filterVal instanceof Key, Entity.KEY_RESERVED_PROPERTY + " must be compared to a key");

      Key keyLimit = (Key) filterVal;

      // Update our search limits based on the filters
      if (op == Operator.LESS_THAN) {
        if (endKey == null || keyLimit.compareTo(endKey) <= 0) {
          endKey = keyLimit;
          endInclusive = false;
        }
      } else if (op == Operator.LESS_THAN_OR_EQUAL || op == Operator.EQUAL) {
        if (endKey == null || keyLimit.compareTo(endKey) < 0) {
          endKey = keyLimit;
          endInclusive = true;
        }
      }
      if (op == Operator.GREATER_THAN) {
        if (startKey == null || keyLimit.compareTo(startKey) >= 0) {
          startKey = keyLimit;
          startInclusive = false;
        }
      } else if (op == Operator.GREATER_THAN_OR_EQUAL || op == Operator.EQUAL) {
        if (startKey == null || keyLimit.compareTo(startKey) > 0) {
          startKey = keyLimit;
          startInclusive = true;
        }
      }
    }
    query.clearFilter();

    // The only allowed order we can handle is an initial ascending on key
    if (query.orderSize() > 0) {
      Order order = query.getOrder(0);
      if (order.getDirectionEnum() == Order.Direction.ASCENDING
          && Entity.KEY_RESERVED_PROPERTY.equals(order.getProperty())) {
        query.removeOrder(0);
      }
    }
    checkRequest(
        query.orderSize() == 0,
        "Only ascending order on " + Entity.KEY_RESERVED_PROPERTY + " supported");

    return runQuery(query, startKey, startInclusive, endKey, endInclusive);
  }