Skip to content

Develop #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 6, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/lib/diet_plan.dart
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ class DietPlan extends ParseObject {
static const String STATUS = 'Status';

@override
dynamic fromJson(Map<String, dynamic> objectData) {
dynamic fromJson(Map objectData) {
this.name = objectData[NAME];
this.description = objectData[DESCRIPTION];
this.protein = objectData[PROTEIN];
96 changes: 49 additions & 47 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -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<MyApp> {

@override
void initState() {
super.initState();
@@ -35,84 +31,90 @@ class _MyAppState extends State<MyApp> {
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(){
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());
}
}
}

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<dynamic>).first as DietPlan)
.toString());
} else {
print(ApplicationConstants.APP_NAME +
": " +
response.exception.message);
}
});
var queryBuilder = QueryBuilder<DietPlan>(DietPlan())
..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<dynamic>).first as DietPlan).toString());
} else {
print(ApplicationConstants.APP_NAME + ": " + response.exception.message);
}
}

initUser() async {
ParseUser().create("TestFlutter", "TestPassword123", "[email protected]");
ParseUser().signUp();
ParseUser()
.create("TestFlutter", "TestPassword123", "[email protected]");
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();
}
}
19 changes: 7 additions & 12 deletions lib/data/parse_data_server.dart
Original file line number Diff line number Diff line change
@@ -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;

20 changes: 14 additions & 6 deletions lib/data/parse_data_user.dart
Original file line number Diff line number Diff line change
@@ -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<String, dynamic> 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;
}

284 changes: 189 additions & 95 deletions lib/network/parse_query.dart
Original file line number Diff line number Diff line change
@@ -1,142 +1,236 @@
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 extends ParseObject> {

ParseObject object;
final ParseHTTPClient client = ParseHTTPClient();
String path;
String field;
Map results;
Map constraint;
Map<String, Map<String, String>> whereMap =
Map<String, Map<String, String>>();
static const String _NO_OPERATOR_NEEDED = "NO_OP";

T object;

// QueryParams
List<dynamic> equals;
List<dynamic> lessThan;
List<dynamic> lessThanOrEqualTo;
List<dynamic> greaterThan;
List<dynamic> greaterThanOrEqualTo;
List<dynamic> notEqualTo;
List<dynamic> contains;
List<dynamic> containedIn;
List<dynamic> notContainerIn;
List<dynamic> exists;
List<dynamic> select;
List<dynamic> dontSelect;
List<dynamic> all;
List<dynamic> regEx;
List<dynamic> text;
List<MapEntry> _equalsQueries = List();
List<MapEntry> _lessThanQueries = List();
List<MapEntry> _lessThanOrEqualToQueries = List();
List<MapEntry> _greaterThanQueries = List();
List<MapEntry> _greaterThanOrEqualToQueries = List();
List<MapEntry> _notEqualToQueries = List();
List<MapEntry> _containsQueries = List();
List<MapEntry> _containedInQueries = List();
List<MapEntry> _notContainedInQueries = List();
List<MapEntry> _existsQueries = List();
List<MapEntry> _selectQueries = List();
List<MapEntry> _dontSelectQueries = List();
List<MapEntry> _allQueries = List();
List<MapEntry> _regExQueries = List();
List<MapEntry> _textQueries = List();
int limit = 0;
int skip = 0;

String get objectId => null;
Map<String, dynamic> objectData = {};
QueryBuilder(this.object) : super();

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 greaterThan(String column, dynamic value) {
_greaterThanQueries.add(MapEntry(column, value));
}

void greaterThanOrEqualsTo(String column, dynamic value) {
_greaterThanOrEqualToQueries.add(MapEntry(column, value));
}

QueryBuilder() : super();
void notEqualTo(String column, dynamic value) {
_notEqualToQueries.add(MapEntry(column, value));
}

void ascending(String attribute) {}
void contains(String column, dynamic value) {
_containsQueries.add(MapEntry(column, value));
}

void descending(String attribute) {}
void containedIn(String column, dynamic value) {
_containedInQueries.add(MapEntry(column, value));
}

void startsWith(String key, dynamic value) {}
void exists(String column, dynamic value) {
_existsQueries.add(MapEntry(column, value));
}

Future<Map> first() {
Map<String, dynamic> t = {};
foo() => t;
return new Future(foo);
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 existsMap = Map<String, String>();

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)}";
var queries = List<MapEntry>();

