diff --git a/Parse/src/main/java/com/parse/OfflineQueryLogic.java b/Parse/src/main/java/com/parse/OfflineQueryLogic.java index 6487767b8..aee9ed7f1 100644 --- a/Parse/src/main/java/com/parse/OfflineQueryLogic.java +++ b/Parse/src/main/java/com/parse/OfflineQueryLogic.java @@ -13,6 +13,7 @@ import com.parse.ParseQuery.RelationConstraint; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; @@ -178,6 +179,24 @@ private static boolean compareList(Object constraint, List values, Decider de } /** + * Returns true if decider returns true for any value in the given list. + */ + private static boolean compareArray(Object constraint, JSONArray values, Decider decider) { + for (int i = 0; i < values.length(); ++i) { + try { + if (decider.decide(constraint, values.get(i))) { + return true; + } + } catch (JSONException e) { + // This can literally never happen. + throw new RuntimeException(e); + } + } + return false; + } + + /** + * * Returns true if the decider returns true for the given value and the given constraint. This * method handles Mongo's logic where an item can match either an item itself, or any item within * the item, if the item is an array. @@ -185,6 +204,8 @@ private static boolean compareList(Object constraint, List values, Decider de private static boolean compare(Object constraint, Object value, Decider decider) { if (value instanceof List) { return compareList(constraint, (List) value, decider); + } else if (value instanceof JSONArray) { + return compareArray(constraint, (JSONArray) value, decider); } else { return decider.decide(constraint, value); } diff --git a/Parse/src/test/java/com/parse/OfflineQueryLogicTest.java b/Parse/src/test/java/com/parse/OfflineQueryLogicTest.java index abcd7d74c..7a705cbd9 100644 --- a/Parse/src/test/java/com/parse/OfflineQueryLogicTest.java +++ b/Parse/src/test/java/com/parse/OfflineQueryLogicTest.java @@ -510,6 +510,56 @@ public void testMatchesWithin() throws ParseException { //endregion + //region compare + + @Test + public void testCompareList() throws Exception { + ParseObject object = new ParseObject("SomeObject"); + List list = new ArrayList<>(); + list.add(1); + list.add(2); + list.add(3); + object.put("list", list); + + ParseQuery.State query; + OfflineQueryLogic logic = new OfflineQueryLogic(null); + + query = new ParseQuery.State.Builder<>("SomeObject") + .whereEqualTo("list", 2) + .build(); + assertTrue(matches(logic, query, object)); + + query = new ParseQuery.State.Builder<>("SomeObject") + .whereEqualTo("list", 4) + .build(); + assertFalse(matches(logic, query, object)); + } + + @Test + public void testCompareJSONArray() throws Exception { + ParseObject object = new ParseObject("SomeObject"); + JSONArray array = new JSONArray(); + array.put(1); + array.put(2); + array.put(3); + object.put("array", array); + + ParseQuery.State query; + OfflineQueryLogic logic = new OfflineQueryLogic(null); + + query = new ParseQuery.State.Builder<>("SomeObject") + .whereEqualTo("array", 2) + .build(); + assertTrue(matches(logic, query, object)); + + query = new ParseQuery.State.Builder<>("SomeObject") + .whereEqualTo("array", 4) + .build(); + assertFalse(matches(logic, query, object)); + } + + //endregion + //region compareTo @Test