aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m21
-rw-r--r--Interfaces/English.lproj/ConnectionView.xib13
-rw-r--r--Source/SPConnectionController.m44
-rw-r--r--Source/SPSSHTunnel.m2
-rw-r--r--Source/SPTableData.m7
5 files changed, 60 insertions, 27 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
index 06a8a757..fd2d6444 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
@@ -192,8 +192,7 @@ static BOOL sTruncateLongFieldInLogs = YES;
{
delegate = connectionDelegate;
- // Check that the delegate implements willQueryString:connection: and cache the result as its used
- // vert frequently.
+ // Check that the delegate implements willQueryString:connection: and cache the result as its used very frequently.
delegateResponseToWillQueryString = [delegate respondsToSelector:@selector(willQueryString:connection:)];
}
@@ -273,11 +272,11 @@ static BOOL sTruncateLongFieldInLogs = YES;
*/
- (BOOL)connect
{
- const char *theLogin = [self cStringFromString:connectionLogin];
- const char *theHost;
- const char *thePass;
- const char *theSocket;
- void *theRet;
+ const char *theLogin = [self cStringFromString:connectionLogin];
+ const char *theHost;
+ const char *thePass;
+ const char *theSocket;
+ void *theRet;
// Disconnect if a connection is already active
if (mConnected) {
@@ -301,8 +300,6 @@ static BOOL sTruncateLongFieldInLogs = YES;
// Set the host as appropriate
if (!connectionHost || ![connectionHost length]) {
theHost = NULL;
-
-
} else {
theHost = [self cStringFromString:connectionHost];
}
@@ -559,7 +556,7 @@ static BOOL sTruncateLongFieldInLogs = YES;
* ping, but cause long queries to be terminated.
* Unlike mysql_ping, this function returns FALSE on failure and TRUE on success.
*/
-- (BOOL) pingConnection
+- (BOOL)pingConnection
{
struct sigaction timeoutAction;
NSDate *startDate = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
@@ -1531,7 +1528,7 @@ static void forcePingTimeout(NSInteger signalNumber)
const char *theCDBsName = (const char *)[self cStringFromString:dbsName];
if (theResPtr = mysql_list_dbs(mConnection, theCDBsName)) {
- [theResult initWithResPtr: theResPtr encoding: mEncoding timeZone:mTimeZone];
+ [theResult initWithResPtr:theResPtr encoding:mEncoding timeZone:mTimeZone];
}
else {
[theResult init];
@@ -1593,11 +1590,13 @@ static void forcePingTimeout(NSInteger signalNumber)
[theResult init];
}
}
+
[queryLock unlock];
if (theResult) {
[theResult autorelease];
}
+
return theResult;
}
diff --git a/Interfaces/English.lproj/ConnectionView.xib b/Interfaces/English.lproj/ConnectionView.xib
index 2eb2d7a1..c47e0ab7 100644
--- a/Interfaces/English.lproj/ConnectionView.xib
+++ b/Interfaces/English.lproj/ConnectionView.xib
@@ -2,9 +2,9 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">1050</int>
- <string key="IBDocument.SystemVersion">9J61</string>
+ <string key="IBDocument.SystemVersion">9L30</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
- <string key="IBDocument.AppKitVersion">949.46</string>
+ <string key="IBDocument.AppKitVersion">949.54</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -3673,7 +3673,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
- <string>{{61, 193}, {882, 563}}</string>
+ <string>{{280, 258}, {882, 563}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
@@ -4069,6 +4069,13 @@
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Source/SPQueryFavoriteManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">toggleCollapse:</string>
<string key="NS.object.0">id</string>
diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m
index 34446959..5d93a4f4 100644
--- a/Source/SPConnectionController.m
+++ b/Source/SPConnectionController.m
@@ -27,6 +27,7 @@
#import "SPAppController.h"
#import "SPPreferenceController.h"
#import "ImageAndTextCell.h"
+#import "RegexKitLite.h"
@implementation SPConnectionController
@@ -145,7 +146,6 @@
*/
- (IBAction)initiateConnection:(id)sender
{
-
// Ensure that host is not empty if this is a TCP/IP or SSH connection
if (([self type] == SP_CONNECTION_TCPIP || [self type] == SP_CONNECTION_SSHTUNNEL) && ![[self host] length]) {
NSRunAlertPanel(NSLocalizedString(@"Insufficient connection details", @"insufficient details message"), NSLocalizedString(@"Insufficient details provided to establish a connection. Please provide at least a host.", @"insufficient details informative message"), NSLocalizedString(@"OK", @"OK button"), nil, nil);
@@ -260,6 +260,7 @@
[progressIndicatorText setStringValue:NSLocalizedString(@"MySQL connecting...", @"MySQL connecting very short status message")];
else
[progressIndicatorText setStringValue:NSLocalizedString(@"Connecting...", @"Generic connecting very short status message")];
+
[progressIndicatorText display];
// Initialise to socket if appropriate.
@@ -366,6 +367,8 @@
*/
- (void)failConnectionWithTitle:(NSString *)theTitle errorMessage:(NSString *)theErrorMessage detail:(NSString *)errorDetail
{
+ BOOL isSSHTunnelBindError = NO;
+
// Clean up the interface
[progressIndicator stopAnimation:self];
[progressIndicator display];
@@ -376,23 +379,29 @@
[tableDocument clearStatusIcon];
// Release as appropriate
- if (sshTunnel) [sshTunnel disconnect], [sshTunnel release], sshTunnel = nil;
+ if (sshTunnel) {
+ [sshTunnel disconnect], [sshTunnel release], sshTunnel = nil;
+
+ // If the SSH tunnel connection failed because the port it was trying to bind to was already in use take note
+ // of it so we can give the user the option of connecting via standard connection and use the existing tunnel.
+ if ([theErrorMessage rangeOfString:@"bind"].location != NSNotFound) {
+ isSSHTunnelBindError = YES;
+ }
+ }
if (errorDetail) [errorDetailText setString:errorDetail];
// Display the connection error message
- NSBeginAlertSheet(theTitle, NSLocalizedString(@"OK", @"OK button"), errorDetail?NSLocalizedString(@"Show detail", @"Show detail button"):nil, nil, documentWindow, self, nil, @selector(errorSheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage);
+ NSBeginAlertSheet(theTitle, NSLocalizedString(@"OK", @"OK button"), (errorDetail) ? NSLocalizedString(@"Show Detail", @"Show detail button") : nil, (isSSHTunnelBindError) ? NSLocalizedString(@"Use Standard Connection", @"use standard connection button") : nil, documentWindow, self, nil, @selector(errorSheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage);
}
-
/**
* Alert sheet callback method - invoked when an error sheet is closed.
*/
- (void)errorSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo
{
[sheet orderOut:self];
- if (returnCode == NSAlertAlternateReturn) [errorDetailWindow makeKeyAndOrderFront:self];
-
+
// Restore the passwords from keychain for editing if appropriate
if (connectionKeychainItemName) {
[self setPassword:[keychain getPasswordForName:connectionKeychainItemName account:connectionKeychainItemAccount]];
@@ -400,6 +409,29 @@
if (connectionSSHKeychainItemName) {
[self setSshPassword:[keychain getPasswordForName:connectionSSHKeychainItemName account:connectionSSHKeychainItemAccount]];
}
+
+ if (returnCode == NSAlertAlternateReturn) {
+ [errorDetailWindow makeKeyAndOrderFront:self];
+ }
+ // Currently only SSH port bind errors offer a 3rd option in the error dialog, but if this ever changes
+ // this will definitely need to be updated.
+ else if (returnCode == NSAlertOtherReturn) {
+ // Extract the local port number that SSH attempted to bind to from the debug output
+ NSString *tunnelPort = [[[errorDetailText string] componentsMatchedByRegex:@"LOCALHOST:([0-9]+)" capture:1L] lastObject];
+
+ // Change the connection type to standard TCP/IP
+ [self setType:SP_CONNECTION_TCPIP];
+
+ // Change connection details
+ [self setPort:tunnelPort];
+ [self setHost:@"127.0.0.1"];
+
+ // Change to standard TCP/IP connection view
+ [self resizeTabViewToConnectionType:SP_CONNECTION_TCPIP animating:YES];
+
+ // Initiate the connection after half a second to give the connection view a chance to resize
+ [self performSelector:@selector(initiateConnection:) withObject:self afterDelay:0.5];
+ }
}
/**
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m
index 3623a2f2..6c5be81c 100644
--- a/Source/SPSSHTunnel.m
+++ b/Source/SPSSHTunnel.m
@@ -387,7 +387,7 @@
connectionState = PROXY_STATE_IDLE;
[task terminate];
if (lastError) [lastError release];
- lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was unable to bind to the local port. This error may occur if you already have an SSH connection to the same server and are using a 'LocalForward' option in your SSH configuration.", @"SSH tunnel unable to bind to local port message")];
+ lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was unable to bind to the local port. This error may occur if you already have an SSH connection to the same server and are using a 'LocalForward' setting in your SSH configuration.\n\nWould you like to fall back to a standard connection to localhost in order to use the existing tunnel?", @"SSH tunnel unable to bind to local port message")];
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index e61eb552..083de094 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -433,9 +433,8 @@
int nextOffs = 12;
if( [parts count] > 8 ) {
- // NOTE: this won't get SET NULL | NO ACTION
+ // NOTE: this won't get SET NULL | NO ACTION | RESTRICT
if( [[parts objectAtIndex:9] hasPrefix:@"UPDATE"] ) {
- //NSLog( @"update: %@", [parts objectAtIndex:10] );
if( [NSArrayObjectAtIndex(parts, 10) hasPrefix:@"SET"] ) {
[constraintDetails setObject:@"SET NULL"
forKey:@"update"];
@@ -450,7 +449,6 @@
}
}
else if( [NSArrayObjectAtIndex(parts, 9) hasPrefix:@"DELETE"] ) {
- //NSLog( @"delete: %@", [parts objectAtIndex:10] );
if( [NSArrayObjectAtIndex(parts, 10) hasPrefix:@"SET"] ) {
[constraintDetails setObject:@"SET NULL"
forKey:@"delete"];
@@ -467,7 +465,6 @@
}
if( [parts count] > nextOffs - 1 ) {
if( [NSArrayObjectAtIndex(parts, nextOffs) hasPrefix:@"UPDATE"] ) {
- //NSLog( @"update: %@", [parts objectAtIndex:13] );
if( [NSArrayObjectAtIndex(parts, nextOffs+1) hasPrefix:@"SET"] ) {
[constraintDetails setObject:@"SET NULL"
forKey:@"update"];
@@ -480,7 +477,6 @@
}
}
else if( [NSArrayObjectAtIndex(parts, nextOffs) hasPrefix:@"DELETE"] ) {
- //NSLog( @"delete: %@", [parts objectAtIndex:13] );
if( [NSArrayObjectAtIndex(parts, nextOffs+1) hasPrefix:@"SET"] ) {
[constraintDetails setObject:@"SET NULL"
forKey:@"delete"];
@@ -498,7 +494,6 @@
}
// primary key
else if( [NSArrayObjectAtIndex(parts, 0) hasPrefix:@"PRIMARY"] ) {
- //NSLog( @"pkey is %@", [[parts objectAtIndex:2] stringByTrimmingCharactersInSet:junk] );
}
// key
else if( [NSArrayObjectAtIndex(parts, 0) hasPrefix:@"KEY"] ) {