// START QUERY
const String QUERY_START = "where={";
const String QUERY_END = "}";

var query = QUERY_START;

// ADD PARAM TO MAP
//Needs fixing
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"));
if (_greaterThanOrEqualToQueries.length != 0) queries.addAll(_getAllQueries(_greaterThanOrEqualToQueries, "\$gte"));
if (_notEqualToQueries.length != 0) queries.addAll(_getAllQueries(_notEqualToQueries, "\$ne"));

// Not sure
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 (_regExQueries.length != 0) queries.addAll(_getAllQueries(_regExQueries, "\$regex"));

// Doesnt
if (_textQueries.length != 0) queries.addAll(_getAllQueries(_textQueries, "\$text"));

queries = _checkForMultipleColumnInstances(queries);

// -- BUILD QUERY USING MAP
for (var item in queries) {
if (query == QUERY_START) {
query += item.value;
} else {
query += ",${item.value}";
}
}

// -- ADD LIMITER
if (limit != 0) query += '?limit=$limit';
if (skip != 0) query += '?skip=$skip';

query += QUERY_END;

// -- TEST
print("QUERY: $query");

return query;
}

Map<String, String> _runThroughQueryParams(
List<dynamic> list, String queryParam) {
Map<String, String> mapToReturn = Map<String, String>();
var params = "";
_getAllQueries(List<MapEntry> queries, String queryOperator){
List<MapEntry> queriesToReturn = List();
for (var query in queries){
queriesToReturn.add(_buildQueryWithColumnValueAndOperator(query, queryOperator));
}
return queriesToReturn;
}

if (list.isNotEmpty) {
if (list.length == 1) {
params = list[0];
} else {
for (var listItem in list) {
params += "$listItem, ";
}
_buildQueryWithColumnValueAndOperator(MapEntry columnAndValue, String queryOperator) {

params.substring(0, params.length - 2);
}
}
var key = columnAndValue.key;
var value = convertValueToCorrectType(columnAndValue.value);

mapToReturn[queryParam] = params;
if (queryOperator == _NO_OPERATOR_NEEDED){
return MapEntry(_NO_OPERATOR_NEEDED, "\"${columnAndValue.key}\": $value");
} else {
var queryString = "\"$key\":";

return mapToReturn;
}
var queryOperatorAndValueMap = Map();
queryOperatorAndValueMap[queryOperator] = columnAndValue.value;

Map<String, String> _runThroughQueryParamsWithName(
List<dynamic> list, String queryParam, String fieldName) {
Map<String, String> mapToReturn = Map<String, String>();
Map<String, dynamic> mapWithParamData = Map<String, dynamic>();
var formattedQueryOperatorAndValue = JsonEncoder().convert(queryOperatorAndValueMap);
queryString += "$formattedQueryOperatorAndValue";

for (var item in list) {
mapWithParamData["\$$queryParam"] = item;
return MapEntry(key, queryString);
}
}

var params = JsonEncoder().convert(mapWithParamData).toString();
_checkForMultipleColumnInstances(List<MapEntry> queries) {
List<MapEntry> sanitisedQueries = List();
List<String> keysAlreadyCompacted = List();

mapToReturn[fieldName] = params;
// Run through each query
for (var query in queries){

return mapToReturn;
}
// Add queries that don't need sanitising
if (query.key == _NO_OPERATOR_NEEDED) {
sanitisedQueries.add(MapEntry(_NO_OPERATOR_NEEDED, query.value));
}

Map<String, String> _runThroughQueryParamsWithSearchTerms(
List<dynamic> list, String queryParam, String fieldName) {
Map<String, String> mapToReturn = Map<String, String>();
Map<String, dynamic> mapWithParamData = Map<String, dynamic>();
Map<String, String> textEntry = Map<String, String>();
Map<String, String> searchEntry = Map<String, String>();
// Check if query with same column name has been sanitised
if (!keysAlreadyCompacted.contains(query.key) && query.key != _NO_OPERATOR_NEEDED) {

for (var item in list) {
mapWithParamData["\$$queryParam"] = item;
}
// 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 = "";

var jsonMapWithParamData = JsonEncoder().convert(mapWithParamData);
searchEntry['search'] = jsonMapWithParamData;
// Compact all the queries in the correct format
for (var queryToCompact in listOfQueriesCompact) {

var jsonSearchEntry = JsonEncoder().convert(searchEntry);
textEntry['text'] = jsonSearchEntry;
var queryToCompactValue = queryToCompact.value.toString();
queryToCompactValue = queryToCompactValue.replaceFirst("{", "");
queryToCompactValue = queryToCompactValue.replaceAll("}", "");

var params = JsonEncoder().convert(textEntry).toString();
mapToReturn[fieldName] = params;
if (listOfQueriesCompact.first == queryToCompact){
queryEnd += (queryToCompactValue.replaceAll(queryStart, " "));
} else {
queryEnd += (queryToCompactValue.replaceAll(queryStart, ", "));
}
}

sanitisedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}"));
}
}

return sanitisedQueries;
}

return mapToReturn;
convertValueToCorrectType(dynamic value) {
if (value is int) return (value as num);
if (value is String) return "\"$value\"";
}
}
18 changes: 12 additions & 6 deletions lib/objects/parse_base.dart
Original file line number Diff line number Diff line change
@@ -3,13 +3,16 @@ import 'dart:convert';
import 'package:meta/meta.dart';

