Skip to content

Bugfix #250

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

Closed
Closed
Show file tree
Hide file tree
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
8 changes: 5 additions & 3 deletions lib/parse_server_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ part 'src/utils/parse_utils.dart';

part 'src/utils/parse_login_helpers.dart';

part 'src/objects/parse_merge.dart';

class Parse {
ParseCoreData data;
bool _hasBeenInitialized = false;
Expand All @@ -116,8 +118,8 @@ class Parse {
String masterKey,
String sessionId,
bool autoSendSessionId,
SecurityContext securityContext,
CoreStore coreStore}) async {
SecurityContext securityContext,
CoreStore coreStore}) async {
final String url = removeTrailingSlash(serverUrl);

await ParseCoreData.init(appId, url,
Expand Down Expand Up @@ -147,7 +149,7 @@ class Parse {
final ParseHTTPClient _client = client ??
ParseHTTPClient(
sendSessionId:
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
sendSessionIdByDefault ?? ParseCoreData().autoSendSessionId,
securityContext: ParseCoreData().securityContext);

const String className = 'parseBase';
Expand Down
12 changes: 10 additions & 2 deletions lib/src/network/parse_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,23 @@ class QueryBuilder<T extends ParseObject> {
/// [String] order will be the column of the table that the results are
/// ordered by
void orderByAscending(String order) {
limiters['order'] = order;
if (limiters.containsKey('order')) {
limiters['order'] += ',$order';
} else {
limiters['order'] = order;
}
}

/// Sorts the results descending order.
///
/// [String] order will be the column of the table that the results are
/// ordered by
void orderByDescending(String order) {
limiters['order'] = '-$order';
if (limiters.containsKey('order')) {
limiters['order'] += ',-$order';
} else {
limiters['order'] = '-$order';
}
}

/// Define which keys in an object to return.
Expand Down
7 changes: 3 additions & 4 deletions lib/src/objects/parse_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,12 @@ abstract class ParseBase {
if (_getObjectData()[key] == value) {
return;
}
if (forceUpdate) {
_getObjectData()[key] = value;
}
_getObjectData()[key] =
ParseMergeTool().mergeWithPrevious(_unsavedChanges[key], value);
} else {
_getObjectData()[key] = value;
}
_unsavedChanges[key] = value;
_unsavedChanges[key] = _getObjectData()[key];
}
}

Expand Down
251 changes: 251 additions & 0 deletions lib/src/objects/parse_merge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
part of flutter_parse_sdk;

class ParseMergeTool {
// merge method
dynamic mergeWithPrevious(dynamic previous, dynamic values) {
if (previous == null) {
return values;
}
String previousAction = 'Set';
if (previous is Map) {
previousAction = previous['__op'];
}
if (values is Map) {
if (values['__op'] == 'Add') {
values = _mergeWithPreviousAdd(previousAction, previous, values);
} else if (values['__op'] == 'Remove') {
values = _mergeWithPreviousRemove(previousAction, previous, values);
} else if (values['__op'] == 'Increment') {
values = _mergeWithPreviousIncrement(previousAction, previous, values);
} else if (values['__op'] == 'AddUnique') {
values = _mergeWithPreviousAddUnique(previousAction, previous, values);
} else if (values['__op'] == 'AddRelation') {
values =
_mergeWithPreviousAddRelation(previousAction, previous, values);
} else if (values['__op'] == 'RemoveRelation') {
values =
_mergeWithPreviousRemoveRelation(previousAction, previous, values);
}
}
return values;
}

// Add operation Merge
dynamic _mergeWithPreviousAdd(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'Set') {
if (previous is List) {
return List<dynamic>.from(previous)..addAll(values['objects']);
} else {
throw 'Unable to add an item to a non-array.';
}
}
if (previousAction == 'Add') {
if (values['objects'].length == 1) {
previous['objects'].add(values['objects'].first);
} else {
previous['objects'].add(values['objects']);
}
values = previous;
}
if (previousAction == 'Increment') {
throw 'Add operation is invalid after Increment operation';
}
if (previousAction == 'Remove') {
throw 'Add operation is invalid after Remove operation';
}
if (previousAction == 'AddUnique') {
throw 'Add operation is invalid after AddUnique operation';
}
if (previousAction == 'AddRelation') {
throw 'Add operation is invalid after AddRelation operation';
}
if (previousAction == 'RemoveRelation') {
throw 'Add operation is invalid after RemoveRelation operation';
}
return values;
}

// Remove operation Merge
dynamic _mergeWithPreviousRemove(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'Set') {
return previous;
}
if (previousAction == 'Remove') {
if (values['objects'].length == 1) {
previous['objects'].add(values['objects'].first);
} else {
previous['objects'].add(values['objects']);
}
values = previous;
}
if (previousAction == 'Increment') {
throw 'Remove operation is invalid after Increment operation';
}
if (previousAction == 'Add') {
throw 'Remove operation is invalid after Add operation';
}
if (previousAction == 'AddUnique') {
throw 'Remove operation is invalid after AddUnique operation';
}
if (previousAction == 'AddRelation') {
throw 'Remove operation is invalid after AddRelation operation';
}
if (previousAction == 'RemoveRelation') {
throw 'Remove operation is invalid after RemoveRelation operation';
}
return values;
}

// Increment operation Merge
dynamic _mergeWithPreviousIncrement(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'Set') {
if (previous is num) {
values['amount'] += previous;
} else {
throw 'Invalid Operation';
}
}
if (previousAction == 'Increment') {
values['amount'] += previous['amount'];
}
if (previousAction == 'Add') {
throw 'Increment operation is invalid after Add operation';
}
if (previousAction == 'Remove') {
throw 'Increment operation is invalid after Remove operation';
}
if (previousAction == 'AddUnique') {
throw 'Increment operation is invalid after AddUnique operation';
}
if (previousAction == 'AddRelation') {
throw 'Increment operation is invalid after AddRelation operation';
}
if (previousAction == 'RemoveRelation') {
throw 'Increment operation is invalid after RemoveRelation operation';
}
return values;
}

