aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2013-05-06 19:48:58 +0000
committerrowanbeentje <rowan@beent.je>2013-05-06 19:48:58 +0000
commit5c126c28f177ebf961905f67a0535897e74d53ef (patch)
tree29243ec1967c45f69ab2c626c09e3f64c3edba80
parent967454835a7fc99853bee5398ac20cff92be8845 (diff)
downloadsequelpro-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.rtf62
-rw-r--r--Source/SPDataAdditions.m2
-rw-r--r--Source/SPTableContentDataSource.m8
-rw-r--r--Source/SPTablesList.h6
-rw-r--r--Source/SPTablesList.m169
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 */