Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 94BBC9620 for ; Fri, 23 Mar 2012 10:54:36 +0000 (UTC) Received: (qmail 29165 invoked by uid 500); 23 Mar 2012 10:54:36 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 29109 invoked by uid 500); 23 Mar 2012 10:54:36 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 29094 invoked by uid 99); 23 Mar 2012 10:54:35 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Mar 2012 10:54:35 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id A1F468922; Fri, 23 Mar 2012 10:54:35 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: shazron@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: ios commit: Cleaned up and tweaked CDVLocalStorage fixes for CB-330, CB-347 Message-Id: <20120323105435.A1F468922@tyr.zones.apache.org> Date: Fri, 23 Mar 2012 10:54:35 +0000 (UTC) Updated Branches: refs/heads/master a58624232 -> bd4345411 Cleaned up and tweaked CDVLocalStorage fixes for CB-330, CB-347 Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/commit/bd434541 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/bd434541 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/bd434541 Branch: refs/heads/master Commit: bd434541123f909e9f384fa8cdae75d7226b0158 Parents: a586242 Author: Shazron Abdullah Authored: Fri Mar 23 03:54:24 2012 -0700 Committer: Shazron Abdullah Committed: Fri Mar 23 03:54:24 2012 -0700 ---------------------------------------------------------------------- CordovaLib/Classes/CDVLocalStorage.h | 7 +- CordovaLib/Classes/CDVLocalStorage.m | 152 +++++++++++++++++++++++++---- 2 files changed, 139 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bd434541/CordovaLib/Classes/CDVLocalStorage.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVLocalStorage.h b/CordovaLib/Classes/CDVLocalStorage.h index 0abd43d..cca2160 100644 --- a/CordovaLib/Classes/CDVLocalStorage.h +++ b/CordovaLib/Classes/CDVLocalStorage.h @@ -19,7 +19,7 @@ #import "CDVPlugin.h" -#define kCDVLocalStorageErrorDomain @"kCDVLocalStorageErrorDomain" +#define kCDVLocalStorageErrorDomain @"kCDVLocalStorageErrorDomain" #define kCDVLocalStorageFileOperationError 1 @interface CDVLocalStorage : CDVPlugin < UIWebViewDelegate > @@ -30,6 +30,8 @@ - (void) restore:(NSArray*)arguments withDict:(NSMutableDictionary*)options; - (void) verifyAndFixDatabaseLocations:(NSArray*)arguments withDict:(NSMutableDictionary*)options; ++ (void) verifyAndFixDatabaseLocations; + @end @interface CDVBackupInfo : NSObject @@ -38,4 +40,7 @@ @property (nonatomic, copy) NSString* backup; @property (nonatomic, copy) NSString* label; +- (BOOL) shouldBackup; +- (BOOL) shouldRestore; + @end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bd434541/CordovaLib/Classes/CDVLocalStorage.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVLocalStorage.m b/CordovaLib/Classes/CDVLocalStorage.m index fbd5d1c..fa171cd 100644 --- a/CordovaLib/Classes/CDVLocalStorage.m +++ b/CordovaLib/Classes/CDVLocalStorage.m @@ -170,16 +170,33 @@ /* copy from webkitDbLocation to persistentDbLocation */ - (void) backup:(NSArray*)arguments withDict:(NSMutableDictionary*)options; { + NSString* callbackId = [arguments objectAtIndex:0]; + NSError* error = nil; + CDVPluginResult* result = nil; + NSString* message = nil; for (CDVBackupInfo* info in self.backupInfo) { - [self copyFrom:info.original to:info.backup error:&error]; - - if (error == nil) { - NSLog(@"Backed up: %@", info.label); - } else { - NSLog(@"Error in CDVLocalStorage (%@) backup: %@", info.label, [error localizedDescription]); + if ([info shouldBackup]) + { + [self copyFrom:info.original to:info.backup error:&error]; + + if (error == nil) { + message = [NSString stringWithFormat:@"Backed up: %@", info.label]; + NSLog(@"%@", message); + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; + [self writeJavascript:[result toSuccessCallbackString:callbackId]]; + + } else { + message = [NSString stringWithFormat:@"Error in CDVLocalStorage (%@) backup: %@", info.label, [error localizedDescription]]; + NSLog(@"%@", message); + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:message]; + [self writeJavascript:[result toErrorCallbackString:callbackId]]; + + } } } } @@ -187,44 +204,77 @@ /* copy from persistentDbLocation to webkitDbLocation */ - (void) restore:(NSArray*)arguments withDict:(NSMutableDictionary*)options; { + NSString* callbackId = [arguments objectAtIndex:0]; + NSError* error = nil; + CDVPluginResult* result = nil; + NSString* message = nil; for (CDVBackupInfo* info in self.backupInfo) { - [self copyFrom:info.backup to:info.original error:&error]; - - if (error == nil) { - NSLog(@"CDVLocalStorage restored: %@", info.label); - } else { - NSLog(@"Error in CDVLocalStorage (%@) restore: %@", info.label, [error localizedDescription]); + if ([info shouldRestore]) + { + [self copyFrom:info.backup to:info.original error:&error]; + + if (error == nil) { + message = [NSString stringWithFormat:@"Restored: %@", info.label]; + NSLog(@"%@", message); + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; + [self writeJavascript:[result toSuccessCallbackString:callbackId]]; + + } else { + message = [NSString stringWithFormat:@"Error in CDVLocalStorage (%@) restore: %@", info.label, [error localizedDescription]]; + NSLog(@"%@", message); + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:message]; + [self writeJavascript:[result toErrorCallbackString:callbackId]]; + + } } } } - (void) verifyAndFixDatabaseLocations:(NSArray*)arguments withDict:(NSMutableDictionary*)options { + [[self class] verifyAndFixDatabaseLocations]; +} + ++ (void) verifyAndFixDatabaseLocations +{ + NSString* libraryCaches = @"Library/Caches"; + NSString* libraryWebKit = @"Library/WebKit"; + NSString* libraryPreferences = @"Library/Preferences"; + NSUserDefaults* appPreferences = [NSUserDefaults standardUserDefaults]; NSBundle* mainBundle = [NSBundle mainBundle]; NSString* bundlePath = [[mainBundle bundlePath] stringByDeletingLastPathComponent]; NSString* bundleIdentifier = [[mainBundle infoDictionary] objectForKey:@"CFBundleIdentifier"]; - NSString* appPlistPath = [[bundlePath stringByAppendingPathComponent:@"Library/Preferences"] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", bundleIdentifier]]; + NSString* appPlistPath = [[bundlePath stringByAppendingPathComponent:libraryPreferences] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", bundleIdentifier]]; NSMutableDictionary* appPlistDict = [NSMutableDictionary dictionaryWithContentsOfFile:appPlistPath]; NSArray* keysToCheck = [NSArray arrayWithObjects: - @"WebKitLocalStorageDatabasePathPreferenceKey", @"WebDatabaseDirectory", nil]; - + @"WebKitLocalStorageDatabasePathPreferenceKey", + @"WebDatabaseDirectory", + nil]; BOOL dirty = NO; - NSString* pathSuffix = (IsiOSVersion(@"5.1")) ? @"Library/Caches" : @"Library/WebKit"; - + for (NSString* key in keysToCheck) { NSString* value = [appPlistDict objectForKey:key]; // verify path is in app bundle, if not - fix - if (![value hasPrefix:bundlePath]) { - [appPlistDict setValue:[bundlePath stringByAppendingPathComponent:pathSuffix] forKey:key]; + if (![value hasPrefix:bundlePath]) + { + // the pathSuffix to use may be wrong - OTA upgrades from < 5.1 to 5.1 do keep the old path Library/WebKit, + // while Xcode synced ones do change the storage location to Library/Caches + NSString* newBundlePath = [bundlePath stringByAppendingPathComponent:libraryCaches]; + if (![[NSFileManager defaultManager] fileExistsAtPath:newBundlePath]) { + newBundlePath = [bundlePath stringByAppendingPathComponent:libraryWebKit]; + } + [appPlistDict setValue:newBundlePath forKey:key]; dirty = YES; } } @@ -296,4 +346,68 @@ @synthesize original, backup, label; +- (BOOL) file:(NSString*)aPath isNewerThanFile:(NSString*)bPath +{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSError* error = nil; + + NSDictionary* aPathAttribs = [fileManager attributesOfItemAtPath:aPath error:&error]; + NSDictionary* bPathAttribs = [fileManager attributesOfItemAtPath:bPath error:&error]; + + NSDate* aPathModDate = [aPathAttribs objectForKey:NSFileModificationDate]; + NSDate* bPathModDate = [bPathAttribs objectForKey:NSFileModificationDate]; + + if (nil == aPathModDate && nil == bPathModDate) { + return NO; + } + + return ([aPathModDate compare:bPathModDate] == NSOrderedDescending || bPathModDate == nil); +} + +- (BOOL) item:(NSString*)aPath isNewerThanItem:(NSString*)bPath +{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + + BOOL aPathIsDir = NO, bPathIsDir = NO; + BOOL aPathExists = [fileManager fileExistsAtPath:aPath isDirectory:&aPathIsDir]; + [fileManager fileExistsAtPath:bPath isDirectory:&bPathIsDir]; + + if (!aPathExists) { + return NO; + } + + if (!(aPathIsDir && bPathIsDir)){ // just a file + return [self file:aPath isNewerThanFile:bPath]; + } + + // essentially we want rsync here, but have to settle for our poor man's implementation + // we get the files in aPath, and see if it is newer than the file in bPath + // (it is newer if it doesn't exist in bPath) if we encounter the FIRST file that is newer, + // we return YES + NSDirectoryEnumerator* directoryEnumerator = [fileManager enumeratorAtPath:aPath]; + NSString* path; + + while ((path = [directoryEnumerator nextObject])) { + NSString* aPathFile = [aPath stringByAppendingPathComponent:path]; + NSString* bPathFile = [bPath stringByAppendingPathComponent:path]; + + BOOL isNewer = [self file:aPathFile isNewerThanFile:bPathFile]; + if (isNewer) { + return YES; + } + } + + return NO; +} + +- (BOOL) shouldBackup +{ + return [self item:self.original isNewerThanItem:self.backup]; +} + +- (BOOL) shouldRestore +{ + return [self item:self.backup isNewerThanItem:self.original]; +} + @end \ No newline at end of file