2020NSString * const FCModelChangeNotification = @" FCModelChangeNotification" ;
2121NSString * const FCModelInstanceKey = @" FCModelInstanceKey" ;
2222NSString * const FCModelChangedFieldsKey = @" FCModelChangedFieldsKey" ;
23-
23+ NSString * const FCModelChangeTypeKey = @" FCModelChangeTypeKey" ;
24+ NSString * const FCModelOldFieldValuesKey = @" FCModelOldFieldValuesKey" ;
2425NSString * const FCModelWillSendChangeNotification = @" FCModelWillSendChangeNotification" ; // for FCModelCachedObject
2526
2627static NSMutableDictionary *g_instances = NULL ;
@@ -41,7 +42,7 @@ @interface FCModel () {
4142 FCModelInDatabaseStatus _inDatabaseStatus;
4243}
4344@property (nonatomic , copy ) NSDictionary *_rowValuesInDatabase;
44- + (void )postChangeNotificationWithChangedFields : (NSSet *)changedFields ;
45+ + (void )postChangeNotificationWithChangedFields : (NSSet *)changedFields changedObject : (FCModel *) changedObject changeType : (FCModelChangeType) changeType priorFieldValues : ( NSDictionary *) priorFieldValues ;
4546@end
4647
4748static inline BOOL checkForOpenDatabaseFatal (BOOL fatal)
@@ -575,6 +576,8 @@ - (BOOL)_save
575576
576577 __block BOOL hadChanges = NO ;
577578 __block NSSet *changedFields;
579+ __block FCModelChangeType changeType = FCModelChangeTypeUnspecified;
580+ __block NSDictionary *previousRowValuesInDatabase = nil ;
578581 fcm_onMainThread (^{
579582 [g_database inDatabase: ^(FMDatabase *db) {
580583
@@ -594,11 +597,13 @@ - (BOOL)_save
594597 if (update) {
595598 columnNames = [changes allKeys ];
596599 changedFields = [NSSet setWithArray: columnNames];
600+ changeType = FCModelChangeTypeUpdate;
597601 } else {
598602 changedFields = [NSSet setWithArray: self .class.databaseFieldNames];
599603 NSMutableSet *columnNamesMinusPK = [[NSSet setWithArray: [g_fieldInfo[self .class] allKeys ]] mutableCopy ];
600604 [columnNamesMinusPK removeObject: pkName];
601605 columnNames = [columnNamesMinusPK allObjects ];
606+ changeType = FCModelChangeTypeInsert;
602607 }
603608
604609 // Validate NOT NULL columns
@@ -649,8 +654,8 @@ - (BOOL)_save
649654 g_database.isInInternalWrite = NO ;
650655 if (! success) [self .class queryFailedInDatabase: db];
651656
652- NSDictionary *rowValuesInDatabase = self._rowValuesInDatabase ;
653- NSMutableDictionary *newRowValues = rowValuesInDatabase ? [rowValuesInDatabase mutableCopy ] : [NSMutableDictionary dictionary ];
657+ previousRowValuesInDatabase = self._rowValuesInDatabase ;
658+ NSMutableDictionary *newRowValues = previousRowValuesInDatabase ? [previousRowValuesInDatabase mutableCopy ] : [NSMutableDictionary dictionary ];
654659 [changes enumerateKeysAndObjectsUsingBlock: ^(NSString *fieldName, id obj, BOOL *stop) {
655660 newRowValues[fieldName] = obj ?: NSNull .null ;
656661 }];
@@ -660,7 +665,7 @@ - (BOOL)_save
660665 hadChanges = YES ;
661666 }];
662667
663- if (hadChanges) [self .class postChangeNotificationWithChangedFields: changedFields];
668+ if (hadChanges) [self .class postChangeNotificationWithChangedFields: changedFields changedObject: self changeType: changeType priorFieldValues: previousRowValuesInDatabase ];
664669 });
665670 return hadChanges;
666671}
@@ -687,7 +692,7 @@ - (void)delete
687692
688693 [g_instances[self .class] removeObjectForKey: pkValue];
689694
690- [self .class postChangeNotificationWithChangedFields: nil ];
695+ [self .class postChangeNotificationWithChangedFields: nil changedObject: self changeType: FCModelChangeTypeDelete priorFieldValues: nil ];
691696 });
692697}
693698
@@ -1006,7 +1011,7 @@ + (BOOL)vacuumIfPossible
10061011 return success;
10071012}
10081013
1009- + (void )postChangeNotificationWithChangedFields : (NSSet *)changedFields
1014+ + (void )postChangeNotificationWithChangedFields : (NSSet *)changedFields changedObject : (FCModel *) changedObject changeType : (FCModelChangeType) changeType priorFieldValues : ( NSDictionary *) priorFieldValues
10101015{
10111016 if (! changedFields) changedFields = [NSSet setWithArray: self .class.databaseFieldNames];
10121017
@@ -1017,7 +1022,24 @@ + (void)postChangeNotificationWithChangedFields:(NSSet *)changedFields
10171022 else g_database.enqueuedChangedFieldsByClass [class] = [changedFields mutableCopy ];
10181023 } else {
10191024 // notify immediately
1020- NSDictionary *userInfo = @{ FCModelChangedFieldsKey : changedFields };
1025+ NSDictionary *userInfo =
1026+ changedObject ? (
1027+ changeType == FCModelChangeTypeUpdate && priorFieldValues ?
1028+ @{
1029+ FCModelChangedFieldsKey : changedFields,
1030+ FCModelChangeTypeKey : @(changeType),
1031+ FCModelInstanceKey : changedObject,
1032+ FCModelOldFieldValuesKey : priorFieldValues,
1033+ } : @{
1034+ FCModelChangedFieldsKey : changedFields,
1035+ FCModelChangeTypeKey : @(changeType),
1036+ FCModelInstanceKey : changedObject,
1037+ }
1038+ ) : @{
1039+ FCModelChangedFieldsKey : changedFields,
1040+ FCModelChangeTypeKey : @(FCModelChangeTypeUnspecified)
1041+ }
1042+ ;
10211043 [NSNotificationCenter .defaultCenter postNotificationName: FCModelWillSendChangeNotification object: self userInfo: userInfo];
10221044 [NSNotificationCenter .defaultCenter postNotificationName: FCModelChangeNotification object: self userInfo: userInfo];
10231045 }
@@ -1032,7 +1054,7 @@ + (void)dataChangedExternally
10321054 for (FCModel *m in classCache.objectEnumerator .allObjects ) [m reload ];
10331055 }
10341056
1035- [modelClass postChangeNotificationWithChangedFields: nil ];
1057+ [modelClass postChangeNotificationWithChangedFields: nil changedObject: nil changeType: FCModelChangeTypeUnspecified priorFieldValues: nil ];
10361058 }];
10371059 });
10381060}
0 commit comments