// AddUnique operation Merge
dynamic _mergeWithPreviousAddUnique(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'Set') {
if (previous is List) {
return _applyToValueAddUnique(previous, values['objects']);
} else {
throw 'Unable to add an item to a non-array.';
}
}
if (previousAction == 'AddUnique') {
values['objects'] =
_applyToValueAddUnique(previous['objects'], values['objects']);
return values;
}
if (previousAction == 'Add') {
throw 'AddUnique operation is invalid after Add operation';
}
if (previousAction == 'Remove') {
throw 'AddUnique operation is invalid after Reomve operation';
}
if (previousAction == 'Increment') {
throw 'AddUnique operation is invalid after Increment operation';
}
if (previousAction == 'AddRelation') {
throw 'AddUnique operation is invalid after AddRelation operation';
}
if (previousAction == 'RemoveRelation') {
throw 'AddUnique operation is invalid after RemoveRelation operation';
}
return values;
}

// AddRelation operation Merge
dynamic _mergeWithPreviousAddRelation(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'AddRelation') {
if (values['objects'].length == 1) {
previous['objects'].add(values['objects'].first);
} else {
previous['objects'].add(values['objects']);
}
values = previous;
}
if (previousAction == 'Set') {
throw 'AddRelation operation is invalid after Set operation.';
}
if (previousAction == 'Increment') {
throw 'AddRelation operation is invalid after Increment operation';
}
if (previousAction == 'Add') {
throw 'AddRelation operation is invalid after Add operation';
}
if (previousAction == 'Remove') {
throw 'AddRelation operation is invalid after Remove operation';
}
if (previousAction == 'AddUnique') {
throw 'AddRelation operation is invalid after AddUnique operation';
}
if (previousAction == 'RemoveRelation') {
throw 'AddRelation operation is invalid after RemoveRelation operation';
}
return values;
}

// RemoveRelation operation Merge
dynamic _mergeWithPreviousRemoveRelation(
String previousAction, dynamic previous, dynamic values) {
if (previousAction == 'RemoveRelation') {
if (values['objects'].length == 1) {
previous['objects'].add(values['objects'].first);
} else {
previous['objects'].add(values['objects']);
}
values = previous;
}
if (previousAction == 'Set') {
throw 'RemoveRelation operation is invalid after Set operation.';
}
if (previousAction == 'Increment') {
throw 'RemoveRelation operation is invalid after Increment operation';
}
if (previousAction == 'Add') {
throw 'RemoveRelation operation is invalid after Add operation';
}
if (previousAction == 'Remove') {
throw 'RemoveRelation operation is invalid after Remove operation';
}
if (previousAction == 'AddUnique') {
throw 'RemoveRelation operation is invalid after AddUnique operation';
}
if (previousAction == 'AddRelation') {
throw 'RemoveRelation operation is invalid after AddRelation operation';
}
return values;
}

// service for AddUnique method
dynamic _applyToValueAddUnique(dynamic oldValue, dynamic newValue) {
for (var objectToAdd in newValue) {
if (objectToAdd is ParseObject && objectToAdd.objectId != null) {
var index = 0;
for (var objc in oldValue) {
if (objc is ParseObject && objc.objectId == objectToAdd.objectId) {
oldValue[index] = objectToAdd;
break;
}
index += 1;
}
if (index == oldValue.length) {
oldValue.add(objectToAdd);
}
} else if (!oldValue.contains(objectToAdd)) {
oldValue.add(objectToAdd);
}
}
print(oldValue);
return oldValue;
}
}