diff options
Diffstat (limited to 'Source/SPExtendedTableInfo.m')
-rw-r--r-- | Source/SPExtendedTableInfo.m | 201 |
1 files changed, 133 insertions, 68 deletions
diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m index a1e59110..9baaecab 100644 --- a/Source/SPExtendedTableInfo.m +++ b/Source/SPExtendedTableInfo.m @@ -33,9 +33,14 @@ #import "SPAlertSheets.h" #import "SPTableStructure.h" #import "SPServerSupport.h" +#import "SPMySQL.h" -@interface SPExtendedTableInfo (PrivateAPI) +static NSString *SPUpdateTableTypeCurrentType = @"SPUpdateTableTypeCurrentType"; +static NSString *SPUpdateTableTypeNewType = @"SPUpdateTableTypeNewType"; +@interface SPExtendedTableInfo () + +- (void)_changeCurrentTableTypeFrom:(NSString *)currentType to:(NSString *)newType; - (NSString *)_formatValueWithKey:(NSString *)key inDictionary:(NSDictionary *)statusDict; @end @@ -49,17 +54,6 @@ */ - (void)awakeFromNib { - [tableCreateSyntaxTextView setAllowsDocumentBackgroundColorChange:YES]; - - NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; - - [bindingOptions setObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"]; - - [tableCreateSyntaxTextView bind:@"backgroundColor" - toObject:[NSUserDefaultsController sharedUserDefaultsController] - withKeyPath:@"values.CustomQueryEditorBackgroundColor" - options:bindingOptions]; - // Add observers for document task activity [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startDocumentTaskForTab:) @@ -95,24 +89,32 @@ NSString *currentType = [tableDataInstance statusValueForKey:@"Engine"]; // Check if the user selected the same type - if ([currentType isEqualToString:newType]) { - return; - } - - // Alter table's storage type - [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ %@ = %@", [selectedTable backtickQuotedString], [[tableDocumentInstance serverSupport] engineTypeQueryName], newType]]; - - if ([connection getLastErrorID] == 0) { - // Reload the table's data - [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]]; - } - else { - [sender selectItemWithTitle:currentType]; - - SPBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"), - NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table type to '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), newType, [connection getLastErrorMessage]]); - } + if ([currentType isEqualToString:newType]) return; + + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Change table type", @"change table type message") + defaultButton:NSLocalizedString(@"Change", @"change button") + alternateButton:NSLocalizedString(@"Cancel", @"cancel button") + otherButton:nil + informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to change this table's type to %@?\n\nPlease be aware that changing a table's type has the potential to cause the loss of some or all of it's data. This action cannot be undone.", @"change table type informative message"), newType]; + + [alert setAlertStyle:NSCriticalAlertStyle]; + + NSArray *buttons = [alert buttons]; + + // Change the alert's cancel button to have the key equivalent of return + [[buttons objectAtIndex:0] setKeyEquivalent:@"d"]; + [[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask]; + [[buttons objectAtIndex:1] setKeyEquivalent:@"\r"]; + + NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] initWithCapacity:2]; + + [dataDict setObject:currentType forKey:SPUpdateTableTypeCurrentType]; + [dataDict setObject:newType forKey:SPUpdateTableTypeNewType]; + + [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] + modalDelegate:self + didEndSelector:@selector(confirmChangeTableTypeDidEnd:returnCode:contextInfo:) + contextInfo:dataDict]; } /** @@ -129,7 +131,7 @@ // Alter table's character set encoding [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ CHARACTER SET = %@", [selectedTable backtickQuotedString], newEncoding]]; - if ([connection getLastErrorID] == 0) { + if (![connection queryErrored]) { // Reload the table's data [self reloadTable:self]; } @@ -138,7 +140,7 @@ SPBeginAlertSheet(NSLocalizedString(@"Error changing table encoding", @"error changing table encoding message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table encoding to '%@'.\n\nMySQL said: %@", @"error changing table encoding informative message"), newEncoding, [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table encoding to '%@'.\n\nMySQL said: %@", @"error changing table encoding informative message"), newEncoding, [connection lastErrorMessage]]); } } @@ -156,7 +158,7 @@ // Alter table's character set collation [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COLLATE = %@", [selectedTable backtickQuotedString], newCollation]]; - if ([connection getLastErrorID] == 0) { + if (![connection queryErrored]) { // Reload the table's data [self reloadTable:self]; } @@ -165,7 +167,7 @@ SPBeginAlertSheet(NSLocalizedString(@"Error changing table collation", @"error changing table collation message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table collation to '%@'.\n\nMySQL said: %@", @"error changing table collation informative message"), newCollation, [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table collation to '%@'.\n\nMySQL said: %@", @"error changing table collation informative message"), newCollation, [connection lastErrorMessage]]); } } @@ -245,7 +247,8 @@ [tableCreateSyntaxTextView didChangeText]; [tableCreateSyntaxTextView setEditable:NO]; } - } else { + } + else { [tableCreateSyntaxTextView setEditable:YES]; [tableCreateSyntaxTextView shouldChangeTextInRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length]) replacementString:@""]; [tableCreateSyntaxTextView setString:@""]; @@ -278,6 +281,7 @@ [tableEncodingPopUpButton addItemWithTitle:[statusFields objectForKey:@"CharacterSetClient"]]; [tableCollationPopUpButton addItemWithTitle:[statusFields objectForKey:@"Collation"]]; } + return; } @@ -353,7 +357,9 @@ // Set comments NSString *commentText = [statusFields objectForKey:@"Comment"]; + if (!commentText) commentText = @""; + [tableCommentsTextView setEditable:YES]; [tableCommentsTextView shouldChangeTextInRange:NSMakeRange(0, [[tableCommentsTextView string] length]) replacementString:commentText]; [tableCommentsTextView setString:commentText]; @@ -366,14 +372,16 @@ [tableCreateSyntaxTextView setString:@""]; [tableCreateSyntaxTextView didChangeText]; [tableCreateSyntaxTextView shouldChangeTextInRange:NSMakeRange(0, 0) replacementString:[tableDataInstance tableCreateSyntax]]; + if ([tableDataInstance tableCreateSyntax]) { [tableCreateSyntaxTextView insertText:[[tableDataInstance tableCreateSyntax] stringByAppendingString:@";"]]; } + [tableCreateSyntaxTextView didChangeText]; [tableCreateSyntaxTextView setEditable:NO]; // Validate Reset AUTO_INCREMENT button - if ([statusFields objectForKey:@"Auto_increment"] && ![[statusFields objectForKey:@"Auto_increment"] isKindOfClass:[NSNull class]]) { + if ([statusFields objectForKey:@"Auto_increment"] && ![[statusFields objectForKey:@"Auto_increment"] isNSNull]) { [resetAutoIncrementResetButton setHidden:NO]; } } @@ -389,35 +397,59 @@ NSMutableDictionary *tableInfo = [NSMutableDictionary dictionary]; NSDictionary *statusFields = [tableDataInstance statusValues]; - if([tableTypePopUpButton titleOfSelectedItem]) + if ([tableTypePopUpButton titleOfSelectedItem]) { [tableInfo setObject:[tableTypePopUpButton titleOfSelectedItem] forKey:@"type"]; - if([tableEncodingPopUpButton titleOfSelectedItem]) + } + + if ([tableEncodingPopUpButton titleOfSelectedItem]) { [tableInfo setObject:[tableEncodingPopUpButton titleOfSelectedItem] forKey:@"encoding"]; - if([tableCollationPopUpButton titleOfSelectedItem]) + } + + if ([tableCollationPopUpButton titleOfSelectedItem]) { [tableInfo setObject:[tableCollationPopUpButton titleOfSelectedItem] forKey:@"collation"]; + } - if([self _formatValueWithKey:@"Create_time" inDictionary:statusFields]) + if ([self _formatValueWithKey:@"Create_time" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Create_time" inDictionary:statusFields] forKey:@"createdAt"]; - if([self _formatValueWithKey:@"Update_time" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Update_time" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Update_time" inDictionary:statusFields] forKey:@"updatedAt"]; - if([self _formatValueWithKey:@"Rows" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Rows" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Rows" inDictionary:statusFields] forKey:@"rowNumber"]; - if([self _formatValueWithKey:@"Row_format" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Row_format" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Row_format" inDictionary:statusFields] forKey:@"rowFormat"]; - if([self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields] forKey:@"rowAvgLength"]; - if([self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields] forKey:@"rowAutoIncrement"]; - if([self _formatValueWithKey:@"Data_length" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Data_length" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Data_length" inDictionary:statusFields] forKey:@"dataSize"]; - if([self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields] forKey:@"maxDataSize"]; - if([self _formatValueWithKey:@"Index_length" inDictionary:statusFields]) + } + + if ([self _formatValueWithKey:@"Index_length" inDictionary:statusFields]) { [tableInfo setObject:[self _formatValueWithKey:@"Index_length" inDictionary:statusFields] forKey:@"indexSize"]; + } + [tableInfo setObject:[self _formatValueWithKey:@"Data_free" inDictionary:statusFields] forKey:@"sizeFree"]; - if([tableCommentsTextView string]) + if ([tableCommentsTextView string]) { [tableInfo setObject:[tableCommentsTextView string] forKey:@"comments"]; + } NSError *error = nil; NSArray *HTMLExcludes = [NSArray arrayWithObjects:@"doctype", @"html", @"head", @"body", @"xml", nil]; @@ -428,12 +460,12 @@ // Set tableCreateSyntaxTextView's font size temporarily to 10pt for printing NSFont *oldFont = [tableCreateSyntaxTextView font]; BOOL editableStatus = [tableCreateSyntaxTextView isEditable]; + [tableCreateSyntaxTextView setEditable:YES]; - [tableCreateSyntaxTextView setFont:[NSFont fontWithName:[oldFont fontName] size:10.0]]; + [tableCreateSyntaxTextView setFont:[NSFont fontWithName:[oldFont fontName] size:10.0f]]; // Convert tableCreateSyntaxTextView to HTML - NSData *HTMLData = [[tableCreateSyntaxTextView textStorage] dataFromRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length]) - documentAttributes:attributes error:&error]; + NSData *HTMLData = [[tableCreateSyntaxTextView textStorage] dataFromRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length]) documentAttributes:attributes error:&error]; // Restore original font settings [tableCreateSyntaxTextView setFont:oldFont]; @@ -468,21 +500,37 @@ if (![currentComment isEqualToString:newComment]) { // Alter table's comment - [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COMMENT = '%@'", [selectedTable backtickQuotedString], [connection prepareString:newComment]]]; + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COMMENT = %@", [selectedTable backtickQuotedString], [connection escapeAndQuoteString:newComment]]]; - if ([connection getLastErrorID] == 0) { + if (![connection queryErrored]) { // Reload the table's data [self reloadTable:self]; } else { SPBeginAlertSheet(NSLocalizedString(@"Error changing table comment", @"error changing table comment message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table's comment to '%@'.\n\nMySQL said: %@", @"error changing table comment informative message"), newComment, [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table's comment to '%@'.\n\nMySQL said: %@", @"error changing table comment informative message"), newComment, [connection lastErrorMessage]]); } } } } +/** + * Called when the user dismisses the change table type confirmation dialog. + */ +- (void)confirmChangeTableTypeDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSDictionary *)contextInfo +{ + if (returnCode == NSAlertDefaultReturn) { + [self _changeCurrentTableTypeFrom:[contextInfo objectForKey:SPUpdateTableTypeCurrentType] + to:[contextInfo objectForKey:SPUpdateTableTypeNewType]]; + } + else { + [tableTypePopUpButton selectItemWithTitle:[contextInfo objectForKey:SPUpdateTableTypeCurrentType]]; + } + + [contextInfo release]; +} + #pragma mark - #pragma mark Task interaction @@ -514,8 +562,10 @@ // If we are viewing tables in the information_schema database, then disable all controls that cause table // changes as these tables are not modifiable by anyone. - //also affects mysql and performance_schema - BOOL isSystemSchemaDb = ([[tableDocumentInstance database] isEqualToString:@"information_schema"] || [[tableDocumentInstance database] isEqualToString:@"performance_schema"] || [[tableDocumentInstance database] isEqualToString:@"mysql"]); + // also affects mysql and performance_schema + BOOL isSystemSchemaDb = ([[tableDocumentInstance database] isEqualToString:SPMySQLInformationSchemaDatabase] || + [[tableDocumentInstance database] isEqualToString:SPMySQLPerformanceSchemaDatabase] || + [[tableDocumentInstance database] isEqualToString:SPMySQLDatabase]); if ([[databaseDataInstance getDatabaseStorageEngines] count] && [statusFields objectForKey:@"Engine"]) { [tableTypePopUpButton setEnabled:(!isSystemSchemaDb)]; @@ -525,8 +575,7 @@ [tableEncodingPopUpButton setEnabled:(!isSystemSchemaDb)]; } - if ([[databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]] count] - && [statusFields objectForKey:@"Collation"]) + if ([[databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]] count] && [statusFields objectForKey:@"Collation"]) { [tableCollationPopUpButton setEnabled:(!isSystemSchemaDb)]; } @@ -548,9 +597,30 @@ [super dealloc]; } -@end +#pragma mark - +#pragma mark Private API -@implementation SPExtendedTableInfo (PrivateAPI) +/** + * Changes the current table's storage engine to the supplied type. + */ +- (void)_changeCurrentTableTypeFrom:(NSString *)currentType to:(NSString *)newType +{ + // Alter table's storage type + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ %@ = %@", [selectedTable backtickQuotedString], [[tableDocumentInstance serverSupport] engineTypeQueryName], newType]]; + + if ([connection queryErrored]) { + + // Reload the table's data + [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]]; + } + else { + [tableTypePopUpButton selectItemWithTitle:currentType]; + + SPBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table type to '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), newType, [connection lastErrorMessage]]); + } +} /** * Format and returns the value within the info dictionary with the associated key. @@ -559,7 +629,7 @@ { NSString *value = [infoDict objectForKey:key]; - if ([value isKindOfClass:[NSNull class]]) { + if ([value isNSNull]) { value = @""; } else { @@ -603,12 +673,7 @@ } } - if ([key isEqualToString:@"Auto_increment"]) { - return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label"); - } - else { - return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label"); - } + return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label"); } @end |