Search in sources :

Example 1 with KeyConstraints

use of com.parse.ParseQuery.KeyConstraints in project Parse-SDK-Android by ParsePlatform.

the class OfflineQueryLogic method sort.

/**
   * Sorts the given array based on the parameters of the given query.
   */
/* package */
static <T extends ParseObject> void sort(List<T> results, ParseQuery.State<T> state) throws ParseException {
    final List<String> keys = state.order();
    // Do some error checking just for maximum compatibility with the server.
    for (String key : state.order()) {
        if (!key.matches("^-?[A-Za-z][A-Za-z0-9_]*$")) {
            if (!"_created_at".equals(key) && !"_updated_at".equals(key)) {
                throw new ParseException(ParseException.INVALID_KEY_NAME, String.format("Invalid key name: \"%s\".", key));
            }
        }
    }
    // See if there's a $nearSphere constraint that will override the other sort parameters.
    String mutableNearSphereKey = null;
    ParseGeoPoint mutableNearSphereValue = null;
    for (String queryKey : state.constraints().keySet()) {
        Object queryKeyConstraints = state.constraints().get(queryKey);
        if (queryKeyConstraints instanceof KeyConstraints) {
            KeyConstraints keyConstraints = (KeyConstraints) queryKeyConstraints;
            if (keyConstraints.containsKey("$nearSphere")) {
                mutableNearSphereKey = queryKey;
                mutableNearSphereValue = (ParseGeoPoint) keyConstraints.get("$nearSphere");
            }
        }
    }
    final String nearSphereKey = mutableNearSphereKey;
    final ParseGeoPoint nearSphereValue = mutableNearSphereValue;
    // If there's nothing to sort based on, then don't do anything.
    if (keys.size() == 0 && mutableNearSphereKey == null) {
        return;
    }
    /*
     * TODO(klimt): Test whether we allow dotting into objects for sorting.
     */
    Collections.sort(results, new Comparator<T>() {

        @Override
        public int compare(T lhs, T rhs) {
            if (nearSphereKey != null) {
                ParseGeoPoint lhsPoint;
                ParseGeoPoint rhsPoint;
                try {
                    lhsPoint = (ParseGeoPoint) getValue(lhs, nearSphereKey);
                    rhsPoint = (ParseGeoPoint) getValue(rhs, nearSphereKey);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                // GeoPoints can't be null if there's a $nearSphere.
                double lhsDistance = lhsPoint.distanceInRadiansTo(nearSphereValue);
                double rhsDistance = rhsPoint.distanceInRadiansTo(nearSphereValue);
                if (lhsDistance != rhsDistance) {
                    return (lhsDistance - rhsDistance > 0) ? 1 : -1;
                }
            }
            for (String key : keys) {
                boolean descending = false;
                if (key.startsWith("-")) {
                    descending = true;
                    key = key.substring(1);
                }
                Object lhsValue;
                Object rhsValue;
                try {
                    lhsValue = getValue(lhs, key);
                    rhsValue = getValue(rhs, key);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                int result;
                try {
                    result = compareTo(lhsValue, rhsValue);
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException(String.format("Unable to sort by key %s.", key), e);
                }
                if (result != 0) {
                    return descending ? -result : result;
                }
            }
            return 0;
        }
    });
}
Also used : JSONObject(org.json.JSONObject) KeyConstraints(com.parse.ParseQuery.KeyConstraints)

Example 2 with KeyConstraints

use of com.parse.ParseQuery.KeyConstraints in project Parse-SDK-Android by ParsePlatform.

the class OfflineQueryLogic method createMatcher.

/**
   * Returns a ConstraintMatcher that return true iff the object matches QueryConstraints. This
   * takes in a SQLiteDatabase connection because SQLite is finicky about nesting connections, so we
   * want to reuse them whenever possible.
   */
private <T extends ParseObject> ConstraintMatcher<T> createMatcher(ParseUser user, QueryConstraints queryConstraints) {
    // Make a list of all the matchers to AND together.
    final ArrayList<ConstraintMatcher<T>> matchers = new ArrayList<>();
    for (final String key : queryConstraints.keySet()) {
        final Object queryConstraintValue = queryConstraints.get(key);
        if (key.equals("$or")) {
            /*
         * A set of queries to be OR-ed together.
         */
            @SuppressWarnings("unchecked") ConstraintMatcher<T> matcher = createOrMatcher(user, (ArrayList<QueryConstraints>) queryConstraintValue);
            matchers.add(matcher);
        } else if (queryConstraintValue instanceof KeyConstraints) {
            /*
         * It's a set of constraints that should be AND-ed together.
         */
            KeyConstraints keyConstraints = (KeyConstraints) queryConstraintValue;
            for (String operator : keyConstraints.keySet()) {
                final Object keyConstraintValue = keyConstraints.get(operator);
                ConstraintMatcher<T> matcher = createMatcher(user, operator, keyConstraintValue, key, keyConstraints);
                matchers.add(matcher);
            }
        } else if (queryConstraintValue instanceof RelationConstraint) {
            /*
         * It's a $relatedTo constraint.
         */
            final RelationConstraint relation = (RelationConstraint) queryConstraintValue;
            matchers.add(new ConstraintMatcher<T>(user) {

                @Override
                public Task<Boolean> matchesAsync(T object, ParseSQLiteDatabase db) {
                    return Task.forResult(relation.getRelation().hasKnownObject(object));
                }
            });
        } else {
            /*
         * It's not a set of constraints, so it's just a value to compare against.
         */
            matchers.add(new ConstraintMatcher<T>(user) {

                @Override
                public Task<Boolean> matchesAsync(T object, ParseSQLiteDatabase db) {
                    Object objectValue;
                    try {
                        objectValue = getValue(object, key);
                    } catch (ParseException e) {
                        return Task.forError(e);
                    }
                    return Task.forResult(matchesEqualConstraint(queryConstraintValue, objectValue));
                }
            });
        }
    }
    /*
     * Now AND together the constraints for each key.
     */
    return new ConstraintMatcher<T>(user) {

        @Override
        public Task<Boolean> matchesAsync(final T object, final ParseSQLiteDatabase db) {
            Task<Boolean> task = Task.forResult(true);
            for (final ConstraintMatcher<T> matcher : matchers) {
                task = task.onSuccessTask(new Continuation<Boolean, Task<Boolean>>() {

                    @Override
                    public Task<Boolean> then(Task<Boolean> task) throws Exception {
                        if (!task.getResult()) {
                            return task;
                        }
                        return matcher.matchesAsync(object, db);
                    }
                });
            }
            return task;
        }
    };
}
Also used : Task(bolts.Task) Continuation(bolts.Continuation) ArrayList(java.util.ArrayList) QueryConstraints(com.parse.ParseQuery.QueryConstraints) RelationConstraint(com.parse.ParseQuery.RelationConstraint) JSONObject(org.json.JSONObject) KeyConstraints(com.parse.ParseQuery.KeyConstraints)

Aggregations

KeyConstraints (com.parse.ParseQuery.KeyConstraints)2 JSONObject (org.json.JSONObject)2 Continuation (bolts.Continuation)1 Task (bolts.Task)1 QueryConstraints (com.parse.ParseQuery.QueryConstraints)1 RelationConstraint (com.parse.ParseQuery.RelationConstraint)1 ArrayList (java.util.ArrayList)1