diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPAppController.m | 4 | ||||
-rw-r--r-- | Source/SPConstants.h | 20 | ||||
-rw-r--r-- | Source/SPConstants.m | 16 | ||||
-rw-r--r-- | Source/SPFavoritesController.h | 20 | ||||
-rw-r--r-- | Source/SPFavoritesController.m | 178 | ||||
-rw-r--r-- | Source/SPPreferencesUpgrade.h | 1 | ||||
-rw-r--r-- | Source/SPPreferencesUpgrade.m | 48 |
7 files changed, 271 insertions, 16 deletions
diff --git a/Source/SPAppController.m b/Source/SPAppController.m index c6c5c44a..a1f8b292 100644 --- a/Source/SPAppController.m +++ b/Source/SPAppController.m @@ -31,6 +31,7 @@ #import "SPDataImport.h" #import "SPEncodingPopupAccessory.h" #import "SPWindowController.h" +#import "SPPreferencesUpgrade.h" #import <PSMTabBar/PSMTabBarControl.h> #import <Sparkle/Sparkle.h> @@ -61,6 +62,8 @@ // Register application defaults [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PreferenceDefaults" ofType:@"plist"]]]; + // Migrate old connection favorites to the app's support directory (only uncomment when ready) + //SPMigrateConnectionFavoritesData(); } /** @@ -68,7 +71,6 @@ */ - (void)awakeFromNib { - // Register url scheme handle [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; diff --git a/Source/SPConstants.h b/Source/SPConstants.h index 651a68c5..6e20a5b3 100644 --- a/Source/SPConstants.h +++ b/Source/SPConstants.h @@ -241,6 +241,7 @@ extern NSString *SPBundleSupportFolder; extern NSString *SPDataSupportFolder; // Preference key constants +// // General Prefpane extern NSString *SPDefaultFavorite; extern NSString *SPSelectLastFavoriteUsed; @@ -365,14 +366,13 @@ extern NSString *SPLastImportIntoNewTableEncoding; extern NSString *SPLastImportIntoNewTableType; extern NSString *SPGlobalValueHistory; - // URLs extern NSString *SPDonationsURL; extern NSString *SPMySQLSearchURL; extern NSString *SPDevURL; // Toolbar constants - +// // Main window toolbar extern NSString *SPMainToolbarDatabaseSelection; extern NSString *SPMainToolbarHistoryNavigation; @@ -396,3 +396,19 @@ extern NSString *SPPreferenceToolbarAutoUpdate; extern NSString *SPPreferenceToolbarNetwork; extern NSString *SPPreferenceToolbarEditor; extern NSString *SPPreferenceToolbarShortcuts; + +// Connection favorite keys +extern NSString *SPFavoritesRootKey; +extern NSString *SPFavoriteChildrenKey; +extern NSString *SPFavoriteIDKey; +extern NSString *SPFavoriteNameKey; +extern NSString *SPFavoriteDatabaseKey; +extern NSString *SPFavoriteHostKey; +extern NSString *SPFavoritePortKey; +extern NSString *SPFavoriteUserKey; +extern NSString *SPFavoriteTypeKey; +extern NSString *SPFavoriteSocketKey; +extern NSString *SPFavoriteSSHHostKey; +extern NSString *SPFavoriteSSHPortKey; +extern NSString *SPFavoriteSSHUserKey; +extern NSString *SPFavoriteSSHKeyLocationKey; diff --git a/Source/SPConstants.m b/Source/SPConstants.m index bfacad2d..17e20849 100644 --- a/Source/SPConstants.m +++ b/Source/SPConstants.m @@ -216,3 +216,19 @@ NSString *SPPreferenceToolbarAutoUpdate = @"SPPreferenceToolbarAutoUpda NSString *SPPreferenceToolbarNetwork = @"SPPreferenceToolbarNetwork"; NSString *SPPreferenceToolbarEditor = @"SPPreferenceToolbarEditor"; NSString *SPPreferenceToolbarShortcuts = @"SPPreferenceToolbarShortcuts"; + +// Connection favorite keys +NSString *SPFavoritesRootKey = @"Favorites Root"; +NSString *SPFavoriteChildrenKey = @"Children"; +NSString *SPFavoriteIDKey = @"id"; +NSString *SPFavoriteNameKey = @"name"; +NSString *SPFavoriteDatabaseKey = @"database"; +NSString *SPFavoriteHostKey = @"host"; +NSString *SPFavoritePortKey = @"port"; +NSString *SPFavoriteUserKey = @"user"; +NSString *SPFavoriteTypeKey = @"type"; +NSString *SPFavoriteSocketKey = @"socket"; +NSString *SPFavoriteSSHHostKey = @"sshHost"; +NSString *SPFavoriteSSHPortKey = @"sshPort"; +NSString *SPFavoriteSSHUserKey = @"sshUser"; +NSString *SPFavoriteSSHKeyLocationKey = @"sshKeyLocationEnabled"; diff --git a/Source/SPFavoritesController.h b/Source/SPFavoritesController.h index 5e9d714c..bb698d16 100644 --- a/Source/SPFavoritesController.h +++ b/Source/SPFavoritesController.h @@ -25,11 +25,27 @@ #import "SPSingleton.h" +/** + * @class SPFavoritesController SPFavoritesController.h + * + * @author Stuart Connolly http://stuconnolly.com/ + * + * Connection favorites controller that provides a single point of access for managing the user's connection + * favorites in memory and on disk. + */ @interface SPFavoritesController : SPSingleton { - NSDictionary *favorties; + NSDictionary *favorites; } -- (SPFavoritesController *)sharedFavoritesController; +/** + * @property favorites Favorites data dictionary + */ +@property (readonly) NSDictionary *favorites; + ++ (SPFavoritesController *)sharedFavoritesController; + +- (void)saveFavorites; +- (void)reloadFavoritesWithSave:(BOOL)save; @end diff --git a/Source/SPFavoritesController.m b/Source/SPFavoritesController.m index dacd35dc..85f4e587 100644 --- a/Source/SPFavoritesController.m +++ b/Source/SPFavoritesController.m @@ -27,8 +27,41 @@ static SPFavoritesController *sharedFavoritesController = nil; +@interface SPFavoritesController (PrivateAPI) + +- (void)_loadFavorites; + +@end + @implementation SPFavoritesController +@synthesize favorites; + +#pragma mark - +#pragma mark Initialisation + ++ (id)allocWithZone:(NSZone *)zone +{ + @synchronized(self) { + return [[self sharedFavoritesController] retain]; + } +} + +- (id)init +{ + if ((self = [super init])) { + + favorites = nil; + + [self _loadFavorites]; + } + + return self; +} + +#pragma mark - +#pragma mark Public API + /** * Returns the shared favorites controller. */ @@ -43,20 +76,143 @@ static SPFavoritesController *sharedFavoritesController = nil; return sharedFavoritesController; } -+ (id)allocWithZone:(NSZone *)zone -{ - @synchronized(self) { - return [[self sharedFavoritesController] retain]; - } +/** + * Saves the current favorites dictionary in memory to disk. Note that the current favorites data file is moved + * rather than overwritten in the event that we can't write the new file, the original can simply be restored. + * This method also does a lot of error checking to ensure we don't lose the user's favorites data. + */ +- (void)saveFavorites +{ + NSError *error = nil; + NSString *errorString = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + + NSString *dataPath = [fileManager applicationSupportDirectoryForSubDirectory:SPDataSupportFolder error:&error]; + + if (error) { + NSLog(@"Error retrieving data directory path: %@", [error localizedDescription]); + return; + } + + NSString *favoritesFile = [dataPath stringByAppendingPathComponent:SPFavoritesDataFile]; + NSString *favoritesBackupFile = [dataPath stringByAppendingPathComponent:[@"~" stringByAppendingString:SPFavoritesDataFile]]; + + if ([fileManager fileExistsAtPath:favoritesFile]) { + [fileManager moveItemAtPath:favoritesFile toPath:favoritesBackupFile error:&error]; + } + + if (error) { + NSLog(@"Unable to backup (move) existing favorites data file during save. Deleting instead: %@", [error localizedDescription]); + + error = nil; + + if (![fileManager removeItemAtPath:favoritesFile error:&error] && error) { + NSLog(@"Unable to delete existing favorites data file during save. Something is wrong, permissions perhaps: %@", [error localizedDescription]); + return; + } + } + else { + NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:favorites + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&errorString]; + + if (plistData) { + [plistData writeToFile:favoritesFile options:NSAtomicWrite error:&error]; + + if (error) { + NSLog(@"Error writing favorites data. Restoring backup if available: %@", [error localizedDescription]); + + [fileManager moveItemAtPath:favoritesBackupFile toPath:favoritesFile error:NULL]; + } + else { + [fileManager removeItemAtPath:favoritesBackupFile error:NULL]; + } + } + else if (errorString) { + NSLog(@"Error converting favorites data to plist format: %@", errorString); + + [errorString release]; + } + } } -- (id)init +/** + * Reloads the favorites data from disk with the option to save before doing so. + * + * @param save Indicates whether the current favorites data in memory should be saved to disk before being + * reloaded. Specifying NO effectively discards any changes since the last save operation. + */ +- (void)reloadFavoritesWithSave:(BOOL)save { - if ((self = [super init])) { - - } - - return self; + if (save) [self saveFavorites]; + + if (favorites) [self _loadFavorites]; +} + +#pragma mark - +#pragma mark Private API + +/** + * Attempts to load the users connection favorites from ~/Library/Application Support/Sequel Pro/Data/Favorites.plist + * If the 'Data' directory doesn't already exist it will be created, as well as an empty favorites plist. + */ +- (void)_loadFavorites +{ + NSError *error = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if (favorites) [favorites release], favorites = nil; + + NSString *dataPath = [fileManager applicationSupportDirectoryForSubDirectory:SPDataSupportFolder error:&error]; + + if (error) { + NSLog(@"Error retrieving data directory path: %@", [error localizedDescription]); + return; + } + + NSString *favoritesFile = [dataPath stringByAppendingPathComponent:SPFavoritesDataFile]; + + if ([fileManager fileExistsAtPath:favoritesFile]) { + favorites = [[NSDictionary alloc] initWithContentsOfFile:favoritesFile]; + } + else { + NSDictionary *newFavorites = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSArray array] forKey:SPFavoriteChildrenKey] forKey:SPFavoritesRootKey]; + + NSError *error = nil; + NSString *errorString = nil; + + NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:newFavorites + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&errorString]; + if (plistData) { + [plistData writeToFile:favoritesFile options:NSAtomicWrite error:&error]; + + if (error) { + NSLog(@"Error writing default favorites data: %@", [error localizedDescription]); + } + } + else if (errorString) { + NSLog(@"Error converting default favorites data to plist format: %@", errorString); + + [errorString release]; + return; + } + + favorites = newFavorites; + } +} + +#pragma mark - + +/** + * Dealloc. + */ +- (void)dealloc +{ + if (favorites) [favorites release], favorites = nil; + + [super dealloc]; } @end diff --git a/Source/SPPreferencesUpgrade.h b/Source/SPPreferencesUpgrade.h index 03241880..33691da5 100644 --- a/Source/SPPreferencesUpgrade.h +++ b/Source/SPPreferencesUpgrade.h @@ -33,5 +33,6 @@ @interface SPPreferencesUpgrade : NSObject void SPApplyRevisionChanges(void); +void SPMigrateConnectionFavoritesData(void); @end diff --git a/Source/SPPreferencesUpgrade.m b/Source/SPPreferencesUpgrade.m index 887289e7..081be36a 100644 --- a/Source/SPPreferencesUpgrade.m +++ b/Source/SPPreferencesUpgrade.m @@ -297,4 +297,52 @@ void SPApplyRevisionChanges(void) [prefs setObject:[NSNumber numberWithInteger:currentVersionNumber] forKey:SPLastUsedVersion]; } +/** + * Attempts to migrate the user's connection favorites from their preference file to the new Favaorites + * plist in the application's support 'Data' directory. + */ +void SPMigrateConnectionFavoritesData(void) +{ + NSError *error = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + + NSString *dataPath = [fileManager applicationSupportDirectoryForSubDirectory:SPDataSupportFolder error:&error]; + + if (error) { + NSLog(@"Error loading favorites: %@", [error localizedDescription]); + return; + } + + NSString *favoritesFile = [dataPath stringByAppendingPathComponent:SPFavoritesDataFile]; + + // Only proceed if the new favorites plist doesn't already exist + if (![fileManager fileExistsAtPath:favoritesFile]) { + NSDictionary *newFavorites = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[[NSUserDefaults standardUserDefaults] objectForKey:SPFavorites] forKey:SPFavoriteChildrenKey] forKey:SPFavoritesRootKey]; + + NSError *error = nil; + NSString *errorString = nil; + + NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:newFavorites + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&errorString]; + if (plistData) { + [plistData writeToFile:favoritesFile options:NSAtomicWrite error:&error]; + + if (error) { + NSLog(@"Error migrating favorites data: %@", [error localizedDescription]); + } + else { + // Only uncomment when migration is complete + //[[NSUserDefaults standardUserDefaults] removeObjectForKey:SPFavorites]; + } + } + else if (errorString) { + NSLog(@"Error converting migrating favorites data to plist format: %@", errorString); + + [errorString release]; + return; + } + } +} + @end |