Skip to content

Commit

Permalink
Merge pull request #390 from SyncDB/rename-hyper-isprimarykey
Browse files Browse the repository at this point in the history
Rename hyper.isPrimaryKey to sync.isPrimaryKey
  • Loading branch information
3lvis committed Mar 21, 2017
2 parents 3155a98 + 06d5dd1 commit 48c5e2d
Show file tree
Hide file tree
Showing 24 changed files with 67 additions and 54 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ Sync requires your entities to have a primary key, this is important for diffing

By default **Sync** uses `id` from the JSON and `id` (or `remoteID`) from Core Data as the primary key.

You can mark any attribute as primary key by adding `hyper.isPrimaryKey` and the value `true` (or `YES`). For example, in our [Designer News](https://github.com/SyncDB/DesignerNewsDemo) project we have a `Comment` entity that uses `body` as the primary key.
You can mark any attribute as primary key by adding `sync.isPrimaryKey` and the value `true` (or `YES`). For example, in our [Designer News](https://github.com/SyncDB/DesignerNewsDemo) project we have a `Comment` entity that uses `body` as the primary key.

![Custom primary key](https://raw.githubusercontent.com/SyncDB/Sync/master/Images/custom-primary-key-v3.png)

If you add the flag `hyper.isPrimaryKey` to the attribute `contractID` then:
If you add the flag `sync.isPrimaryKey` to the attribute `contractID` then:

- Local primary key will be: `contractID`
- Remote primary key will be: `contract_id`
Expand Down Expand Up @@ -457,7 +457,7 @@ If you're using Swift to be able to use `NSNotificationCenter` your class should

#### Crash on NSParameterAssert

This means that the local primary key was not found, Sync uses `id` (or `remoteID`) by default, but if you have another local primary key make sure to mark it with `"hyper.isPrimaryKey" : "true"` in your attribute's user info. For more information check the [Primary Key](https://github.com/SyncDB/Sync#primary-key) section.
This means that the local primary key was not found, Sync uses `id` (or `remoteID`) by default, but if you have another local primary key make sure to mark it with `"sync.isPrimaryKey" : "true"` in your attribute's user info. For more information check the [Primary Key](https://github.com/SyncDB/Sync#primary-key) section.

```swift
let localKey = entity.sync_localPrimaryKey()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@ static NSString * const SyncDefaultLocalCompatiblePrimaryKey = @"remoteID";

static NSString * const SyncDefaultRemotePrimaryKey = @"id";

static NSString * const SyncCustomLocalPrimaryKey = @"hyper.isPrimaryKey";
static NSString * const SyncCustomLocalPrimaryKeyValue = @"YES";
static NSString * const SyncCustomLocalPrimaryKeyAlternativeValue = @"true";

static NSString * const SyncCustomRemoteKey = @"sync.remoteKey";
static NSString * const SyncCompatibilityCustomRemoteKey = @"hyper.remoteKey";

@interface NSEntityDescription (SyncPrimaryKey)

/**
Returns the Core Data attribute used as the primary key. By default it will look for the attribute named `id`.
You can mark any attribute as primary key by adding `hyper.isPrimaryKey` and the value `YES` to the Core Data model userInfo.
You can mark any attribute as primary key by adding `sync.isPrimaryKey` and the value `YES` to the Core Data model userInfo.
@return The attribute description that represents the primary key.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ - (nonnull NSAttributeDescription *)sync_primaryKeyAttribute {
[self.propertiesByName enumerateKeysAndObjectsUsingBlock:^(NSString *key,
NSAttributeDescription *attributeDescription,
BOOL *stop) {
NSString *isPrimaryKey = attributeDescription.userInfo[SyncCustomLocalPrimaryKey];
BOOL hasCustomPrimaryKey = (isPrimaryKey &&
([isPrimaryKey isEqualToString:SyncCustomLocalPrimaryKeyValue] || [isPrimaryKey isEqualToString:SyncCustomLocalPrimaryKeyAlternativeValue]) );
if (hasCustomPrimaryKey) {
if (attributeDescription.isCustomPrimaryKey) {
primaryKeyAttribute = attributeDescription;
*stop = YES;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

@interface NSPropertyDescription (Sync)

@property (readonly) BOOL isCustomPrimaryKey;

@property (nonatomic, nullable, readonly) NSString *customKey;

@end
20 changes: 20 additions & 0 deletions Source/NSPropertyDescription-Sync/NSPropertyDescription+Sync.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,28 @@

#import "NSEntityDescription+SyncPrimaryKey.h"

static NSString * const SyncCustomLocalPrimaryKey = @"sync.isPrimaryKey";
static NSString * const SyncCompatibilityCustomLocalPrimaryKey = @"hyper.isPrimaryKey";
static NSString * const SyncCustomLocalPrimaryKeyValue = @"YES";
static NSString * const SyncCustomLocalPrimaryKeyAlternativeValue = @"true";

static NSString * const SyncCustomRemoteKey = @"sync.remoteKey";
static NSString * const SyncCompatibilityCustomRemoteKey = @"hyper.remoteKey";

@implementation NSPropertyDescription (Sync)

- (BOOL)isCustomPrimaryKey {
NSString *keyName = self.userInfo[SyncCustomLocalPrimaryKey];
if (keyName == nil) {
keyName = self.userInfo[SyncCompatibilityCustomLocalPrimaryKey];
}

BOOL hasCustomPrimaryKey = (keyName &&
([keyName isEqualToString:SyncCustomLocalPrimaryKeyValue] || [keyName isEqualToString:SyncCustomLocalPrimaryKeyAlternativeValue]) );

return hasCustomPrimaryKey;
}

- (NSString *)customKey {
NSString *keyName = self.userInfo[SyncCustomRemoteKey];
if (keyName == nil) {
Expand Down
2 changes: 1 addition & 1 deletion Source/Sync/Sync.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public protocol SyncDelegate: class {
}

if localPrimaryKey.isEmpty {
fatalError("Local primary key not found for entity: \(entityName), add a primary key named id or mark an existing attribute using hyper.isPrimaryKey")
fatalError("Local primary key not found for entity: \(entityName), add a primary key named id or mark an existing attribute using sync.isPrimaryKey")
}

if remotePrimaryKey.isEmpty {
Expand Down
2 changes: 1 addition & 1 deletion Tests/NSEntityDescription-SyncPrimaryKey/PrimaryKeyTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ - (void)testLocalPrimaryKey {
XCTAssertEqualObjects([entity sync_localPrimaryKey], @"alternativeID");

entity = [self entityForName:@"Compatibility"];
XCTAssertEqualObjects([entity sync_localPrimaryKey], @"id");
XCTAssertEqualObjects([entity sync_localPrimaryKey], @"custom");
}

- (void)testRemotePrimaryKey {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
<entity name="AlternativeID" syncable="YES">
<attribute name="alternativeID" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
</userInfo>
</attribute>
</entity>
<entity name="Compatibility" syncable="YES">
<attribute name="id" optional="YES" attributeType="String" syncable="YES">
<attribute name="custom" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="hyper.remoteKey" value="greeting"/>
</userInfo>
</attribute>
Expand All @@ -21,7 +22,7 @@
<attribute name="attribute" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="uniqueID" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
</entity>
Expand All @@ -33,7 +34,7 @@
<attribute name="attribute" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="randomId" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand All @@ -44,11 +45,11 @@
</entity>
<elements>
<element name="AlternativeID" positionX="-27" positionY="18" width="128" height="60"/>
<element name="Compatibility" positionX="-27" positionY="18" width="128" height="60"/>
<element name="NoID" positionX="-27" positionY="18" width="128" height="60"/>
<element name="Note" positionX="-20" positionY="18" width="128" height="75"/>
<element name="SimpleID" positionX="-27" positionY="18" width="128" height="75"/>
<element name="Tag" positionX="160" positionY="0" width="128" height="75"/>
<element name="User" positionX="-207" positionY="-15" width="128" height="73"/>
<element name="Compatibility" positionX="-27" positionY="18" width="128" height="60"/>
</elements>
</model>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<entity name="AwesomeComment" syncable="YES">
<attribute name="body" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="awesomeComments" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="AwesomeComment" inverseName="awesomeComments" inverseEntity="AwesomeComment" syncable="YES"/>
Expand Down
10 changes: 5 additions & 5 deletions Tests/Sync/Models/125.xcdatamodeld/125.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<entity name="Element" syncable="YES">
<attribute name="label" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="element" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Element" inverseName="elements" inverseEntity="Element" syncable="YES"/>
Expand All @@ -14,7 +14,7 @@
<entity name="Form" syncable="YES">
<attribute name="uri" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="element" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Element" inverseName="form" inverseEntity="Element" syncable="YES"/>
Expand All @@ -23,7 +23,7 @@
<entity name="Model" syncable="YES">
<attribute name="uri" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="form" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Form" inverseName="model" inverseEntity="Form" syncable="YES"/>
Expand All @@ -37,15 +37,15 @@
<entity name="Restriction" syncable="YES">
<attribute name="restriction" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="property" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="ModelProperty" inverseName="restrictions" inverseEntity="ModelProperty" syncable="YES"/>
</entity>
<entity name="SelectionItem" syncable="YES">
<attribute name="value" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="element" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Element" inverseName="items" inverseEntity="Element" syncable="YES"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="noteID" attributeType="Integer 32" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand All @@ -14,7 +14,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="tagID" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="noteID" attributeType="Integer 32" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand All @@ -14,7 +14,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="userID" attributeType="Integer 32" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand Down
4 changes: 2 additions & 2 deletions Tests/Sync/Models/157.xcdatamodeld/157.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<entity name="City" syncable="YES">
<attribute name="cityID" attributeType="Integer 16" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand All @@ -13,7 +13,7 @@
<entity name="Location" syncable="YES">
<attribute name="locationID" attributeType="Integer 16" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
<entry key="sync.remoteKey" value="id"/>
</userInfo>
</attribute>
Expand Down
4 changes: 2 additions & 2 deletions Tests/Sync/Models/179.xcdatamodeld/179.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<entity name="Place" syncable="YES">
<attribute name="name" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="endRoutes" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Route" inverseName="endPlace" inverseEntity="Route" syncable="YES"/>
Expand All @@ -12,7 +12,7 @@
<entity name="Route" syncable="YES">
<attribute name="ident" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="endPlace" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Place" inverseName="endRoutes" inverseEntity="Place" syncable="YES">
Expand Down
4 changes: 2 additions & 2 deletions Tests/Sync/Models/239.xcdatamodeld/239.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="remoteID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="NO" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="car" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Car" inverseName="passengers" inverseEntity="Car" syncable="YES"/>
Expand All @@ -16,7 +16,7 @@
<attribute name="maxSpeed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="remoteID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="NO" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
</entity>
Expand Down
4 changes: 2 additions & 2 deletions Tests/Sync/Models/277.xcdatamodeld/239.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
<entity name="Passenger" syncable="YES">
<attribute name="remoteID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="NO" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="cars" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Car" inverseName="passengers" inverseEntity="Car" syncable="YES"/>
</entity>
<entity name="Racecar" parentEntity="Car" syncable="YES">
<attribute name="remoteID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="NO" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
</entity>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<entity name="Route" syncable="YES">
<attribute name="busID" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
<entry key="sync.remoteKey" value="busID"/>
</userInfo>
</attribute>
Expand All @@ -13,15 +13,15 @@
<entity name="RoutePolylineItem" syncable="YES">
<attribute name="index" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
</userInfo>
</attribute>
<relationship name="route" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Route" inverseName="polyline" inverseEntity="Route" syncable="YES"/>
</entity>
<entity name="RouteStop" syncable="YES">
<attribute name="index" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="true"/>
<entry key="sync.isPrimaryKey" value="true"/>
</userInfo>
</attribute>
<relationship name="route" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Route" inverseName="stops" inverseEntity="Route" syncable="YES"/>
Expand Down
4 changes: 2 additions & 2 deletions Tests/Sync/Models/84.xcdatamodeld/84.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="xid" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="staff" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="MSStaff" inverseName="fulfillers" inverseEntity="MSStaff" syncable="YES"/>
Expand All @@ -13,7 +13,7 @@
<attribute name="image" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="xid" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="hyper.isPrimaryKey" value="YES"/>
<entry key="sync.isPrimaryKey" value="YES"/>
</userInfo>
</attribute>
<relationship name="fulfillers" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="MSFulfiller" inverseName="staff" inverseEntity="MSFulfiller" syncable="YES"/>
Expand Down
Loading

0 comments on commit 48c5e2d

Please sign in to comment.