Skip to content

Commit

Permalink
Improve handling of relationship by ids
Browse files Browse the repository at this point in the history
  • Loading branch information
3lvis committed Nov 26, 2015
1 parent 3bf053f commit d02d755
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 54 deletions.
5 changes: 4 additions & 1 deletion Source/NSManagedObject+Sync.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ - (void)sync_processRelationshipsUsingDictionary:(NSDictionary *)objectDictionar
NSArray *relationships = [self.entity sync_relationships];

for (NSRelationshipDescription *relationship in relationships) {
NSString *keyName = [[relationship.destinationEntity.name lowercaseString] stringByAppendingString:@"_id"];
NSEntityDescription *entity = [NSEntityDescription entityForName:relationship.entity.name inManagedObjectContext:self.managedObjectContext];
NSArray<NSRelationshipDescription *> *relationships = [entity relationshipsWithDestinationEntity:relationship.destinationEntity];
NSString *keyName = [[relationships.firstObject.name hyp_remoteString] stringByAppendingString:@"_id"];
NSLog(@"keyName: %@", keyName);
if (relationship.isToMany) {
[self sync_processToManyRelationship:relationship
usingDictionary:objectDictionary
Expand Down
5 changes: 4 additions & 1 deletion Source/Sync.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ + (void)changes:(NSArray *)changes
NSError *error = nil;
NSManagedObject *safeParent = [parent sync_copyInContext:backgroundContext
error:&error];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", [parent.entity.name lowercaseString], safeParent];

NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:backgroundContext];
NSArray<NSRelationshipDescription *> *relationships = [entity relationshipsWithDestinationEntity:parent.entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", relationships.firstObject.name, safeParent];

[self changes:changes
inEntityNamed:entityName
Expand Down
10 changes: 5 additions & 5 deletions Tests/JSONs/notes_with_user_id.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
{
"id": 0,
"text": "Melisa White's diary, episode 0",
"user_id": 0
"super_user_id": 0
},
{
"id": 1,
"text": "Melisa White's diary, episode 1",
"user_id": 0
"super_user_id": 0
},
{
"id": 2,
"text": "Melisa White's diary, episode 2",
"user_id": 0
"super_user_id": 0
},
{
"id": 3,
"text": "Glass Oconnor's diary, episode 0",
"user_id": 1
"super_user_id": 1
},
{
"id": 4,
"text": "Glass Oconnor's diary, episode 1",
"user_id": 1
"super_user_id": 1
}
]
8 changes: 4 additions & 4 deletions Tests/JSONs/tagged_notes.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"id": 0,
"text": "Shawn Merril's diary, episode 0",
"tags": [
"super_tags": [
{
"id": 1,
"name": "diary"
Expand All @@ -16,7 +16,7 @@
{
"id": 1,
"text": "Shawn Merril's diary, episode 1",
"tags": [
"super_tags": [
{
"id": 1,
"name": "diary"
Expand All @@ -26,7 +26,7 @@
{
"id": 2,
"text": "Shawn Merril's diary, episode 2",
"tags": [
"super_tags": [
{
"id": 1,
"name": "diary"
Expand All @@ -36,7 +36,7 @@
{
"id": 3,
"text": "Shawn Merril's diary, episode 3",
"tags": [
"super_tags": [
{
"id": 1,
"name": "diary"
Expand Down
22 changes: 11 additions & 11 deletions Tests/Models/Notes.xcdatamodeld/Demo.xcdatamodel/contents
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="7549" systemVersion="14E7f" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="Note" syncable="YES">
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="9057" systemVersion="15B42" minimumToolsVersion="Automatic">
<entity name="SuperNote" syncable="YES">
<attribute name="remoteID" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
<attribute name="text" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="tags" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Tag" inverseName="notes" inverseEntity="Tag" syncable="YES"/>
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="User" inverseName="notes" inverseEntity="User" syncable="YES"/>
<relationship name="superTags" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="SuperTag" inverseName="superNotes" inverseEntity="SuperTag" syncable="YES"/>
<relationship name="superUser" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SuperUser" inverseName="superNotes" inverseEntity="SuperUser" syncable="YES"/>
</entity>
<entity name="Tag" syncable="YES">
<entity name="SuperTag" syncable="YES">
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="remoteID" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
<relationship name="notes" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Note" inverseName="tags" inverseEntity="Note" syncable="YES"/>
<relationship name="superNotes" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="SuperNote" inverseName="superTags" inverseEntity="SuperNote" syncable="YES"/>
</entity>
<entity name="User" representedClassName="" syncable="YES">
<entity name="SuperUser" representedClassName="" syncable="YES">
<attribute name="createdAt" optional="YES" attributeType="Date" syncable="YES"/>
<attribute name="email" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="remoteID" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
<attribute name="updatedAt" optional="YES" attributeType="Date" syncable="YES"/>
<relationship name="notes" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Note" inverseName="user" inverseEntity="Note" syncable="YES">
<relationship name="superNotes" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="SuperNote" inverseName="superUser" inverseEntity="SuperNote" syncable="YES">
<userInfo>
<entry key="hyper.remoteKey" value="annotations"/>
</userInfo>
</relationship>
</entity>
<elements>
<element name="Note" positionX="-20" positionY="18" width="128" height="103"/>
<element name="Tag" positionX="160" positionY="0" width="128" height="90"/>
<element name="User" positionX="-207" positionY="-15" width="128" height="135"/>
<element name="SuperNote" positionX="-20" positionY="18" width="128" height="105"/>
<element name="SuperTag" positionX="160" positionY="0" width="128" height="90"/>
<element name="SuperUser" positionX="-207" positionY="-15" width="128" height="135"/>
</elements>
</model>
64 changes: 32 additions & 32 deletions Tests/SyncTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,20 @@ - (void)testRelationshipsA {
DATAStack *dataStack = [self dataStackWithModelName:@"Notes"];

[Sync changes:objects
inEntityNamed:@"User"
inEntityNamed:@"SuperUser"
dataStack:dataStack
completion:nil];

XCTAssertEqual([self countForEntity:@"User"
XCTAssertEqual([self countForEntity:@"SuperUser"
inContext:dataStack.mainContext], 4);
NSArray *users = [self fetchEntity:@"User"
NSArray *users = [self fetchEntity:@"SuperUser"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @6]
inContext:dataStack.mainContext];
NSManagedObject *user = [users firstObject];
XCTAssertEqualObjects([user valueForKey:@"name"], @"Shawn Merrill");

NSInteger notesCount = [self countForEntity:@"Note"
predicate:[NSPredicate predicateWithFormat:@"user = %@", user]
NSInteger notesCount = [self countForEntity:@"SuperNote"
predicate:[NSPredicate predicateWithFormat:@"superUser = %@", user]
inContext:dataStack.mainContext];
XCTAssertEqual(notesCount, 5);

Expand All @@ -165,7 +165,7 @@ - (void)testObjectsForParent {
[dataStack performInNewBackgroundContext:^(NSManagedObjectContext *backgroundContext) {

// First, we create a parent user, this user is the one that will own all the notes
NSManagedObject *user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
NSManagedObject *user = [NSEntityDescription insertNewObjectForEntityForName:@"SuperUser"
inManagedObjectContext:backgroundContext];
[user setValue:@6 forKey:@"remoteID"];
[user setValue:@"Shawn Merrill" forKey:@"name"];
Expand All @@ -179,27 +179,27 @@ - (void)testObjectsForParent {
}];

// Then we fetch the user on the main context, because we don't want to break things between contexts
NSArray *users = [self fetchEntity:@"User"
NSArray *users = [self fetchEntity:@"SuperUser"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @6]
inContext:dataStack.mainContext];
if (users.count != 1) abort();
XCTAssertEqual(users.count, 1);

// Finally we say "Sync all the notes, for this user"
[Sync changes:objects
inEntityNamed:@"Note"
inEntityNamed:@"SuperNote"
parent:[users firstObject]
dataStack:dataStack
completion:nil];

// Here we just make sure that the user has the notes that we just inserted
users = [self fetchEntity:@"User"
users = [self fetchEntity:@"SuperUser"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @6]
inContext:dataStack.mainContext];
NSManagedObject *user = [users firstObject];
XCTAssertEqualObjects([user valueForKey:@"name"], @"Shawn Merrill");

NSInteger notesCount = [self countForEntity:@"Note"
predicate:[NSPredicate predicateWithFormat:@"user = %@", user]
NSInteger notesCount = [self countForEntity:@"SuperNote"
predicate:[NSPredicate predicateWithFormat:@"superUser = %@", user]
inContext:dataStack.mainContext];
XCTAssertEqual(notesCount, 5);

Expand All @@ -211,28 +211,28 @@ - (void)testTaggedNotesForUser {
DATAStack *dataStack = [self dataStackWithModelName:@"Notes"];

[Sync changes:objects
inEntityNamed:@"Note"
inEntityNamed:@"SuperNote"
dataStack:dataStack
completion:nil];

XCTAssertEqual([self countForEntity:@"Note"
XCTAssertEqual([self countForEntity:@"SuperNote"
inContext:dataStack.mainContext], 5);
NSArray *notes = [self fetchEntity:@"Note"
NSArray *notes = [self fetchEntity:@"SuperNote"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @0]
inContext:dataStack.mainContext];
NSManagedObject *note = [notes firstObject];
XCTAssertEqual([[[note valueForKey:@"tags"] allObjects] count], 2,
XCTAssertEqual([[[note valueForKey:@"superTags"] allObjects] count], 2,
@"Note with ID 0 should have 2 tags");

XCTAssertEqual([self countForEntity:@"Tag"
XCTAssertEqual([self countForEntity:@"SuperTag"
inContext:dataStack.mainContext], 2);
NSArray *tags = [self fetchEntity:@"Tag"
NSArray *tags = [self fetchEntity:@"SuperTag"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @1]
inContext:dataStack.mainContext];
XCTAssertEqual(tags.count, 1);

NSManagedObject *tag = [tags firstObject];
XCTAssertEqual([[[tag valueForKey:@"notes"] allObjects] count], 4,
XCTAssertEqual([[[tag valueForKey:@"superNotes"] allObjects] count], 4,
@"Tag with ID 1 should have 4 notes");

[dataStack drop];
Expand All @@ -243,14 +243,14 @@ - (void)testCustomKeysInRelationshipsToMany {
DATAStack *dataStack = [self dataStackWithModelName:@"Notes"];

[Sync changes:objects
inEntityNamed:@"User"
inEntityNamed:@"SuperUser"
dataStack:dataStack
completion:nil];

NSArray *array = [self fetchEntity:@"User"
NSArray *array = [self fetchEntity:@"SuperUser"
inContext:dataStack.mainContext];
NSManagedObject *user = [array firstObject];
XCTAssertEqual([[[user valueForKey:@"notes"] allObjects] count], 3);
XCTAssertEqual([[[user valueForKey:@"superNotes"] allObjects] count], 3);

[dataStack drop];
}
Expand All @@ -267,11 +267,11 @@ - (void)testSyncWithPredicateAfterDate {
NSArray *objects = @[old1, old2];
[Sync changes:objects
inEntityNamed:@"User"
inEntityNamed:@"SuperUser"
dataStack:dataStack
completion:nil];
NSArray *array = [self fetchEntity:@"User"
NSArray *array = [self fetchEntity:@"SuperUser"
sortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"remoteID" ascending:YES]]
inContext:dataStack.mainContext];
XCTAssertEqual(array.count, 2);
Expand All @@ -287,12 +287,12 @@ - (void)testSyncWithPredicateAfterDate {
NSArray *newObjects = @[updatedOld2, new];
[Sync changes:newObjects
inEntityNamed:@"User"
inEntityNamed:@"SuperUser"
predicate:[NSPredicate predicateWithFormat:@"createdAt > %@", [NSDate date]]
dataStack:dataStack
completion:nil];
NSArray *updatedArray = [self fetchEntity:@"User"
NSArray *updatedArray = [self fetchEntity:@"SuperUser"
sortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"remoteID" ascending:YES]]
inContext:dataStack.mainContext];
XCTAssertEqual(updatedArray.count, 3);
Expand Down Expand Up @@ -738,28 +738,28 @@ - (void)testIDRelationshipMapping {
DATAStack *dataStack = [self dataStackWithModelName:@"Notes"];

[Sync changes:usersDictionary
inEntityNamed:@"User"
inEntityNamed:@"SuperUser"
dataStack:dataStack
completion:nil];

NSInteger usersCount = [self countForEntity:@"User" inContext:dataStack.mainContext];
NSInteger usersCount = [self countForEntity:@"SuperUser" inContext:dataStack.mainContext];
XCTAssertEqual(usersCount, 8);

NSArray *notesDictionary = [self objectsFromJSON:@"notes_with_user_id.json"];

[Sync changes:notesDictionary
inEntityNamed:@"Note"
inEntityNamed:@"SuperNote"
dataStack:dataStack
completion:nil];

NSInteger notesCount = [self countForEntity:@"Note" inContext:dataStack.mainContext];
NSInteger notesCount = [self countForEntity:@"SuperNote" inContext:dataStack.mainContext];
XCTAssertEqual(notesCount, 5);

NSArray *notes = [self fetchEntity:@"Note"
NSArray *notes = [self fetchEntity:@"SuperNote"
predicate:[NSPredicate predicateWithFormat:@"remoteID = %@", @0]
inContext:dataStack.mainContext];
NSManagedObject *note = notes.firstObject;
NSManagedObject *user = [note valueForKey:@"user"];
NSManagedObject *user = [note valueForKey:@"superUser"];
XCTAssertEqualObjects([user valueForKey:@"name"], @"Melisa White");

[dataStack drop];
Expand Down

0 comments on commit d02d755

Please sign in to comment.