Skip to content
Snippets Groups Projects
Commit df1c14ea authored by cramakri's avatar cramakri
Browse files

Added pruning of potentially outdated information.

SVN: 27444
parent 0ff2d079
No related branches found
No related tags found
No related merge requests found
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
@property (nonatomic, retain) NSString * permId; @property (nonatomic, retain) NSString * permId;
@property (nonatomic, retain) NSString * refconJson; @property (nonatomic, retain) NSString * refconJson;
@property (readonly) id refcon; @property (readonly) id refcon;
@property (nonatomic, retain) NSString * serverUrlString;
@property (nonatomic, retain) NSDate * lastUpdateDate;
// Potentially nil properties // Potentially nil properties
@property (nonatomic, retain) NSString * summaryHeader; @property (nonatomic, retain) NSString * summaryHeader;
......
...@@ -45,6 +45,8 @@ id ObjectFromJsonData(NSString *jsonData, NSError **error) ...@@ -45,6 +45,8 @@ id ObjectFromJsonData(NSString *jsonData, NSError **error)
@dynamic childrenPermIdsJson; @dynamic childrenPermIdsJson;
@dynamic propertiesJson; @dynamic propertiesJson;
@dynamic rootLevel; @dynamic rootLevel;
@dynamic serverUrlString;
@dynamic lastUpdateDate;
@synthesize image; @synthesize image;
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
// Local Actions -- actions that do not require a network connection // Local Actions -- actions that do not require a network connection
- (NSArray *)allIpadEntitiesOrError:(NSError **)error; - (NSArray *)allIpadEntitiesOrError:(NSError **)error;
- (NSArray *)entitiesByPermId:(NSArray *)permIds error:(NSError **)error; - (NSArray *)entitiesByPermId:(NSArray *)permIds error:(NSError **)error;
- (NSArray *)entitiesNotUpdatedSince:(NSDate *)date error:(NSError **)error;
- (NSFetchRequest *)entityFetchRequest; - (NSFetchRequest *)entityFetchRequest;
- (NSArray *)executeFetchRequest:(NSFetchRequest *)fetchRequest error:(NSError **)error; - (NSArray *)executeFetchRequest:(NSFetchRequest *)fetchRequest error:(NSError **)error;
......
...@@ -61,25 +61,6 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl, ...@@ -61,25 +61,6 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl,
return moc; return moc;
} }
static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity, NSManagedObjectModel *model, NSManagedObjectContext *moc, NSError **error)
{
// Create new entities in the moc, and store them.
CISDOBIpadEntity *entity;
NSDictionary *fetchVariables = [NSDictionary dictionaryWithObject: [NSArray arrayWithObject: rawEntity.permId] forKey: @"PERM_IDS"];
NSFetchRequest *request = [model fetchRequestFromTemplateWithName: @"EntitiesByPermIds" substitutionVariables: fetchVariables];
NSArray *matchedEntities = [moc executeFetchRequest: request error: error];
if (!matchedEntities) return NO;
if ([matchedEntities count] > 0) {
entity = [matchedEntities objectAtIndex: 0];
[entity updateFromRawEntity: rawEntity];
} else {
entity = [NSEntityDescription insertNewObjectForEntityForName: @"CISDOBIpadEntity" inManagedObjectContext: moc];
[entity initializeFromRawEntity: rawEntity];
}
return YES;
}
@implementation CISDOBIpadServiceManager @implementation CISDOBIpadServiceManager
...@@ -101,25 +82,57 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity, ...@@ -101,25 +82,57 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity,
return self; return self;
} }
- (BOOL)syncEntities:(NSArray *)rawEntities error:(NSError **)error - (BOOL)synchEntity:(CISDOBIpadRawEntity *)rawEntity lastUpdateDate:(NSDate *)date error:(NSError **)error
{ {
{
// Create new entities in the moc, and store them.
CISDOBIpadEntity *entity;
NSArray *matchedEntities = [self entitiesByPermId: [NSArray arrayWithObject: rawEntity.permId] error: error];
if (!matchedEntities) return NO;
if ([matchedEntities count] > 0) {
entity = [matchedEntities objectAtIndex: 0];
[entity updateFromRawEntity: rawEntity];
} else {
entity = [NSEntityDescription insertNewObjectForEntityForName: @"CISDOBIpadEntity" inManagedObjectContext: self.managedObjectContext];
[entity initializeFromRawEntity: rawEntity];
}
entity.lastUpdateDate = date;
entity.serverUrlString = [((CISDOBLiveConnection *)(self.service.connection)).url absoluteString];
return YES;
}
}
- (BOOL)syncEntities:(NSArray *)rawEntities pruning:(BOOL)prune error:(NSError **)error
{
NSDate *lastUpdateDate = [NSDate date];
BOOL success; BOOL success;
for (CISDOBIpadRawEntity *rawEntity in rawEntities) { for (CISDOBIpadRawEntity *rawEntity in rawEntities) {
success = SynchEntityWithManagedObjectContext(rawEntity, self.managedObjectModel, self.managedObjectContext, error); success = [self synchEntity: rawEntity lastUpdateDate: lastUpdateDate error: error];
if (!success) return NO; if (!success) return NO;
} }
// If pruning is requested, remove entities that cannot be reached from the server result set.
// TODO : we should treat the intial results as a root set and trace out to do a gc, but the simpler implementation is just to remove everything that is not mentioned
if (prune) {
// Remove all entities that were not mentioned
NSArray *entitiesToDelete = [self entitiesNotUpdatedSince: lastUpdateDate error: error];
for (CISDOBIpadEntity *entity in entitiesToDelete) {
[self.managedObjectContext deleteObject: entity];
}
}
success = [self.managedObjectContext save: error]; success = [self.managedObjectContext save: error];
return success; return success;
} }
- (CISDOBIpadServiceManagerCall *)managerCallWrappingServiceCall:(CISDOBAsyncCall *)serviceCall - (CISDOBIpadServiceManagerCall *)managerCallWrappingServiceCall:(CISDOBAsyncCall *)serviceCall pruning:(BOOL)prune
{ {
CISDOBIpadServiceManagerCall *managerCall = [[CISDOBIpadServiceManagerCall alloc] initWithServiceManager: self serviceCall: serviceCall]; CISDOBIpadServiceManagerCall *managerCall = [[CISDOBIpadServiceManagerCall alloc] initWithServiceManager: self serviceCall: serviceCall];
serviceCall.success = ^(id result) { serviceCall.success = ^(id result) {
// Update the cache // Update the cache
NSError *error; NSError *error;
BOOL didSync = [self syncEntities: result error: &error]; BOOL didSync = [self syncEntities: result pruning: prune error: &error];
if (!didSync) { if (!didSync) {
serviceCall.fail(error); serviceCall.fail(error);
} else if (managerCall.success) { } else if (managerCall.success) {
...@@ -132,6 +145,11 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity, ...@@ -132,6 +145,11 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity,
return managerCall; return managerCall;
} }
- (CISDOBIpadServiceManagerCall *)managerCallWrappingServiceCall:(CISDOBAsyncCall *)serviceCall
{
return [self managerCallWrappingServiceCall: serviceCall pruning: NO];
}
- (CISDOBAsyncCall *)loginUser:(NSString *)user password:(NSString *)password - (CISDOBAsyncCall *)loginUser:(NSString *)user password:(NSString *)password
{ {
return [self.service loginUser: user password: password]; return [self.service loginUser: user password: password];
...@@ -140,7 +158,8 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity, ...@@ -140,7 +158,8 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity,
- (CISDOBAsyncCall *)retrieveRootLevelEntities - (CISDOBAsyncCall *)retrieveRootLevelEntities
{ {
CISDOBAsyncCall *call = [self.service listRootLevelEntities]; CISDOBAsyncCall *call = [self.service listRootLevelEntities];
return [self managerCallWrappingServiceCall: call]; // get rid of entities not mentioned in the original call
return [self managerCallWrappingServiceCall: call pruning: YES];
} }
- (CISDOBAsyncCall *)drillOnEntity:(CISDOBIpadEntity *)entity - (CISDOBAsyncCall *)drillOnEntity:(CISDOBIpadEntity *)entity
...@@ -168,6 +187,13 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity, ...@@ -168,6 +187,13 @@ static BOOL SynchEntityWithManagedObjectContext(CISDOBIpadRawEntity *rawEntity,
return [self executeFetchRequest: request error: error]; return [self executeFetchRequest: request error: error];
} }
- (NSArray *)entitiesNotUpdatedSince:(NSDate *)date error:(NSError **)error
{
NSDictionary *fetchVariables = [NSDictionary dictionaryWithObject: date forKey: @"LAST_UPDATE_DATE"];
NSFetchRequest *request = [self.managedObjectModel fetchRequestFromTemplateWithName: @"EntitiesNotUpdatedSince" substitutionVariables: fetchVariables];
return [self executeFetchRequest: request error: error];
}
- (NSFetchRequest *)entityFetchRequest - (NSFetchRequest *)entityFetchRequest
{ {
NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSFetchRequest *request = [[NSFetchRequest alloc] init];
......
...@@ -6,19 +6,22 @@ ...@@ -6,19 +6,22 @@
<attribute name="childrenPermIdsJson" optional="YES" attributeType="String" indexed="YES" syncable="YES"/> <attribute name="childrenPermIdsJson" optional="YES" attributeType="String" indexed="YES" syncable="YES"/>
<attribute name="identifier" optional="YES" attributeType="String" indexed="YES" syncable="YES"/> <attribute name="identifier" optional="YES" attributeType="String" indexed="YES" syncable="YES"/>
<attribute name="imageUrl" optional="YES" attributeType="String" syncable="YES"/> <attribute name="imageUrl" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="lastUpdateDate" optional="YES" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="permId" optional="YES" attributeType="String" indexed="YES" syncable="YES"/> <attribute name="permId" optional="YES" attributeType="String" indexed="YES" syncable="YES"/>
<attribute name="properties" optional="YES" transient="YES" syncable="YES"/> <attribute name="properties" optional="YES" transient="YES" syncable="YES"/>
<attribute name="propertiesJson" optional="YES" attributeType="String" syncable="YES"/> <attribute name="propertiesJson" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="refcon" optional="YES" transient="YES" syncable="YES"/> <attribute name="refcon" optional="YES" transient="YES" syncable="YES"/>
<attribute name="refconJson" optional="YES" attributeType="String" syncable="YES"/> <attribute name="refconJson" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="rootLevel" optional="YES" attributeType="Boolean" syncable="YES"/> <attribute name="rootLevel" optional="YES" attributeType="Boolean" indexed="YES" syncable="YES"/>
<attribute name="serverUrlString" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="summary" optional="YES" attributeType="String" syncable="YES"/> <attribute name="summary" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="summaryHeader" optional="YES" attributeType="String" syncable="YES"/> <attribute name="summaryHeader" optional="YES" attributeType="String" syncable="YES"/>
</entity> </entity>
<fetchRequest name="EntitiesByPermIds" entity="CISDOBIpadEntity" predicateString="permId IN $PERM_IDS" fetchBatchSize="20"/> <fetchRequest name="EntitiesByPermIds" entity="CISDOBIpadEntity" predicateString="permId IN $PERM_IDS" fetchBatchSize="20"/>
<fetchRequest name="EntitiesNotUpdatedSince" entity="CISDOBIpadEntity" predicateString="lastUpdateDate &lt; $LAST_UPDATE_DATE"/>
<fetchRequest name="EntityAndChildren" entity="CISDOBIpadEntity" predicateString="SELF == $ENTITY OR permId IN $CHILDREN" fetchBatchSize="20"/> <fetchRequest name="EntityAndChildren" entity="CISDOBIpadEntity" predicateString="SELF == $ENTITY OR permId IN $CHILDREN" fetchBatchSize="20"/>
<fetchRequest name="RootEntities" entity="CISDOBIpadEntity" predicateString="rootLevel == 0" fetchBatchSize="20"/> <fetchRequest name="RootEntities" entity="CISDOBIpadEntity" predicateString="rootLevel == 0" fetchBatchSize="20"/>
<elements> <elements>
<element name="CISDOBIpadEntity" positionX="0" positionY="0" width="128" height="240"/> <element name="CISDOBIpadEntity" positionX="0" positionY="0" width="128" height="270"/>
</elements> </elements>
</model> </model>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment