diff options
author | stuconnolly <stuart02@gmail.com> | 2012-07-04 09:41:57 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2012-07-04 09:41:57 +0000 |
commit | b414bddc98508b09d37ece8f4394194f3a0234b8 (patch) | |
tree | b023f775363e70a3b4f6c108bed25910948bb04a /Source/SPTableStructure.m | |
parent | 2a81ccd4c2047179d572019bb7c1158481c7810d (diff) | |
download | sequelpro-b414bddc98508b09d37ece8f4394194f3a0234b8.tar.gz sequelpro-b414bddc98508b09d37ece8f4394194f3a0234b8.tar.bz2 sequelpro-b414bddc98508b09d37ece8f4394194f3a0234b8.zip |
Move the table structure's loading logic into it's own category.
Diffstat (limited to 'Source/SPTableStructure.m')
-rw-r--r-- | Source/SPTableStructure.m | 308 |
1 files changed, 2 insertions, 306 deletions
diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index ba8c5eb9..671f7202 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -36,6 +36,8 @@ #import "SPIndexesController.h" #import "RegexKitLite.h" #import "SPTableFieldValidation.h" +#import "SPTableStructureLoading.h" + #import <SPMySQL/SPMySQL.h> @interface SPTableStructure (PrivateAPI) @@ -224,312 +226,6 @@ } #pragma mark - -#pragma mark Table loading - -/** - * Loads aTable, put it in an array, update the tableViewColumns and reload the tableView - */ -- (void)loadTable:(NSString *)aTable -{ - NSMutableDictionary *theTableEnumLists = [NSMutableDictionary dictionary]; - - // Check whether a save of the current row is required. - if (![[self onMainThread] saveRowOnDeselect]) return; - - // If no table is selected, reset the interface and return - if (!aTable || ![aTable length]) { - [[self onMainThread] setTableDetails:nil]; - return; - } - - NSMutableArray *theTableFields = [[NSMutableArray alloc] init]; - - // Make a mutable copy out of the cached [tableDataInstance columns] since we're adding infos - for (id col in [tableDataInstance columns]) - { - [theTableFields addObject:[[col mutableCopy] autorelease]]; - } - - // Retrieve the indexes for the table - SPMySQLResult *indexResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]]; - - // If an error occurred, reset the interface and abort - if ([mySQLConnection queryErrored]) { - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; - [[self onMainThread] setTableDetails:nil]; - - if ([mySQLConnection isConnected]) { - SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), - nil, nil, [NSApp mainWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"), - [mySQLConnection lastErrorMessage]]); - } - - return; - } - - // Process the indexes into a local array of dictionaries - NSArray *theTableIndexes = [self convertIndexResultToArray:indexResult]; - - // Set the Key column - for (NSDictionary* theIndex in theTableIndexes) - { - for (id field in theTableFields) - { - if ([[field objectForKey:@"name"] isEqualToString:[theIndex objectForKey:@"Column_name"]]) { - if ([[theIndex objectForKey:@"Key_name"] isEqualToString:@"PRIMARY"]) { - [field setObject:@"PRI" forKey:@"Key"]; - } - else { - if ([[field objectForKey:@"typegrouping"] isEqualToString:@"geometry"]) { - [field setObject:@"SPA" forKey:@"Key"]; - } - else { - [field setObject:(([[theIndex objectForKey:@"Non_unique"] isEqualToString:@"1"]) ? @"MUL" : @"UNI") forKey:@"Key"]; - } - } - - break; - } - } - } - - // Set up the encoding PopUpButtonCell - NSArray *encodings = [databaseDataInstance getDatabaseCharacterSetEncodings]; - - if ([encodings count]) { - - // Populate encoding popup button - NSMutableArray *encodingTitles = [[NSMutableArray alloc] initWithCapacity:[encodings count]+1]; - - [encodingTitles addObject:@""]; - - for (NSDictionary *encoding in encodings) - { - [encodingTitles addObject:(![encoding objectForKey:@"DESCRIPTION"]) ? [encoding objectForKey:@"CHARACTER_SET_NAME"] : [NSString stringWithFormat:@"%@ (%@)", [encoding objectForKey:@"DESCRIPTION"], [encoding objectForKey:@"CHARACTER_SET_NAME"]]]; - } - - [[encodingPopupCell onMainThread] removeAllItems]; - [[encodingPopupCell onMainThread] addItemsWithTitles:encodingTitles]; - [encodingTitles release]; - } - else { - [[encodingPopupCell onMainThread] removeAllItems]; - [[encodingPopupCell onMainThread] addItemWithTitle:NSLocalizedString(@"Not available", @"not available label")]; - } - - // Process all the fields to normalise keys and add additional information - for (id theField in theTableFields) - { - // Select and re-map encoding and collation since [self dataSource] stores the choice as NSNumbers - NSString *fieldEncoding = @""; - NSInteger selectedIndex = 0; - - NSString *type = [[[theField objectForKey:@"type"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - NSString *collation = nil; - NSString *encoding = nil; - - if ([fieldValidation isFieldTypeString:type] || ![type hasSuffix:@"BINARY"] || ![type hasSuffix:@"BLOB"]) { - - collation = [theField objectForKey:@"collation"] ? [theField objectForKey:@"collation"] : [[tableDataInstance statusValues] objectForKey:@"collation"]; - encoding = [theField objectForKey:@"encoding"] ? [theField objectForKey:@"encoding"] : [tableDataInstance tableEncoding]; - - // If we still don't have a collation then fallback on the database default (not available on MySQL < 4.1.1). - if (!collation) { - collation = [databaseDataInstance getDatabaseDefaultCollation]; - } - } - - if (encoding) { - for (id enc in encodings) - { - if ([[enc objectForKey:@"CHARACTER_SET_NAME"] isEqualToString:encoding]) { - fieldEncoding = encoding; - break; - } - - selectedIndex++; - } - - // Due to leading @"" in popup list - selectedIndex++; - } - - [theField setObject:[NSNumber numberWithInteger:selectedIndex] forKey:@"encoding"]; - - selectedIndex = 0; - - if (encoding && collation) { - - NSArray *theCollations = [databaseDataInstance getDatabaseCollationsForEncoding:fieldEncoding]; - - for (id col in theCollations) - { - if ([[col objectForKey:@"COLLATION_NAME"] isEqualToString:collation]) { - - // Set BINARY if collation ends with _bin for convenience - if ([[col objectForKey:@"COLLATION_NAME"] hasSuffix:@"_bin"]) { - [theField setObject:[NSNumber numberWithInt:1] forKey:@"binary"]; - } - - break; - } - - selectedIndex++; - } - - // Due to leading @"" in popup list - selectedIndex++; - } - - [theField setObject:[NSNumber numberWithInteger:selectedIndex] forKey:@"collation"]; - - // Get possible values if the field is an enum or a set - if (([type isEqualToString:@"ENUM"] || [type isEqualToString:@"SET"]) && [theField objectForKey:@"values"]) { - [theTableEnumLists setObject:[NSArray arrayWithArray:[theField objectForKey:@"values"]] forKey:[theField objectForKey:@"name"]]; - [theField setObject:[NSString stringWithFormat:@"'%@'", [[theField objectForKey:@"values"] componentsJoinedByString:@"','"]] forKey:@"length"]; - } - - // Join length and decimals if any - if ([theField objectForKey:@"decimals"]) - [theField setObject:[NSString stringWithFormat:@"%@,%@", [theField objectForKey:@"length"], [theField objectForKey:@"decimals"]] forKey:@"length"]; - - // Normalize default - if(![theField objectForKey:@"default"]) - [theField setObject:@"" forKey:@"default"]; - else if([[theField objectForKey:@"default"] isNSNull]) - [theField setObject:[prefs stringForKey:SPNullValue] forKey:@"default"]; - - // Init Extra field - [theField setObject:@"None" forKey:@"Extra"]; - - // Check for auto_increment and set Extra accordingly - if([[theField objectForKey:@"autoincrement"] integerValue]) - [theField setObject:@"auto_increment" forKey:@"Extra"]; - - // For timestamps check to see whether "on update CURRENT_TIMESTAMP" and set Extra accordingly - else if ([type isEqualToString:@"TIMESTAMP"] && [[theField objectForKey:@"onupdatetimestamp"] integerValue]) - [theField setObject:@"on update CURRENT_TIMESTAMP" forKey:@"Extra"]; - } - - // Set up the table details for the new table, and request an data/interface update - NSDictionary *tableDetails = [NSDictionary dictionaryWithObjectsAndKeys: - aTable, @"name", - theTableFields, @"tableFields", - theTableIndexes, @"tableIndexes", - theTableEnumLists, @"enumLists", - nil]; - - [[self onMainThread] setTableDetails:tableDetails]; - - isCurrentExtraAutoIncrement = [tableDataInstance tableHasAutoIncrementField]; - autoIncrementIndex = nil; - - // Send the query finished/work complete notification - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; - - [theTableFields release]; -} - -/** - * Reloads the table (performing a new mysql-query) - */ -- (IBAction)reloadTable:(id)sender -{ - - // Check whether a save of the current row is required - if ( ![[self onMainThread] saveRowOnDeselect] ) return; - - [tableDataInstance resetAllData]; - [tableDocumentInstance setStatusRequiresReload:YES]; - - // Query the structure of all databases in the background (mainly for completion) - [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; - - [self loadTable:selectedTable]; -} - -/** - * Update stored table details and update the interface to match the supplied - * table details. - * Should be called on the main thread. - */ -- (void) setTableDetails:(NSDictionary *)tableDetails -{ - NSString *newTableName = [tableDetails objectForKey:@"name"]; - NSMutableDictionary *newDefaultValues; - - BOOL enableInteraction = -#ifndef SP_REFACTOR /* patch */ - ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure] || -#endif - ![tableDocumentInstance isWorking]; - - // Update the selected table name - if (selectedTable) [selectedTable release], selectedTable = nil; - if (newTableName) selectedTable = [[NSString alloc] initWithString:newTableName]; - - [indexesController setTable:selectedTable]; - - // Reset the table store and display - [tableSourceView deselectAll:self]; - [tableFields removeAllObjects]; - [enumFields removeAllObjects]; - [indexesTableView deselectAll:self]; - [addFieldButton setEnabled:NO]; - [duplicateFieldButton setEnabled:NO]; - [removeFieldButton setEnabled:NO]; -#ifndef SP_REFACTOR - [addIndexButton setEnabled:NO]; - [removeIndexButton setEnabled:NO]; - [editTableButton setEnabled:NO]; -#endif - - // If no table is selected, refresh the table/index display to blank and return - if (!selectedTable) { - [tableSourceView reloadData]; - // Empty indexesController's fields and indices explicitly before reloading - [indexesController setFields:[NSArray array]]; - [indexesController setIndexes:[NSArray array]]; - [indexesTableView reloadData]; - return; - } - - // Update the fields and indexes stores - [tableFields setArray:[tableDetails objectForKey:@"tableFields"]]; - - [indexesController setFields:tableFields]; - [indexesController setIndexes:[tableDetails objectForKey:@"tableIndexes"]]; - - if (defaultValues) [defaultValues release], defaultValues = nil; - - newDefaultValues = [NSMutableDictionary dictionaryWithCapacity:[tableFields count]]; - - for (id theField in tableFields) - [newDefaultValues setObject:[theField objectForKey:@"default"] forKey:[theField objectForKey:@"name"]]; - - defaultValues = [[NSDictionary dictionaryWithDictionary:newDefaultValues] retain]; - -#ifndef SP_REFACTOR - // Enable the edit table button - [editTableButton setEnabled:enableInteraction]; -#endif - - // If a view is selected, disable the buttons; otherwise enable. - BOOL editingEnabled = ([tablesListInstance tableType] == SPTableTypeTable) && enableInteraction; - - [addFieldButton setEnabled:editingEnabled]; -#ifndef SP_REFACTOR - [addIndexButton setEnabled:editingEnabled]; -#endif - - // Reload the views - [indexesTableView reloadData]; - [tableSourceView reloadData]; -} - -#pragma mark - #pragma mark Edit methods /** |