From 9d8c0a5cca4095daa9d2091a3b4ecb3812a242a7 Mon Sep 17 00:00:00 2001 From: Phill Date: Wed, 2 Jan 2019 17:23:48 +0000 Subject: [PATCH 1/5] Code tidy, User section updated --- example/lib/diet_plan.dart | 2 +- example/lib/main.dart | 9 +++- lib/data/parse_data_server.dart | 19 +++----- lib/data/parse_data_user.dart | 20 +++++--- lib/objects/parse_base.dart | 18 +++++--- lib/objects/parse_object.dart | 9 +++- lib/objects/parse_response.dart | 4 +- lib/objects/parse_user.dart | 73 ++++++++++++++++++------------ lib/utils/parse_utils_date.dart | 7 ++- lib/utils/parse_utils_objects.dart | 17 +++---- 10 files changed, 106 insertions(+), 72 deletions(-) diff --git a/example/lib/diet_plan.dart b/example/lib/diet_plan.dart index b1ec90d51..fa83e128b 100644 --- a/example/lib/diet_plan.dart +++ b/example/lib/diet_plan.dart @@ -21,7 +21,7 @@ class DietPlan extends ParseObject { static const String STATUS = 'Status'; @override - dynamic fromJson(Map objectData) { + dynamic fromJson(Map objectData) { this.name = objectData[NAME]; this.description = objectData[DESCRIPTION]; this.protein = objectData[PROTEIN]; diff --git a/example/lib/main.dart b/example/lib/main.dart index e388c77a8..5f2c0a6a4 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -113,6 +113,13 @@ class _MyAppState extends State { initUser() async { ParseUser().create("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com"); - ParseUser().signUp(); + var user = await ParseUser().signUp(); + user = await ParseUser().login(); + user = await ParseUser().currentUser(fromServer: true); + user = await ParseUser().requestPasswordReset(); + user = await ParseUser().verificationEmailRequest(); + user = await ParseUser().all(); + user = await ParseUser().save(); + user = await ParseUser().destroy(); } } diff --git a/lib/data/parse_data_server.dart b/lib/data/parse_data_server.dart index e52599550..2fcae8889 100644 --- a/lib/data/parse_data_server.dart +++ b/lib/data/parse_data_server.dart @@ -3,13 +3,13 @@ class ParseDataServer { static ParseDataServer get instance => _instance; static void init(appId, serverUrl, {debug, appName, liveQueryUrl, masterKey, sessionId}){ - _instance ??= ParseDataServer._init(appId, serverUrl); + _instance = ParseDataServer._init(appId, serverUrl); - if (debug != null) _instance..debug = debug; - if (appName != null) _instance..appName = appName; - if (liveQueryUrl != null) _instance..liveQueryURL = liveQueryUrl; - if (masterKey != null) _instance..masterKey = masterKey; - if (sessionId != null) _instance..sessionId = sessionId; + if (debug != null) _instance.debug = debug; + if (appName != null) _instance.appName = appName; + if (liveQueryUrl != null) _instance.liveQueryURL = liveQueryUrl; + if (masterKey != null) _instance.masterKey = masterKey; + if (sessionId != null) _instance.sessionId = sessionId; } String appName; @@ -22,12 +22,7 @@ class ParseDataServer { ParseDataServer._init( this.applicationId, - this.serverUrl, - {this.debug: false, - this.appName: "ParseApplication", - this.liveQueryURL, - this.masterKey, - this.sessionId}); + this.serverUrl); factory ParseDataServer() => _instance; diff --git a/lib/data/parse_data_user.dart b/lib/data/parse_data_user.dart index 6fcf17b5b..c30f74047 100644 --- a/lib/data/parse_data_user.dart +++ b/lib/data/parse_data_user.dart @@ -1,4 +1,6 @@ +import 'package:parse_server_sdk/base/parse_constants.dart'; import 'package:parse_server_sdk/objects/parse_base.dart'; +import 'package:parse_server_sdk/utils/parse_utils_date.dart'; class User extends ParseBase { static User _instance; @@ -17,13 +19,19 @@ class User extends ParseBase { factory User() => _instance; - fromJson(Map objectData) { - setObjectData(objectData); + fromJson(Map objectData) { + if (getObjectData() == null) setObjectData(objectData); + getObjectData().addAll(objectData); + if (getObjectData().containsKey(ParseConstants.OBJECT_ID)) objectId = getValue(ParseConstants.OBJECT_ID).toString(); + if (getObjectData().containsKey(ParseConstants.CREATED_AT)) createdAt = convertStringToDateTime(getValue(ParseConstants.CREATED_AT).toString()); + if (getObjectData().containsKey(ParseConstants.UPDATED_AT)) updatedAt = convertStringToDateTime(getValue(ParseConstants.UPDATED_AT).toString()); + if (getObjectData().containsKey(ACL)) acl = getValue(ACL).toString(); + if (getObjectData().containsKey(USERNAME)) username = getValue(USERNAME).toString(); + if (getObjectData().containsKey(PASSWORD)) password = getValue(PASSWORD).toString(); + if (getObjectData().containsKey(EMAIL)) emailAddress = getValue(EMAIL).toString(); + + if (updatedAt == null) updatedAt = createdAt; - acl = getObjectData()[ACL]; - username = getObjectData()[USERNAME]; - password = getObjectData()[PASSWORD]; - emailAddress = getObjectData()[EMAIL]; return this; } diff --git a/lib/objects/parse_base.dart b/lib/objects/parse_base.dart index a5b03d651..2eae594ec 100644 --- a/lib/objects/parse_base.dart +++ b/lib/objects/parse_base.dart @@ -3,13 +3,16 @@ import 'dart:convert'; import 'package:meta/meta.dart'; abstract class ParseBase { - Map _objectData; + Map _objectData; - String get objectId => _objectData['objectId']; + get getObjectId => _objectData['objectId'] == null ? objectId : _objectData['objectId']; + String objectId; - DateTime get createdAt => _objectData['createdAt']; + get getCreatedAt => _objectData['createdAt'] == null ? createdAt : _objectData['createdAt']; + DateTime createdAt; - DateTime get updatedAt => _objectData['updatedAt']; + get getUpdatedAt => _objectData['updatedAt'] == null ? updatedAt : _objectData['updatedAt']; + DateTime updatedAt; @protected toJson() => JsonEncoder().convert(getObjectData()); @@ -18,13 +21,16 @@ abstract class ParseBase { copy() => JsonDecoder().convert(fromJson(getObjectData())); @protected - setObjectData(Map objectData) => _objectData = objectData; + setObjectData(Map objectData) => _objectData = objectData; @protected getObjectData() => _objectData; @protected - fromJson(Map objectData) => objectData; + fromJson(Map objectData) { + if (_objectData == null) _objectData = Map(); + _objectData.addAll(objectData); + } setValue(String key, dynamic value, {bool forceUpdate: true}) { if (value != null) { diff --git a/lib/objects/parse_object.dart b/lib/objects/parse_object.dart index 0975d688d..de27aaf8a 100644 --- a/lib/objects/parse_object.dart +++ b/lib/objects/parse_object.dart @@ -13,8 +13,13 @@ class ParseObject extends ParseBase { bool _debug; ParseHTTPClient _client; - ParseObject(this.className, {bool debug: false, ParseHTTPClient client}) { - _debug = debug; + ParseObject(this.className, {bool debug, ParseHTTPClient client}) { + if (debug == null) { + _debug = client.data.debug; + } else { + _debug = debug; + } + _path = "/classes/$className"; setObjectData(Map()); client == null ? _client = ParseHTTPClient() : _client = client; diff --git a/lib/objects/parse_response.dart b/lib/objects/parse_response.dart index 0a7c9224a..b29d6d2fd 100644 --- a/lib/objects/parse_response.dart +++ b/lib/objects/parse_response.dart @@ -1,9 +1,9 @@ import 'dart:convert'; +import 'package:http/http.dart'; import 'package:parse_server_sdk/objects/parse_exception.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/utils/parse_utils_objects.dart'; -import 'package:http/http.dart'; class ParseResponse { bool success = false; @@ -51,7 +51,7 @@ class ParseResponse { } static _handleSingleResult(ParseObject object, map) { - ParseUtilsObjects.populateObjectBaseData(object, map); + populateObjectBaseData(object, map); return object.fromJson(map); } diff --git a/lib/objects/parse_user.dart b/lib/objects/parse_user.dart index 35df6b3f8..f72905bdf 100644 --- a/lib/objects/parse_user.dart +++ b/lib/objects/parse_user.dart @@ -10,30 +10,41 @@ class ParseUser { ParseHTTPClient _client; static final String className = '_User'; String path = "/classes/$className"; - bool debug; + bool _debug; - ParseUser({this.debug: false, ParseHTTPClient client}) { + ParseUser({debug, ParseHTTPClient client}) { client != null ? _client = client : _client = ParseHTTPClient(); + + if (_debug == null) { + _debug = client.data.debug; + } else { + _debug = _debug; + } } create(String username, String password, String emailAddress) { - User.init(username, password, emailAddress.toLowerCase()); - return User(); + User.init(username, password, emailAddress); + return User.instance; } - _getBasePath(String path) => "${_client.data.serverUrl}$path"; - currentUser({bool fromServer: false}) async { - if (User() == null) { + if (_client.data.sessionId == null) { return null; } else if (fromServer == false) { - return User(); + return User.instance; } else { - var uri = "${_getBasePath(path)}/me"; - var result = await _client.get(uri, headers: { + + Uri tempUri = Uri.parse(_client.data.serverUrl); + + Uri uri= Uri( + scheme: tempUri.scheme, + host: tempUri.host, + path: "${tempUri.path}$path/me"); + + final response = await _client.get(uri, headers: { ParseConstants.HEADER_SESSION_TOKEN: _client.data.sessionId }); - return _handleResult(result, ParseApiUserCallType.currentUser); + return _handleResponse(response, ParseApiUserCallType.currentUser); } } @@ -56,8 +67,8 @@ class ParseUser { }, body: JsonEncoder().convert(bodyData)); - _handleResult(response, ParseApiUserCallType.signUp); - return User(); + _handleResponse(response, ParseApiUserCallType.signUp); + return User.instance; } login() async { @@ -68,16 +79,16 @@ class ParseUser { host: tempUri.host, path: "${tempUri.path}/login", queryParameters: { - "username": User().username, - "password": User().password + "username": User.instance.username, + "password": User.instance.password }); final response = await _client.post(url, headers: { ParseConstants.HEADER_REVOCABLE_SESSION: "1", }); - _handleResult(response, ParseApiUserCallType.login); - return User(); + _handleResponse(response, ParseApiUserCallType.login); + return User.instance; } verificationEmailRequest() async { @@ -85,7 +96,7 @@ class ParseUser { "${_client.data.serverUrl}/verificationEmailRequest", body: JsonEncoder().convert({"email": User().emailAddress})); - return _handleResult( + return _handleResponse( response, ParseApiUserCallType.verificationEmailRequest); } @@ -94,17 +105,17 @@ class ParseUser { "${_client.data.serverUrl}/requestPasswordReset", body: JsonEncoder().convert({"email": User().emailAddress})); - return _handleResult(response, ParseApiUserCallType.requestPasswordReset); + return _handleResponse(response, ParseApiUserCallType.requestPasswordReset); } save() async { - if (User().objectId == null) { + if (User.instance.objectId == null) { return signUp(); } else { final response = await _client.put( _client.data.serverUrl + "$path/${User().objectId}", body: JsonEncoder().convert(User().getObjectData())); - return _handleResult(response, ParseApiUserCallType.save); + return _handleResponse(response, ParseApiUserCallType.save); } } @@ -112,16 +123,18 @@ class ParseUser { final response = await _client.delete( _client.data.serverUrl + "$path/${User().objectId}", headers: {"X-Parse-Session-Token": _client.data.sessionId}); - _handleResult(response, ParseApiUserCallType.destroy); - return User().objectId; + + _handleResponse(response, ParseApiUserCallType.destroy); + + return User.instance.objectId; } all() async { final response = await _client.get(_client.data.serverUrl + "$path"); - return _handleResult(response, ParseApiUserCallType.all); + return _handleResponse(response, ParseApiUserCallType.all); } - _handleResult(Response response, ParseApiUserCallType type) { + _handleResponse(Response response, ParseApiUserCallType type) { Map responseData = JsonDecoder().convert(response.body); var responseString = ' \n'; @@ -129,24 +142,24 @@ class ParseUser { responseString += "----" "\n${_client.data.appName} API Response ($className : ${getEnumValue(type)}) :"; - if (response.statusCode == 200) { + if (response.statusCode == 200 || response.statusCode == 201) { responseString += "\nStatus Code: ${response.statusCode}"; responseString += "\nPayload: ${responseData.toString()}"; if (responseData.containsKey('objectId')) { - User().fromJson(JsonDecoder().convert(response.body) as Map); - _client.data.sessionId = responseData['sessionId']; + User.instance.fromJson(JsonDecoder().convert(response.body) as Map); + _client.data.sessionId = responseData['sessionToken']; } } else { responseString += "\nStatus Code: ${responseData['code']}"; responseString += "\nException: ${responseData['error']}"; } - if (_client.data.debug || debug) { + if (_client.data.debug || _debug) { responseString += "\n----\n"; print(responseString); } - return User(); + return User.instance; } } diff --git a/lib/utils/parse_utils_date.dart b/lib/utils/parse_utils_date.dart index 8525e0b35..be4d85824 100644 --- a/lib/utils/parse_utils_date.dart +++ b/lib/utils/parse_utils_date.dart @@ -1,8 +1,7 @@ import 'package:parse_server_sdk/base/parse_constants.dart'; import 'package:intl/intl.dart'; -class ParseUtilsDates { - static DateTime convertStringToDateTime(String date) { + DateTime convertStringToDateTime(String date) { if (date == null) return null; var formatter = DateFormat(ParseConstants.PARSE_DATE_FORMAT); @@ -10,7 +9,7 @@ class ParseUtilsDates { return dateToReturn; } - static String _removeTimeZones(String date) { + String _removeTimeZones(String date) { // TODO - library doesn't support timezones. Monitor this if (date.contains('zzzZ')) { return date.replaceRange(date.length - 4, date.length, ''); @@ -18,4 +17,4 @@ class ParseUtilsDates { return date; } } -} + diff --git a/lib/utils/parse_utils_objects.dart b/lib/utils/parse_utils_objects.dart index 0684c1d1b..8e61908cb 100644 --- a/lib/utils/parse_utils_objects.dart +++ b/lib/utils/parse_utils_objects.dart @@ -2,11 +2,12 @@ import 'package:parse_server_sdk/base/parse_constants.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/utils/parse_utils_date.dart'; -class ParseUtilsObjects { - static populateObjectBaseData(ParseObject object, Map objectData) { - object.setValue(ParseConstants.OBJECT_ID, objectData[ParseConstants.OBJECT_ID]); - object.setValue(ParseConstants.CREATED_AT, ParseUtilsDates.convertStringToDateTime(objectData[ParseConstants.CREATED_AT])); - object.setValue(ParseConstants.OBJECT_ID, ParseUtilsDates.convertStringToDateTime(objectData[ParseConstants.UPDATED_AT])); - return object; - } -} \ No newline at end of file +populateObjectBaseData(ParseObject object, Map objectData) { + object.setValue( + ParseConstants.OBJECT_ID, objectData[ParseConstants.OBJECT_ID]); + object.setValue(ParseConstants.CREATED_AT, + convertStringToDateTime(objectData[ParseConstants.CREATED_AT])); + object.setValue(ParseConstants.OBJECT_ID, + convertStringToDateTime(objectData[ParseConstants.UPDATED_AT])); + return object; +} From 41e9ff7e83835234f3ab90a71e0f86d848e0e224 Mon Sep 17 00:00:00 2001 From: Phill Date: Fri, 4 Jan 2019 21:00:18 +0000 Subject: [PATCH 2/5] Added more working queries, startsWith, greaterThan, lessThan etc --- example/lib/main.dart | 68 +++++++++++++-------------- lib/network/parse_query.dart | 82 ++++++++++++++++++++------------- lib/objects/parse_object.dart | 10 ++-- lib/objects/parse_response.dart | 32 +++++-------- 4 files changed, 99 insertions(+), 93 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 5f2c0a6a4..02d3f9f3e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -35,7 +35,8 @@ class _MyAppState extends State { body: new Center( child: new Text('Running Parse init'), ), - floatingActionButton: new FloatingActionButton(onPressed: runTestQueries), + floatingActionButton: new FloatingActionButton( + onPressed: runTestQueries), ), ); } @@ -51,18 +52,18 @@ class _MyAppState extends State { ); } - runTestQueries(){ - getAllItems(); - getAllItemsByName(); - getSingleItem(); + runTestQueries() { + //getAllItems(); + //getAllItemsByName(); + //getSingleItem(); query(); - initUser(); + //initUser(); } void getAllItemsByName() async { var apiResponse = await ParseObject('ParseTableName').getAll(); - if (apiResponse.success){ + if (apiResponse.success) { for (var testObject in apiResponse.result) { print(ApplicationConstants.APP_NAME + ": " + testObject.toString()); } @@ -70,45 +71,40 @@ class _MyAppState extends State { } void getAllItems() async { - var dietPlans = await DietPlan().getAll(); - - if (dietPlans.success) { - for (var plan in dietPlans.result) { - print(ApplicationConstants.APP_NAME + ": " + (plan as DietPlan).name); - } - } else { - print(ApplicationConstants.APP_NAME + ": " + dietPlans.exception.message); + var response = await DietPlan().getAll(); + + if (response.success) { + for (var plan in response.result) { + print(ApplicationConstants.APP_NAME + ": " + (plan as DietPlan).name); } + } else { + print(ApplicationConstants.APP_NAME + ": " + response.exception.message); + } } void getSingleItem() async { - var dietPlan = await DietPlan().get('R5EonpUDWy'); + var response = await DietPlan().get('R5EonpUDWy'); - if (dietPlan.success) { - print(ApplicationConstants.APP_NAME + ": " + (dietPlan.result as DietPlan).toString()); + if (response.success) { + print(ApplicationConstants.APP_NAME + ": " + (response.result as DietPlan).toString()); } else { - print(ApplicationConstants.APP_NAME + ": " + dietPlan.exception.message); + print(ApplicationConstants.APP_NAME + ": " + response.exception.message); } } - void query() { + void query() async { // Query for an object by name - QueryBuilder() - ..object = DietPlan() - ..field = DietPlan.NAME - ..equals = ['Paleo'] - ..query().then((response) { - if (response.success) { - print(ApplicationConstants.APP_NAME + - ": " + - ((response.result as List).first as DietPlan) - .toString()); - } else { - print(ApplicationConstants.APP_NAME + - ": " + - response.exception.message); - } - }); + var queryBuilder = QueryBuilder(DietPlan()) + ..field = DietPlan.FAT + ..notEqualTo = [60, 65]; + + var response = await queryBuilder.query(); + + if (response.success) { + print(ApplicationConstants.APP_NAME + ": " + ((response.result as List).first as DietPlan).toString()); + } else { + print(ApplicationConstants.APP_NAME + ": " + response.exception.message); + } } initUser() async { diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index af0e94741..b2cf7221e 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -5,16 +5,15 @@ import 'package:parse_server_sdk/network/parse_http_client.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/objects/parse_response.dart'; -class QueryBuilder { +class QueryBuilder { - ParseObject object; + T object; final ParseHTTPClient client = ParseHTTPClient(); String path; String field; Map results; Map constraint; - Map> whereMap = - Map>(); + Map> whereMap = Map(); // QueryParams List equals; @@ -25,7 +24,7 @@ class QueryBuilder { List notEqualTo; List contains; List containedIn; - List notContainerIn; + List notContainedIn; List exists; List select; List dontSelect; @@ -38,7 +37,7 @@ class QueryBuilder { String get objectId => null; Map objectData = {}; - QueryBuilder() : super(); + QueryBuilder(this.object) : super(); void ascending(String attribute) {} @@ -46,43 +45,61 @@ class QueryBuilder { void startsWith(String key, dynamic value) {} - Future first() { - Map t = {}; - foo() => t; - return new Future(foo); - } - query() async { return object.query(_buildQuery()); } String _buildQuery() { - var existsMap = Map(); + var existsMap = Map(); + + // START QUERY + String query = "where="; + // ADD PARAM TO MAP + + //Needs fixing if (equals != null) existsMap = _runThroughQueryParams(equals, field); - if (containedIn != null) - existsMap = _runThroughQueryParamsWithName(containedIn, "in", field); - if (regEx != null) - existsMap = _runThroughQueryParamsWithName(regEx, "regex", field); - if (greaterThan != null) - existsMap = _runThroughQueryParamsWithName(greaterThan, "gt", field); - if (contains != null) - existsMap = - _runThroughQueryParamsWithSearchTerms(contains, "term", field); - - //String query = r"""where={"Name":{"$text":{"$search":{"$term":"Diet"}}}}"""; - String query = "where=${JsonEncoder().convert(existsMap)}"; + if (contains != null) existsMap = _runThroughQueryParamsWithName(contains, "\$term", field); + + // Works + if (lessThan != null) existsMap = _runThroughQueryParamsWithName(lessThan, "\$lt", field); + if (lessThanOrEqualTo != null) existsMap = _runThroughQueryParamsWithName(lessThanOrEqualTo, "\$lte", field); + if (greaterThan != null) existsMap = _runThroughQueryParamsWithName(greaterThan, "\$gt", field); + if (greaterThanOrEqualTo != null) existsMap = _runThroughQueryParamsWithName(greaterThanOrEqualTo, "\$gte", field); + if (notEqualTo != null) existsMap = _runThroughQueryParamsWithName(notEqualTo, "\$ne", field); + + // Not sure + if (containedIn != null) existsMap = _runThroughQueryParamsWithName(containedIn, "\$in", field); + if (notContainedIn != null) existsMap = _runThroughQueryParamsWithName(notContainedIn, "\$nin", field); + if (exists != null) existsMap = _runThroughQueryParamsWithName(exists, "\$exists", field); + if (select != null) existsMap = _runThroughQueryParamsWithName(select, "\$select", field); + if (dontSelect != null) existsMap = _runThroughQueryParamsWithName(dontSelect, "\$dontSelect", field); + if (all != null) existsMap = _runThroughQueryParamsWithName(all, "\$all", field); + + // Works + if (regEx != null) existsMap = _runThroughQueryParamsWithName(regEx, "\$regex", field); + + // Doesnt + if (text != null) existsMap = _runThroughQueryParamsWithName(text, "\$text", field); + + // -- BUILD QUERY USING MAP + for(var item in existsMap.entries){ + query += "{\"${item.key.toString()}\":${item.value}}"; + } + // -- ADD LIMITER if (limit != 0) query += '?limit=$limit'; if (skip != 0) query += '?skip=$skip'; + // -- TEST + print("QUERY: $query"); + return query; } - Map _runThroughQueryParams( - List list, String queryParam) { - Map mapToReturn = Map(); - var params = ""; + Map _runThroughQueryParams(List list, String queryParam) { + Map mapToReturn = Map(); + var params; if (list.isNotEmpty) { if (list.length == 1) { @@ -101,16 +118,15 @@ class QueryBuilder { return mapToReturn; } - Map _runThroughQueryParamsWithName( - List list, String queryParam, String fieldName) { + Map _runThroughQueryParamsWithName(List list, String queryParam, String fieldName) { Map mapToReturn = Map(); Map mapWithParamData = Map(); for (var item in list) { - mapWithParamData["\$$queryParam"] = item; + mapWithParamData.putIfAbsent(queryParam, item); } - var params = JsonEncoder().convert(mapWithParamData).toString(); + var params = JsonEncoder().convert(mapWithParamData); mapToReturn[fieldName] = params; diff --git a/lib/objects/parse_object.dart b/lib/objects/parse_object.dart index de27aaf8a..196a1475d 100644 --- a/lib/objects/parse_object.dart +++ b/lib/objects/parse_object.dart @@ -14,15 +14,17 @@ class ParseObject extends ParseBase { ParseHTTPClient _client; ParseObject(this.className, {bool debug, ParseHTTPClient client}) { + + client == null ? _client = ParseHTTPClient() : _client = client; + if (debug == null) { - _debug = client.data.debug; + _debug = _client.data.debug; } else { _debug = debug; } _path = "/classes/$className"; setObjectData(Map()); - client == null ? _client = ParseHTTPClient() : _client = client; } get(String objectId) async { @@ -84,8 +86,8 @@ class ParseObject extends ParseBase { responseString += "\nStatus Code: ${parseResponse.statusCode}"; responseString += "\nPayload: ${responseData.toString()}"; } else if (!parseResponse.success) { - responseString += "\nStatus Code: ${responseData['code']}"; - responseString += "\nException: ${responseData['error']}"; + responseString += "\nStatus Code: ${responseData['code'] == null ? parseResponse.statusCode : responseData['code']}"; + responseString += "\nException: ${responseData['error'] == null ? responseData.toString() : responseData['error']}"; } responseString += "\n----\n"; diff --git a/lib/objects/parse_response.dart b/lib/objects/parse_response.dart index b29d6d2fd..d7e0028af 100644 --- a/lib/objects/parse_response.dart +++ b/lib/objects/parse_response.dart @@ -11,8 +11,7 @@ class ParseResponse { dynamic result; ParseException exception; - static ParseResponse _handleSuccess( - ParseResponse response, ParseObject object, String responseBody) { + static ParseResponse _handleSuccess(ParseResponse response, ParseObject object, String responseBody) { response.success = true; var map = JsonDecoder().convert(responseBody) as Map; @@ -23,20 +22,6 @@ class ParseResponse { response.result = _handleSingleResult(object, map); } - response = _checkForEmptyResult(response); - - return response; - } - - static ParseResponse _checkForEmptyResult(ParseResponse response) { - if (response.result == null || - ((response.result == List) && - (response.result as List).length == 0)) { - response.exception = ParseException(); - response.exception.message = "No result found for query"; - response.success = false; - } - return response; } @@ -55,13 +40,19 @@ class ParseResponse { return object.fromJson(map); } - static ParseResponse _handleError( - ParseResponse response, Response value) { + static ParseResponse _handleError(ParseResponse response, Response value) { response.exception = ParseException(); response.exception.message = value.reasonPhrase; return response; } + static ParseResponse _handleSuccessWithNoResults(ParseResponse response, String value) { + response.statusCode = 200; + response.exception = ParseException(); + response.exception.message = value; + return response; + } + static handleResponse(ParseObject object, Response value) { var response = ParseResponse(); @@ -70,13 +61,14 @@ class ParseResponse { if (value.statusCode != 200) { return _handleError(response, value); + } else if (value.body == "{\"results\":[]}"){ + return _handleSuccessWithNoResults(response, "Successful request but no results found"); } else { return _handleSuccess(response, object, value.body); } } else { response.exception = ParseException(); - response.exception.message = - "Error reaching server, or server response was null"; + response.exception.message = "Error reaching server, or server response was null"; return response; } } From c9beb941a69750f736751d209f647910a8031f55 Mon Sep 17 00:00:00 2001 From: Phill Date: Sat, 5 Jan 2019 17:09:27 +0000 Subject: [PATCH 3/5] Added ability to use less than and greater than in single query --- example/lib/main.dart | 30 ++++++------- lib/network/parse_query.dart | 85 +++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 02d3f9f3e..4e03288d6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,11 +1,8 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:flutter_plugin_example/application_constants.dart'; import 'package:flutter_plugin_example/diet_plan.dart'; -import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/network/parse_query.dart'; -import 'package:parse_server_sdk/objects/parse_response.dart'; +import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/objects/parse_user.dart'; import 'package:parse_server_sdk/parse.dart'; @@ -17,7 +14,6 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - @override void initState() { super.initState(); @@ -35,21 +31,19 @@ class _MyAppState extends State { body: new Center( child: new Text('Running Parse init'), ), - floatingActionButton: new FloatingActionButton( - onPressed: runTestQueries), + floatingActionButton: + new FloatingActionButton(onPressed: runTestQueries), ), ); } initParse() async { // Initialize parse - Parse().initialize( - ApplicationConstants.PARSE_APPLICATION_ID, + Parse().initialize(ApplicationConstants.PARSE_APPLICATION_ID, ApplicationConstants.PARSE_SERVER_URL, masterKey: ApplicationConstants.PARSE_MASTER_KEY, appName: ApplicationConstants.APP_NAME, - debug: true - ); + debug: true); } runTestQueries() { @@ -86,7 +80,9 @@ class _MyAppState extends State { var response = await DietPlan().get('R5EonpUDWy'); if (response.success) { - print(ApplicationConstants.APP_NAME + ": " + (response.result as DietPlan).toString()); + print(ApplicationConstants.APP_NAME + + ": " + + (response.result as DietPlan).toString()); } else { print(ApplicationConstants.APP_NAME + ": " + response.exception.message); } @@ -96,19 +92,23 @@ class _MyAppState extends State { // Query for an object by name var queryBuilder = QueryBuilder(DietPlan()) ..field = DietPlan.FAT - ..notEqualTo = [60, 65]; + ..greaterThan = [59] + ..lessThan = [61]; var response = await queryBuilder.query(); if (response.success) { - print(ApplicationConstants.APP_NAME + ": " + ((response.result as List).first as DietPlan).toString()); + print(ApplicationConstants.APP_NAME + + ": " + + ((response.result as List).first as DietPlan).toString()); } else { print(ApplicationConstants.APP_NAME + ": " + response.exception.message); } } initUser() async { - ParseUser().create("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com"); + ParseUser() + .create("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com"); var user = await ParseUser().signUp(); user = await ParseUser().login(); user = await ParseUser().currentUser(fromServer: true); diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index b2cf7221e..5699d4861 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -50,54 +50,77 @@ class QueryBuilder { } String _buildQuery() { - var existsMap = Map(); + var queries = List(); // START QUERY - String query = "where="; + const String QUERY_START = "where={"; + const String QUERY_END = "}"; - // ADD PARAM TO MAP + var query = QUERY_START; + // ADD PARAM TO MAP //Needs fixing - if (equals != null) existsMap = _runThroughQueryParams(equals, field); - if (contains != null) existsMap = _runThroughQueryParamsWithName(contains, "\$term", field); + if (equals != null) queries.add(_runThroughQueryParams(equals, field)); + if (contains != null) queries.add(_buildQueryWithOperatorAndField(contains, "\$term", field)); // Works - if (lessThan != null) existsMap = _runThroughQueryParamsWithName(lessThan, "\$lt", field); - if (lessThanOrEqualTo != null) existsMap = _runThroughQueryParamsWithName(lessThanOrEqualTo, "\$lte", field); - if (greaterThan != null) existsMap = _runThroughQueryParamsWithName(greaterThan, "\$gt", field); - if (greaterThanOrEqualTo != null) existsMap = _runThroughQueryParamsWithName(greaterThanOrEqualTo, "\$gte", field); - if (notEqualTo != null) existsMap = _runThroughQueryParamsWithName(notEqualTo, "\$ne", field); + if (lessThan != null) queries.add(_buildQueryWithOperatorAndField(lessThan, "\$lt", field)); + if (lessThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(lessThanOrEqualTo, "\$lte", field)); + if (greaterThan != null) queries.add(_buildQueryWithOperatorAndField(greaterThan, "\$gt", field)); + if (greaterThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(greaterThanOrEqualTo, "\$gte", field)); + if (notEqualTo != null) queries.add(_buildQueryWithOperatorAndField(notEqualTo, "\$ne", field)); // Not sure - if (containedIn != null) existsMap = _runThroughQueryParamsWithName(containedIn, "\$in", field); - if (notContainedIn != null) existsMap = _runThroughQueryParamsWithName(notContainedIn, "\$nin", field); - if (exists != null) existsMap = _runThroughQueryParamsWithName(exists, "\$exists", field); - if (select != null) existsMap = _runThroughQueryParamsWithName(select, "\$select", field); - if (dontSelect != null) existsMap = _runThroughQueryParamsWithName(dontSelect, "\$dontSelect", field); - if (all != null) existsMap = _runThroughQueryParamsWithName(all, "\$all", field); + if (containedIn != null) queries.add(_buildQueryWithOperatorAndField(containedIn, "\$in", field)); + if (notContainedIn != null) queries.add(_buildQueryWithOperatorAndField(notContainedIn, "\$nin", field)); + if (exists != null) queries.add(_buildQueryWithOperatorAndField(exists, "\$exists", field)); + if (select != null) queries.add(_buildQueryWithOperatorAndField(select, "\$select", field)); + if (dontSelect != null) queries.add( _buildQueryWithOperatorAndField(dontSelect, "\$dontSelect", field)); + if (all != null) queries.add(_buildQueryWithOperatorAndField(all, "\$all", field)); // Works - if (regEx != null) existsMap = _runThroughQueryParamsWithName(regEx, "\$regex", field); + if (regEx != null) queries.add(_buildQueryWithOperatorAndField(regEx, "\$regex", field)); // Doesnt - if (text != null) existsMap = _runThroughQueryParamsWithName(text, "\$text", field); + if (text != null) queries.add(_buildQueryWithOperatorAndField(text, "\$text", field)); // -- BUILD QUERY USING MAP - for(var item in existsMap.entries){ - query += "{\"${item.key.toString()}\":${item.value}}"; + for(var item in queries){ + if (query == QUERY_START) { + query += item; + } else { + query += ",$item"; + } } // -- ADD LIMITER if (limit != 0) query += '?limit=$limit'; if (skip != 0) query += '?skip=$skip'; + query += QUERY_END; + // -- TEST print("QUERY: $query"); return query; } - Map _runThroughQueryParams(List list, String queryParam) { + _buildQueryWithOperatorAndField(List listOfValuesToQuery, String queryOperator, String tableNameToQuery) { + + var queryOperatorAndValueMap = Map(); + var queryString = "\"$tableNameToQuery\":"; + + for (var queryValue in listOfValuesToQuery) { + queryOperatorAndValueMap[queryOperator] = queryValue; + } + + var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap); + queryString += "$formattedQueryOperatorAndValue"; + + return queryString; + } + + _runThroughQueryParams(List list, String queryParam) { Map mapToReturn = Map(); var params; @@ -115,26 +138,10 @@ class QueryBuilder { mapToReturn[queryParam] = params; - return mapToReturn; - } - - Map _runThroughQueryParamsWithName(List list, String queryParam, String fieldName) { - Map mapToReturn = Map(); - Map mapWithParamData = Map(); - - for (var item in list) { - mapWithParamData.putIfAbsent(queryParam, item); - } - - var params = JsonEncoder().convert(mapWithParamData); - - mapToReturn[fieldName] = params; - - return mapToReturn; + return JsonEncoder().convert(mapToReturn); } - Map _runThroughQueryParamsWithSearchTerms( - List list, String queryParam, String fieldName) { + Map _runThroughQueryParamsWithSearchTerms(List list, String queryParam, String fieldName) { Map mapToReturn = Map(); Map mapWithParamData = Map(); Map textEntry = Map(); From bed40ea48202014732215e84f60f8d67343f2ff3 Mon Sep 17 00:00:00 2001 From: Phill Date: Sun, 6 Jan 2019 11:02:39 +0000 Subject: [PATCH 4/5] Now can use multiple queries on same fields --- example/lib/main.dart | 5 +- lib/network/parse_query.dart | 216 +++++++++++++++++++++++++---------- 2 files changed, 157 insertions(+), 64 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 4e03288d6..9a19a9534 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -91,9 +91,8 @@ class _MyAppState extends State { void query() async { // Query for an object by name var queryBuilder = QueryBuilder(DietPlan()) - ..field = DietPlan.FAT - ..greaterThan = [59] - ..lessThan = [61]; + ..lessThan(DietPlan.FAT, 61) + ..greaterThan(DietPlan.FAT, 59); var response = await queryBuilder.query(); diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index 5699d4861..2ad8c63e5 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -1,56 +1,102 @@ -import 'dart:async'; import 'dart:convert'; -import 'package:parse_server_sdk/network/parse_http_client.dart'; import 'package:parse_server_sdk/objects/parse_object.dart'; -import 'package:parse_server_sdk/objects/parse_response.dart'; -class QueryBuilder { +class QueryBuilder { T object; - final ParseHTTPClient client = ParseHTTPClient(); - String path; - String field; - Map results; - Map constraint; - Map> whereMap = Map(); // QueryParams - List equals; - List lessThan; - List lessThanOrEqualTo; - List greaterThan; - List greaterThanOrEqualTo; - List notEqualTo; - List contains; - List containedIn; - List notContainedIn; - List exists; - List select; - List dontSelect; - List all; - List regEx; - List text; + List _equalsQueries = List(); + List _lessThanQueries = List(); + List _lessThanOrEqualToQueries = List(); + List _greaterThanQueries = List(); + List _greaterThanOrEqualToQueries = List(); + List _notEqualToQueries = List(); + List _containsQueries = List(); + List _containedInQueries = List(); + List _notContainedInQueries = List(); + List _existsQueries = List(); + List _selectQueries = List(); + List _dontSelectQueries = List(); + List _allQueries = List(); + List _regExQueries = List(); + List _textQueries = List(); int limit = 0; int skip = 0; - String get objectId => null; - Map objectData = {}; - QueryBuilder(this.object) : super(); - void ascending(String attribute) {} + void startsWith(String key, dynamic value) { + _regExQueries.add(MapEntry(key, "^$value")); + } + + void endsWith(String key, dynamic value) { + _regExQueries.add(MapEntry(key, "$value^")); + } + + void equals(String column, dynamic value) { + _equalsQueries.add(MapEntry(column, value)); + } + + void lessThan(String column, dynamic value) { + _lessThanQueries.add(MapEntry(column, value)); + } + + void lessThanOrEqualTo(String column, dynamic value) { + _lessThanOrEqualToQueries.add(MapEntry(column, value)); + } - void descending(String attribute) {} + void greaterThan(String column, dynamic value) { + _greaterThanQueries.add(MapEntry(column, value)); + } - void startsWith(String key, dynamic value) {} + void greaterThanOrEqualsTo(String column, dynamic value) { + _greaterThanOrEqualToQueries.add(MapEntry(column, value)); + } + + void notEqualTo(String column, dynamic value) { + _notEqualToQueries.add(MapEntry(column, value)); + } + + void contains(String column, dynamic value) { + _containsQueries.add(MapEntry(column, value)); + } + + void containedIn(String column, dynamic value) { + _containedInQueries.add(MapEntry(column, value)); + } + + void exists(String column, dynamic value) { + _existsQueries.add(MapEntry(column, value)); + } + + void select(String column, dynamic value) { + _selectQueries.add(MapEntry(column, value)); + } + + void dontSelect(String column, dynamic value) { + _dontSelectQueries.add(MapEntry(column, value)); + } + + void all(String column, dynamic value) { + _allQueries.add(MapEntry(column, value)); + } + + void regEx(String column, dynamic value) { + _regExQueries.add(MapEntry(column, value)); + } + + void text(String column, dynamic value) { + _textQueries.add(MapEntry(column, value)); + } query() async { return object.query(_buildQuery()); } String _buildQuery() { - var queries = List(); + var queries = List(); // START QUERY const String QUERY_START = "where={"; @@ -60,36 +106,38 @@ class QueryBuilder { // ADD PARAM TO MAP //Needs fixing - if (equals != null) queries.add(_runThroughQueryParams(equals, field)); - if (contains != null) queries.add(_buildQueryWithOperatorAndField(contains, "\$term", field)); + if (_equalsQueries.length != 0) queries.addAll(_runThroughQueryParams(_equalsQueries)); + if (_containsQueries.length != 0) queries.addAll(_getAllQueries(_containsQueries, "\$term")); // Works - if (lessThan != null) queries.add(_buildQueryWithOperatorAndField(lessThan, "\$lt", field)); - if (lessThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(lessThanOrEqualTo, "\$lte", field)); - if (greaterThan != null) queries.add(_buildQueryWithOperatorAndField(greaterThan, "\$gt", field)); - if (greaterThanOrEqualTo != null) queries.add(_buildQueryWithOperatorAndField(greaterThanOrEqualTo, "\$gte", field)); - if (notEqualTo != null) queries.add(_buildQueryWithOperatorAndField(notEqualTo, "\$ne", field)); + if (_lessThanQueries.length != 0) queries.addAll(_getAllQueries(_lessThanQueries, "\$lt")); + if (_lessThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_lessThanOrEqualToQueries, "\$lte")); + if (_greaterThanQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanQueries, "\$gt")); + if (_greaterThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanOrEqualToQueries, "\$gte")); + if (_notEqualToQueries.length != 0) queries.addAll(_getAllQueries(_notEqualToQueries, "\$ne")); // Not sure - if (containedIn != null) queries.add(_buildQueryWithOperatorAndField(containedIn, "\$in", field)); - if (notContainedIn != null) queries.add(_buildQueryWithOperatorAndField(notContainedIn, "\$nin", field)); - if (exists != null) queries.add(_buildQueryWithOperatorAndField(exists, "\$exists", field)); - if (select != null) queries.add(_buildQueryWithOperatorAndField(select, "\$select", field)); - if (dontSelect != null) queries.add( _buildQueryWithOperatorAndField(dontSelect, "\$dontSelect", field)); - if (all != null) queries.add(_buildQueryWithOperatorAndField(all, "\$all", field)); + if (_containedInQueries.length != 0) queries.addAll(_getAllQueries(_containedInQueries, "\$in")); + if (_notContainedInQueries.length != 0) queries.addAll(_getAllQueries(_notContainedInQueries, "\$nin")); + if (_existsQueries.length != 0) queries.addAll(_getAllQueries(_existsQueries, "\$exists")); + if (_selectQueries.length != 0) queries.addAll(_getAllQueries(_selectQueries, "\$select")); + if (_dontSelectQueries.length != 0) queries.addAll(_getAllQueries(_dontSelectQueries, "\$dontSelect")); + if (_allQueries.length != 0) queries.addAll(_getAllQueries(_allQueries, "\$all")); // Works - if (regEx != null) queries.add(_buildQueryWithOperatorAndField(regEx, "\$regex", field)); + if (_regExQueries.length != 0) queries.addAll(_getAllQueries(_regExQueries, "\$regex")); // Doesnt - if (text != null) queries.add(_buildQueryWithOperatorAndField(text, "\$text", field)); + if (_textQueries.length != 0) queries.addAll(_getAllQueries(_textQueries, "\$text")); + + queries = _checkForMultipleColumnInstances(queries); // -- BUILD QUERY USING MAP - for(var item in queries){ + for (var item in queries) { if (query == QUERY_START) { - query += item; + query += item.value; } else { - query += ",$item"; + query += ",${item.value}"; } } @@ -105,22 +153,28 @@ class QueryBuilder { return query; } - _buildQueryWithOperatorAndField(List listOfValuesToQuery, String queryOperator, String tableNameToQuery) { + _getAllQueries(List queries, String queryOperator){ + List queriesToReturn = List(); + for (var query in queries){ + queriesToReturn.add(_buildQueryWithColumnValueAndOperator(query, queryOperator)); + } + return queriesToReturn; + } - var queryOperatorAndValueMap = Map(); - var queryString = "\"$tableNameToQuery\":"; + _buildQueryWithColumnValueAndOperator(MapEntry columnAndValue, String queryOperator) { - for (var queryValue in listOfValuesToQuery) { - queryOperatorAndValueMap[queryOperator] = queryValue; - } + var queryString = "\"${columnAndValue.key}\":"; + + var queryOperatorAndValueMap = Map(); + queryOperatorAndValueMap[queryOperator] = columnAndValue.value; var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap); queryString += "$formattedQueryOperatorAndValue"; - return queryString; + return MapEntry(columnAndValue.key, queryString); } - _runThroughQueryParams(List list, String queryParam) { + _runThroughQueryParams(List list) { Map mapToReturn = Map(); var params; @@ -136,12 +190,11 @@ class QueryBuilder { } } - mapToReturn[queryParam] = params; + mapToReturn["wasField"] = params; return JsonEncoder().convert(mapToReturn); } - - Map _runThroughQueryParamsWithSearchTerms(List list, String queryParam, String fieldName) { + _runThroughQueryParamsWithSearchTerms(List list, String queryParam, String fieldName) { Map mapToReturn = Map(); Map mapWithParamData = Map(); Map textEntry = Map(); @@ -162,4 +215,45 @@ class QueryBuilder { return mapToReturn; } + + _checkForMultipleColumnInstances(List queries) { + List sanitisedQueries = List(); + List keysAlreadyCompacted = List(); + + // Run through each query + for (var query in queries){ + + // Check if query with same column name has been sanitised + if (!keysAlreadyCompacted.contains(query.key)) { + + // If not, check that it now has + keysAlreadyCompacted.add(query.key); + + // Build a list of all queries with the same column name + var listOfQueriesCompact = queries.where((i) => query.key == i.key).toList(); + + // Build first part of query + var queryStart = "\"${query.key}\":"; + var queryEnd = ""; + + // Compact all the queries in the correct format + for (var queryToCompact in listOfQueriesCompact) { + + var queryToCompactValue = queryToCompact.value.toString(); + queryToCompactValue = queryToCompactValue.replaceFirst("{", ""); + queryToCompactValue = queryToCompactValue.replaceAll("}", ""); + + if (listOfQueriesCompact.first == queryToCompact){ + queryEnd += (queryToCompactValue.replaceAll(queryStart, " ")); + } else { + queryEnd += (queryToCompactValue.replaceAll(queryStart, ", ")); + } + } + + sanitisedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}")); + } + } + + return sanitisedQueries; + } } From 508f102d4ce91aad1afde2b7d72d23a6fe5cdb57 Mon Sep 17 00:00:00 2001 From: Phill Date: Sun, 6 Jan 2019 13:07:44 +0000 Subject: [PATCH 5/5] Added equals correction, now can check for num vs string --- example/lib/main.dart | 10 ++--- lib/network/parse_query.dart | 73 ++++++++++++------------------------ 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 9a19a9534..925ba6157 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -91,15 +91,15 @@ class _MyAppState extends State { void query() async { // Query for an object by name var queryBuilder = QueryBuilder(DietPlan()) - ..lessThan(DietPlan.FAT, 61) - ..greaterThan(DietPlan.FAT, 59); + ..startsWith(DietPlan.NAME, "Keto") + ..greaterThan(DietPlan.FAT, 64) + ..lessThan(DietPlan.FAT, 66) + ..equals(DietPlan.CARBS, 5); var response = await queryBuilder.query(); if (response.success) { - print(ApplicationConstants.APP_NAME + - ": " + - ((response.result as List).first as DietPlan).toString()); + print(ApplicationConstants.APP_NAME + ": " + ((response.result as List).first as DietPlan).toString()); } else { print(ApplicationConstants.APP_NAME + ": " + response.exception.message); } diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index 2ad8c63e5..78c5a3f36 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -4,6 +4,8 @@ import 'package:parse_server_sdk/objects/parse_object.dart'; class QueryBuilder { + static const String _NO_OPERATOR_NEEDED = "NO_OP"; + T object; // QueryParams @@ -106,10 +108,10 @@ class QueryBuilder { // ADD PARAM TO MAP //Needs fixing - if (_equalsQueries.length != 0) queries.addAll(_runThroughQueryParams(_equalsQueries)); if (_containsQueries.length != 0) queries.addAll(_getAllQueries(_containsQueries, "\$term")); // Works + if (_equalsQueries.length != 0) queries.addAll(_getAllQueries(_equalsQueries, _NO_OPERATOR_NEEDED)); if (_lessThanQueries.length != 0) queries.addAll(_getAllQueries(_lessThanQueries, "\$lt")); if (_lessThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_lessThanOrEqualToQueries, "\$lte")); if (_greaterThanQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanQueries, "\$gt")); @@ -163,57 +165,22 @@ class QueryBuilder { _buildQueryWithColumnValueAndOperator(MapEntry columnAndValue, String queryOperator) { - var queryString = "\"${columnAndValue.key}\":"; - - var queryOperatorAndValueMap = Map(); - queryOperatorAndValueMap[queryOperator] = columnAndValue.value; + var key = columnAndValue.key; + var value = convertValueToCorrectType(columnAndValue.value); - var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap); - queryString += "$formattedQueryOperatorAndValue"; + if (queryOperator == _NO_OPERATOR_NEEDED){ + return MapEntry(_NO_OPERATOR_NEEDED, "\"${columnAndValue.key}\": $value"); + } else { + var queryString = "\"$key\":"; - return MapEntry(columnAndValue.key, queryString); - } + var queryOperatorAndValueMap = Map(); + queryOperatorAndValueMap[queryOperator] = columnAndValue.value; - _runThroughQueryParams(List list) { - Map mapToReturn = Map(); - var params; - - if (list.isNotEmpty) { - if (list.length == 1) { - params = list[0]; - } else { - for (var listItem in list) { - params += "$listItem, "; - } + var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap); + queryString += "$formattedQueryOperatorAndValue"; - params.substring(0, params.length - 2); - } + return MapEntry(key, queryString); } - - mapToReturn["wasField"] = params; - - return JsonEncoder().convert(mapToReturn); - } - _runThroughQueryParamsWithSearchTerms(List list, String queryParam, String fieldName) { - Map mapToReturn = Map(); - Map mapWithParamData = Map(); - Map textEntry = Map(); - Map searchEntry = Map(); - - for (var item in list) { - mapWithParamData["\$$queryParam"] = item; - } - - var jsonMapWithParamData = JsonEncoder().convert(mapWithParamData); - searchEntry['search'] = jsonMapWithParamData; - - var jsonSearchEntry = JsonEncoder().convert(searchEntry); - textEntry['text'] = jsonSearchEntry; - - var params = JsonEncoder().convert(textEntry).toString(); - mapToReturn[fieldName] = params; - - return mapToReturn; } _checkForMultipleColumnInstances(List queries) { @@ -223,8 +190,13 @@ class QueryBuilder { // Run through each query for (var query in queries){ + // Add queries that don't need sanitising + if (query.key == _NO_OPERATOR_NEEDED) { + sanitisedQueries.add(MapEntry(_NO_OPERATOR_NEEDED, query.value)); + } + // Check if query with same column name has been sanitised - if (!keysAlreadyCompacted.contains(query.key)) { + if (!keysAlreadyCompacted.contains(query.key) && query.key != _NO_OPERATOR_NEEDED) { // If not, check that it now has keysAlreadyCompacted.add(query.key); @@ -256,4 +228,9 @@ class QueryBuilder { return sanitisedQueries; } + + convertValueToCorrectType(dynamic value) { + if (value is int) return (value as num); + if (value is String) return "\"$value\""; + } }