abstract class ParseBase {
Map<String, dynamic> _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<String, dynamic> objectData) => _objectData = objectData;
setObjectData(Map objectData) => _objectData = objectData;

@protected
getObjectData() => _objectData;

@protected
fromJson(Map<String, dynamic> objectData) => objectData;
fromJson(Map objectData) {
if (_objectData == null) _objectData = Map();
_objectData.addAll(objectData);
}

setValue(String key, dynamic value, {bool forceUpdate: true}) {
if (value != null) {
17 changes: 12 additions & 5 deletions lib/objects/parse_object.dart
Original file line number Diff line number Diff line change
@@ -13,11 +13,18 @@ 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}) {

client == null ? _client = ParseHTTPClient() : _client = client;

if (debug == null) {
_debug = _client.data.debug;
} else {
_debug = debug;
}

_path = "/classes/$className";
setObjectData(Map<String, dynamic>());
client == null ? _client = ParseHTTPClient() : _client = client;
}

get(String objectId) async {
@@ -79,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";
36 changes: 14 additions & 22 deletions lib/objects/parse_response.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
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;
int statusCode = -1;
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<ParseObject>).length == 0)) {
response.exception = ParseException();
response.exception.message = "No result found for query";
response.success = false;
}

return response;
}

@@ -51,17 +36,23 @@ class ParseResponse {
}

static _handleSingleResult(ParseObject object, map) {
ParseUtilsObjects.populateObjectBaseData(object, map);
populateObjectBaseData(object, map);
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;
}
}
73 changes: 43 additions & 30 deletions lib/objects/parse_user.dart
Original file line number Diff line number Diff line change
@@ -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,24 +79,24 @@ 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 {
final response = await _client.post(
"${_client.data.serverUrl}/verificationEmailRequest",
body: JsonEncoder().convert({"email": User().emailAddress}));

return _handleResult(
return _handleResponse(
response, ParseApiUserCallType.verificationEmailRequest);
}

@@ -94,59 +105,61 @@ 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);
}
}

destroy() async {
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<String, dynamic> responseData = JsonDecoder().convert(response.body);

var responseString = ' \n';

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;
}
}
7 changes: 3 additions & 4 deletions lib/utils/parse_utils_date.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
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);
var dateToReturn = formatter.parse(_removeTimeZones(date));
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, '');
} else {
return date;
}
}
}

17 changes: 9 additions & 8 deletions lib/utils/parse_utils_objects.dart
Original file line number Diff line number Diff line change
@@ -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<String, dynamic> 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;
}
}
populateObjectBaseData(ParseObject object, Map<String, dynamic> 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;
}