diff options
author | rowanbeentje <rowan@beent.je> | 2013-05-06 19:48:58 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2013-05-06 19:48:58 +0000 |
commit | 5c126c28f177ebf961905f67a0535897e74d53ef (patch) | |
tree | 29243ec1967c45f69ab2c626c09e3f64c3edba80 | |
parent | 967454835a7fc99853bee5398ac20cff92be8845 (diff) | |
download | sequelpro-5c126c28f177ebf961905f67a0535897e74d53ef.tar.gz sequelpro-5c126c28f177ebf961905f67a0535897e74d53ef.tar.bz2 sequelpro-5c126c28f177ebf961905f67a0535897e74d53ef.zip |
Merge further revisions from trunk back to the 1.0.x release branch:
- r4090: Issue #1536: Add the option to force delete a table, which will disable then re-enable foreign checks. Also, provide a more helpful error message when a table cannot be deleted because of foreign key constraints
- r4091: Update localisation comment
- r4092: Include Spanish translators in Credits
- r4093: Fix truncation of table content BINARY values which are being edited in-place, addressing Issue #1702; Ensure that truncation of data values includes an ellipsis to make it clear when performance-based truncation is occurring
-rw-r--r-- | Resources/English.lproj/Credits.rtf | 62 | ||||
-rw-r--r-- | Source/SPDataAdditions.m | 2 | ||||
-rw-r--r-- | Source/SPTableContentDataSource.m | 8 | ||||
-rw-r--r-- | Source/SPTablesList.h | 6 | ||||
-rw-r--r-- | Source/SPTablesList.m | 169 |
5 files changed, 156 insertions, 91 deletions
diff --git a/Resources/English.lproj/Credits.rtf b/Resources/English.lproj/Credits.rtf index 532e2788..bca3b853 100644 --- a/Resources/English.lproj/Credits.rtf +++ b/Resources/English.lproj/Credits.rtf @@ -1,8 +1,9 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510 +{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360 {\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fnil\fcharset128 HiraKakuProN-W3;\f2\fmodern\fcharset0 Courier; } {\colortbl;\red255\green255\blue255;\red25\green25\blue25;\red0\green27\blue199;} -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\vieww16180\viewh13320\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \f0\b\fs30 \cf2 Current Developers \b0\fs22 \cf0 \ @@ -32,13 +33,14 @@ French\ \pard\pardeftab720\qc \b0 \cf0 Micha\'ebl Gallego\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sb80\sa80\pardirnatural\qc +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sb80\sa80\qc\pardirnatural \cf0 With Help From\ \pard\pardeftab720\qc \cf0 Dominique Guardiola\ Fr\'e9d\'e9ric Latour\ S\'e9bastien Guy\ -Lou Ferrand +Lou Ferrand\ +et al. \b \ \b0 \ @@ -54,7 +56,7 @@ Max Lohrmann\ \f1\b0 \cf0 \'8c\'b4 \'90\'bd \f0 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\sb40\sa120\pardirnatural\qc +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\sb40\sa120\qc\pardirnatural \cf0 With Help From\ \pard\pardeftab720\qc @@ -67,7 +69,7 @@ Max Lohrmann\ \pard\pardeftab720\qc \b0 \cf0 \uc0\u1040 \u1083 \u1077 \u1082 \u1089 \u1072 \u1085 \u1076 \u1088 \u1042 \u1072 \u1089 \u1080 \u1083 \u1100 \u1077 \u1074 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sb80\sa80\pardirnatural\qc +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sb80\sa80\qc\pardirnatural \cf0 With Help From\ \pard\pardeftab720\qc \cf0 \uc0\u1071 \u1088 \u1086 \u1089 \u1083 \u1072 \u1074 \u1050 \u1086 \u1085 \u1094 \u1077 \u1074 \u1086 \u1081 \ @@ -75,24 +77,38 @@ Max Lohrmann\ \ \pard\pardeftab720\qc +\b \cf0 Spanish\ +\pard\pardeftab720\qc + +\b0 \cf0 Juan Pablo Atienza Mart\'ednez\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\sb80\sa80\qc\pardirnatural +\cf0 With Help From\ +\pard\pardeftab720\qc +\cf0 Pablo Oneto\ +Jaime Martin\ +Samuel Abraham de Vega Garc\'eda\ +et al.\ +\ +\pard\pardeftab720\qc + \b \cf0 Swedish \b0 \ Peter H\'e4ggstrand\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b\fs30 \cf0 Past Developers \fs28 \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b0\fs22 \cf0 \ Lorenz Textor <lorenz@textor.ch>\ Jeff Skrysak\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b\fs30 \cf0 Additional Code\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b0\fs22 \cf0 \ Serge Cohen and\ @@ -127,14 +143,14 @@ Matt Gallagher\ ( \f2\fs24 NSFileManagerAddition \f0\fs22 )\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural {\field{\*\fldinst{HYPERLINK "http://www.linville.org/"}}{\fldrslt \cf0 Aaron Linville}}\ Tim Davis\ ( \f2\fs24 BGHUDButtonCell \f0\fs22 )\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 RegexKitLite \b0 \ @@ -142,10 +158,10 @@ Tim Davis\ \cf0 Copyright (c) 2008-2010\ \pard\pardeftab720\qc {\field{\*\fldinst{HYPERLINK "http://regexkit.sourceforge.net/RegexKitLite/"}}{\fldrslt \cf0 John Engelhart}}\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 All rights reserved.\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 AQDataExtension \b0 \ @@ -153,36 +169,36 @@ Tim Davis\ \cf0 Copyright (c) 2005\ \pard\pardeftab720\qc {\field{\*\fldinst{HYPERLINK "http://aquaticmac.com/cocoa.php"}}{\fldrslt \cf0 Lucas Newman}}\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 All rights reserved.\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 FeedbackReporter \b0 \ Copyright (c) 2009\ \pard\pardeftab720\qc {\field{\*\fldinst{HYPERLINK "http://vafer.org/"}}{\fldrslt \cf0 Torsten Curdt}}\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 All rights reserved.\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 ShortcutRecorderFramework \b0 \ Copyright (c) 2006-2010\ \pard\pardeftab720\qc {\field{\*\fldinst{HYPERLINK "http://code.google.com/p/shortcutrecorder/"}}{\fldrslt \cf0 Jesper, Dauer, Kirkpatrick}}\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 All rights reserved.\ \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b \cf0 Sparkle\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \b0 \cf0 Copyright \'a9 2006\ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt \cf0 Andy Matuschak}}\ All rights reserved.\ \ @@ -192,7 +208,7 @@ All rights reserved.\ \pard\pardeftab720\qc \b0\fs22 \cf0 \ -\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural \cf0 Icon by {\field{\*\fldinst{HYPERLINK "http://kenichiyoshida.jp/"}}{\fldrslt Kenichi Yoshida}}, with thanks to {\field{\*\fldinst{HYPERLINK "http://panic.com/"}}{\fldrslt Panic}}\ GUI design by {\field{\*\fldinst{HYPERLINK "http://www.sequelpro.com/"}}{\fldrslt Sequel Pro}} team.\ }
\ No newline at end of file diff --git a/Source/SPDataAdditions.m b/Source/SPDataAdditions.m index ab0bfb01..351ef4d8 100644 --- a/Source/SPDataAdditions.m +++ b/Source/SPDataAdditions.m @@ -304,7 +304,7 @@ string = @"-- cannot display --"; } else if ([string length] > 255) { - string = [string substringToIndex:255]; + string = [[string substringToIndex:254] stringByAppendingString:@"…"]; } return string; diff --git a/Source/SPTableContentDataSource.m b/Source/SPTableContentDataSource.m index 21743464..321469e5 100644 --- a/Source/SPTableContentDataSource.m +++ b/Source/SPTableContentDataSource.m @@ -108,8 +108,12 @@ if ([value isNSNull]) return [prefs objectForKey:SPNullValue]; - if ([value isKindOfClass:[NSData class]]) - return [value shortStringRepresentationUsingEncoding:[mySQLConnection stringEncoding]]; + if ([value isKindOfClass:[NSData class]]) { + if ([tableContentView shouldUseFieldEditorForRow:rowIndex column:columnIndex]) { + return [value shortStringRepresentationUsingEncoding:[mySQLConnection stringEncoding]]; + } + return [value stringRepresentationUsingEncoding:[mySQLConnection stringEncoding]]; + } if ([value isSPNotLoaded]) return NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields"); diff --git a/Source/SPTablesList.h b/Source/SPTablesList.h index 8d267c71..07c0cf0c 100644 --- a/Source/SPTablesList.h +++ b/Source/SPTablesList.h @@ -197,9 +197,9 @@ - (IBAction) updateFilter:(id)sender; // Task interaction -- (void) startDocumentTaskForTab:(NSNotification *)aNotification; -- (void) endDocumentTaskForTab:(NSNotification *)aNotification; -- (void) setTableListSelectability:(BOOL)isSelectable; +- (void)startDocumentTaskForTab:(NSNotification *)aNotification; +- (void)endDocumentTaskForTab:(NSNotification *)aNotification; +- (void)setTableListSelectability:(BOOL)isSelectable; - (BOOL)isTableNameValid:(NSString *)tableName forType:(SPTableType)tableType; - (BOOL)isTableNameValid:(NSString *)tableName forType:(SPTableType)tableType ignoringSelectedTable:(BOOL)ignoreSelectedTable; diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index 93ebfe91..7887b167 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -79,7 +79,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; @interface SPTablesList () #ifndef SP_REFACTOR -- (void)_removeTable; +- (void)_removeTable:(NSNumber *)force; - (void)_truncateTable; #endif - (void)_addTable; @@ -439,8 +439,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; */ - (IBAction)removeTable:(id)sender { - if (![tablesListView numberOfSelectedRows]) - return; + if (![tablesListView numberOfSelectedRows]) return; [[tableDocumentInstance parentWindow] endEditingFor:nil]; @@ -466,56 +465,76 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; NSUInteger currentIndex = [indexes lastIndex]; if ([tablesListView numberOfSelectedRows] == 1) { - if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeView) + if ([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeView) { tblTypes = NSLocalizedString(@"view", @"view"); - else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeTable) + } + else if ([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeTable) { tblTypes = NSLocalizedString(@"table", @"table"); - else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeProc) + } + else if ([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeProc) { tblTypes = NSLocalizedString(@"procedure", @"procedure"); - else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeFunc) + } + else if ([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeFunc) { tblTypes = NSLocalizedString(@"function", @"function"); + } [alert setMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete %@ '%@'?", @"delete table/view message"), tblTypes, [filteredTables objectAtIndex:[tablesListView selectedRow]]]]; [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete the %@ '%@'? This operation cannot be undone.", @"delete table/view informative message"), tblTypes, [filteredTables objectAtIndex:[tablesListView selectedRow]]]]; } else { - BOOL areTableTypeEqual = YES; NSInteger lastType = [[filteredTableTypes objectAtIndex:currentIndex] integerValue]; + while (currentIndex != NSNotFound) { - if([[filteredTableTypes objectAtIndex:currentIndex] integerValue]!=lastType) - { + if ([[filteredTableTypes objectAtIndex:currentIndex] integerValue] != lastType) { areTableTypeEqual = NO; break; } + currentIndex = [indexes indexLessThanIndex:currentIndex]; } - if(areTableTypeEqual) + + if (areTableTypeEqual) { - switch(lastType) { + switch (lastType) { case SPTableTypeTable: - tblTypes = NSLocalizedString(@"tables", @"tables"); - break; + tblTypes = NSLocalizedString(@"tables", @"tables"); + break; case SPTableTypeView: - tblTypes = NSLocalizedString(@"views", @"views"); - break; + tblTypes = NSLocalizedString(@"views", @"views"); + break; case SPTableTypeProc: - tblTypes = NSLocalizedString(@"procedures", @"procedures"); - break; + tblTypes = NSLocalizedString(@"procedures", @"procedures"); + break; case SPTableTypeFunc: - tblTypes = NSLocalizedString(@"functions", @"functions"); - break; + tblTypes = NSLocalizedString(@"functions", @"functions"); + break; } - } else + } + else { tblTypes = NSLocalizedString(@"items", @"items"); + } [alert setMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete selected %@?", @"delete tables/views message"), tblTypes]]; [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete the selected %@? This operation cannot be undone.", @"delete tables/views informative message"), tblTypes]]; } + + NSButton *button = [alert suppressionButton]; + + [button setTitle:NSLocalizedString(@"Force delete (disables integrity checks)", @"force table deletion button text")]; + [button setToolTip:NSLocalizedString(@"Disables foreign key checks (FOREIGN_KEY_CHECKS) before deletion and re-enables them afterwards.", @"force table deltion button text tooltip")]; + [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + + [[button cell] setControlSize:NSSmallControlSize]; + + [alert setShowsSuppressionButton:YES]; - [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:SPRemoveTable]; + [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:SPRemoveTable]; } #ifndef SP_REFACTOR /* whole table operations */ @@ -554,8 +573,6 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } [copyTableMessageField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Duplicate %@ '%@' to:", @"duplicate object message"), tableType, [self tableName]]]; - - //open copyTableSheet [copyTableNameField setStringValue:[NSString stringWithFormat:@"%@_copy", [filteredTables objectAtIndex:[tablesListView selectedRow]]]]; [copyTableContentSwitch setState:NSOffState]; @@ -679,7 +696,9 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } else if ([contextInfo isEqualToString:SPRemoveTable]) { if (returnCode == NSAlertDefaultReturn) { - [self performSelector:@selector(_removeTable) withObject:nil afterDelay:0.0]; + [self performSelector:@selector(_removeTable:) + withObject:[NSNumber numberWithInteger:[[(NSAlert *)sheet suppressionButton] state]] + afterDelay:0.0]; } } #ifndef SP_REFACTOR @@ -2045,90 +2064,113 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; /** * Removes the selected object (table, view, procedure, function, etc.) from the database and tableView. */ -- (void)_removeTable +- (void)_removeTable:(NSNumber *)force { NSIndexSet *indexes = [tablesListView selectedRowIndexes]; + [tablesListView selectRowIndexes:[NSIndexSet indexSet] byExtendingSelection:NO]; - // get last index + // Get last index NSUInteger currentIndex = [indexes lastIndex]; + + if ([force boolValue]) { + [mySQLConnection queryString:@"SET FOREIGN_KEY_CHECKS = 0"]; + } while (currentIndex != NSNotFound) { - if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeView) { - [mySQLConnection queryString: [NSString stringWithFormat: @"DROP VIEW %@", - [[filteredTables objectAtIndex:currentIndex] backtickQuotedString] - ]]; - } else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeTable) { - [mySQLConnection queryString: [NSString stringWithFormat: @"DROP TABLE %@", - [[filteredTables objectAtIndex:currentIndex] backtickQuotedString] - ]]; - } else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeProc) { - [mySQLConnection queryString: [NSString stringWithFormat: @"DROP PROCEDURE %@", - [[filteredTables objectAtIndex:currentIndex] backtickQuotedString] - ]]; - } else if([[filteredTableTypes objectAtIndex:currentIndex] integerValue] == SPTableTypeFunc) { - [mySQLConnection queryString: [NSString stringWithFormat: @"DROP FUNCTION %@", - [[filteredTables objectAtIndex:currentIndex] backtickQuotedString] - ]]; + NSString *objectIdentifier = @""; + NSString *databaseObject = [[filteredTables objectAtIndex:currentIndex] backtickQuotedString]; + NSInteger objectType = [[filteredTableTypes objectAtIndex:currentIndex] integerValue]; + + if (objectType == SPTableTypeView) { + objectIdentifier = @"VIEW"; + } + else if (objectType == SPTableTypeTable) { + objectIdentifier = @"TABLE"; } + else if (objectType == SPTableTypeProc) { + objectIdentifier = @"PROCEDURE"; + } + else if (objectType == SPTableTypeFunc) { + objectIdentifier = @"FUNCTION"; + } + + [mySQLConnection queryString:[NSString stringWithFormat:@"DROP %@ %@", objectIdentifier, databaseObject]]; // If no error is recorded, the table was successfully dropped - remove it from the list if (![mySQLConnection queryErrored]) { - //dropped table with success + + // Dropped table with success if (isTableListFiltered) { NSInteger unfilteredIndex = [tables indexOfObject:[filteredTables objectAtIndex:currentIndex]]; + [tables removeObjectAtIndex:unfilteredIndex]; [tableTypes removeObjectAtIndex:unfilteredIndex]; } + [filteredTables removeObjectAtIndex:currentIndex]; [filteredTableTypes removeObjectAtIndex:currentIndex]; // Get next index (beginning from the end) currentIndex = [indexes indexLessThanIndex:currentIndex]; - + } // Otherwise, display an alert - and if there's tables left, ask whether to proceed - } else { - + else { NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + if ([indexes indexLessThanIndex:currentIndex] == NSNotFound) { [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")]; - } else { + } + else { [alert addButtonWithTitle:NSLocalizedString(@"Continue", @"continue button")]; [alert addButtonWithTitle:NSLocalizedString(@"Stop", @"stop button")]; } + + NSString *databaseError = [mySQLConnection lastErrorMessage]; + NSString *userMessage = NSLocalizedString(@"Couldn't delete '%@'.\n\nMySQL said: %@", @"message of panel when an item cannot be deleted"); + + // Try to provide a more helpful message + if ([databaseError rangeOfString:@"a foreign key constraint fails" options:NSCaseInsensitiveSearch].location != NSNotFound) { + userMessage = NSLocalizedString(@"Couldn't delete '%@'.\n\nSelecting the 'Force delete' option may prevent this issue, but may leave the database in an inconsistent state.\n\nMySQL said: %@", + @"message of panel when an item cannot be deleted including informative message about using force deletion"); + } + [alert setMessageText:NSLocalizedString(@"Error", @"error")]; - [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete '%@'.\n\nMySQL said: %@", @"message of panel when an item cannot be deleted"), [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]]; + [alert setInformativeText:[NSString stringWithFormat:userMessage, [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]]; [alert setAlertStyle:NSWarningAlertStyle]; + if ([indexes indexLessThanIndex:currentIndex] == NSNotFound) { [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:nil contextInfo:nil]; + currentIndex = NSNotFound; - } else { + } + else { NSInteger choice = [alert runModal]; - if (choice == NSAlertFirstButtonReturn) { - currentIndex = [indexes indexLessThanIndex:currentIndex]; - } else { - currentIndex = NSNotFound; - } + + currentIndex = choice == NSAlertFirstButtonReturn ? [indexes indexLessThanIndex:currentIndex] : NSNotFound; } } } + + if ([force boolValue]) { + [mySQLConnection queryString:@"SET FOREIGN_KEY_CHECKS = 1"]; + } - // Remove the isolated "current selection" item for filtered lists if appropriate - if (isTableListFiltered && [filteredTables count] > 1 - && [[filteredTableTypes objectAtIndex:[filteredTableTypes count]-1] integerValue] == SPTableTypeNone - && [[filteredTables objectAtIndex:[filteredTables count]-1] isEqualToString:NSLocalizedString(@"CURRENT SELECTION",@"header for current selection in filtered list")]) + // Remove the isolated 'current selection' item for filtered lists if appropriate + if (isTableListFiltered && + [filteredTables count] > 1 && + [[filteredTableTypes objectAtIndex:[filteredTableTypes count] - 1] integerValue] == SPTableTypeNone && + [[filteredTables objectAtIndex:[filteredTables count] - 1] isEqualToString:NSLocalizedString(@"CURRENT SELECTION",@"header for current selection in filtered list")]) { [filteredTables removeLastObject]; [filteredTableTypes removeLastObject]; } [tablesListView reloadData]; - [tablesListView deselectAll:self]; #ifndef SP_REFACTOR - // set window title [tableDocumentInstance updateWindowTitle:self]; #endif #ifdef SP_REFACTOR @@ -2136,7 +2178,10 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; #endif // Query the structure of all databases in the background (mainly for completion) - [NSThread detachNewThreadWithName:@"SPNavigatorController database structure querier" target:[tableDocumentInstance databaseStructureRetrieval] selector:@selector(queryDbStructureWithUserInfo:) object:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; + [NSThread detachNewThreadWithName:@"SPNavigatorController database structure querier" + target:[tableDocumentInstance databaseStructureRetrieval] + selector:@selector(queryDbStructureWithUserInfo:) + object:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; } #ifndef SP_REFACTOR /* operations performed on whole tables */ |