diff --git a/lib/src/network/parse_query.dart b/lib/src/network/parse_query.dart index d06536b07..d32a5c1ea 100644 --- a/lib/src/network/parse_query.dart +++ b/lib/src/network/parse_query.dart @@ -237,6 +237,22 @@ class QueryBuilder { '\"$column\":{\"\$within\":{\"\$box\": [{\"__type\": \"GeoPoint\",\"latitude\":$latitudeS,\"longitude\":$longitudeS},{\"__type\": \"GeoPoint\",\"latitude\":$latitudeN,\"longitude\":$longitudeN}]}}')); } + // Add a constraint to the query that requires a particular key's value match another QueryBuilder + void whereMatchesQuery(String column, QueryBuilder query) { + String inQuery = query._buildQueryRelational(query.object.className); + + queries.add(MapEntry( + _SINGLE_QUERY, '\"$column\":{\"\$inQuery\":$inQuery}')); + } + + //Add a constraint to the query that requires a particular key's value does not match another QueryBuilder + void whereDoesNotMatchQuery(String column, QueryBuilder query) { + String inQuery = query._buildQueryRelational(query.object.className); + + queries.add(MapEntry( + _SINGLE_QUERY, '\"$column\":{\"\$notInQuery\":$inQuery}')); + } + /// Finishes the query and calls the server /// /// Make sure to call this after defining your queries @@ -244,12 +260,29 @@ class QueryBuilder { return object.query(_buildQuery()); } + ///Counts the number of objects that match this query + Future count() async { + return object.query(_buildQueryCount()); + } + /// Builds the query for Parse String _buildQuery() { queries = _checkForMultipleColumnInstances(queries); return 'where={${buildQueries(queries)}}${getLimiters(limiters)}'; } + /// Builds the query relational for Parse + String _buildQueryRelational(String className) { + queries = _checkForMultipleColumnInstances(queries); + return '{\"where\":{${buildQueries(queries)}},\"className\":\"$className\"${getLimitersRelational(limiters)}}'; + } + + /// Builds the query for Parse + String _buildQueryCount() { + queries = _checkForMultipleColumnInstances(queries); + return 'where={${buildQueries(queries)}}&count=1'; + } + /// Runs through all queries and adds them to a query string String buildQueries(List> queries) { String queryBuilder = ''; @@ -284,17 +317,20 @@ class QueryBuilder { /// that the column and value are being queried against MapEntry _buildQueryWithColumnValueAndOperator( MapEntry columnAndValue, String queryOperator) { - final String key = columnAndValue.key; - final dynamic value = convertValueToCorrectType(parseEncode(columnAndValue.value)); + final dynamic value = + convertValueToCorrectType(parseEncode(columnAndValue.value)); if (queryOperator == _NO_OPERATOR_NEEDED) { - return MapEntry(_NO_OPERATOR_NEEDED, '\"$key\": ${jsonEncode(value)}'); + return MapEntry( + _NO_OPERATOR_NEEDED, '\"$key\": ${jsonEncode(value)}'); } else { String queryString = '\"$key\":'; - final Map queryOperatorAndValueMap = Map(); + final Map queryOperatorAndValueMap = + Map(); queryOperatorAndValueMap[queryOperator] = parseEncode(value); - final String formattedQueryOperatorAndValue = jsonEncode(queryOperatorAndValueMap); + final String formattedQueryOperatorAndValue = + jsonEncode(queryOperatorAndValueMap); queryString += '$formattedQueryOperatorAndValue'; return MapEntry(key, queryString); } @@ -336,7 +372,8 @@ class QueryBuilder { for (MapEntry queryToCompact in listOfQueriesCompact) { var queryToCompactValue = queryToCompact.value.toString(); queryToCompactValue = queryToCompactValue.replaceFirst("{", ""); - queryToCompactValue = queryToCompactValue.replaceRange(queryToCompactValue.length - 1, queryToCompactValue.length, ""); + queryToCompactValue = queryToCompactValue.replaceRange( + queryToCompactValue.length - 1, queryToCompactValue.length, ""); if (listOfQueriesCompact.first == queryToCompact) { queryEnd += queryToCompactValue.replaceAll(queryStart, ' '); } else { @@ -364,4 +401,17 @@ class QueryBuilder { }); return result; } + + /// Adds the limiters to the query relational, i.e. skip=10, limit=10 + String getLimitersRelational(Map map) { + String result = ''; + map.forEach((String key, dynamic value) { + if (result != null) { + result = result + ',\"$key":$value'; + } else { + result = '\"$key\":$value'; + } + }); + return result; + } } diff --git a/lib/src/objects/response/parse_response_builder.dart b/lib/src/objects/response/parse_response_builder.dart index 74075ca03..b7e06767b 100644 --- a/lib/src/objects/response/parse_response_builder.dart +++ b/lib/src/objects/response/parse_response_builder.dart @@ -71,6 +71,11 @@ class _ParseResponseBuilder { response.results = items; response.result = items; response.count = items.length; + } else if (map != null && map.length == 2 && map.containsKey('count')) { + final List results = [map['count']]; + response.results = results; + response.result = results; + response.count = map['count']; } else { final T item = _handleSingleResult(object, map, false); response.count = 1;