diff --git a/example/lib/main.dart b/example/lib/main.dart index 73d25c00d..e70d2dfaa 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,48 +16,67 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { + @override void initState() { super.initState(); initParse(); - getAllItems(); - getSingleItem(); - //query(); - //queryByContainedIn(); - initUser(); + runTestQueries(); } - Future initParse() async { + @override + Widget build(BuildContext context) { + return new MaterialApp( + home: new Scaffold( + appBar: new AppBar( + title: const Text('Plugin example app'), + ), + body: new Center( + child: new Text('Running Parse init'), + ), + floatingActionButton: new FloatingActionButton(onPressed: runTestQueries), + ), + ); + } + initParse() async { // Initialize parse Parse().initialize( ApplicationConstants.PARSE_APPLICATION_ID, ApplicationConstants.PARSE_SERVER_URL, - masterKey: ApplicationConstants.PARSE_MASTER_KEY); + masterKey: ApplicationConstants.PARSE_MASTER_KEY, + appName: ApplicationConstants.APP_NAME, + debug: true + ); } - void getAllItems() { - DietPlan().getAll().then((response) { - if (response.success){ + runTestQueries(){ + getAllItems(); + getSingleItem(); + query(); + initUser(); + } + + void getAllItems() async { + var dietPlans = await DietPlan().getAll(); - for (var plan in response.result) { + if (dietPlans.success) { + for (var plan in dietPlans.result) { print(ApplicationConstants.APP_NAME + ": " + (plan as DietPlan).name); } - } else { - print(ApplicationConstants.APP_NAME + ": " + response.exception.message); + print(ApplicationConstants.APP_NAME + ": " + dietPlans.exception.message); } - }); } - void getSingleItem() { - DietPlan().get('R5EonpUDWy').then((response) { - if (response.success){ - print(ApplicationConstants.APP_NAME + ": " + (response.result as DietPlan).toString()); - } else { - print(ApplicationConstants.APP_NAME + ": " + response.exception.message); - } - }); + void getSingleItem() async { + var dietPlan = await DietPlan().get('R5EonpUDWy'); + + if (dietPlan.success) { + print(ApplicationConstants.APP_NAME + ": " + (dietPlan.result as DietPlan).toString()); + } else { + print(ApplicationConstants.APP_NAME + ": " + dietPlan.exception.message); + } } void query() { @@ -66,51 +85,25 @@ class _MyAppState extends State { ..object = DietPlan() ..field = DietPlan.NAME ..equals = ['Paleo'] - ..query().then((response){ - - if (response.success){ - print(ApplicationConstants.APP_NAME + ": " + ((response.result as List)[0] as DietPlan).toString()); - } else { - print(ApplicationConstants.APP_NAME + ": " + response.exception.message); - } - }); - } - - void queryByContainedIn() { - // Query for an object by name - QueryBuilder() - ..object = DietPlan() - ..field = DietPlan.NAME - ..contains = ['Diet'] - ..query().then((response){ - - if (response.success){ - print(ApplicationConstants.APP_NAME + ": " + ((response.result as List)[0] as DietPlan).toString()); + ..query().then((response) { + if (response.success) { + print(ApplicationConstants.APP_NAME + + ": " + + ((response.result as List)[0] as DietPlan) + .toString()); } else { - print(ApplicationConstants.APP_NAME + ": " + response.exception.message); + print(ApplicationConstants.APP_NAME + + ": " + + response.exception.message); } }); } - Future initUser() async { - User().createNewUser("TestFlutter", "TestPassword123", "TestEmail@Email.com"); + initUser() async { + User().createNewUser("TestFlutter", "TestPassword123", "TestEmail@Email.com"); User().login().then((val) { print(val); }); } - - @override - Widget build(BuildContext context) { - return new MaterialApp( - home: new Scaffold( - appBar: new AppBar( - title: const Text('Plugin example app'), - ), - body: new Center( - child: new Text('Running Parse init'), - ), - ), - ); - } } diff --git a/lib/data/parse_data_server.dart b/lib/data/parse_data_server.dart index cea9d7a68..e52599550 100644 --- a/lib/data/parse_data_server.dart +++ b/lib/data/parse_data_server.dart @@ -1,19 +1,33 @@ class ParseDataServer { static ParseDataServer _instance; - static ParseDataServer get instance => _instance; - static void init(appId, serverUrl, {liveQueryUrl, masterKey, sessionId}) => - _instance ??= ParseDataServer._init(appId, serverUrl, liveQueryURL: liveQueryUrl, masterKey: masterKey, sessionId: sessionId); + static void init(appId, serverUrl, {debug, appName, liveQueryUrl, masterKey, sessionId}){ + _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; + } + String appName; String applicationId; String serverUrl; String liveQueryURL; String masterKey; String sessionId; + bool debug; - ParseDataServer._init(this.applicationId, this.serverUrl, - {this.liveQueryURL, this.masterKey, this.sessionId}); + ParseDataServer._init( + this.applicationId, + this.serverUrl, + {this.debug: false, + this.appName: "ParseApplication", + this.liveQueryURL, + this.masterKey, + this.sessionId}); factory ParseDataServer() => _instance; diff --git a/lib/network/parse_query.dart b/lib/network/parse_query.dart index daacc7126..ff96ce15f 100644 --- a/lib/network/parse_query.dart +++ b/lib/network/parse_query.dart @@ -6,9 +6,8 @@ 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 implements ParseBaseObject { - // BaseParams - String _className; +class QueryBuilder extends ParseBaseObject { + ParseObject object; final ParseHTTPClient client = ParseHTTPClient(); String path; @@ -40,7 +39,7 @@ class QueryBuilder implements ParseBaseObject { String get objectId => null; Map objectData = {}; - QueryBuilder(); + QueryBuilder() : super(); void ascending(String attribute) {} @@ -55,7 +54,7 @@ class QueryBuilder implements ParseBaseObject { } Future query() async { - return object.getQuery(_buildQuery()); + return object.query(_buildQuery()); } String _buildQuery() { diff --git a/lib/objects/parse_base.dart b/lib/objects/parse_base.dart index 1f08ff310..3b17adb11 100644 --- a/lib/objects/parse_base.dart +++ b/lib/objects/parse_base.dart @@ -1,15 +1,106 @@ +import 'dart:convert'; + +import 'package:meta/meta.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; abstract class ParseBaseObject { - final String _className; - final ParseHTTPClient _client; - String _path; - Map _objectData; + ParseHTTPClient _client; + Map _objectData; String get objectId => _objectData['objectId']; + DateTime get createdAt => _objectData['createdAt']; + DateTime get updatedAt => _objectData['updatedAt']; + + ParseBaseObject([this._client]){ + _objectData = Map(); + } + + @protected + setClient(ParseHTTPClient client) => _client = client; + @protected + getDebugStatus() => _client.data.debug; + @protected + getAppName() => _client.data.appName; + @protected + getObjectData() => _objectData; + @protected + fromJson(Map objectData) => objectData; + + toJson() => JsonEncoder().convert(getObjectData()); + + copy() { + var copy = fromJson(_objectData); + return JsonDecoder().convert(copy); + } + + _getBasePath(String path) => "${_client.data.serverUrl}$path"; + + setValue(String key, dynamic value, {bool forceUpdate: true}) { + if (value != null) { + if (_objectData.containsKey(key)) { + if (forceUpdate) _objectData[key] = value; + } else { + _objectData[key] = value; + } + } + } + + getValue(String key, {dynamic defaultValue, bool fromServer}) { + if (_objectData.containsKey(key)) { + return _objectData[key]; + } else { + return defaultValue; + } + } + + _get(String objectId, String path) async { + var uri = _getBasePath(path); + if (objectId != null) uri += "/$objectId"; + return _client.get(uri); + } + + _getAll(String path) async { + return _client.get(_getBasePath(path)); + } + + @protected + parseGetAll(String path) => _getAll(path); + @protected + parseGetObjectById(String objectId, String path) => _get(objectId, path); + + _create(String path) async { + var uri = _client.data.serverUrl + "$path"; + return _client.post(uri, body: JsonEncoder().convert(_objectData)); + } + + @protected + parseCreate(String path, Map objectData) => _create(path); + + _save(String path) { + if (_objectData == null) { + return _create(path); + } else { + var uri = "${_getBasePath(path)}/$objectId"; + return _client.put(uri, body: JsonEncoder().convert(_objectData)); + } + } + + @protected + parseSave(String path) => _save(path); + + _query(String path, String query) async { + var uri = "${_getBasePath(path)}?$query"; + return _client.get(uri); + } + + @protected + parseQuery(String path, String query) => _query(path, query); - // ignore: unused_element - void _handleResponse(Map response) {} + _delete(String path, String objectId){ + var uri = "${_getBasePath(path)}/$objectId"; + return _client.delete(uri); + } - ParseBaseObject(this._className, [this._client]); + @protected + parseDelete(String path, String query) => _delete(path, objectId); } diff --git a/lib/objects/parse_object.dart b/lib/objects/parse_object.dart index 5c39cd38f..8c729198f 100644 --- a/lib/objects/parse_object.dart +++ b/lib/objects/parse_object.dart @@ -1,91 +1,66 @@ -import 'dart:async'; -import 'dart:convert'; - +import 'package:http/http.dart'; +import 'package:meta/meta.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; import 'package:parse_server_sdk/objects/parse_base.dart'; import 'package:parse_server_sdk/objects/parse_response.dart'; -class ParseObject implements ParseBaseObject { - final ParseHTTPClient _client = ParseHTTPClient(); - Map objectData = {}; +class ParseObject extends ParseBaseObject { final String className; String path; + bool debug; - String objectId; - DateTime createdAt; - DateTime updatedAt; - - ParseObject(this.className) { + ParseObject(this.className, {this.debug: false}) : super(ParseHTTPClient()) { path = "/classes/$className"; } - Future create([Map objectInitialData]) async { - objectData = {}..addAll(objectData)..addAll(objectInitialData); - - final response = this._client.post("${_client.data.serverUrl}$path", - body: JsonEncoder().convert(objectData)); - return response.then((value) { - return ParseResponse.handleResponse(this, value); - }); + get(String id) async { + var result = await parseGetObjectById(id, path); + return _handleResult(result); } - Future save([Map objectInitialData]) { - objectData = {}..addAll(objectData)..addAll(objectInitialData); - if (objectId == null) { - return create(objectData); - } else { - final response = this._client.put( - _client.data.serverUrl + "$path/$objectId", - body: JsonEncoder().convert(objectData)); - return response.then((value) { - return ParseResponse.handleResponse(this, value); - }); - } + getAll() async { + var result = await parseGetAll(path); + return _handleResult(result); } - Future getAll({String query}) async { - String uri = _client.data.serverUrl + "$path"; - - return this._client.get(uri).then((value) { - return ParseResponse.handleResponse(this, value); - }); + create([Map objectData]) async { + var result = await parseCreate(path, objectData); + return _handleResult(result); } - Future get(String objectId) async { - String uri = _client.data.serverUrl + "$path"; - - if (objectId != null) uri += "/$objectId"; + save() async { + var result = await parseSave(path); + return _handleResult(result); + } - return this._client.get(uri).then((value) { - return ParseResponse.handleResponse(this, value); - }); + @protected + query(String query) async { + var result = await parseQuery(path, query); + return _handleResult(result); } - Future getQuery(String bodyBytes) async { - String uri = _client.data.serverUrl + "$path" + "?" + bodyBytes; + _handleResult(Response response) { + ParseResponse parseResponse = ParseResponse.handleResponse(this, response); - return this._client.get(uri).then((value) { - return ParseResponse.handleResponse(this, value); - }); - } + if (getDebugStatus() || debug) { - Future destroy() { - final response = - this._client.delete(_client.data.serverUrl + "$path/$objectId"); - return response.then((value) { - return JsonDecoder().convert(value.body); - }); - } + var responseString = " \n"; - dynamic fromJson(Map objectData) { - return objectData; - } + responseString += + "----" + "\n${getAppName()} API Response:" + + "\nStatus Code: ${parseResponse.statusCode}"; - void set(String attribute, dynamic value) { - objectData[attribute] = value; - } + if (parseResponse.success && parseResponse.result != null) { + responseString += "\nPayload: ${parseResponse.result.toString()}"; + } else if (!parseResponse.success) { + responseString += "\nException: ${parseResponse.exception.message}"; + } + + responseString += "\n----"; + print(responseString); + } - dynamic copy() { - return ParseObject(className); + return ParseResponse.handleResponse(this, response); } } diff --git a/lib/objects/parse_response.dart b/lib/objects/parse_response.dart index 5b933346e..6739c2bd9 100644 --- a/lib/objects/parse_response.dart +++ b/lib/objects/parse_response.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'dart:convert'; import 'package:parse_server_sdk/objects/parse_exception.dart'; @@ -12,7 +11,8 @@ class ParseResponse { dynamic result; ParseException exception; - static Future _handleSuccess(ParseResponse response, ParseObject object, String responseBody) async { + static ParseResponse _handleSuccess( + ParseResponse response, ParseObject object, String responseBody) { response.success = true; var map = JsonDecoder().convert(responseBody) as Map; @@ -29,16 +29,19 @@ class ParseResponse { } static ParseResponse _checkForEmptyResult(ParseResponse response) { - if (response.result == null || (response.result as List).length == 0) { - response.exception = ParseException(); - response.exception.message = "No result found for query"; - response.success = false; + 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; } - static List _handleMultipleResults(ParseObject object, dynamic map) { + static List _handleMultipleResults( + ParseObject object, dynamic map) { var resultsList = List(); for (var value in map) { @@ -53,14 +56,14 @@ class ParseResponse { return object.fromJson(map); } - static Future _handleError( - ParseResponse response, Response value) async { + static ParseResponse _handleError( + ParseResponse response, Response value) { response.exception = ParseException(); response.exception.message = value.reasonPhrase; return response; } - static Future handleResponse(ParseObject object, Response value) async { + static handleResponse(ParseObject object, Response value) { var response = ParseResponse(); if (value != null) { diff --git a/lib/objects/parse_user.dart b/lib/objects/parse_user.dart index 61074f158..54c0c4936 100644 --- a/lib/objects/parse_user.dart +++ b/lib/objects/parse_user.dart @@ -6,20 +6,20 @@ import 'package:parse_server_sdk/data/parse_data_user.dart'; import 'package:parse_server_sdk/objects/parse_base.dart'; import 'package:parse_server_sdk/network/parse_http_client.dart'; -class User implements ParseBaseObject { - final String className = '_User'; +class User extends ParseBaseObject { + static final String className = '_User'; final ParseHTTPClient client = ParseHTTPClient(); String path = "/classes/_User"; Map objectData = {}; static ParseDataUser userData; + User() : super(ParseHTTPClient()); + String get objectId => objectData['objectId']; String get sessionId => objectData['sessionToken']; String get userId => objectData['objectId']; - User(); - User createNewUser(String username, String password, String emailAddress) { ParseDataUser.init(username, password, emailAddress); userData = ParseDataUser(); @@ -30,18 +30,6 @@ class User implements ParseBaseObject { return User(); } - void set(String attribute, dynamic value) { - objectData[attribute] = value; - } - - Future get(attribute) async { - final response = this.client.get(client.data.serverUrl + "$path/$objectId"); - return response.then((value) { - objectData = JsonDecoder().convert(value.body); - return objectData[attribute]; - }); - } - Future me(attribute) async { final response = this.client.get(client.data.serverUrl + "$path/me", headers: {"X-Parse-Session-Token": sessionId}); diff --git a/lib/parse.dart b/lib/parse.dart index 376a7955f..5372a026a 100644 --- a/lib/parse.dart +++ b/lib/parse.dart @@ -10,9 +10,14 @@ class Parse { Parse(); - Parse initialize(appId, serverUrl, {liveQueryUrl, masterKey, sessionId}) { - ParseDataServer.init(appId, serverUrl, - liveQueryUrl: liveQueryUrl, masterKey: masterKey, sessionId: sessionId); + Parse initialize(appId, serverUrl, {debug, appName, liveQueryUrl, masterKey, sessionId}) { + ParseDataServer.init(appId, + serverUrl, + debug: debug, + appName: appName, + liveQueryUrl: liveQueryUrl, + masterKey: masterKey, + sessionId: sessionId); return newInstance(ParseDataServer()); } diff --git a/lib/utils/parse_utils_objects.dart b/lib/utils/parse_utils_objects.dart index 45d7ce498..0684c1d1b 100644 --- a/lib/utils/parse_utils_objects.dart +++ b/lib/utils/parse_utils_objects.dart @@ -3,10 +3,10 @@ import 'package:parse_server_sdk/objects/parse_object.dart'; import 'package:parse_server_sdk/utils/parse_utils_date.dart'; class ParseUtilsObjects { - static ParseObject populateObjectBaseData(ParseObject object, Map objectData) { - object.objectId = objectData[ParseConstants.OBJECT_ID]; - object.createdAt = ParseUtilsDates.convertStringToDateTime(objectData[ParseConstants.CREATED_AT]); - object.updatedAt = ParseUtilsDates.convertStringToDateTime(objectData[ParseConstants.UPDATED_AT]); + 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