Skip to content

Ability to revert all changes or changes for key #70

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 1 commit into from
Aug 27, 2015
Merged
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
17 changes: 15 additions & 2 deletions Parse/PFObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ NS_REQUIRES_PROPERTY_DEFINITIONS
/*!
@abstract Sets the object associated with a given key.

@param object The object for `key`. A strong reference to the object is maintaned by PFObject.
@param object The object for `key`. A strong reference to the object is maintained by PFObject.
Raises an `NSInvalidArgumentException` if `object` is `nil`.
If you need to represent a `nil` value - use `NSNull`.
@param key The key for `object`.
Expand Down Expand Up @@ -176,7 +176,7 @@ NS_REQUIRES_PROPERTY_DEFINITIONS
@discussion This method enables usage of literal syntax on `PFObject`.
E.g. `object[@"key"] = @"value";`

@param object The object for `key`. A strong reference to the object is maintaned by PFObject.
@param object The object for `key`. A strong reference to the object is maintained by PFObject.
Raises an `NSInvalidArgumentException` if `object` is `nil`.
If you need to represent a `nil` value - use `NSNull`.
@param key The key for `object`.
Expand All @@ -202,6 +202,19 @@ NS_REQUIRES_PROPERTY_DEFINITIONS
*/
- (PFRelation *)relationforKey:(NSString *)key PARSE_DEPRECATED("Please use -relationForKey: instead.");

/*!
@abstract Clears any changes to this object made since the last call to save and sets it back to the server state.
*/
- (void)revert;

/*!
@abstract Clears any changes to this object's key that were done after last successful save and sets it back to the
server state.

@param key The key to revert changes for.
*/
- (void)revertObjectForKey:(NSString *)key;

///--------------------------------------
/// @name Array Accessors
///--------------------------------------
Expand Down
32 changes: 32 additions & 0 deletions Parse/PFObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,38 @@ - (void)removeObjectForKey:(NSString *)key {
}
}

- (void)revert {
@synchronized (self.lock) {
if ([self isDirty]) {
NSMutableSet *persistentKeys = [NSMutableSet setWithArray:[self._state.serverData allKeys]];

PFOperationSet *unsavedChanges = [self unsavedChanges];
for (PFOperationSet *operationSet in operationSetQueue) {
if (operationSet != unsavedChanges) {
[persistentKeys addObjectsFromArray:[operationSet.keyEnumerator allObjects]];
}
}

[unsavedChanges removeAllObjects];
[_availableKeys intersectSet:persistentKeys];

[self rebuildEstimatedData];
[self checkpointAllMutableContainers];
}
}
}

- (void)revertObjectForKey:(NSString *)key {
@synchronized (self.lock) {
if ([self isDirtyForKey:key]) {
[[self unsavedChanges] removeObjectForKey:key];
[self rebuildEstimatedData];
[_availableKeys removeObject:key];
[self checkpointAllMutableContainers];
}
}
}

#pragma mark Relations

- (PFRelation *)relationforKey:(NSString *)key {
Expand Down
30 changes: 29 additions & 1 deletion Tests/Unit/ObjectUnitTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "PFObject.h"
#import "PFUnitTestCase.h"
#import "Parse_Private.h"
#import "PFObjectPrivate.h"

@interface ObjectUnitTests : PFUnitTestCase

Expand Down Expand Up @@ -186,7 +187,7 @@ - (void)testKeyValueCoding {

- (void)testFetchObjectWithoutObjectIdError {
PFObject *object = [PFObject objectWithClassName:@"Test"];

XCTestExpectation *expectation = [self currentSelectorTestExpectation];
[[object fetchInBackground] continueWithBlock:^id(BFTask *task) {
XCTAssertNotNil(task.error);
Expand All @@ -198,4 +199,31 @@ - (void)testFetchObjectWithoutObjectIdError {
[self waitForTestExpectations];
}

#pragma mark Revert

- (void)testRevert {
NSDate *date = [NSDate date];
NSNumber *number = @0.75;
PFObject *object = [PFObject _objectFromDictionary:@{ @"yarr" : date,
@"score": number }
defaultClassName:@"Test" completeData:YES];
object[@"yarr"] = @"yolo";
[object revert];
XCTAssertEqualObjects(object[@"yarr"], date);
XCTAssertEqualObjects(object[@"score"], number);
}

- (void)testRevertObjectForKey {
NSDate *date = [NSDate date];
NSNumber *number = @0.75;
PFObject *object = [PFObject _objectFromDictionary:@{ @"yarr" : date,
@"score" : @1.0 }
defaultClassName:@"Test" completeData:YES];
object[@"yarr"] = @"yolo";
object[@"score"] = number;
[object revertObjectForKey:@"yarr"];
XCTAssertEqualObjects(object[@"yarr"], date);
XCTAssertEqualObjects(object[@"score"], number);
}

@end