From 05f1612cbb7e33cf9135a346fc2505cc0e87e853 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Thu, 23 Feb 2012 02:13:56 +0000 Subject: Warning: this branch commit is largely untested, and known to throw exceptions as database structure retrieval is currently missing! Further work on SPMySQLFramework integration: - Improve SPMySQL framework build settings including correct ppc builds and a Distribution configuration for the build distributions to match - Add new convenience querying and result methods to the framework - Amend Sequel Pro source to use the new SPMySQL.framework methods everywhere, replacing MCPKit methods where they differ and improving some functions - Remove MCPKit from the source - Fix a number of warnings on Release-style builds --- Source/DMLocalizedNib.m | 2 +- Source/ImageAndTextCell.m | 10 +- Source/NSMutableArray-MultipleSort.m | 2 +- Source/SPBundleHTMLOutputController.m | 1 + Source/SPCSVExporter.m | 21 ++-- Source/SPCSVParser.m | 4 +- Source/SPCategoryAdditions.h | 1 + Source/SPColorAdditions.m | 6 +- Source/SPConnectionController.h | 9 +- Source/SPConnectionController.m | 73 ++++++------ Source/SPConnectionDelegate.h | 8 +- Source/SPConnectionDelegate.m | 26 ++--- Source/SPCopyTable.m | 36 +++--- Source/SPCustomQuery.h | 13 +-- Source/SPCustomQuery.m | 129 +++++++++++----------- Source/SPDBActionCommons.h | 8 +- Source/SPDataImport.h | 6 +- Source/SPDataImport.m | 46 ++++---- Source/SPDatabaseCopy.m | 3 +- Source/SPDatabaseData.h | 8 +- Source/SPDatabaseData.m | 32 ++---- Source/SPDatabaseDocument.h | 17 ++- Source/SPDatabaseDocument.m | 201 +++++++++++++++++----------------- Source/SPDatabaseInfo.m | 33 +----- Source/SPDatabaseRename.m | 5 +- Source/SPDatabaseViewController.m | 1 + Source/SPEditorPreferencePane.m | 16 +-- Source/SPExportController.h | 14 +-- Source/SPExportController.m | 17 ++- Source/SPExportFileUtilities.m | 1 + Source/SPExportInitializer.m | 3 +- Source/SPExporter.h | 6 +- Source/SPExtendedTableInfo.h | 8 +- Source/SPExtendedTableInfo.m | 26 +++-- Source/SPFavoritesController.m | 3 +- Source/SPFieldEditorController.h | 1 - Source/SPFieldEditorController.m | 7 +- Source/SPFieldMapperController.h | 39 +++---- Source/SPFieldMapperController.m | 13 ++- Source/SPGeometryDataView.m | 18 +-- Source/SPIndexesController.h | 8 +- Source/SPIndexesController.m | 14 +-- Source/SPLogger.m | 1 + Source/SPNarrowDownCompletion.m | 12 +- Source/SPNavigatorController.h | 5 +- Source/SPNavigatorController.m | 36 +++--- Source/SPNotLoaded.m | 4 +- Source/SPObjectAdditions.h | 31 ++++++ Source/SPObjectAdditions.m | 40 +++++++ Source/SPProcessListController.h | 12 +- Source/SPProcessListController.m | 25 ++--- Source/SPQueryController.m | 4 +- Source/SPSQLExporter.m | 76 ++++++------- Source/SPSSHTunnel.h | 7 +- Source/SPSSHTunnel.m | 41 +++---- Source/SPServerVariablesController.h | 6 +- Source/SPServerVariablesController.m | 12 +- Source/SPTableContent.h | 14 +-- Source/SPTableContent.m | 161 +++++++++++++-------------- Source/SPTableCopy.m | 7 +- Source/SPTableData.h | 9 +- Source/SPTableData.m | 62 +++++------ Source/SPTableRelations.h | 8 +- Source/SPTableRelations.m | 18 ++- Source/SPTableStructure.h | 14 +-- Source/SPTableStructure.m | 98 ++++++++--------- Source/SPTableStructureDelegate.m | 7 +- Source/SPTableTextFieldCell.m | 2 +- Source/SPTableTriggers.h | 8 +- Source/SPTableTriggers.m | 9 +- Source/SPTablesList.h | 8 +- Source/SPTablesList.m | 95 ++++++++-------- Source/SPTextView.h | 7 +- Source/SPTextView.m | 3 +- Source/SPUserMO.h | 2 +- Source/SPUserManager.h | 8 +- Source/SPUserManager.m | 56 +++------- Source/SPWindowAdditions.m | 4 +- Source/SPWindowController.m | 6 +- Source/SPXMLExporter.m | 32 +++--- Source/SPXMLExporterDelegate.m | 1 + 81 files changed, 897 insertions(+), 949 deletions(-) create mode 100644 Source/SPObjectAdditions.h create mode 100644 Source/SPObjectAdditions.m (limited to 'Source') diff --git a/Source/DMLocalizedNib.m b/Source/DMLocalizedNib.m index 55e51e35..3f56a07d 100644 --- a/Source/DMLocalizedNib.m +++ b/Source/DMLocalizedNib.m @@ -136,4 +136,4 @@ static NSMutableDictionary *deliciousNibNames = nil; [self deliciousDealloc]; } -@end \ No newline at end of file +@end diff --git a/Source/ImageAndTextCell.m b/Source/ImageAndTextCell.m index eb2f6678..e3c835f0 100644 --- a/Source/ImageAndTextCell.m +++ b/Source/ImageAndTextCell.m @@ -53,7 +53,7 @@ imageFrame.size = [image size]; imageFrame.origin = cellFrame.origin; imageFrame.origin.x += ((1 - MIN(1,INDENT_AMOUNT)) * 3) + (INDENT_AMOUNT * _indentationLevel); - imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); + imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2); return imageFrame; } else @@ -115,9 +115,9 @@ imageFrame.size = imageSize; if ([view isFlipped]) - imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2); + imageFrame.origin.y += ceilf((cellFrame.size.height + imageFrame.size.height) / 2); else - imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); + imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2); imageFrame.origin.y -= 1; @@ -154,9 +154,9 @@ imageFrame.size = imageSize; if ([controlView isFlipped]) - imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2); + imageFrame.origin.y += ceilf((cellFrame.size.height + imageFrame.size.height) / 2); else - imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); + imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2); [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver]; } diff --git a/Source/NSMutableArray-MultipleSort.m b/Source/NSMutableArray-MultipleSort.m index 55a55962..e48db16b 100644 --- a/Source/NSMutableArray-MultipleSort.m +++ b/Source/NSMutableArray-MultipleSort.m @@ -74,4 +74,4 @@ } } } -@end \ No newline at end of file +@end diff --git a/Source/SPBundleHTMLOutputController.m b/Source/SPBundleHTMLOutputController.m index 1b37be2e..9243741c 100644 --- a/Source/SPBundleHTMLOutputController.m +++ b/Source/SPBundleHTMLOutputController.m @@ -126,6 +126,7 @@ - (void)dealloc { if(webPreferences) [webPreferences release]; + [super dealloc]; } - (void)keyDown:(NSEvent *)theEvent diff --git a/Source/SPCSVExporter.m b/Source/SPCSVExporter.m index 6e0fa715..c40bc8f0 100644 --- a/Source/SPCSVExporter.m +++ b/Source/SPCSVExporter.m @@ -23,13 +23,12 @@ // // More info at -#import - #import "SPCSVExporter.h" #import "SPFileHandle.h" #import "SPTableData.h" #import "SPExportUtilities.h" #import "SPExportFile.h" +#import "SPMySQL.h" @implementation SPCSVExporter @@ -77,7 +76,7 @@ NSArray *csvRow = nil; NSScanner *csvNumericTester = nil; - MCPStreamingResult *streamingResult = nil; + SPMySQLFastStreamingResult *streamingResult = nil; NSString *escapedEscapeString, *escapedFieldSeparatorString, *escapedEnclosingString, *escapedLineEndString, *dataConversionString; id csvCell; @@ -122,7 +121,7 @@ // Make a streaming request for the data if the data array isn't set if ((![self csvDataArray]) && [self csvTableName]) { - totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self csvTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue]; + totalRows = [[connection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self csvTableName] backtickQuotedString]]] integerValue]; streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self csvTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]]; } @@ -184,12 +183,12 @@ NSDictionary *tableDetails = nil; // Determine whether the supplied table is actually a table or a view via the CREATE TABLE command, and get the table details - MCPResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [[self csvTableName] backtickQuotedString]]]; + SPMySQLResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [[self csvTableName] backtickQuotedString]]]; [queryResult setReturnDataAsStrings:YES]; - if ([queryResult numOfRows]) { - id object = [[[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]] objectForKey:@"Create View"]; + if ([queryResult numberOfRows]) { + id object = [[queryResult getRowAsDictionary] objectForKey:@"Create View"]; tableDetails = [[NSDictionary alloc] initWithDictionary:(object) ? [[self csvTableData] informationForView:[self csvTableName]] : [[self csvTableData] informationForTable:[self csvTableName]]]; } @@ -238,11 +237,11 @@ else { // If still requested to read the field names, get the field names if ([self csvOutputFieldNames]) { - csvRow = [streamingResult fetchFieldNames]; + csvRow = [streamingResult fieldNames]; [self setCsvOutputFieldNames:NO]; } else { - csvRow = [streamingResult fetchNextRowAsArray]; + csvRow = [streamingResult getRowAsArray]; if (!csvRow) break; } @@ -266,7 +265,7 @@ csvCell = NSArrayObjectAtIndex(csvRow, i); // For NULL objects supplied from a queryResult, add an unenclosed null string as per prefs - if ([csvCell isKindOfClass:[NSNull class]]) { + if ([csvCell isNSNull]) { [csvString appendString:[self csvNULLString]]; if (i < (csvCellCount - 1)) [csvString appendString:[self csvFieldSeparatorString]]; @@ -285,7 +284,7 @@ [csvCellString setString:[NSString stringWithString:dataConversionString]]; [dataConversionString release]; } - else if ([csvCell isKindOfClass:[MCPGeometryData class]]) { + else if ([csvCell isKindOfClass:[SPMySQLGeometryData class]]) { [csvCellString setString:[csvCell wktString]]; } else { diff --git a/Source/SPCSVParser.m b/Source/SPCSVParser.m index e012e323..431c89a8 100644 --- a/Source/SPCSVParser.m +++ b/Source/SPCSVParser.m @@ -284,7 +284,7 @@ // Skip empty rows if ([csvRowArray count] == 0 || ([csvRowArray count] == 1 - && ([[csvRowArray objectAtIndex:0] isMemberOfClass:[NSNull class]] + && ([csvRowArray objectAtIndex:0] == [NSNull null] || ![[csvRowArray objectAtIndex:0] length]))) { @@ -659,4 +659,4 @@ [super dealloc]; } -@end \ No newline at end of file +@end diff --git a/Source/SPCategoryAdditions.h b/Source/SPCategoryAdditions.h index 347dd957..2243d4f5 100644 --- a/Source/SPCategoryAdditions.h +++ b/Source/SPCategoryAdditions.h @@ -31,6 +31,7 @@ #import "SPArrayAdditions.h" #import "SPStringAdditions.h" +#import "SPObjectAdditions.h" #import "SPTextViewAdditions.h" #import "SPWindowAdditions.h" #import "SPDataAdditions.h" diff --git a/Source/SPColorAdditions.m b/Source/SPColorAdditions.m index b9353921..aee0458a 100644 --- a/Source/SPColorAdditions.m +++ b/Source/SPColorAdditions.m @@ -71,19 +71,19 @@ unsigned int color = 0; scanner = [NSScanner scannerWithString:code]; if( ! [scanner scanHexInt:&color] ) return nil; - return [self colorWithCalibratedRed:( ( ( color >> 24 ) & 0xff ) / 255. ) green:( ( ( color >> 16 ) & 0xff ) / 255. ) blue:( ( ( color >> 8) & 0xff ) / 255. ) alpha:( ( color & 0xff ) / 255. )]; + return [self colorWithCalibratedRed:( ( ( color >> 24 ) & 0xff ) / 255.f ) green:( ( ( color >> 16 ) & 0xff ) / 255.f ) blue:( ( ( color >> 8) & 0xff ) / 255.f ) alpha:( ( color & 0xff ) / 255.f )]; } else if( [code length] == 6 ) { // decode colors like #ffee33 unsigned int color = 0; scanner = [NSScanner scannerWithString:code]; if( ! [scanner scanHexInt:&color] ) return nil; - return [self colorWithCalibratedRed:( ( ( color >> 16 ) & 0xff ) / 255. ) green:( ( ( color >> 8 ) & 0xff ) / 255. ) blue:( ( color & 0xff ) / 255. ) alpha:1.]; + return [self colorWithCalibratedRed:( ( ( color >> 16 ) & 0xff ) / 255.f ) green:( ( ( color >> 8 ) & 0xff ) / 255.f ) blue:( ( color & 0xff ) / 255.f ) alpha:1.f]; } else if( [code length] == 3 ) { // decode short-hand colors like #fe3 unsigned int color = 0; scanner = [NSScanner scannerWithString:code]; if( ! [scanner scanHexInt:&color] ) return nil; - return [self colorWithCalibratedRed:( ( ( ( ( color >> 8 ) & 0xf ) << 4 ) | ( ( color >> 8 ) & 0xf ) ) / 255. ) green:( ( ( ( ( color >> 4 ) & 0xf ) << 4 ) | ( ( color >> 4 ) & 0xf ) ) / 255. ) blue:( ( ( ( color & 0xf ) << 4 ) | ( color & 0xf ) ) / 255. ) alpha:1.]; + return [self colorWithCalibratedRed:( ( ( ( ( color >> 8 ) & 0xf ) << 4 ) | ( ( color >> 8 ) & 0xf ) ) / 255.f ) green:( ( ( ( ( color >> 4 ) & 0xf ) << 4 ) | ( ( color >> 4 ) & 0xf ) ) / 255.f ) blue:( ( ( ( color & 0xf ) << 4 ) | ( color & 0xf ) ) / 255.f ) alpha:1.f]; } return nil; diff --git a/Source/SPConnectionController.h b/Source/SPConnectionController.h index 4ecff7e5..a6b63b41 100644 --- a/Source/SPConnectionController.h +++ b/Source/SPConnectionController.h @@ -23,14 +23,13 @@ // // More info at -#import #import "SPConnectionControllerDelegateProtocol.h" #ifndef SP_REFACTOR /* headers */ #import "SPFavoritesOutlineView.h" #endif -@class SPDatabaseDocument, SPSSHTunnel, SPKeychain +@class SPDatabaseDocument, SPSSHTunnel, SPKeychain, SPMySQLConnection #ifndef SP_REFACTOR /* class decl */ , BWAnchoredButtonBar, SPFavoriteNode #endif @@ -67,7 +66,7 @@ NSMutableArray *favorites; #endif SPSSHTunnel *sshTunnel; - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; #ifndef SP_REFACTOR /* ivars */ BOOL automaticFavoriteSelection; #endif @@ -207,7 +206,7 @@ - (void)addConnectionToDocument; // Interface interaction -- (IBAction)chooseKeyLocation:(id)sender; +- (IBAction)chooseKeyLocation:(NSButton *)sender; #ifndef SP_REFACTOR /* method decls */ - (IBAction)editFavorites:(id)sender; - (IBAction)showHelp:(id)sender; @@ -215,7 +214,7 @@ - (IBAction)updateKeyLocationFileVisibility:(id)sender; - (void)resizeTabViewToConnectionType:(NSUInteger)theType animating:(BOOL)animate; - (IBAction)sortFavorites:(id)sender; -- (IBAction)reverseSortFavorites:(id)sender; +- (IBAction)reverseSortFavorites:(NSMenuItem *)sender; #endif // Connection details interaction diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m index 94af9056..acec49de 100644 --- a/Source/SPConnectionController.m +++ b/Source/SPConnectionController.m @@ -25,6 +25,7 @@ #import "SPConnectionController.h" #import "SPDatabaseDocument.h" +#import "SPMySQL.h" #ifndef SP_REFACTOR /* headers */ #import "SPAppController.h" @@ -437,7 +438,7 @@ return; } - if (newState == PROXY_STATE_IDLE) { + if (newState == SPMySQLProxyIdle) { #ifndef SP_REFACTOR [tableDocument setTitlebarStatus:NSLocalizedString(@"SSH Disconnected", @"SSH disconnected titlebar marker")]; #endif @@ -445,7 +446,7 @@ [self failConnectionWithTitle:NSLocalizedString(@"SSH connection failed!", @"SSH connection failed title") errorMessage:[theTunnel lastError] detail:[sshTunnel debugMessages]]; [self _restoreConnectionInterface]; } - else if (newState == PROXY_STATE_CONNECTED) { + else if (newState == SPMySQLProxyConnected) { #ifndef SP_REFACTOR [tableDocument setTitlebarStatus:NSLocalizedString(@"SSH Connected", @"SSH connected titlebar marker")]; #endif @@ -600,7 +601,7 @@ /** * Opens the SSH/SSL key selection window, ready to select a key file. */ -- (IBAction)chooseKeyLocation:(id)sender +- (IBAction)chooseKeyLocation:(NSButton *)sender { #ifndef SP_REFACTOR /* favorites */ [favoritesTable deselectAll:self]; @@ -930,7 +931,7 @@ /** * Reverses the favorites table view sorting based on the selected criteria. */ -- (void)reverseSortFavorites:(id)sender +- (void)reverseSortFavorites:(NSMenuItem *)sender { reverseFavoritesSort = (![sender state]); @@ -1388,22 +1389,26 @@ - (void)_initiateMySQLConnectionInBackground { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + mySQLConnection = [[SPMySQLConnection alloc] init]; + + // Set up shared details + [mySQLConnection setUsername:[self user]]; // Initialise to socket if appropriate. if ([self type] == SPSocketConnection) { - mySQLConnection = [[MCPConnection alloc] initToSocket:[self socket] withLogin:[self user]]; + [mySQLConnection setUseSocket:YES]; + [mySQLConnection setSocketPath:[self socket]]; - // Otherwise, initialise to host, using tunnel if appropriate + // Otherwise, initialise to host, using tunnel if appropriate } else { + [mySQLConnection setUseSocket:NO]; if ([self type] == SPSSHTunnelConnection) { - mySQLConnection = [[MCPConnection alloc] initToHost:@"127.0.0.1" - withLogin:[self user] - usingPort:[sshTunnel localPort]]; - [mySQLConnection setConnectionProxy:sshTunnel]; + [mySQLConnection setHost:@"127.0.0.1"]; + [mySQLConnection setPort:[sshTunnel localPort]]; + [mySQLConnection setProxy:sshTunnel]; } else { - mySQLConnection = [[MCPConnection alloc] initToHost:[self host] - withLogin:[self user] - usingPort:([[self port] length]?[[self port] integerValue]:3306)]; + [mySQLConnection setHost:[self host]]; + if ([[self port] length]) [mySQLConnection setPort:[[self port] integerValue]]; } } @@ -1414,24 +1419,30 @@ // Enable SSL if set if ([self useSSL]) { - [mySQLConnection setSSL:YES - usingKeyFilePath:[self sslKeyFileLocationEnabled] ? [self sslKeyFileLocation] : nil - certificatePath:[self sslCertificateFileLocationEnabled] ? [self sslCertificateFileLocation] : nil - certificateAuthorityCertificatePath:[self sslCACertFileLocationEnabled] ? [self sslCACertFileLocation] : nil]; + [mySQLConnection setUseSSL:YES]; + if ([self sslKeyFileLocationEnabled]) { + [mySQLConnection setSslKeyFilePath:[self sslKeyFileLocation]]; + } + if ([self sslCertificateFileLocationEnabled]) { + [mySQLConnection setSslCertificatePath:[self sslCertificateFileLocation]]; + } + if ([self sslCACertFileLocationEnabled]) { + [mySQLConnection setSslCACertificatePath:[self sslCACertFileLocation]]; + } } - // Connection delegate must be set before actual connection attempt is made [mySQLConnection setDelegate:tableDocument]; + #ifndef SP_REFACTOR /* set mysql connection settings from prefs */ // Set whether or not we should enable delegate logging according to the prefs [mySQLConnection setDelegateQueryLogging:[prefs boolForKey:SPConsoleEnableLogging]]; #endif // Set options from preferences - [mySQLConnection setConnectionTimeout:[[prefs objectForKey:SPConnectionTimeoutValue] integerValue]]; + [mySQLConnection setTimeout:[[prefs objectForKey:SPConnectionTimeoutValue] integerValue]]; [mySQLConnection setUseKeepAlive:[[prefs objectForKey:SPUseKeepAlive] boolValue]]; - [mySQLConnection setKeepAliveInterval:[[prefs objectForKey:SPKeepAliveInterval] doubleValue]]; + [mySQLConnection setKeepAliveInterval:[[prefs objectForKey:SPKeepAliveInterval] floatValue]]; // Connect [mySQLConnection connect]; @@ -1443,7 +1454,7 @@ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]]; // If the state is connection refused, attempt the MySQL connection again with the host using the hostfield value. - if ([sshTunnel state] == PROXY_STATE_FORWARDING_FAILED) { + if ([sshTunnel state] == SPMySQLProxyForwardingFailed) { if ([sshTunnel localPortFallback]) { [mySQLConnection setPort:[sshTunnel localPortFallback]]; [mySQLConnection connect]; @@ -1456,20 +1467,20 @@ if (![mySQLConnection isConnected]) { NSString *errorMessage = @""; - if (sshTunnel && [sshTunnel state] == PROXY_STATE_FORWARDING_FAILED) { - errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because the port connection via SSH was refused.\n\nPlease ensure that your MySQL host is set up to allow TCP/IP connections (no --skip-networking) and is configured to allow connections from the host you are tunnelling via.\n\nYou may also want to check the port is correct and that you have the necessary privileges.\n\nChecking the error detail will show the SSH debug log which may provide more details.\n\nMySQL said: %@", @"message of panel when SSH port forwarding failed"), [self host], [mySQLConnection getLastErrorMessage]]; + if (sshTunnel && [sshTunnel state] == SPMySQLProxyForwardingFailed) { + errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because the port connection via SSH was refused.\n\nPlease ensure that your MySQL host is set up to allow TCP/IP connections (no --skip-networking) and is configured to allow connections from the host you are tunnelling via.\n\nYou may also want to check the port is correct and that you have the necessary privileges.\n\nChecking the error detail will show the SSH debug log which may provide more details.\n\nMySQL said: %@", @"message of panel when SSH port forwarding failed"), [self host], [mySQLConnection lastErrorMessage]]; [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"SSH port forwarding failed", @"title when ssh tunnel port forwarding failed") errorMessage:errorMessage detail:[sshTunnel debugMessages]]; - } else if ([mySQLConnection getLastErrorID] == 1045) { // "Access denied" error - errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because access was denied.\n\nDouble-check your username and password and ensure that access from your current location is permitted.\n\nMySQL said: %@", @"message of panel when connection to host failed due to access denied error"), [self host], [mySQLConnection getLastErrorMessage]]; + } else if ([mySQLConnection lastErrorID] == 1045) { // "Access denied" error + errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because access was denied.\n\nDouble-check your username and password and ensure that access from your current location is permitted.\n\nMySQL said: %@", @"message of panel when connection to host failed due to access denied error"), [self host], [mySQLConnection lastErrorMessage]]; [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Access denied!", @"connection failed due to access denied title") errorMessage:errorMessage detail:nil]; - } else if ([self type] == SPSocketConnection && (![self socket] || ![[self socket] length]) && ![mySQLConnection findSocketPath]) { - errorMessage = [NSString stringWithFormat:NSLocalizedString(@"The socket file could not be found in any common location. Please supply the correct socket location.\n\nMySQL said: %@", @"message of panel when connection to socket failed because optional socket could not be found"), [mySQLConnection getLastErrorMessage]]; + } else if ([self type] == SPSocketConnection && (![self socket] || ![[self socket] length]) && ![SPMySQLConnection findSocketPath]) { + errorMessage = [NSString stringWithFormat:NSLocalizedString(@"The socket file could not be found in any common location. Please supply the correct socket location.\n\nMySQL said: %@", @"message of panel when connection to socket failed because optional socket could not be found"), [mySQLConnection lastErrorMessage]]; [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Socket not found!", @"socket not found title") errorMessage:errorMessage detail:nil]; } else if ([self type] == SPSocketConnection) { - errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect via the socket, or the request timed out.\n\nDouble-check that the socket path is correct and that you have the necessary privileges, and that the server is running.\n\nMySQL said: %@", @"message of panel when connection to host failed"), [mySQLConnection getLastErrorMessage]]; + errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect via the socket, or the request timed out.\n\nDouble-check that the socket path is correct and that you have the necessary privileges, and that the server is running.\n\nMySQL said: %@", @"message of panel when connection to host failed"), [mySQLConnection lastErrorMessage]]; [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Socket connection failed!", @"socket connection failed title") errorMessage:errorMessage detail:nil]; } else { - errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [self host], (long)[[prefs objectForKey:SPConnectionTimeoutValue] integerValue], [mySQLConnection getLastErrorMessage]]; + errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [self host], (long)[[prefs objectForKey:SPConnectionTimeoutValue] integerValue], [mySQLConnection lastErrorMessage]]; [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Connection failed!", @"connection failed title") errorMessage:errorMessage detail:nil]; } @@ -1489,8 +1500,8 @@ } if ([self database] && ![[self database] isEqualToString:@""]) { - if (![mySQLConnection selectDB:[self database]]) { - [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Could not select database", @"message when database selection failed") errorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [self database], [mySQLConnection getLastErrorMessage]] detail:nil]; + if (![mySQLConnection selectDatabase:[self database]]) { + [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Could not select database", @"message when database selection failed") errorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [self database], [mySQLConnection lastErrorMessage]] detail:nil]; // Tidy up isConnecting = NO; diff --git a/Source/SPConnectionDelegate.h b/Source/SPConnectionDelegate.h index 777b032a..04bee877 100644 --- a/Source/SPConnectionDelegate.h +++ b/Source/SPConnectionDelegate.h @@ -25,13 +25,13 @@ #import "SPDatabaseDocument.h" -#import +#import "SPMySQLConnectionDelegate.h" -@interface SPDatabaseDocument (SPConnectionDelegate) +@interface SPDatabaseDocument (SPConnectionDelegate) - (void) closeAndDisconnect; -- (NSString *)keychainPasswordForConnection:(MCPConnection *)connection; -- (NSString *)keychainPasswordForSSHConnection:(MCPConnection *)connection; +- (NSString *)keychainPasswordForConnection:(SPMySQLConnection *)connection; +- (NSString *)keychainPasswordForSSHConnection:(SPMySQLConnection *)connection; @end diff --git a/Source/SPConnectionDelegate.m b/Source/SPConnectionDelegate.m index 58482d1c..2936ba82 100644 --- a/Source/SPConnectionDelegate.m +++ b/Source/SPConnectionDelegate.m @@ -28,11 +28,12 @@ #import "SPQueryController.h" #import "SPKeychain.h" #import "SPAlertSheets.h" +#import "SPMySQLConstants.h" @implementation SPDatabaseDocument (SPConnectionDelegate) #pragma mark - -#pragma mark MCPKit connection delegate methods +#pragma mark SPMySQLConnection delegate methods /** * Invoked when the framework is about to perform a query. @@ -59,19 +60,10 @@ } } -/** - * Invoked when the framework is in the process of reconnecting to the server and needs to know - * which database to select. - */ -- (NSString *)onReconnectShouldSelectDatabase:(id)connection -{ - return selectedDatabase; -} - /** * Invoked when the current connection needs a password from the Keychain. */ -- (NSString *)keychainPasswordForConnection:(MCPConnection *)connection +- (NSString *)keychainPasswordForConnection:(SPMySQLConnection *)connection { // If no keychain item is available, return an empty password @@ -89,8 +81,10 @@ /** * Invoked when the current connection needs a ssh password from the Keychain. + * This isn't actually part of the SPMySQLConnection delegate protocol, but is here + * due to its similarity to the previous method. */ -- (NSString *)keychainPasswordForSSHConnection:(MCPConnection *)connection +- (NSString *)keychainPasswordForSSHConnection:(SPMySQLConnection *)connection { // If no keychain item is available, return an empty password @@ -123,9 +117,9 @@ /** * Invoked when the connection fails and the framework needs to know how to proceed. */ -- (MCPConnectionCheck)connectionLost:(id)connection +- (SPMySQLConnectionLostDecision)connectionLost:(id)connection { - NSInteger connectionErrorCode = MCPConnectionCheckDisconnect; + NSInteger connectionErrorCode = SPMySQLConnectionLostDisconnect; // Only display the reconnect dialog if the window is visible if ([self parentWindow] && [[self parentWindow] isVisible]) { @@ -144,7 +138,7 @@ [connectionErrorDialog orderOut:nil]; // If 'disconnect' was selected, trigger a window close. - if (connectionErrorCode == MCPConnectionCheckDisconnect) { + if (connectionErrorCode == SPMySQLConnectionLostDisconnect) { [self performSelectorOnMainThread:@selector(closeAndDisconnect) withObject:nil waitUntilDone:YES]; } } @@ -179,7 +173,7 @@ _isConnected = NO; if ([[[self parentTabViewItem] tabView] numberOfTabViewItems] == 1) { [theParentWindow orderOut:self]; - [theParentWindow setAlphaValue:0.0]; + [theParentWindow setAlphaValue:0.0f]; [theParentWindow performSelector:@selector(close) withObject:nil afterDelay:1.0]; } else { [[[self parentTabViewItem] tabView] performSelector:@selector(removeTabViewItem:) withObject:[self parentTabViewItem] afterDelay:0.5]; diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index 78773412..b5137935 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -22,11 +22,6 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#import -#ifndef SP_REFACTOR /* headers */ -#import "MCPGeometryData.h" -#endif - #import "SPCopyTable.h" #import "SPTableContent.h" #import "SPTableTriggers.h" @@ -41,6 +36,7 @@ #import "SPBundleEditorController.h" #import "SPAppController.h" #import "SPTablesList.h" +#import "SPMySQL.h" NSInteger SPEditMenuCopy = 2001; NSInteger SPEditMenuCopyWithColumns = 2002; @@ -157,7 +153,7 @@ static const NSInteger kBlobAsImageFile = 4; // Loop through the rows, adding their descriptive contents NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; - Class mcpGeometryData = [MCPGeometryData class]; + Class spmysqlGeometryData = [SPMySQLGeometryData class]; NSUInteger rowCounter = 0; if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) { @@ -210,7 +206,7 @@ static const NSInteger kBlobAsImageFile = 4; [result appendString:@"BLOB\t"]; } } - else if ([cellData isKindOfClass:mcpGeometryData]) { + else if ([cellData isKindOfClass:spmysqlGeometryData]) { if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) { NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", tmpBlobFileDirectory, rowCounter, c]; SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]]; @@ -295,7 +291,7 @@ static const NSInteger kBlobAsImageFile = 4; // Loop through the rows, adding their descriptive contents NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; - Class mcpGeometryData = [MCPGeometryData class]; + Class spmysqlGeometryData = [SPMySQLGeometryData class]; NSUInteger rowCounter = 0; @@ -349,7 +345,7 @@ static const NSInteger kBlobAsImageFile = 4; [result appendString:@"\"BLOB\","]; } } - else if ([cellData isKindOfClass:mcpGeometryData]) { + else if ([cellData isKindOfClass:spmysqlGeometryData]) { if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) { NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", tmpBlobFileDirectory, rowCounter, c]; SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]]; @@ -511,15 +507,15 @@ static const NSInteger kBlobAsImageFile = 4; case 1: case 2: if ([cellData isKindOfClass:nsDataClass]) { - [value appendFormat:@"X'%@', ", [mySQLConnection prepareBinaryData:cellData]]; + [value appendString:[mySQLConnection escapeAndQuoteData:cellData]]; } else { - [value appendFormat:@"'%@', ", [mySQLConnection prepareString:[cellData description]]]; + [value appendString:[mySQLConnection escapeAndQuoteString:[cellData description]]]; } break; // GEOMETRY case 3: - [value appendFormat:@"X'%@', ", [mySQLConnection prepareBinaryData:[cellData data]]]; + [value appendString:[mySQLConnection escapeAndQuoteData:[cellData data]]]; break; // Unhandled cases - abort default: @@ -617,7 +613,7 @@ static const NSInteger kBlobAsImageFile = 4; NSUInteger rowIndex = [selectedRows firstIndex]; NSString *nullString = [prefs objectForKey:SPNullValue]; Class nsDataClass = [NSData class]; - Class mcpGeometryData = [MCPGeometryData class]; + Class spmysqlGeometryData = [SPMySQLGeometryData class]; NSStringEncoding connectionEncoding = [mySQLConnection stringEncoding]; while ( rowIndex != NSNotFound ) { @@ -639,7 +635,7 @@ static const NSInteger kBlobAsImageFile = 4; [displayString release]; } } - else if ([cellData isKindOfClass:mcpGeometryData]) { + else if ([cellData isKindOfClass:spmysqlGeometryData]) { [result appendFormat:@"%@\t", [cellData wktString]]; } else [result appendFormat:@"%@\t", [cellData description]]; @@ -705,7 +701,7 @@ static const NSInteger kBlobAsImageFile = 4; // Determine the available size NSScrollView *parentScrollView = (NSScrollView*)[[self superview] superview]; - CGFloat visibleTableWidth = [parentScrollView bounds].size.width - [NSScroller scrollerWidth] - [columnDefinitions count] * 3.5; + CGFloat visibleTableWidth = [parentScrollView bounds].size.width - [NSScroller scrollerWidth] - [columnDefinitions count] * 3.5f; for (NSDictionary *columnDefinition in columnDefinitions) { if ([[NSThread currentThread] isCancelled]) return nil; @@ -735,7 +731,7 @@ static const NSInteger kBlobAsImageFile = 4; for (NSString *columnIdentifier in columnIdentifiers) { columnWidth = [[columnWidths objectForKey:columnIdentifier] integerValue]; if (columnWidth > SP_MAX_CELL_WIDTH_MULTICOLUMN) { - columnWidth -= ceil((double)(columnWidth - SP_MAX_CELL_WIDTH_MULTICOLUMN) / availableWidthToReduce * widthToReduce); + columnWidth -= ceilf((double)(columnWidth - SP_MAX_CELL_WIDTH_MULTICOLUMN) / availableWidthToReduce * widthToReduce); [columnWidths setObject:[NSNumber numberWithUnsignedInteger:columnWidth] forKey:columnIdentifier]; } } @@ -764,13 +760,13 @@ static const NSInteger kBlobAsImageFile = 4; #endif NSUInteger columnIndex = (NSUInteger)[[columnDefinition objectForKey:@"datacolumnindex"] integerValue]; NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:tableFont forKey:NSFontAttributeName]; - Class mcpGeometryData = [MCPGeometryData class]; + Class spmysqlGeometryData = [SPMySQLGeometryData class]; // Check the number of rows available to check, sampling every n rows if ([tableStorage count] < rowsToCheck) rowStep = 1; else - rowStep = floor([tableStorage count] / rowsToCheck); + rowStep = floorf([tableStorage count] / rowsToCheck); rowsToCheck = [tableStorage count]; @@ -784,8 +780,8 @@ static const NSInteger kBlobAsImageFile = 4; // Retrieve the cell's content contentString = [tableStorage cellDataAtRow:i column:columnIndex]; - // Get WKT string out of the MCPGeometryData for calculation - if ([contentString isKindOfClass:mcpGeometryData]) + // Get WKT string out of the SPMySQLGeometryData for calculation + if ([contentString isKindOfClass:spmysqlGeometryData]) contentString = [contentString wktString]; // Replace NULLs with their placeholder string diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index aa78a250..1e330682 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -23,7 +23,6 @@ // // More info at -#import #import #import "SPCopyTable.h" @@ -47,9 +46,9 @@ #define SP_HISTORY_CLEAR_MENUITEM_TAG 300002 #ifndef SP_REFACTOR -@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView, SPFieldEditorController; +@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult; #else -@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, NSSplitView, SPFieldEditorController; +@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, NSSplitView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult; #endif @interface SPCustomQuery : NSObject @@ -129,7 +128,7 @@ SPQueryFavoriteManager *favoritesManager; NSUserDefaults *prefs; - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; NSString *usedQuery; NSRange currentQueryRange; @@ -221,7 +220,7 @@ - (IBAction)copyQueryHistory:(id)sender; - (IBAction)clearQueryHistory:(id)sender; - (IBAction)showCompletionList:(id)sender; -- (IBAction)toggleQueryInfoPaneCollapse:(id)sender; +- (IBAction)toggleQueryInfoPaneCollapse:(NSButton *)sender; // Query actions - (void)performQueries:(NSArray *)queries withCallback:(SEL)customQueryCallbackMethod; @@ -239,7 +238,7 @@ // Accessors - (NSArray *)currentResult; - (NSArray *)currentDataResultWithNULLs:(BOOL)includeNULLs; -- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult; +- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult; // Retrieving and setting table state - (void) updateTableView; @@ -271,7 +270,7 @@ - (void)tableSortCallback; // Other -- (void)setConnection:(MCPConnection *)theConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; - (void)doPerformQueryService:(NSString *)query; - (void)doPerformLoadQueryService:(NSString *)query; - (void)selectCurrentQuery; diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 61cac5f6..da15da11 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -25,6 +25,7 @@ #import "SPCustomQuery.h" #import "SPSQLParser.h" +#import "SPMySQL.h" #ifndef SP_REFACTOR /* headers */ #import "SPGrowlController.h" #endif @@ -47,6 +48,7 @@ #import "SPGeometryDataView.h" #import "SPAppController.h" #import "SPBundleHTMLOutputController.h" +#include #ifndef SP_REFACTOR /* headers */ #import @@ -540,7 +542,7 @@ /** * Toggle whether the query info pane is visible. */ -- (IBAction)toggleQueryInfoPaneCollapse:(id)sender +- (IBAction)toggleQueryInfoPaneCollapse:(NSButton *)sender { [queryInfoPaneSplitView toggleCollapse:sender]; @@ -585,12 +587,12 @@ - (void)performQueriesTask:(NSDictionary *)taskArguments { - NSAutoreleasePool *queryRunningPool = [[NSAutoreleasePool alloc] init]; - NSArray *queries = [taskArguments objectForKey:@"queries"]; - MCPStreamingResult *streamingResult = nil; - NSMutableString *errors = [NSMutableString string]; - SEL callbackMethod = NULL; - NSString *taskButtonString; + NSAutoreleasePool *queryRunningPool = [[NSAutoreleasePool alloc] init]; + NSArray *queries = [taskArguments objectForKey:@"queries"]; + SPMySQLFastStreamingResult *streamingResult = nil; + NSMutableString *errors = [NSMutableString string]; + SEL callbackMethod = NULL; + NSString *taskButtonString; NSUInteger i, totalQueriesRun = 0, totalAffectedRows = 0; double executionTime = 0; @@ -627,7 +629,7 @@ } // Disable automatic query retries on failure for the custom queries - [mySQLConnection setAllowQueryRetries:NO]; + [mySQLConnection setRetryQueriesOnConnectionFailure:NO]; NSUInteger queryCount = [queries count]; NSMutableArray *tempQueries = [NSMutableArray arrayWithCapacity:queryCount]; @@ -659,16 +661,16 @@ // Run the query, timing execution (note this also includes network and overhead) streamingResult = [[mySQLConnection streamingQueryString:query] retain]; - executionTime += [mySQLConnection lastQueryExecutionTime]; + executionTime += [streamingResult queryExecutionTime]; totalQueriesRun++; // If this is the last query, retrieve and store the result; otherwise, // discard the result without fully loading. - if (totalQueriesRun == queryCount || [mySQLConnection queryCancelled]) { + if (totalQueriesRun == queryCount || [mySQLConnection lastQueryWasCancelled]) { // Retrieve and cache the column definitions for the result array if (cqColumnDefinition) [cqColumnDefinition release]; - cqColumnDefinition = [[streamingResult fetchResultFieldsStructure] retain]; + cqColumnDefinition = [[streamingResult fieldDefinitions] retain]; if(!reloadingExistingResult) { [[self onMainThread] updateTableView]; @@ -695,24 +697,24 @@ } // Record any affected rows - if ( [mySQLConnection affectedRows] != (my_ulonglong)~0 ) - totalAffectedRows += (NSUInteger)[mySQLConnection affectedRows]; - else if ( [streamingResult numOfRows] ) - totalAffectedRows += (NSUInteger)[streamingResult numOfRows]; + if ( [mySQLConnection rowsAffectedByLastQuery] != (unsigned long long)~0 ) + totalAffectedRows += (NSUInteger)[mySQLConnection rowsAffectedByLastQuery]; + else if ( [streamingResult numberOfRows] ) + totalAffectedRows += (NSUInteger)[streamingResult numberOfRows]; [streamingResult release]; // Store any error messages - if ([mySQLConnection queryErrored] || [mySQLConnection queryCancelled]) { + if ([mySQLConnection queryErrored] || [mySQLConnection lastQueryWasCancelled]) { NSString *errorString; - if ([mySQLConnection queryCancelled]) { - if ([mySQLConnection queryCancellationUsedReconnect]) + if ([mySQLConnection lastQueryWasCancelled]) { + if ([mySQLConnection lastQueryWasCancelledUsingReconnect]) errorString = NSLocalizedString(@"Query cancelled. Please note that to cancel the query the connection had to be reset; transactions and connection variables were reset.", @"Query cancel by resetting connection error"); else errorString = NSLocalizedString(@"Query cancelled.", @"Query cancelled error"); } else { - errorString = [mySQLConnection getLastErrorMessage]; + errorString = [mySQLConnection lastErrorMessage]; } // If the query errored, append error to the error log for display at the end @@ -729,7 +731,7 @@ [[errorText onMainThread] setString:errors]; // ask the user to continue after detecting an error - if (![mySQLConnection queryCancelled]) { + if (![mySQLConnection lastQueryWasCancelled]) { [tableDocumentInstance setTaskIndicatorShouldAnimate:NO]; SPBeginWaitingAlertSheet(@"title", @@ -738,7 +740,7 @@ @selector(sheetDidEnd:returnCode:contextInfo:), @"runAllContinueStopSheet", NSLocalizedString(@"MySQL Error", @"mysql error message"), - [mySQLConnection getLastErrorMessage], + [mySQLConnection lastErrorMessage], &runAllContinueStopSheetReturnCode ); [tableDocumentInstance setTaskIndicatorShouldAnimate:YES]; @@ -771,7 +773,7 @@ databaseWasChanged = YES; } // If the query was cancelled, end all queries. - if ([mySQLConnection queryCancelled]) break; + if ([mySQLConnection lastQueryWasCancelled]) break; } // Reload table list if at least one query began with drop, alter, rename, or create @@ -800,7 +802,7 @@ if ( !queryCount ) { streamingResult = [mySQLConnection streamingQueryString:@""]; [streamingResult cancelResultLoad]; - [errors setString:[mySQLConnection getLastErrorMessage]]; + [errors setString:[mySQLConnection lastErrorMessage]]; } // add query to history @@ -817,7 +819,7 @@ // Set up the status string NSString *statusString = nil; NSString *statusErrorString = [errors length]?NSLocalizedString(@"Errors", @"Errors title"):NSLocalizedString(@"No errors", @"No errors title"); - if ( [mySQLConnection queryCancelled] ) { + if ( [mySQLConnection lastQueryWasCancelled] ) { if (totalQueriesRun > 1) { statusString = [NSString stringWithFormat:NSLocalizedString(@"%@; Cancelled in query %ld, after %@", @"text showing multiple queries were cancelled"), statusErrorString, @@ -862,7 +864,7 @@ [[affectedRowsText onMainThread] setStringValue:statusString]; // Restore automatic query retries - [mySQLConnection setAllowQueryRetries:YES]; + [mySQLConnection setRetryQueriesOnConnectionFailure:YES]; #ifndef SP_REFACTOR /* [tableDocumentInstance setQueryMode:] */ [tableDocumentInstance setQueryMode:SPInterfaceQueryMode]; @@ -937,9 +939,8 @@ /** * Processes a supplied streaming result set, loading it into the data array. */ -- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult +- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult { - NSArray *tempRow; NSAutoreleasePool *dataLoadingPool; // Remove all items from the table @@ -951,7 +952,7 @@ // Set the column count on the data store before setting up anything else - // ensures that SPDataStorage is set up for timer-driven data loads - [resultData setColumnCount:[theResult numOfFields]]; + [resultData setColumnCount:[theResult numberOfFields]]; // Set up the table updates timer [[self onMainThread] initQueryLoadTimer]; @@ -960,10 +961,10 @@ dataLoadingPool = [[NSAutoreleasePool alloc] init]; // Loop through the result rows as they become available - while ((tempRow = [theResult fetchNextRowAsArray])) { + for (NSArray *eachRow in theResult) { pthread_mutex_lock(&resultDataLock); - SPDataStorageAddRow(resultData, tempRow); + SPDataStorageAddRow(resultData, eachRow); resultDataCount++; pthread_mutex_unlock(&resultDataLock); @@ -1289,7 +1290,7 @@ NSInteger firstErrorOccuredInQuery = [[errorDetails objectForKey:@"firstErrorQueryNumber"] integerValue]; // If errors occur, display them - if ( [mySQLConnection queryCancelled] || ([errorsString length] && !queryIsTableSorter)) { + if ( [mySQLConnection lastQueryWasCancelled] || ([errorsString length] && !queryIsTableSorter)) { // set the error text [errorText setString:[errorsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; @@ -1300,7 +1301,7 @@ NSRange errorLineNumberRange = [errorsString rangeOfRegex:@"([0-9]+)[^0-9]*$" options:RKLNoOptions inRange:NSMakeRange(0, [errorsString length]) capture:1L error:nil]; // if error ID 1064 and a line number was found - if([mySQLConnection getLastErrorID] == 1064 && errorLineNumberRange.length) + if([mySQLConnection lastErrorID] == 1064 && errorLineNumberRange.length) { // Get the line number NSUInteger errorAtLine = [[errorsString substringWithRange:errorLineNumberRange] integerValue]; @@ -1508,7 +1509,7 @@ /** * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once */ -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; currentQueryRanges = nil; @@ -1764,7 +1765,7 @@ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")]; // Actual check whether field can be identified bijectively - MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", + SPMySQLResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], fieldIDQueryStr]]; @@ -1774,7 +1775,7 @@ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil]; } - NSArray *tempRow = [tempResult fetchRowAsArray]; + NSArray *tempRow = [tempResult getRowAsArray]; if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] > 1) { // try to identify the cell by using blob data @@ -1794,7 +1795,7 @@ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil]; } - tempRow = [tempResult fetchRowAsArray]; + tempRow = [tempResult getRowAsArray]; if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] < 1) { [tableDocumentInstance endTask]; @@ -1817,7 +1818,6 @@ - (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database includeBlobs:(BOOL)includeBlobs { NSArray *dataRow; - NSDictionary *theRow; id field; NSMutableArray *argumentParts = [NSMutableArray array]; @@ -1832,17 +1832,14 @@ dataRow = [resultData rowContentsAtIndex:rowIndex]; // Get the primary key if there is one, using any columns present within it - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@", + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@", [database backtickQuotedString], [tableForColumn backtickQuotedString]]]; [theResult setReturnDataAsStrings:YES]; - if ([theResult numOfRows]) [theResult dataSeek:0]; NSMutableArray *primaryColumnsInSpecifiedTable = [NSMutableArray array]; - NSUInteger i; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - theRow = [theResult fetchRowAsDictionary]; - if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { + for (NSDictionary *eachRow in theResult) { + if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { for (field in columnsInSpecifiedTable) { - if([[field objectForKey:@"org_name"] isEqualToString:[theRow objectForKey:@"Field"]]) { + if([[field objectForKey:@"org_name"] isEqualToString:[eachRow objectForKey:@"Field"]]) { [primaryColumnsInSpecifiedTable addObject:field]; } } @@ -1855,7 +1852,7 @@ // Build up the argument for (field in columnsToQuery) { id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] integerValue]]; - if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) { + if ([aValue isNSNull]) { [argumentParts addObject:[NSString stringWithFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]]]; } else { NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"]; @@ -1875,14 +1872,14 @@ [argumentParts addObject:[NSString stringWithFormat:@"%@=b'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]]; } else if ([fieldTypeGrouping isEqualToString:@"geometry"]) { - [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:[aValue data]]]]; } // BLOB/TEXT data else if ([aValue isKindOfClass:[NSData class]]) { - [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:aValue]]]; } else { - [argumentParts addObject:[NSString stringWithFormat:@"%@='%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteString:aValue]]]; } } } @@ -1919,11 +1916,11 @@ NSString *newObject = nil; if ( [anObject isKindOfClass:[NSCalendarDate class]] ) { - newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]]; + newObject = [mySQLConnection escapeAndQuoteString:[anObject description]]; } else if ( [anObject isKindOfClass:[NSNumber class]] ) { newObject = [anObject stringValue]; } else if ( [anObject isKindOfClass:[NSData class]] ) { - newObject = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:anObject]]; + newObject = [mySQLConnection escapeAndQuoteData:anObject]; } else { if ( [[anObject description] isEqualToString:@"CURRENT_TIMESTAMP"] ) { newObject = @"CURRENT_TIMESTAMP"; @@ -1940,7 +1937,7 @@ && [[anObject description] isEqualToString:@"NOW()"]) { newObject = @"NOW()"; } else { - newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]]; + newObject = [mySQLConnection escapeAndQuoteString:[anObject description]]; } } @@ -1952,13 +1949,13 @@ // Check for errors while UPDATE if ([mySQLConnection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection lastErrorMessage]]); return; } // This shouldn't happen – for safety reasons - if ( ![mySQLConnection affectedRows] ) { + if ( ![mySQLConnection rowsAffectedByLastQuery] ) { #ifndef SP_REFACTOR if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) { SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, @@ -2335,7 +2332,7 @@ return nil; } } - else if ([theValue isKindOfClass:[MCPGeometryData class]]) { + else if ([theValue isKindOfClass:[SPMySQLGeometryData class]]) { SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[theValue coordinates]]; image = [v thumbnailImage]; if(image) { @@ -3070,7 +3067,7 @@ if(![searchString length]) return @""; NSRange aRange; - MCPResult *theResult = nil; + SPMySQLResult *theResult = nil; NSDictionary *tableDetails; NSMutableString *theHelp = [NSMutableString string]; @@ -3089,14 +3086,16 @@ return SP_HELP_NOT_AVAILABLE; } // nothing found? - if(![theResult numOfRows]) { + if(![theResult numberOfRows]) { + // try to search via: HELP 'searchString%' theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"HELP '%@%%'", [searchString stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]]; + // really nothing found? - if(![theResult numOfRows]) + if(![theResult numberOfRows]) return @""; } - tableDetails = [[NSDictionary alloc] initWithDictionary:[theResult fetchRowAsDictionary]]; + tableDetails = [[NSDictionary alloc] initWithDictionary:[theResult getRowAsDictionary]]; if ([tableDetails objectForKey:@"description"]) { // one single help topic found if ([tableDetails objectForKey:@"name"]) { @@ -3171,9 +3170,9 @@ } } else { // list all found topics - NSUInteger i; - NSUInteger r = (NSUInteger)[theResult numOfRows]; - if (r) [theResult dataSeek:0]; + NSUInteger r = (NSUInteger)[theResult numberOfRows]; + if (r) [theResult seekToRow:0]; + // check if HELP 'contents' is called if(![searchString isEqualToString:SP_HELP_TOC_SEARCH_STRING]) [theHelp appendFormat:@"
%@ “%@”
", NSLocalizedString(@"Help topics for", @"help topics for"), searchString]; @@ -3182,9 +3181,9 @@ // iterate through all found rows and print them as HTML ul/li list [theHelp appendString:@"
    "]; - for ( i = 0 ; i < r ; i++ ) { - NSArray *anArray = [theResult fetchRowAsArray]; - NSString *topic = [anArray objectAtIndex:[anArray count]-2]; + [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray]; + for (NSArray *eachRow in theResult) { + NSString *topic = [eachRow objectAtIndex:[eachRow count]-2]; [theHelp appendFormat:@"
  • %@
  • ", NSLocalizedString(@"Show MySQL help for", @"show mysql help for"), topic, topic, topic]; } @@ -4008,7 +4007,7 @@ value = [prefs objectForKey:SPNullValue]; } - if ([value isKindOfClass:[MCPGeometryData class]]) { + if ([value isKindOfClass:[SPMySQLGeometryData class]]) { value = [value wktString]; } diff --git a/Source/SPDBActionCommons.h b/Source/SPDBActionCommons.h index 6ff6e11c..7ae7ec79 100644 --- a/Source/SPDBActionCommons.h +++ b/Source/SPDBActionCommons.h @@ -22,18 +22,18 @@ // // More info at -#import +@class SPMySQLConnection; @interface SPDBActionCommons : NSObject { - MCPConnection *connection; + SPMySQLConnection *connection; NSWindow *messageWindow; } /** - * @property connection References the MCPKit connection to MySQL; it has to be set. + * @property connection References the SPMySQL.framework MySQL connection; it has to be set. */ -@property (retain) MCPConnection *connection; +@property (retain) SPMySQLConnection *connection; /** * @property messageWindow The NSWindow instance to send message sheets to. diff --git a/Source/SPDataImport.h b/Source/SPDataImport.h index 1b668be9..6bad573d 100644 --- a/Source/SPDataImport.h +++ b/Source/SPDataImport.h @@ -23,7 +23,7 @@ // // More info at -#import +@class SPMySQLConnection; typedef enum { SPFieldMapperInProgress = 1, @@ -77,7 +77,7 @@ typedef enum { IBOutlet id singleProgressTitle; IBOutlet id singleProgressText; - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; NSMutableArray *nibObjectsToRelease; @@ -138,7 +138,7 @@ typedef enum { - (NSString *)mappedUpdateSetStatementStringForRowArray:(NSArray *)csvRowArray; // Additional methods -- (void)setConnection:(MCPConnection *)theConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; - (void)showErrorSheetWithMessage:(NSString*)message; // Import delegate notifications diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m index 7f90eea7..e0917858 100644 --- a/Source/SPDataImport.m +++ b/Source/SPDataImport.m @@ -39,8 +39,8 @@ #import "SPFieldMapperController.h" #import "SPFileHandle.h" #import "SPEncodingPopupAccessory.h" +#import "SPMySQL.h" -#import #import #define SP_FILE_READ_ERROR_STRING NSLocalizedString(@"File read error", @"File read error title (Import Dialog)") @@ -424,9 +424,9 @@ [fileEncodingDetector analyzeData:[detectorFileHandle readDataOfLength:2500000]]; sqlEncoding = [fileEncodingDetector encoding]; [fileEncodingDetector release]; - if ([MCPConnection mySQLEncodingForStringEncoding:sqlEncoding]) { + if ([SPMySQLConnection mySQLCharsetForStringEncoding:sqlEncoding]) { connectionEncodingToRestore = [mySQLConnection encoding]; - [mySQLConnection queryString:[NSString stringWithFormat:@"SET NAMES '%@'", [MCPConnection mySQLEncodingForStringEncoding:sqlEncoding]]]; + [mySQLConnection queryString:[NSString stringWithFormat:@"SET NAMES '%@'", [SPMySQLConnection mySQLCharsetForStringEncoding:sqlEncoding]]]; } } @@ -564,11 +564,11 @@ if (![query length]) continue; // Run the query - [mySQLConnection queryString:query usingEncoding:sqlEncoding streamingResult:NO]; + [mySQLConnection queryString:query usingEncoding:sqlEncoding withResultType:SPMySQLResultAsResult]; // Check for any errors - if ([mySQLConnection queryErrored] && ![[mySQLConnection getLastErrorMessage] isEqualToString:@"Query was empty"]) { - [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage]]; + if ([mySQLConnection queryErrored] && ![[mySQLConnection lastErrorMessage] isEqualToString:@"Query was empty"]) { + [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage]]; // If not set to ignore errors, ask what to do. Use NSAlert rather than // SPBeginWaitingAlertSheet as there is already a modal sheet in progress. @@ -580,7 +580,7 @@ defaultButton:NSLocalizedString(@"Continue", @"continue button") alternateButton:NSLocalizedString(@"Ignore All Errors", @"ignore errors button") otherButton:NSLocalizedString(@"Stop", @"stop button") - informativeTextWithFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage] + informativeTextWithFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage] ]; [sqlErrorAlert setAlertStyle:NSWarningAlertStyle]; sqlImportErrorSheetReturnCode = [sqlErrorAlert runModal]; @@ -632,11 +632,11 @@ if ([query length] && !progressCancelled) { // Run the query - [mySQLConnection queryString:query usingEncoding:sqlEncoding streamingResult:NO]; + [mySQLConnection queryString:query usingEncoding:sqlEncoding withResultType:SPMySQLResultAsResult]; // Check for any errors - if ([mySQLConnection queryErrored] && ![[mySQLConnection getLastErrorMessage] isEqualToString:@"Query was empty"]) { - [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage]]; + if ([mySQLConnection queryErrored] && ![[mySQLConnection lastErrorMessage] isEqualToString:@"Query was empty"]) { + [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage]]; } // Increment the processed queries count @@ -1067,10 +1067,10 @@ [tableDocumentInstance showConsole:nil]; [errors appendFormat: NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"), - (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]]; + (long)(rowsImported+1),[mySQLConnection lastErrorMessage]]; } - if ( insertRemainingRowsAfterUpdate && ![mySQLConnection affectedRows]) { + if ( insertRemainingRowsAfterUpdate && ![mySQLConnection rowsAffectedByLastQuery]) { query = [[NSMutableString alloc] initWithString:insertRemainingBaseString]; [query appendString:[self mappedValueStringForRowArray:[parsedRows objectAtIndex:i]]]; @@ -1084,7 +1084,7 @@ if ([mySQLConnection queryErrored]) { [errors appendFormat: NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"), - (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]]; + (long)(rowsImported+1),[mySQLConnection lastErrorMessage]]; } } @@ -1120,7 +1120,7 @@ if ([mySQLConnection queryErrored]) { [errors appendFormat: NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"), - (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]]; + (long)(rowsImported+1),[mySQLConnection lastErrorMessage]]; } rowsImported++; if (fileIsCompressed) { @@ -1379,7 +1379,7 @@ if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) { NSMutableString *globalVar = [NSMutableString string]; id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn); - if([insertItem isKindOfClass:[NSNull class]]) { + if([insertItem isNSNull]) { [globalVar setString:@"NULL"]; } else if([insertItem isSPNotLoaded]) { [globalVar setString:@"NULL"]; @@ -1417,7 +1417,7 @@ if (cellData == [NSNull null]) { [setString appendString:@"NULL"]; } else { - [setString appendFormat:@"'%@'", [mySQLConnection prepareString:cellData]]; + [setString appendString:[mySQLConnection escapeAndQuoteString:cellData]]; } } } @@ -1431,7 +1431,7 @@ if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) { NSMutableString *globalVar = [NSMutableString string]; id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn); - if([insertItem isKindOfClass:[NSNull class]]) { + if([insertItem isNSNull]) { [globalVar setString:@"NULL"]; } else if([insertItem isSPNotLoaded]) { [globalVar setString:@"NULL"]; @@ -1469,7 +1469,8 @@ if (cellData == [NSNull null]) { [whereString appendString:@" IS NULL"]; } else { - [whereString appendFormat:@"='%@'", [mySQLConnection prepareString:cellData]]; + [whereString appendString:@"="]; + [whereString appendString:[mySQLConnection escapeAndQuoteString:cellData]]; } } } @@ -1505,7 +1506,7 @@ if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) { NSMutableString *globalVar = [NSMutableString string]; id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn); - if([insertItem isKindOfClass:[NSNull class]]) { + if([insertItem isNSNull]) { [globalVar setString:@"NULL"]; } else if([insertItem isSPNotLoaded]) { [globalVar setString:@"NULL"]; @@ -1549,9 +1550,10 @@ if([geometryFields count] && [geometryFieldsMapIndex containsIndex:i]) { [valueString appendString:[(NSString*)cellData getGeomFromTextString]]; } else if([bitFields count] && [bitFieldsMapIndex containsIndex:i]) { - [valueString appendFormat:@"b'%@'", [mySQLConnection prepareString:cellData]]; + [valueString appendString:@"b"]; + [valueString appendString:[mySQLConnection escapeAndQuoteString:cellData]]; } else { - [valueString appendFormat:@"'%@'", [mySQLConnection prepareString:cellData]]; + [valueString appendString:[mySQLConnection escapeAndQuoteString:cellData]]; } } } @@ -1636,7 +1638,7 @@ /** * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once. */ -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { NSButtonCell *switchButton = [[NSButtonCell alloc] init]; diff --git a/Source/SPDatabaseCopy.m b/Source/SPDatabaseCopy.m index c2371f3d..61412f76 100644 --- a/Source/SPDatabaseCopy.m +++ b/Source/SPDatabaseCopy.m @@ -25,6 +25,7 @@ #import "SPDBActionCommons.h" #import "SPDatabaseCopy.h" #import "SPTableCopy.h" +#import "SPMySQL.h" @implementation SPDatabaseCopy @@ -58,7 +59,7 @@ if (sourceExists && !targetExists) { // Retrieve the list of tables/views/funcs/triggers from the source database - tables = [connection listTablesFromDB:sourceDatabaseName]; + tables = [connection tablesFromDatabase:sourceDatabaseName]; } else { return NO; diff --git a/Source/SPDatabaseData.h b/Source/SPDatabaseData.h index b0c988eb..e315ca6a 100644 --- a/Source/SPDatabaseData.h +++ b/Source/SPDatabaseData.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPServerSupport; +@class SPServerSupport, SPMySQLConnection; /** * @class SPDatabaseData SPDatabaseData.h @@ -45,14 +43,14 @@ NSMutableArray *characterSetEncodings; NSMutableDictionary *cachedCollationsByEncoding; - MCPConnection *connection; + SPMySQLConnection *connection; SPServerSupport *serverSupport; } /** * @property connection The current database connection */ -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; /** * @property serverSupport The connection's associated SPServerSupport instance diff --git a/Source/SPDatabaseData.m b/Source/SPDatabaseData.m index 2aa809b1..2e827fa9 100644 --- a/Source/SPDatabaseData.m +++ b/Source/SPDatabaseData.m @@ -26,10 +26,11 @@ #import "SPDatabaseData.h" #import "SPServerSupport.h" #import "SPDatabaseCharacterSets.h" +#import "SPMySQL.h" @interface SPDatabaseData (PrivateAPI) -- (NSMutableArray *)_getDatabaseDataForQuery:(NSString *)query; +- (NSArray *)_getDatabaseDataForQuery:(NSString *)query; NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, void *context); @@ -162,12 +163,12 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, [storageEngines addObject:[NSDictionary dictionaryWithObject:@"MyISAM" forKey:@"Engine"]]; // Check if InnoDB support is enabled - MCPResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'have_innodb'"]; + SPMySQLResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'have_innodb'"]; [result setReturnDataAsStrings:YES]; - if ([result numOfRows] == 1) { - if ([[[result fetchRowAsDictionary] objectForKey:@"Value"] isEqualToString:@"YES"]) { + if ([result numberOfRows] == 1) { + if ([[[result getRowAsDictionary] objectForKey:@"Value"] isEqualToString:@"YES"]) { [storageEngines addObject:[NSDictionary dictionaryWithObject:@"InnoDB" forKey:@"Engine"]]; } } @@ -201,9 +202,9 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, if ([serverSupport supportsInformationSchemaEngines]) { // Check the information_schema.engines table is accessible - MCPResult *result = [connection queryString:@"SHOW TABLES IN information_schema LIKE 'ENGINES'"]; + SPMySQLResult *result = [connection queryString:@"SHOW TABLES IN information_schema LIKE 'ENGINES'"]; - if ([result numOfRows] == 1) { + if ([result numberOfRows] == 1) { // Table is accessible so get available storage engines // Note, that the case of the column names specified in this query are important. @@ -212,7 +213,7 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, } else { // Get storage engines - NSMutableArray *engines = [self _getDatabaseDataForQuery:@"SHOW STORAGE ENGINES"]; + NSArray *engines = [self _getDatabaseDataForQuery:@"SHOW STORAGE ENGINES"]; // We only want to include engines that are supported for (NSDictionary *engine in engines) @@ -308,22 +309,13 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, * Executes the supplied query against the current connection and returns the result as an array of * NSDictionarys, one for each row. */ -- (NSMutableArray *)_getDatabaseDataForQuery:(NSString *)query +- (NSArray *)_getDatabaseDataForQuery:(NSString *)query { - NSMutableArray *array = [NSMutableArray array]; + SPMySQLResult *result = [connection queryString:query]; - MCPResult *result = [connection queryString:query]; + if ([connection queryErrored]) return [NSArray array]; - if (![connection queryErrored]) { - [result dataSeek:0]; - - for (NSUInteger i = 0; i < [result numOfRows]; i++) - { - [array addObject:[result fetchRowAsDictionary]]; - } - } - - return array; + return [result getAllRows]; } /** diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h index b56991f5..2a03e589 100644 --- a/Source/SPDatabaseDocument.h +++ b/Source/SPDatabaseDocument.h @@ -25,7 +25,6 @@ // // More info at -#import #ifndef SP_REFACTOR /* headers */ #import #endif @@ -34,7 +33,7 @@ #ifndef SP_REFACTOR /* class forward decls */ SPProcessListController, SPServerVariablesController, SPUserManager, SPWindowController, #endif -SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPServerSupport, SPCustomQuery; +SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPServerSupport, SPCustomQuery, SPMySQLConnection; #import "SPConnectionControllerDelegateProtocol.h" @@ -102,7 +101,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS IBOutlet id addDatabaseButton; IBOutlet id databaseCopyNameField; - IBOutlet id copyDatabaseDataButton; + IBOutlet NSButton *copyDatabaseDataButton; IBOutlet id copyDatabaseMessageField; IBOutlet id copyDatabaseButton; @@ -146,14 +145,14 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS IBOutlet id inputTextWindowSecureTextField; NSInteger passwordSheetReturnCode; + // Master connection + SPMySQLConnection *mySQLConnection; + // Controllers SPConnectionController *connectionController; #ifndef SP_REFACTOR /* ivars */ SPProcessListController *processListController; SPServerVariablesController *serverVariablesController; -#endif - MCPConnection *mySQLConnection; -#ifndef SP_REFACTOR /* ivars */ NSInteger currentTabIndex; #endif @@ -222,7 +221,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS #ifndef SP_REFACTOR /* ivars */ NSThread *printThread; - id statusValues; + NSArray *statusValues; NSInteger saveDocPrefSheetStatus; @@ -280,8 +279,8 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS // Connection callback and methods #endif -- (void)setConnection:(MCPConnection *)theConnection; -- (MCPConnection *)getConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; +- (SPMySQLConnection *)getConnection; - (void)setKeychainID:(NSString *)theID; // Database methods diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 53d9b5c6..fef580ba 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -35,6 +35,8 @@ enum { #import "SPDatabaseDocument.h" #import "SPConnectionController.h" +#import "SPMySQL.h" + #import "SPTablesList.h" #import "SPTableStructure.h" #ifndef SP_REFACTOR /* headers */ @@ -393,7 +395,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; #pragma mark - #pragma mark Connection callback and methods -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { _isConnected = YES; mySQLConnection = [theConnection retain]; @@ -570,7 +572,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; * * @return The document's connection */ -- (MCPConnection *) getConnection +- (SPMySQLConnection *) getConnection { return mySQLConnection; } @@ -604,28 +606,22 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; [[chooseDatabaseButton menu] addItem:[NSMenuItem separatorItem]]; #endif - MCPResult *queryResult = [mySQLConnection listDBs]; - - if ([queryResult numOfRows]) [queryResult dataSeek:0]; - if (allDatabases) [allDatabases release]; if (allSystemDatabases) [allSystemDatabases release]; - allDatabases = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[queryResult numOfRows]]; + NSArray *theDatabaseList = [mySQLConnection databases]; + allDatabases = [[NSMutableArray alloc] initWithCapacity:[theDatabaseList count]]; allSystemDatabases = [[NSMutableArray alloc] initWithCapacity:2]; - for (NSUInteger i = 0 ; i < [queryResult numOfRows] ; i++) - { - NSString *database = NSArrayObjectAtIndex([queryResult fetchRowAsArray], 0); + for (NSString *databaseName in theDatabaseList) { - // If the database is either information_schema or mysql then it is classed as a system table - // 5.5.3+ performance_schema - if ([database isEqualToString:@"information_schema"] || [database isEqualToString:@"mysql"] || [database isEqualToString:@"performance_schema"]) { - [allSystemDatabases addObject:database]; - } - else { - [allDatabases addObject:database]; + // If the database is either information_schema or mysql then it is classed as a + // system table; similarly, for 5.5.3+, performance_schema + if ([databaseName isEqualToString:@"information_schema"] || [databaseName isEqualToString:@"mysql"] || [databaseName isEqualToString:@"performance_schema"]) { + [allSystemDatabases addObject:databaseName]; + } else { + [allDatabases addObject:databaseName]; } } @@ -984,15 +980,13 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:self]; #endif - MCPResult *theResult = [mySQLConnection queryString:@"SELECT DATABASE()"]; + SPMySQLResult *theResult = [mySQLConnection queryString:@"SELECT DATABASE()"]; + [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray]; if (![mySQLConnection queryErrored]) { - NSInteger i; - NSInteger r = (NSInteger)[theResult numOfRows]; - if (r) [theResult dataSeek:0]; - for ( i = 0 ; i < r ; i++ ) { - dbName = NSArrayObjectAtIndex([theResult fetchRowAsArray], 0); + for (NSArray *eachRow in theResult) { + dbName = NSArrayObjectAtIndex(eachRow, 0); } - if(![dbName isKindOfClass:[NSNull class]]) { + if(![dbName isNSNull]) { if(![dbName isEqualToString:selectedDatabase]) { if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil; selectedDatabase = [[NSString alloc] initWithString:dbName]; @@ -1557,7 +1551,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; */ - (void)detectDatabaseEncoding { - MCPResult *charSetResult; + SPMySQLResult *charSetResult; NSString *mysqlEncoding = nil; _supportsEncoding = YES; @@ -1566,11 +1560,11 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if ([serverSupport supportsCharacterSetDatabaseVar]) { charSetResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set_database'"]; [charSetResult setReturnDataAsStrings:YES]; - mysqlEncoding = [[charSetResult fetchRowAsDictionary] objectForKey:@"Value"]; + mysqlEncoding = [[charSetResult getRowAsDictionary] objectForKey:@"Value"]; } // MySQL 4.0 or older -> only default character set possible, cannot choose others using "set names xy" else { - mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] fetchRowAsDictionary] objectForKey:@"Value"]; + mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] getRowAsDictionary] objectForKey:@"Value"]; } [selectedDatabaseEncoding release]; @@ -1656,13 +1650,13 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - MCPResult *theResult = [mySQLConnection queryString:query]; + SPMySQLResult *theResult = [mySQLConnection queryString:query]; [theResult setReturnDataAsStrings:YES]; // Check for errors, only displaying if the connection hasn't been terminated if ([mySQLConnection queryErrored]) { if ([mySQLConnection isConnected]) { - NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while creating table syntax.\n\n: %@", @"Error shown when unable to show create table syntax"),[mySQLConnection getLastErrorMessage]], @"OK", nil, nil); + NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while creating table syntax.\n\n: %@", @"Error shown when unable to show create table syntax"), [mySQLConnection lastErrorMessage]], @"OK", nil, nil); } return; @@ -1670,9 +1664,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; NSString *tableSyntax; if (type == SPTableTypeProc) - tableSyntax = [NSString stringWithFormat:@"DELIMITER ;;\n%@;;\nDELIMITER ", [[theResult fetchRowAsArray] objectAtIndex:colOffs]]; + tableSyntax = [NSString stringWithFormat:@"DELIMITER ;;\n%@;;\nDELIMITER ", [[theResult getRowAsArray] objectAtIndex:colOffs]]; else - tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs]; + tableSyntax = [[theResult getRowAsArray] objectAtIndex:colOffs]; // A NULL value indicates that the user does not have permission to view the syntax if ([tableSyntax isNSNull]) { @@ -1755,7 +1749,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECK TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECK TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -1768,7 +1762,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to check the %@.\n\nMySQL said:%@",@"an error occurred while trying to check the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to check the %@.\n\nMySQL said:%@",@"an error occurred while trying to check the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -1778,10 +1772,10 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSArray *resultStatuses = [theResult getAllRows]; BOOL statusOK = YES; - for(id res in result) { - if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) { + for (NSDictionary *eachRow in theResult) { + if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) { statusOK = NO; break; } @@ -1789,7 +1783,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; // Process result if([selectedItems count] == 1) { - NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject]; + NSDictionary *lastresult = [resultStatuses lastObject]; message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Check table successfully passed.",@"check table successfully passed message") : NSLocalizedString(@"Check table failed.", @"check table failed message"); @@ -1811,7 +1805,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } else { message = NSLocalizedString(@"MySQL said:",@"mysql said message"); if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:message]; [alert setMessageText:NSLocalizedString(@"Error while checking selected items", @"error while checking selected items message")]; @@ -1831,7 +1825,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"ANALYZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"ANALYZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -1844,7 +1838,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while analyzing the %@.\n\nMySQL said:%@",@"an error occurred while analyzing the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while analyzing the %@.\n\nMySQL said:%@",@"an error occurred while analyzing the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -1854,18 +1848,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSArray *resultStatuses = [theResult getAllRows]; BOOL statusOK = YES; - for(id res in result) { - if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) { + for (NSDictionary *eachRow in resultStatuses) { + if(![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) { statusOK = NO; break; } } // Process result - if([selectedItems count] == 1) { - NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject]; + if ([selectedItems count] == 1) { + NSDictionary *lastresult = [resultStatuses lastObject]; message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully analyzed table.",@"analyze table successfully passed message") : NSLocalizedString(@"Analyze table failed.", @"analyze table failed message"); @@ -1887,7 +1881,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } else { message = NSLocalizedString(@"MySQL said:",@"mysql said message"); if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:message]; [alert setMessageText:NSLocalizedString(@"Error while analyzing selected items", @"error while analyzing selected items message")]; @@ -1907,7 +1901,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"OPTIMIZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"OPTIMIZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -1920,7 +1914,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while optimzing the %@.\n\nMySQL said:%@",@"an error occurred while trying to optimze the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while optimzing the %@.\n\nMySQL said:%@",@"an error occurred while trying to optimze the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -1930,18 +1924,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSArray *resultStatuses = [theResult getAllRows]; BOOL statusOK = YES; - for(id res in result) { - if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) { + for (NSDictionary *eachRow in resultStatuses) { + if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) { statusOK = NO; break; } } // Process result - if([selectedItems count] == 1) { - NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject]; + if ([selectedItems count] == 1) { + NSDictionary *lastresult = [resultStatuses lastObject]; message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully optimized table.",@"optimize table successfully passed message") : NSLocalizedString(@"Optimize table failed.", @"optimize table failed message"); @@ -1963,7 +1957,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } else { message = NSLocalizedString(@"MySQL said:",@"mysql said message"); if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:message]; [alert setMessageText:NSLocalizedString(@"Error while optimizing selected items", @"error while optimizing selected items message")]; @@ -1982,7 +1976,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"REPAIR TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"REPAIR TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -1995,7 +1989,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while repairing the %@.\n\nMySQL said:%@",@"an error occurred while trying to repair the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while repairing the %@.\n\nMySQL said:%@",@"an error occurred while trying to repair the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -2005,18 +1999,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSArray *resultStatuses = [theResult getAllRows]; BOOL statusOK = YES; - for(id res in result) { - if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) { + for (NSDictionary *eachRow in resultStatuses) { + if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) { statusOK = NO; break; } } // Process result - if([selectedItems count] == 1) { - NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject]; + if ([selectedItems count] == 1) { + NSDictionary *lastresult = [resultStatuses lastObject]; message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully repaired table.",@"repair table successfully passed message") : NSLocalizedString(@"Repair table failed.", @"repair table failed message"); @@ -2025,7 +2019,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; message = NSLocalizedString(@"Successfully repaired all selected items.",@"successfully repaired all selected items message"); } - if(message) { + if (message) { [[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Repair %@", @"REPAIR one or more tables - result title"), what] defaultButton:@"OK" alternateButton:nil @@ -2038,7 +2032,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } else { message = NSLocalizedString(@"MySQL said:",@"mysql said message"); if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:message]; [alert setMessageText:NSLocalizedString(@"Error while repairing selected items", @"error while repairing selected items message")]; @@ -2057,7 +2051,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"FLUSH TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"FLUSH TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -2070,7 +2064,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while flushing the %@.\n\nMySQL said:%@",@"an error occurred while trying to flush the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while flushing the %@.\n\nMySQL said:%@",@"an error occurred while trying to flush the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -2080,18 +2074,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; return; } - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSArray *resultStatuses = [theResult getAllRows]; BOOL statusOK = YES; - for(id res in result) { - if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) { + for (NSDictionary *eachRow in resultStatuses) { + if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) { statusOK = NO; break; } } // Process result - if([selectedItems count] == 1) { - NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject]; + if ([selectedItems count] == 1) { + NSDictionary *lastresult = [resultStatuses lastObject]; message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully flushed table.",@"flush table successfully passed message") : NSLocalizedString(@"Flush table failed.", @"flush table failed message"); @@ -2100,7 +2094,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; message = NSLocalizedString(@"Successfully flushed all selected items.",@"successfully flushed all selected items message"); } - if(message) { + if (message) { [[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Flush %@", @"FLUSH one or more tables - result title"), what] defaultButton:@"OK" alternateButton:nil @@ -2113,7 +2107,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } else { message = NSLocalizedString(@"MySQL said:",@"mysql said message"); if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:message]; [alert setMessageText:NSLocalizedString(@"Error while flushing selected items", @"error while flushing selected items message")]; @@ -2132,7 +2126,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([selectedItems count] == 0) return; - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECKSUM TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECKSUM TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]]; NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]]; @@ -2144,7 +2138,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while performing the checksum on %@.\n\nMySQL said:%@",@"an error occurred while performing the checksum on the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while performing the checksum on %@.\n\nMySQL said:%@",@"an error occurred while performing the checksum on the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:parentWindow modalDelegate:self didEndSelector:NULL @@ -2155,8 +2149,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } // Process result - if([selectedItems count] == 1) { - message = [[[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject] objectForKey:@"Checksum"]; + NSArray *resultStatuses = [theResult getAllRows]; + if ([selectedItems count] == 1) { + message = [[resultStatuses lastObject] objectForKey:@"Checksum"]; [[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Checksum %@",@"checksum %@ message"), what] defaultButton:@"OK" alternateButton:nil @@ -2167,9 +2162,8 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; didEndSelector:NULL contextInfo:NULL]; } else { - NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; if (statusValues) [statusValues release], statusValues = nil; - statusValues = [result retain]; + statusValues = [resultStatuses retain]; NSAlert *alert = [[NSAlert new] autorelease]; [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Checksums of %@",@"Checksums of %@ message"), what]]; [alert setMessageText:NSLocalizedString(@"Table checksum",@"table checksum message")]; @@ -2297,9 +2291,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } // Before displaying the user manager make sure the current user has access to the mysql.user table. - MCPResult *result = [mySQLConnection queryString:@"SELECT * FROM `mysql`.`user` ORDER BY `user`"]; + SPMySQLResult *result = [mySQLConnection queryString:@"SELECT * FROM `mysql`.`user` ORDER BY `user`"]; - if ([mySQLConnection queryErrored] && ([result numOfRows] == 0)) { + if ([mySQLConnection queryErrored] && ([result numberOfRows] == 0)) { NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Unable to get list of users", @"unable to get list of users message") defaultButton:NSLocalizedString(@"OK", @"OK button") @@ -2357,7 +2351,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; SPBeginAlertSheet(NSLocalizedString(@"Flushed Privileges", @"title of panel when successfully flushed privs"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Successfully flushed privileges.", @"message of panel when successfully flushed privs")); } else { //error while flushing privileges - SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"), [mySQLConnection getLastErrorMessage]]); + SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"), [mySQLConnection lastErrorMessage]]); } } @@ -5088,7 +5082,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } // Get create syntax - MCPResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", + SPMySQLResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", itemTypeStr, [item backtickQuotedString] ]]; @@ -5096,15 +5090,15 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if (changeEncoding) [mySQLConnection restoreStoredEncoding]; - if ( ![queryResult numOfRows] ) { + if ( ![queryResult numberOfRows] ) { //error while getting table structure SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection lastErrorMessage]]); status = @"1"; } else { - NSString *syntaxString = [[queryResult fetchRowAsArray] objectAtIndex:queryCol]; + NSString *syntaxString = [[queryResult getRowAsArray] objectAtIndex:queryCol]; // A NULL value indicates that the user does not have permission to view the syntax if ([syntaxString isNSNull]) { @@ -5179,21 +5173,21 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; SPFileHandle *fh = [SPFileHandle fileHandleForWritingAtPath:resultFileName]; if(!fh) NSLog(@"Couldn't create file handle to %@", resultFileName); - MCPStreamingResult *theResult = [mySQLConnection streamingQueryString:query]; + SPMySQLResult *theResult = [mySQLConnection streamingQueryString:query]; [theResult setReturnDataAsStrings:YES]; if ([mySQLConnection queryErrored]) { - [fh writeData:[[NSString stringWithFormat:@"MySQL said: %@", [mySQLConnection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; + [fh writeData:[[NSString stringWithFormat:@"MySQL said: %@", [mySQLConnection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; status = @"1"; } else { // write header if(writeAsCsv) - [fh writeData:[[[theResult fetchFieldNames] componentsJoinedAsCSV] dataUsingEncoding:NSUTF8StringEncoding]]; + [fh writeData:[[[theResult fieldNames] componentsJoinedAsCSV] dataUsingEncoding:NSUTF8StringEncoding]]; else - [fh writeData:[[[theResult fetchFieldNames] componentsJoinedByString:@"\t"] dataUsingEncoding:NSUTF8StringEncoding]]; + [fh writeData:[[[theResult fieldNames] componentsJoinedByString:@"\t"] dataUsingEncoding:NSUTF8StringEncoding]]; [fh writeData:[[NSString stringWithString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding]]; - NSArray *columnDefinition = [theResult fetchResultFieldsStructure]; + NSArray *columnDefinition = [theResult fieldDefinitions]; // Write table meta data NSMutableString *tableMetaData = [NSMutableString string]; @@ -5221,10 +5215,10 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; NSUInteger i, j; NSArray *theRow; NSMutableString *result = [NSMutableString string]; - if(writeAsCsv) { - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { + if (writeAsCsv) { + for ( i = 0 ; i < [theResult numberOfRows] ; i++ ) { [result setString:@""]; - theRow = [theResult fetchNextRowAsArray]; + theRow = [theResult getRowAsArray]; for( j = 0 ; j < [theRow count] ; j++ ) { NSEvent* event = [NSApp currentEvent]; @@ -5238,9 +5232,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([result length]) [result appendString:@","]; id cell = NSArrayObjectAtIndex(theRow, j); - if([cell isKindOfClass:[NSNull class]]) + if([cell isNSNull]) [result appendString:@"\"NULL\""]; - else if([cell isKindOfClass:[MCPGeometryData class]]) + else if([cell isKindOfClass:[SPMySQLGeometryData class]]) [result appendFormat:@"\"%@\"", [cell wktString]]; else if([cell isKindOfClass:[NSData class]]) { NSString *displayString = [[NSString alloc] initWithData:cell encoding:[mySQLConnection stringEncoding]]; @@ -5261,9 +5255,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; } } else { - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { + for ( i = 0 ; i < [theResult numberOfRows] ; i++ ) { [result setString:@""]; - theRow = [theResult fetchNextRowAsArray]; + theRow = [theResult getRowAsArray]; for( j = 0 ; j < [theRow count] ; j++ ) { NSEvent* event = [NSApp currentEvent]; @@ -5277,9 +5271,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if([result length]) [result appendString:@"\t"]; id cell = NSArrayObjectAtIndex(theRow, j); - if([cell isKindOfClass:[NSNull class]]) + if([cell isNSNull]) [result appendString:@"NULL"]; - else if([cell isKindOfClass:[MCPGeometryData class]]) + else if([cell isKindOfClass:[SPMySQLGeometryData class]]) [result appendFormat:@"%@", [cell wktString]]; else if([cell isKindOfClass:[NSData class]]) { NSString *displayString = [[NSString alloc] initWithData:cell encoding:[mySQLConnection stringEncoding]]; @@ -5817,13 +5811,13 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; if ([mySQLConnection queryErrored]) { // An error occurred - SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection getLastErrorMessage]]); + SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection lastErrorMessage]]); return; } // Error while selecting the new database (is this even possible?) - if (![mySQLConnection selectDB:[databaseNameField stringValue]] ) { + if (![mySQLConnection selectDatabase:[databaseNameField stringValue]] ) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), [databaseNameField stringValue]]); [self setDatabases:self]; @@ -5871,7 +5865,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; [self performSelector:@selector(showErrorSheetWith:) withObject:[NSArray arrayWithObjects:NSLocalizedString(@"Error", @"error"), [NSString stringWithFormat:NSLocalizedString(@"Couldn't delete the database.\nMySQL said: %@", @"message of panel when deleting db failed"), - [mySQLConnection getLastErrorMessage]], + [mySQLConnection lastErrorMessage]], nil] afterDelay:0.3]; @@ -5882,6 +5876,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; // do to threading we have to delete it from 'allDatabases' directly // before calling navigator [allDatabases removeObject:[self database]]; + // This only deletes the db and refreshes the navigator since nothing is changed // that's why we can run this on main thread [mySQLConnection queryDbStructureWithUserInfo:nil]; @@ -5935,7 +5930,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax"; // Attempt to select the specified database, and abort on failure #ifndef SP_REFACTOR /* patch */ if ([chooseDatabaseButton indexOfItemWithTitle:targetDatabaseName] == NSNotFound - || ![mySQLConnection selectDB:targetDatabaseName]) + || ![mySQLConnection selectDatabase:targetDatabaseName]) #else if ( ![mySQLConnection selectDB:targetDatabaseName] ) #endif diff --git a/Source/SPDatabaseInfo.m b/Source/SPDatabaseInfo.m index 3c70aec9..fc487718 100644 --- a/Source/SPDatabaseInfo.m +++ b/Source/SPDatabaseInfo.m @@ -24,6 +24,7 @@ #import "SPDBActionCommons.h" #import "SPDatabaseInfo.h" +#import "SPMySQL.h" @implementation SPDatabaseInfo @@ -36,40 +37,12 @@ - (NSArray *)listDBs { - return [self listDBsLike:nil]; + return [connection databases]; } - (NSArray *)listDBsLike:(NSString *)dbsName { - NSString *listDBStatement = nil; - - if ((dbsName == nil) || ([dbsName isEqualToString:@""])) { - listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES"]; - } - else { - listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES LIKE %@", [dbsName backtickQuotedString]]; - } - - MCPResult *theResult = [connection queryString:listDBStatement]; - - if ([connection queryErrored]) return NO; - - NSMutableArray *names = [NSMutableArray array]; - NSMutableString *name; - - if ([theResult numOfRows] > 1) { - - NSUInteger i; - - for (i = 0 ; i < [theResult numOfRows]; i++) - { - name = [[theResult fetchRowAsArray] objectAtIndex:0]; - - [names addObject:name]; - } - } - - return names; + return [connection databasesLike:dbsName]; } @end diff --git a/Source/SPDatabaseRename.m b/Source/SPDatabaseRename.m index b7aa3f73..1877e955 100644 --- a/Source/SPDatabaseRename.m +++ b/Source/SPDatabaseRename.m @@ -26,6 +26,7 @@ #import "SPDatabaseRename.h" #import "SPTableCopy.h" #import "SPDatabaseInfo.h" +#import "SPMySQL.h" @implementation SPDatabaseRename @@ -59,7 +60,7 @@ if (sourceExists && !targetExists) { // Retrieve the list of tables/views/funcs/triggers from the source database - tables = [connection listTablesFromDB:sourceDatabaseName]; + tables = [connection tablesFromDatabase:sourceDatabaseName]; } else { return NO; @@ -78,7 +79,7 @@ [dbActionTableCopy release]; - tables = [connection listTablesFromDB:sourceDatabaseName]; + tables = [connection tablesFromDatabase:sourceDatabaseName]; if ([tables count] == 0) { [self dropDatabase:sourceDatabaseName]; diff --git a/Source/SPDatabaseViewController.m b/Source/SPDatabaseViewController.m index 19716a22..41e95a38 100644 --- a/Source/SPDatabaseViewController.m +++ b/Source/SPDatabaseViewController.m @@ -32,6 +32,7 @@ #import "SPTableData.h" #import "SPTablesList.h" #import "SPTableTriggers.h" +#import "SPMySQL.h" #ifdef SP_REFACTOR /* headers */ #import "SPTableStructure.h" #endif diff --git a/Source/SPEditorPreferencePane.m b/Source/SPEditorPreferencePane.m index f2802180..3c948e74 100644 --- a/Source/SPEditorPreferencePane.m +++ b/Source/SPEditorPreferencePane.m @@ -281,14 +281,14 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined"; [[NSColorPanel sharedColorPanel] close]; [prefs setObject:SPDefaultColorSchemeName forKey:SPCustomQueryEditorThemeName]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000 green:0.455 blue:0.000 alpha:1.000]] forKey:SPCustomQueryEditorCommentColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.769 green:0.102 blue:0.086 alpha:1.000]] forKey:SPCustomQueryEditorQuoteColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.200 green:0.250 blue:1.000 alpha:1.000]] forKey:SPCustomQueryEditorSQLKeywordColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000 green:0.000 blue:0.658 alpha:1.000]] forKey:SPCustomQueryEditorBacktickColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.506 green:0.263 blue:0.000 alpha:1.000]] forKey:SPCustomQueryEditorNumericColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.500 green:0.500 blue:0.500 alpha:1.000]] forKey:SPCustomQueryEditorVariableColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.950 green:0.950 blue:0.950 alpha:1.000]] forKey:SPCustomQueryEditorHighlightQueryColor]; - [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.7098 green:0.8352 blue:1.000 alpha:1.000]] forKey:SPCustomQueryEditorSelectionColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000f green:0.455f blue:0.000f alpha:1.000f]] forKey:SPCustomQueryEditorCommentColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.769f green:0.102f blue:0.086f alpha:1.000f]] forKey:SPCustomQueryEditorQuoteColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.200f green:0.250f blue:1.000f alpha:1.000f]] forKey:SPCustomQueryEditorSQLKeywordColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000f green:0.000f blue:0.658f alpha:1.000f]] forKey:SPCustomQueryEditorBacktickColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.506f green:0.263f blue:0.000f alpha:1.000f]] forKey:SPCustomQueryEditorNumericColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.500f green:0.500f blue:0.500f alpha:1.000f]] forKey:SPCustomQueryEditorVariableColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.950f green:0.950f blue:0.950f alpha:1.000f]] forKey:SPCustomQueryEditorHighlightQueryColor]; + [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.7098f green:0.8352f blue:1.000f alpha:1.000f]] forKey:SPCustomQueryEditorSelectionColor]; [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor blackColor]] forKey:SPCustomQueryEditorTextColor]; [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor blackColor]] forKey:SPCustomQueryEditorCaretColor]; [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor whiteColor]] forKey:SPCustomQueryEditorBackgroundColor]; diff --git a/Source/SPExportController.h b/Source/SPExportController.h index 7a4fcb3c..9c084334 100644 --- a/Source/SPExportController.h +++ b/Source/SPExportController.h @@ -23,7 +23,7 @@ // // More info at -@class MCPConnection, BWAnchoredButtonBar; +@class SPMySQLConnection, BWAnchoredButtonBar; /** * @class SPExportController SPExportController.h @@ -162,7 +162,7 @@ /** * Database connection */ - MCPConnection *connection; + SPMySQLConnection *connection; /** * Concurrent operation queue @@ -238,7 +238,7 @@ /** * @property connection Database connection */ -@property(readwrite, assign) MCPConnection *connection; +@property(readwrite, assign) SPMySQLConnection *connection; - (void)exportTables:(NSArray *)table asFormat:(SPExportType)format usingSource:(SPExportSource)source; - (void)openExportErrorsSheetWithString:(NSString *)errors; @@ -258,10 +258,10 @@ - (IBAction)exportCustomQueryResultAsFormat:(id)sender; - (IBAction)toggleXMLOutputFormat:(id)sender; -- (IBAction)toggleSQLIncludeStructure:(id)sender; -- (IBAction)toggleSQLIncludeContent:(id)sender; -- (IBAction)toggleSQLIncludeDropSyntax:(id)sender; -- (IBAction)toggleNewFilePerTable:(id)sender; +- (IBAction)toggleSQLIncludeStructure:(NSButton *)sender; +- (IBAction)toggleSQLIncludeContent:(NSButton *)sender; +- (IBAction)toggleSQLIncludeDropSyntax:(NSButton *)sender; +- (IBAction)toggleNewFilePerTable:(NSButton *)sender; - (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; diff --git a/Source/SPExportController.m b/Source/SPExportController.m index 5b61d178..95076ef2 100644 --- a/Source/SPExportController.m +++ b/Source/SPExportController.m @@ -23,8 +23,6 @@ // // More info at -#import - #import "SPExportController.h" #import "SPExportInitializer.h" #import "SPTablesList.h" @@ -36,6 +34,7 @@ #import "SPExportFilenameUtilities.h" #import "SPExportFileNameTokenObject.h" #import "SPDatabaseDocument.h" +#import "SPMySQL.h" // Constants static const NSUInteger SPExportUIPadding = 20; @@ -574,7 +573,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled"; /** * Toggles the export button when choosing to include or table structures in an SQL export. */ -- (IBAction)toggleSQLIncludeStructure:(id)sender +- (IBAction)toggleSQLIncludeStructure:(NSButton *)sender { if (![sender state]) { @@ -593,7 +592,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled"; /** * Toggles the export button when choosing to include or exclude table contents in an SQL export. */ -- (IBAction)toggleSQLIncludeContent:(id)sender +- (IBAction)toggleSQLIncludeContent:(NSButton *)sender { [[exportTableList tableColumnWithIdentifier:SPTableViewContentColumnID] setHidden:(![sender state])]; @@ -603,7 +602,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled"; /** * Toggles the export button when choosing to include or exclude table drop syntax in an SQL export. */ -- (IBAction)toggleSQLIncludeDropSyntax:(id)sender +- (IBAction)toggleSQLIncludeDropSyntax:(NSButton *)sender { [[exportTableList tableColumnWithIdentifier:SPTableViewDropColumnID] setHidden:(![sender state])]; @@ -613,7 +612,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled"; /** * Toggles whether XML and CSV files should be combined into a single file. */ -- (IBAction)toggleNewFilePerTable:(id)sender +- (IBAction)toggleNewFilePerTable:(NSButton *)sender { [self _updateExportFormatInformation]; } @@ -795,12 +794,12 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled"; // to set the export's link case sensitivity setting if (isDot && serverLowerCaseTableNameValue == NSNotFound) { - MCPResult *caseResult = [connection queryString:@"SHOW VARIABLES LIKE 'lower_case_table_names'"]; + SPMySQLResult *caseResult = [connection queryString:@"SHOW VARIABLES LIKE 'lower_case_table_names'"]; [caseResult setReturnDataAsStrings:YES]; - if ([caseResult numOfRows] == 1) { - serverLowerCaseTableNameValue = [[[caseResult fetchRowAsDictionary] objectForKey:@"Value"] integerValue]; + if ([caseResult numberOfRows] == 1) { + serverLowerCaseTableNameValue = [[[caseResult getRowAsDictionary] objectForKey:@"Value"] integerValue]; } else { serverLowerCaseTableNameValue = 0; diff --git a/Source/SPExportFileUtilities.m b/Source/SPExportFileUtilities.m index b5f30470..986c1a23 100644 --- a/Source/SPExportFileUtilities.m +++ b/Source/SPExportFileUtilities.m @@ -29,6 +29,7 @@ #import "SPExportFile.h" #import "SPDatabaseDocument.h" #import "SPCustomQuery.h" +#import "SPMySQL.h" typedef enum { diff --git a/Source/SPExportInitializer.m b/Source/SPExportInitializer.m index 15ab192d..b2f250c4 100644 --- a/Source/SPExportInitializer.m +++ b/Source/SPExportInitializer.m @@ -23,8 +23,6 @@ // // More info at -#import - #import "SPExportInitializer.h" #import "SPTableData.h" #import "SPDatabaseDocument.h" @@ -44,6 +42,7 @@ #import "SPExportFileUtilities.h" #import "SPExportFilenameUtilities.h" #import "SPExportFileNameTokenObject.h" +#import "SPMySQL.h" @implementation SPExportController (SPExportInitializer) diff --git a/Source/SPExporter.h b/Source/SPExporter.h index abc880a0..e58c8d65 100644 --- a/Source/SPExporter.h +++ b/Source/SPExporter.h @@ -48,11 +48,11 @@ * explicity called. */ -@class MCPConnection, SPExportFile; +@class SPMySQLConnection, SPExportFile; @interface SPExporter : NSOperation { - MCPConnection *connection; + SPMySQLConnection *connection; double exportProgressValue; double exportMaxProgress; @@ -74,7 +74,7 @@ /** * @property connection The MySQL connection to use */ -@property(readwrite, retain) MCPConnection *connection; +@property(readwrite, retain) SPMySQLConnection *connection; /** * @property exportProgressValue The export's current progress value diff --git a/Source/SPExtendedTableInfo.h b/Source/SPExtendedTableInfo.h index 962eed6a..dfe6a9e0 100644 --- a/Source/SPExtendedTableInfo.h +++ b/Source/SPExtendedTableInfo.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPTableData, SPDatabaseData, SPTablesList; +@class SPTableData, SPDatabaseData, SPTablesList, SPMySQLConnection; @interface SPExtendedTableInfo : NSObject { @@ -57,10 +55,10 @@ NSString *selectedTable; - MCPConnection *connection; + SPMySQLConnection *connection; } -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; // IBAction methods - (IBAction)reloadTable:(id)sender; diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m index a1e59110..d2afe969 100644 --- a/Source/SPExtendedTableInfo.m +++ b/Source/SPExtendedTableInfo.m @@ -33,6 +33,7 @@ #import "SPAlertSheets.h" #import "SPTableStructure.h" #import "SPServerSupport.h" +#import "SPMySQL.h" @interface SPExtendedTableInfo (PrivateAPI) @@ -102,7 +103,8 @@ // Alter table's storage type [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ %@ = %@", [selectedTable backtickQuotedString], [[tableDocumentInstance serverSupport] engineTypeQueryName], newType]]; - if ([connection getLastErrorID] == 0) { + if (![connection queryErrored]) { + // Reload the table's data [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]]; } @@ -111,7 +113,7 @@ 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]]); + [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]]); } } @@ -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]]); } } @@ -373,7 +375,7 @@ [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]; } } @@ -429,7 +431,7 @@ 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]) @@ -468,16 +470,16 @@ 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]]); } } } @@ -559,7 +561,7 @@ { NSString *value = [infoDict objectForKey:key]; - if ([value isKindOfClass:[NSNull class]]) { + if ([value isNSNull]) { value = @""; } else { diff --git a/Source/SPFavoritesController.m b/Source/SPFavoritesController.m index 2c48823d..222dd119 100644 --- a/Source/SPFavoritesController.m +++ b/Source/SPFavoritesController.m @@ -44,7 +44,8 @@ static SPFavoritesController *sharedFavoritesController = nil; { @synchronized(self) { return [[self sharedFavoritesController] retain]; - } + } + return nil; } - (id)init diff --git a/Source/SPFieldEditorController.h b/Source/SPFieldEditorController.h index 29d4c445..4e978646 100644 --- a/Source/SPFieldEditorController.h +++ b/Source/SPFieldEditorController.h @@ -22,7 +22,6 @@ // // More info at -#import /** * @class SPFieldEditorController SPFieldEditorController.h diff --git a/Source/SPFieldEditorController.m b/Source/SPFieldEditorController.m index 2df24c24..549c994e 100644 --- a/Source/SPFieldEditorController.m +++ b/Source/SPFieldEditorController.m @@ -35,6 +35,7 @@ #include #import "SPCustomQuery.h" #import "SPTableContent.h" +#import "SPMySQLGeometryData.h" @interface SPFieldEditorController (SPFieldEditorControllerDelegate) @@ -351,7 +352,7 @@ [editTextView setHidden:YES]; [editTextScrollView setHidden:YES]; [editSheetSegmentControl setSelectedSegment:2]; - } else if ([sheetEditData isKindOfClass:[MCPGeometryData class]]) { + } else if ([sheetEditData isKindOfClass:[SPMySQLGeometryData class]]) { SPGeometryDataView *v = [[[SPGeometryDataView alloc] initWithCoordinates:[sheetEditData coordinates] targetDimension:2000.0f] autorelease]; image = [v thumbnailImage]; stringValue = [[sheetEditData wktString] retain]; @@ -547,7 +548,7 @@ NSSavePanel *panel = [NSSavePanel savePanel]; NSString *fileDefault = @""; - if([editSheetSegmentControl selectedSegment] == 1 && [sheetEditData isKindOfClass:[MCPGeometryData class]]) { + if([editSheetSegmentControl selectedSegment] == 1 && [sheetEditData isKindOfClass:[SPMySQLGeometryData class]]) { [panel setAllowedFileTypes:[NSArray arrayWithObject:@"pdf"]]; [panel setAllowsOtherFileTypes:NO]; } else { @@ -716,7 +717,7 @@ [sheetEditData writeToURL:fileURL atomically:YES]; } - else if ( [sheetEditData isKindOfClass:[MCPGeometryData class]] ) { + else if ( [sheetEditData isKindOfClass:[SPMySQLGeometryData class]] ) { if ( [editSheetSegmentControl selectedSegment] == 0 || editImage == nil ) { diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h index 860eef81..6fb31b8e 100644 --- a/Source/SPFieldMapperController.h +++ b/Source/SPFieldMapperController.h @@ -22,14 +22,11 @@ // // More info at -#import +@class SPTextView, SPTableView, SPTablesList, SPMySQLConnection; -@class SPTextView, SPTableView, SPTablesList; - -#ifndef SP_REFACTOR @interface SPFieldMapperController : NSWindowController -#else -@interface SPFieldMapperController : NSWindowController +#ifdef SP_REFACTOR + #endif { IBOutlet SPTableView *fieldMapperTableView; @@ -41,8 +38,8 @@ IBOutlet id rowUpButton; IBOutlet id rowDownButton; IBOutlet id recordCountLabel; - IBOutlet id importFieldNamesHeaderSwitch; - IBOutlet id addRemainingDataSwitch; + IBOutlet NSButton *importFieldNamesHeaderSwitch; + IBOutlet NSButton *addRemainingDataSwitch; IBOutlet id importButton; IBOutlet id advancedBox; IBOutlet NSPopUpButton *alignByPopup; @@ -65,20 +62,20 @@ IBOutlet NSButton *addGlobalValueButton; IBOutlet NSButton *removeGlobalValueButton; IBOutlet NSButton *insertNULLValueButton; - IBOutlet id replaceAfterSavingCheckBox; + IBOutlet NSButton *replaceAfterSavingCheckBox; IBOutlet NSPopUpButton *insertPullDownButton; IBOutlet NSMenu *recentGlobalValueMenu; - IBOutlet id ignoreCheckBox; - IBOutlet id ignoreUpdateCheckBox; - IBOutlet id delayedCheckBox; - IBOutlet id delayedReplaceCheckBox; - IBOutlet id onupdateCheckBox; - IBOutlet id lowPriorityCheckBox; - IBOutlet id lowPriorityReplaceCheckBox; - IBOutlet id lowPriorityUpdateCheckBox; - IBOutlet id highPriorityCheckBox; - IBOutlet id skipexistingRowsCheckBox; + IBOutlet NSButton *ignoreCheckBox; + IBOutlet NSButton *ignoreUpdateCheckBox; + IBOutlet NSButton *delayedCheckBox; + IBOutlet NSButton *delayedReplaceCheckBox; + IBOutlet NSButton *onupdateCheckBox; + IBOutlet NSButton *lowPriorityCheckBox; + IBOutlet NSButton *lowPriorityReplaceCheckBox; + IBOutlet NSButton *lowPriorityUpdateCheckBox; + IBOutlet NSButton *highPriorityCheckBox; + IBOutlet NSButton *skipexistingRowsCheckBox; IBOutlet SPTextView *onupdateTextView; IBOutlet id gobackButton; @@ -131,7 +128,7 @@ NSString *primaryKeyField; NSNumber *lastDisabledCSVFieldcolumn; - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; NSString *sourcePath; @@ -146,7 +143,7 @@ - (id)initWithDelegate:(id)managerDelegate; -- (void)setConnection:(MCPConnection *)theConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; - (void)setImportDataArray:(id)theFieldMappingImportArray hasHeader:(BOOL)hasHeader isPreview:(BOOL)isPreview; // Getter methods diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m index 6a558321..b406f134 100644 --- a/Source/SPFieldMapperController.m +++ b/Source/SPFieldMapperController.m @@ -31,6 +31,7 @@ #import "SPCategoryAdditions.h" #import "RegexKitLite.h" #import "SPDatabaseData.h" +#import "SPMySQL.h" #define SP_NUMBER_OF_RECORDS_STRING NSLocalizedString(@"%ld of %@%lu records", @"Label showing the index of the selected CSV row") @@ -231,7 +232,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; #pragma mark - #pragma mark Setter methods -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; [mySQLConnection retain]; @@ -422,7 +423,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; defaultButton:NSLocalizedString(@"OK", @"OK button") alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new column '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new column informative message"), [fieldMappingTableColumnNames objectAtIndex:currentIndex], createString, [mySQLConnection getLastErrorMessage]]]; + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new column '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new column informative message"), [fieldMappingTableColumnNames objectAtIndex:currentIndex], createString, [mySQLConnection lastErrorMessage]]]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil]; @@ -472,7 +473,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; defaultButton:NSLocalizedString(@"OK", @"OK button") alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection getLastErrorMessage]]]; + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection lastErrorMessage]]]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil]; @@ -1189,7 +1190,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; [globalValuesSheet makeFirstResponder:globalValuesTableView]; // Replace the current map pair with the last selected global value - if([replaceAfterSavingCheckBox state] == NSOnState && [globalValuesTableView numberOfSelectedRows] == 1) { + if ([replaceAfterSavingCheckBox state] == NSOnState && [globalValuesTableView numberOfSelectedRows] == 1) { [fieldMappingArray replaceObjectAtIndex:[fieldMapperTableView selectedRow] withObject:[NSNumber numberWithInteger:[globalValuesTableView selectedRow]+numberOfImportColumns]]; @@ -1405,7 +1406,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; CGFloat dist = 1e6f; for(j=0; j < [fileHeaderNames count]; j++) { id fileHeaderName = NSArrayObjectAtIndex(fileHeaderNames,j); - if([fileHeaderName isKindOfClass:[NSNull class]] || [fileHeaderName isSPNotLoaded]) continue; + if([fileHeaderName isNSNull] || [fileHeaderName isSPNotLoaded]) continue; NSString *headerName = [(NSString*)fileHeaderName lowercaseString]; NSString *tableHeadName = [NSArrayObjectAtIndex(tableHeaderNames,i) lowercaseString]; dist = [tableHeadName levenshteinDistanceWithWord:headerName]; @@ -1484,7 +1485,7 @@ static NSString *SPTableViewSqlColumnID = @"sql"; fieldMappingArray = [[NSMutableArray alloc] init]; for (i = 0; i < [fieldMappingTableColumnNames count]; i++) { if (i < [NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow) count] - && ![NSArrayObjectAtIndex(NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow), i) isKindOfClass:[NSNull class]]) { + && NSArrayObjectAtIndex(NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow), i) != [NSNull null]) { value = i; } else { value = 0; diff --git a/Source/SPGeometryDataView.m b/Source/SPGeometryDataView.m index d68bb57b..3150bc19 100644 --- a/Source/SPGeometryDataView.m +++ b/Source/SPGeometryDataView.m @@ -43,7 +43,7 @@ */ - (id)initWithCoordinates:(NSDictionary*)coord { - return [self initWithCoordinates:coord targetDimension:400.0]; + return [self initWithCoordinates:coord targetDimension:400.0f]; } /** @@ -56,7 +56,7 @@ - (id)initWithCoordinates:(NSDictionary*)coord targetDimension:(CGFloat)targetDimension { - margin_offset = 10.0; + margin_offset = 10.0f; type = [coord objectForKey:@"type"]; coordinates = [coord objectForKey:@"coordinates"]; @@ -72,7 +72,7 @@ if(maxDim != 0) zoom_factor = targetDimension/maxDim; else - zoom_factor = 1.0; + zoom_factor = 1.0f; width*=zoom_factor; height*=zoom_factor; @@ -85,14 +85,14 @@ lineColor = [NSColor blackColor]; borderLineColor = [NSColor grayColor]; - backgroundColor = [NSColor colorWithCalibratedRed:1 green:1 blue:1 alpha:0.96]; + backgroundColor = [NSColor colorWithCalibratedRed:1 green:1 blue:1 alpha:0.96f]; pointFillColor = [NSColor redColor]; pointStrokeColor = [NSColor grayColor]; - polygonFillColor1 = [NSColor colorWithCalibratedRed:0.0 green:1.0 blue:0.0 alpha:0.1]; - polygonFillColor2 = [NSColor colorWithCalibratedRed:0.0 green:1.0 blue:1.0 alpha:0.1]; - polygonFillColor3 = [NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.1]; + polygonFillColor1 = [NSColor colorWithCalibratedRed:0.0f green:1.0f blue:0.0f alpha:0.1f]; + polygonFillColor2 = [NSColor colorWithCalibratedRed:0.0f green:1.0f blue:1.0f alpha:0.1f]; + polygonFillColor3 = [NSColor colorWithCalibratedRed:1.0f green:0.0f blue:0.0f alpha:0.1f]; - lineWidth = 1.0; + lineWidth = 1.0f; return self; } @@ -109,7 +109,7 @@ // Draw a rect as border path = [NSBezierPath bezierPathWithRect:[self bounds]]; - [path setLineWidth:0.1]; + [path setLineWidth:0.1f]; [backgroundColor set]; [path fill]; [borderLineColor set]; diff --git a/Source/SPIndexesController.h b/Source/SPIndexesController.h index 7fae2082..e014a4a7 100644 --- a/Source/SPIndexesController.h +++ b/Source/SPIndexesController.h @@ -24,9 +24,9 @@ // More info at #ifndef SP_REFACTOR -@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, MCPConnection, BWAnchoredButtonBar, SPTableView; +@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, SPMySQLConnection, BWAnchoredButtonBar, SPTableView; #else -@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, MCPConnection, SPTableView; +@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, SPMySQLConnection, SPTableView; #endif @interface SPIndexesController : NSWindowController @@ -77,7 +77,7 @@ NSUserDefaults *prefs; #endif - MCPConnection *connection; + SPMySQLConnection *connection; #ifndef SP_REFACTOR /* ivars */ BOOL showAdvancedView; @@ -105,7 +105,7 @@ /** * @property connection The MySQL connection to use */ -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; - (IBAction)addIndex:(id)sender; - (IBAction)removeIndex:(id)sender; diff --git a/Source/SPIndexesController.m b/Source/SPIndexesController.m index 26e4b196..99d359f7 100644 --- a/Source/SPIndexesController.m +++ b/Source/SPIndexesController.m @@ -28,7 +28,7 @@ #import "SPServerSupport.h" #import "SPTableContent.h" #import "SPTableData.h" -#import +#import "SPMySQL.h" #import "SPDatabaseDocument.h" #import "SPTablesList.h" #import "SPTableView.h" @@ -862,9 +862,9 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [tempIndexedColumns release]; // Check for errors, but only if the query wasn't cancelled - if ([connection queryErrored] && ![connection queryCancelled]) { + if ([connection queryErrored] && ![connection lastQueryWasCancelled]) { SPBeginAlertSheet(NSLocalizedString(@"Unable to add index", @"add index error message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [dbDocument parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection lastErrorMessage]]); } else { [tableData resetAllData]; @@ -918,11 +918,11 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [table backtickQuotedString], [constraintName backtickQuotedString]]]; // Check for errors, but only if the query wasn't cancelled - if ([connection queryErrored] && ![connection queryCancelled]) { + if ([connection queryErrored] && ![connection lastQueryWasCancelled]) { NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary]; [errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"]; - [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), constraintName, [connection getLastErrorMessage]] forKey:@"message"]; + [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), constraintName, [connection lastErrorMessage]] forKey:@"message"]; [(SPTableStructure*)[tableStructure onMainThread] showErrorSheetWith:errorDictionary]; } @@ -937,11 +937,11 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize"; } // Check for errors, but only if the query wasn't cancelled - if ([connection queryErrored] && ![connection queryCancelled]) { + if ([connection queryErrored] && ![connection lastQueryWasCancelled]) { NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary]; [errorDictionary setObject:NSLocalizedString(@"Unable to delete index", @"error deleting index message") forKey:@"title"]; - [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to delete the index.\n\nMySQL said: %@", @"error deleting index informative message"), [connection getLastErrorMessage]] forKey:@"message"]; + [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to delete the index.\n\nMySQL said: %@", @"error deleting index informative message"), [connection lastErrorMessage]] forKey:@"message"]; [(SPTableStructure*)[tableStructure onMainThread] showErrorSheetWith:errorDictionary]; } diff --git a/Source/SPLogger.m b/Source/SPLogger.m index b1e16bba..40bcaa69 100644 --- a/Source/SPLogger.m +++ b/Source/SPLogger.m @@ -79,6 +79,7 @@ int _isSPLeaksLog(struct direct *entry); @synchronized(self) { return [[self logger] retain]; } + return nil; } - (id)init diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m index 9079954d..abc40a4e 100644 --- a/Source/SPNarrowDownCompletion.m +++ b/Source/SPNarrowDownCompletion.m @@ -316,12 +316,12 @@ if(caretPos.y >= 0 && caretPos.y < [self frame].size.height) { - caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5); + caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5f); isAbove = YES; } if(caretPos.y < 0 && (mainScreen.size.height-[self frame].size.height) < (caretPos.y*-1)) { - caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5); + caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5f); isAbove = YES; } @@ -334,7 +334,7 @@ [self setLevel:NSNormalWindowLevel]; [self setHidesOnDeactivate:YES]; [self setHasShadow:YES]; - [self setAlphaValue:0.9]; + [self setAlphaValue:0.9f]; NSScrollView* scrollView = [[[NSScrollView alloc] initWithFrame:NSZeroRect] autorelease]; [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; @@ -720,10 +720,10 @@ if(caretPos.y >= 0 && (isAbove || caretPos.y < newHeight)) { isAbove = YES; - old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5); + old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5f); } if(caretPos.y < 0 && (isAbove || ([self rectOfMainScreen].size.height-newHeight) < (caretPos.y*-1))) - old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5); + old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5f); // newHeight is currently the new height for theTableView, but we need to resize the whole window // so here we use the difference in height to find the new height for the window @@ -972,7 +972,7 @@ // Restore the text selection location, and clearly mark the autosuggested text [theView setSelectedRange:NSMakeRange(currentSelectionPosition, 0)]; - NSMutableAttributedStringAddAttributeValueRange([theView textStorage], NSForegroundColorAttributeName, [[theView otherTextColor] colorWithAlphaComponent:0.3], NSMakeRange(currentSelectionPosition, [toInsert length])); + NSMutableAttributedStringAddAttributeValueRange([theView textStorage], NSForegroundColorAttributeName, [[theView otherTextColor] colorWithAlphaComponent:0.3f], NSMakeRange(currentSelectionPosition, [toInsert length])); NSMutableAttributedStringAddAttributeValueRange([theView textStorage], kSPAutoCompletePlaceholderName, kSPAutoCompletePlaceholderVal, NSMakeRange(currentSelectionPosition, [toInsert length])); [self checkSpaceForAllowedCharacter]; diff --git a/Source/SPNavigatorController.h b/Source/SPNavigatorController.h index 20b3a796..f294b000 100644 --- a/Source/SPNavigatorController.h +++ b/Source/SPNavigatorController.h @@ -22,12 +22,12 @@ // // More info at -#import +@class SPNavigatorOutlineView; @interface SPNavigatorController : NSWindowController { #ifndef SP_REFACTOR /* ivars */ - IBOutlet id outlineSchema2; + IBOutlet SPNavigatorOutlineView *outlineSchema2; IBOutlet id navigatorWindow; IBOutlet id infoTable; IBOutlet id searchField; @@ -70,6 +70,7 @@ - (IBAction)outlineViewAction:(id)sender; - (IBAction)reloadAllStructures:(id)sender; - (IBAction)filterTree:(id)sender; +- (void)reloadAfterFiltering; - (IBAction)syncButtonAction:(id)sender; - (void)updateEntriesForConnection:(id)object; diff --git a/Source/SPNavigatorController.m b/Source/SPNavigatorController.m index 30b47006..63c3ed51 100644 --- a/Source/SPNavigatorController.m +++ b/Source/SPNavigatorController.m @@ -33,6 +33,7 @@ #import "SPTooltip.h" #import "SPAppController.h" #import "SPDatabaseViewController.h" +#import "SPMySQL.h" #import #endif @@ -68,9 +69,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte @synchronized(self) { return [[self sharedNavigatorController] retain]; } -#ifdef SP_REFACTOR - return nil; // only here to stop clang's "can reach end of non-void function" -#endif + return nil; } - (id)init @@ -117,9 +116,8 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte [functionIcon release]; [fieldIcon release]; #endif -#ifdef SP_REFACTOR /* patch */ + [super dealloc]; -#endif } /** * The following base protocol methods are implemented to ensure the singleton status of this class. @@ -799,7 +797,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte [expandStatus2 removeObjectForKey:[[parentObject allKeysForObject:item] objectAtIndex:0]]; } -- (id)outlineView:(id)outlineView child:(NSInteger)index ofItem:(id)item +- (id)outlineView:(id)outlineView child:(NSInteger)childIndex ofItem:(id)item { if (item == nil) { @@ -822,7 +820,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte // No parent return the child by using the normal sort routine if(!parentObject || ![parentObject isKindOfClass:NSDictionaryClass]) - return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)]; + return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)]; // Get the parent key name for storing id parentKeys = [parentObject allKeysForObject:item]; @@ -832,26 +830,26 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte // For safety reasons if(!itemRef) - return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)]; + return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)]; // Not yet cached so do it if(![cachedSortedKeys objectForKey:itemRef]) [cachedSortedKeys setObject:[allKeys sortedArrayUsingFunction:compareStrings context:nil] forKey:itemRef]; - return [item objectForKey:NSArrayObjectAtIndex([cachedSortedKeys objectForKey:itemRef],index)]; + return [item objectForKey:NSArrayObjectAtIndex([cachedSortedKeys objectForKey:itemRef],childIndex)]; } // If something failed return the child by using the normal way - return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)]; + return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)]; } else { - return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)]; + return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)]; } } else if ([item isKindOfClass:[NSArray class]]) { - return NSArrayObjectAtIndex(item,index); + return NSArrayObjectAtIndex(item,childIndex); } return nil; @@ -1016,9 +1014,9 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte if(!parentObject) return 0; if([outlineView levelForItem:item] == 3 && [outlineView isExpandable:[outlineView itemAtRow:[outlineView rowForItem:item]-1]]) - return 5.0; + return 5.0f; - return 18.0; + return 18.0f; } - (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item @@ -1163,7 +1161,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row { // Use first row as dummy to increase the distance between content and header - return (row == 0) ? 5.0 : 16.0; + return (row == 0) ? 5.0f : 16.0f; } - (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex @@ -1213,11 +1211,11 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte #pragma mark - #pragma mark others -- (NSString*)tableInfoLabelForIndex:(NSInteger)index ofType:(NSInteger)type +- (NSString*)tableInfoLabelForIndex:(NSInteger)anIndex ofType:(NSInteger)type { if(type == 0 || type == 1) // TABLE / VIEW - switch(index) { + switch(anIndex) { case 0: return NSLocalizedString(@"Type", @"type label (Navigator)"); case 1: @@ -1239,7 +1237,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte } if(type == 2) // PROCEDURE - switch(index) { + switch(anIndex) { case 0: return @"DTD Identifier"; case 1: @@ -1252,7 +1250,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte return @"Definer"; } if(type == 3) // FUNCTION - switch(index) { + switch(anIndex) { case 0: return NSLocalizedString(@"Return Type", @"return type label (Navigator)"); case 1: diff --git a/Source/SPNotLoaded.m b/Source/SPNotLoaded.m index 335ccbfa..99a5a1d0 100644 --- a/Source/SPNotLoaded.m +++ b/Source/SPNotLoaded.m @@ -45,9 +45,7 @@ static SPNotLoaded *notLoaded = nil; @synchronized(self) { return [[self notLoaded] retain]; } -#ifdef SP_REFACTOR - return nil; // only here to stop clang's "can reach end of non-void function" -#endif + return nil; } - (id) init diff --git a/Source/SPObjectAdditions.h b/Source/SPObjectAdditions.h new file mode 100644 index 00000000..215354b5 --- /dev/null +++ b/Source/SPObjectAdditions.h @@ -0,0 +1,31 @@ +// +// $Id$ +// +// SPObjectAdditions.h +// sequel-pro +// +// Created by Rowan Beentje (rowan.beent.je) on February 22, 2012 +// Copyright (c) 2012 Rowan Beentje. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +@interface NSObject (SPObjectAdditions) + +// Detect whether an object is a NSNull instance +- (BOOL)isNSNull; + +@end diff --git a/Source/SPObjectAdditions.m b/Source/SPObjectAdditions.m new file mode 100644 index 00000000..de762f59 --- /dev/null +++ b/Source/SPObjectAdditions.m @@ -0,0 +1,40 @@ +// +// $Id$ +// +// SPObjectAdditions.m +// sequel-pro +// +// Created by Rowan Beentje (rowan.beent.je) on February 22, 2012 +// Copyright (c) 2012 Rowan Beentje. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +@implementation NSObject (SPObjectAdditions) + +/** + * Detect whether an object is a NSNull instance + */ +- (BOOL)isNSNull +{ + id const null = [NSNull null]; + + // [NSNull null] is documented as being a singleton class so a pointer equality + // check is possible - and much faster than checking class membership. + return (self == null); +} + +@end diff --git a/Source/SPProcessListController.h b/Source/SPProcessListController.h index df5f48a6..fbbdc906 100644 --- a/Source/SPProcessListController.h +++ b/Source/SPProcessListController.h @@ -23,11 +23,11 @@ // // More info at -#import +@class SPMySQLConnection; @interface SPProcessListController : NSWindowController { - MCPConnection *connection; + SPMySQLConnection *connection; BOOL showFullProcessList, processListThreadRunning; @@ -49,7 +49,7 @@ IBOutlet NSMenuItem *autoRefreshIntervalMenuItem; } -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; - (IBAction)copy:(id)sender; - (IBAction)closeSheet:(id)sender; @@ -57,9 +57,9 @@ - (IBAction)saveServerProcesses:(id)sender; - (IBAction)killProcessQuery:(id)sender; - (IBAction)killProcessConnection:(id)sender; -- (IBAction)toggleShowProcessID:(id)sender; -- (IBAction)toggeleShowFullProcessList:(id)sender; -- (IBAction)toggleProcessListAutoRefresh:(id)sender; +- (IBAction)toggleShowProcessID:(NSMenuItem *)sender; +- (IBAction)toggeleShowFullProcessList:(NSMenuItem *)sender; +- (IBAction)toggleProcessListAutoRefresh:(NSButton *)sender; - (IBAction)setAutoRefreshInterval:(id)sender; - (IBAction)setCustomAutoRefreshInterval:(id)sender; diff --git a/Source/SPProcessListController.m b/Source/SPProcessListController.m index 825b598d..18263bb4 100644 --- a/Source/SPProcessListController.m +++ b/Source/SPProcessListController.m @@ -27,6 +27,7 @@ #import "SPDatabaseDocument.h" #import "SPAlertSheets.h" #import "SPAppController.h" +#import "SPMySQL.h" static const NSString *SPTableViewIDColumnIdentifier = @"Id"; @@ -97,7 +98,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; // Also, if available restore the table's column widths NSNumber *columnWidth = [[prefs objectForKey:SPProcessListTableColumnWidths] objectForKey:[[column headerCell] stringValue]]; - if (columnWidth) [column setWidth:[columnWidth doubleValue]]; + if (columnWidth) [column setWidth:[columnWidth floatValue]]; } // Register as an observer for the when the UseMonospacedFonts preference changes @@ -284,7 +285,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; /** * Toggles the display of the process ID table column. */ -- (IBAction)toggleShowProcessID:(id)sender +- (IBAction)toggleShowProcessID:(NSMenuItem *)sender { [[processListTableView tableColumnWithIdentifier:SPTableViewIDColumnIdentifier] setHidden:([sender state])]; } @@ -292,7 +293,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; /** * Toggles the display of the FULL process list. */ -- (IBAction)toggeleShowFullProcessList:(id)sender +- (IBAction)toggeleShowFullProcessList:(NSMenuItem *)sender { showFullProcessList = (!showFullProcessList); @@ -302,7 +303,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; /** * Toggles whether or not auto refresh is enabled. */ -- (IBAction)toggleProcessListAutoRefresh:(id)sender +- (IBAction)toggleProcessListAutoRefresh:(NSButton *)sender { BOOL enable = [sender state]; @@ -687,18 +688,16 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; // Get processes if ([connection isConnected]) { - MCPResult *processList = (showFullProcessList) ? [connection queryString:@"SHOW FULL PROCESSLIST"] : [connection listProcesses]; + SPMySQLResult *processList = (showFullProcessList) ? [connection queryString:@"SHOW FULL PROCESSLIST"] : [connection listProcesses]; [processList setReturnDataAsStrings:YES]; - - if ([processList numOfRows]) [processList dataSeek:0]; - + [processes removeAllObjects]; - for (i = 0; i < [processList numOfRows]; i++) + for (i = 0; i < [processList numberOfRows]; i++) { - //MCPKit currently returns numbers as NSString, which will break sorting of numbers in this case. - NSMutableDictionary *rowsFixed = [[processList fetchRowAsDictionary] mutableCopy]; + //SPMySQL.framewokr currently returns numbers as NSString, which will break sorting of numbers in this case. + NSMutableDictionary *rowsFixed = [[processList getRowAsDictionary] mutableCopy]; id idColumn = [rowsFixed objectForKey:@"Id"]; //Id is a signed int(11) - this is a signed 32 bit int value @@ -739,7 +738,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; // Check for errors if ([connection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Unable to kill query", @"error killing query message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill the query associated with connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill the query associated with connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection lastErrorMessage]]); } // Refresh the process list @@ -757,7 +756,7 @@ static const NSString *SPTableViewIDColumnIdentifier = @"Id"; // Check for errors if ([connection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Unable to kill connection", @"error killing connection message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection lastErrorMessage]]); } // Refresh the process list diff --git a/Source/SPQueryController.m b/Source/SPQueryController.m index 82a19091..6c425bc7 100644 --- a/Source/SPQueryController.m +++ b/Source/SPQueryController.m @@ -67,9 +67,7 @@ static SPQueryController *sharedQueryController = nil; return [[self sharedQueryController] retain]; } -#ifdef SP_REFACTOR - return nil; // only here to stop clang's 'can reach end of non-void function' -#endif + return nil; } - (id)init diff --git a/Source/SPSQLExporter.m b/Source/SPSQLExporter.m index 66411932..6090b709 100644 --- a/Source/SPSQLExporter.m +++ b/Source/SPSQLExporter.m @@ -23,8 +23,6 @@ // // More info at -#import - #import "SPSQLExporter.h" #import "SPTablesList.h" #import "SPFileHandle.h" @@ -32,6 +30,7 @@ #import "SPExportFile.h" #import "SPTableData.h" #import "RegexKitLite.h" +#import "SPMySQL.h" @interface SPSQLExporter () @@ -88,8 +87,8 @@ sqlTableDataInstance = [[[SPTableData alloc] init] autorelease]; [sqlTableDataInstance setConnection:connection]; - MCPResult *queryResult; - MCPStreamingResult *streamingResult; + SPMySQLResult *queryResult; + SPMySQLStreamingResult *streamingResult; NSArray *row; NSString *tableName; @@ -228,8 +227,8 @@ [queryResult setReturnDataAsStrings:YES]; - if ([queryResult numOfRows]) { - tableDetails = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]]; + if ([queryResult numberOfRows]) { + tableDetails = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]]; if ([tableDetails objectForKey:@"Create View"]) { [viewSyntaxes setValue:[[[[tableDetails objectForKey:@"Create View"] copy] autorelease] createViewSyntaxPrettifier] forKey:tableName]; @@ -245,9 +244,9 @@ } if ([connection queryErrored]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; continue; } @@ -298,11 +297,11 @@ } // Retrieve the number of rows in the table for progress bar drawing - NSArray *rowArray = [[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [tableName backtickQuotedString]]] fetchRowAsArray]; + NSArray *rowArray = [[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [tableName backtickQuotedString]]] getRowAsArray]; if ([connection queryErrored] || ![rowArray count]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; continue; } @@ -314,7 +313,7 @@ // Set up a result set in streaming mode streamingResult = [[connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [tableName backtickQuotedString]] useLowMemoryBlockingStreaming:([self exportUsingLowMemoryBlockingStreaming])] retain]; - NSArray *fieldNames = [streamingResult fetchFieldNames]; + NSArray *fieldNames = [streamingResult fieldNames]; // Inform the delegate that we are about to start writing data for the current table [delegate performSelectorOnMainThread:@selector(sqlExportProcessWillBeginWritingData:) withObject:self waitUntilDone:NO]; @@ -338,7 +337,7 @@ // Inform the delegate that we are about to start writing the data to disk [delegate performSelectorOnMainThread:@selector(sqlExportProcessWillBeginWritingData:) withObject:self waitUntilDone:NO]; - while ((row = [streamingResult fetchNextRowAsArray])) + while ((row = [streamingResult getRowAsArray])) { // Check for cancellation flag if ([self isCancelled]) { @@ -380,7 +379,7 @@ id object = NSArrayObjectAtIndex(row, t); // Add NULL values directly to the output row - if ([object isMemberOfClass:[NSNull class]]) { + if (object == [NSNull null]) { [sqlString appendString:@"NULL"]; } // If the field is off type BIT, the values need a binary prefix of b'x'. @@ -391,7 +390,7 @@ else if ([object isKindOfClass:[NSData class]]) { if ([self sqlOutputEncodeBLOBasHex]) { - [sqlString appendFormat:@"X'%@'", [connection prepareBinaryData:object]]; + [sqlString appendString:[connection escapeAndQuoteData:object]]; } else { [sqlString appendString:@"'"]; @@ -411,8 +410,8 @@ } // GEOMETRY data types directly as hex data - else if ([object isKindOfClass:[MCPGeometryData class]]) { - [sqlString appendFormat:@"X'%@'", [connection prepareBinaryData:[object data]]]; + else if ([object isKindOfClass:[SPMySQLGeometryData class]]) { + [sqlString appendString:[connection escapeAndQuoteData:[object data]]]; } else { [cellValue setString:[object description]]; @@ -427,9 +426,7 @@ } // Otherwise add a quoted string with special characters escaped else { - [sqlString appendString:@"'"]; - [sqlString appendString:[connection prepareString:cellValue]]; - [sqlString appendString:@"'"]; + [sqlString appendString:[connection escapeAndQuoteString:cellValue]]; } } } @@ -488,10 +485,10 @@ } if ([connection queryErrored]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; if ([self sqlOutputIncludeErrors]) { - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; } } @@ -501,12 +498,12 @@ [queryResult setReturnDataAsStrings:YES]; - if ([queryResult numOfRows]) { + if ([queryResult numberOfRows]) { [metaString setString:@"\n"]; [metaString appendString:@"DELIMITER ;;\n"]; - for (s = 0; s < [queryResult numOfRows]; s++) + for (s = 0; s < [queryResult numberOfRows]; s++) { // Check for cancellation flag if ([self isCancelled]) { @@ -516,7 +513,7 @@ return; } - NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]]; + NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]]; // Definer is user@host but we need to escape it to `user`@`host` NSArray *triggersDefiner = [[triggers objectForKey:@"Definer"] componentsSeparatedByString:@"@"]; @@ -541,10 +538,10 @@ } if ([connection queryErrored]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; if ([self sqlOutputIncludeErrors]) { - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; } } @@ -598,7 +595,7 @@ [queryResult setReturnDataAsStrings:YES]; - if ([queryResult numOfRows]) { + if ([queryResult numberOfRows]) { [metaString setString:@"\n"]; [metaString appendFormat:@"--\n-- Dumping routines (%@) for database %@\n--\nDELIMITER ;;\n\n", procedureType, @@ -606,7 +603,7 @@ // Loop through the definitions, exporting if enabled - for (s = 0; s < [queryResult numOfRows]; s++) + for (s = 0; s < [queryResult numberOfRows]; s++) { // Check for cancellation flag if ([self isCancelled]) { @@ -616,7 +613,7 @@ return; } - NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]]; + NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]]; NSString *procedureName = [NSString stringWithFormat:@"%@", [proceduresList objectForKey:@"Name"]]; // Only proceed if the item is in the list of items @@ -668,20 +665,20 @@ [NSArrayObjectAtIndex(procedureDefiner, 1) backtickQuotedString] ]; - MCPResult *createProcedureResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW CREATE %@ %@ */;;", procedureType, + SPMySQLResult *createProcedureResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW CREATE %@ %@ */;;", procedureType, [procedureName backtickQuotedString]]]; [createProcedureResult setReturnDataAsStrings:YES]; if ([connection queryErrored]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; if ([self sqlOutputIncludeErrors]) { - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; } [proceduresList release]; continue; } - NSDictionary *procedureInfo = [[NSDictionary alloc] initWithDictionary:[createProcedureResult fetchRowAsDictionary]]; + NSDictionary *procedureInfo = [[NSDictionary alloc] initWithDictionary:[createProcedureResult getRowAsDictionary]]; [metaString appendFormat:@"/*!50003 SET SESSION SQL_MODE=\"%@\"*/;;\n", [procedureInfo objectForKey:@"sql_mode"]]; @@ -721,10 +718,10 @@ } if ([connection queryErrored]) { - [errors appendFormat:@"%@\n", [connection getLastErrorMessage]]; + [errors appendFormat:@"%@\n", [connection lastErrorMessage]]; if ([self sqlOutputIncludeErrors]) { - [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; + [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]]; } } @@ -813,7 +810,10 @@ for (j = 0; j < [[column objectForKey:@"values"] count]; j++) { - [fieldString appendFormat:@"'%@'%@", [connection prepareString:NSArrayObjectAtIndex([column objectForKey:@"values"], j)], ((j + 1) == [[column objectForKey:@"values"] count]) ? @"" : @","]; + [fieldString appendString:[connection escapeAndQuoteString:NSArrayObjectAtIndex([column objectForKey:@"values"], j)]]; + if ((j + 1) != [[column objectForKey:@"values"] count]) { + [fieldString appendString:@","]; + } } [fieldString appendString:@")"]; @@ -841,7 +841,7 @@ [fieldString appendString:@" DEFAULT CURRENT_TIMESTAMP"]; } else { - [fieldString appendFormat:@" DEFAULT '%@'", [connection prepareString:[column objectForKey:@"default"]]]; + [fieldString appendFormat:@" DEFAULT %@", [connection escapeAndQuoteString:[column objectForKey:@"default"]]]; } } diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h index bf7fd8a4..231a41a6 100644 --- a/Source/SPSSHTunnel.h +++ b/Source/SPSSHTunnel.h @@ -23,9 +23,10 @@ // // More info at -#import +#import "SPMySQLConnectionProxy.h" +#import "SPMySQLConstants.h" -@interface SPSSHTunnel : NSObject +@interface SPSSHTunnel : NSObject { id delegate; @@ -78,7 +79,7 @@ - (BOOL)setPasswordKeychainName:(NSString *)theName account:(NSString *)theAccount; - (BOOL)setPassword:(NSString *)thePassword; - (BOOL)setKeyFilePath:(NSString *)thePath; -- (NSInteger)state; +- (SPMySQLConnectionProxyState)state; - (NSString *)lastError; - (NSString *)debugMessages; - (NSUInteger)localPort; diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index 0c25c181..1d4870b2 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -27,6 +27,7 @@ #import "RegexKitLite.h" #import "SPKeychain.h" #import "SPAlertSheets.h" +#import "SPMySQL.h" #import @@ -81,7 +82,7 @@ requestedPassphrase = nil; task = nil; localPort = 0; - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; requestedResponse = NO; passwordInKeychain = NO; @@ -163,12 +164,12 @@ /* * Get the state of the connection. */ -- (NSInteger)state +- (SPMySQLConnectionProxyState)state { // See if an auth dialog is up if (![answerAvailableLock tryLock]) { - return PROXY_STATE_WAITING_FOR_AUTH; + return SPMySQLProxyWaitingForAuth; } [answerAvailableLock unlock]; @@ -204,7 +205,7 @@ { localPort = 0; - if (connectionState != PROXY_STATE_IDLE) return; + if (connectionState != SPMySQLProxyIdle) return; [debugMessagesLock lock]; [debugMessages removeAllObjects]; [debugMessagesLock unlock]; @@ -218,18 +219,18 @@ */ - (void)launchTask:(id) dummy { - if (connectionState != PROXY_STATE_IDLE || task) return; + if (connectionState != SPMySQLProxyIdle || task) return; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableArray *taskArguments; NSMutableDictionary *taskEnvironment; NSString *authenticationAppPath; - connectionState = PROXY_STATE_CONNECTING; + connectionState = SPMySQLProxyConnecting; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; // Enforce a parent window being present for dialogs if (!parentWindow) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:@"SSH Tunnel started without a parent window. A parent window must be present."]; @@ -279,7 +280,7 @@ // Abort if no local free port could be allocated if (!localPort || (useHostFallback && !localPortFallback)) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"No local port could be allocated for the SSH Tunnel.", @"SSH tunnel could not be created because no local port could be allocated")]; @@ -379,8 +380,8 @@ object:nil]; // If the task closed unexpectedly, alert appropriately - if (connectionState != PROXY_STATE_IDLE) { - connectionState = PROXY_STATE_IDLE; + if (connectionState != SPMySQLProxyIdle) { + connectionState = SPMySQLProxyIdle; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel has unexpectedly closed.", @"SSH tunnel unexpectedly closed")]; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; @@ -400,7 +401,7 @@ */ - (void)disconnect { - if (connectionState == PROXY_STATE_IDLE) return; + if (connectionState == SPMySQLProxyIdle) return; // Before terminating the tunnel, check that it's actually running. This is to accommodate tunnels which // suddenly disappear as a result of network disconnections. @@ -434,17 +435,17 @@ if ([message rangeOfString:@"Entering interactive session."].location != NSNotFound || [message rangeOfString:@"mux_client_request_session: master session id: "].location != NSNotFound) { - connectionState = PROXY_STATE_CONNECTED; + connectionState = SPMySQLProxyConnected; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } if ([message rangeOfString:@"Connection established"].location != NSNotFound) { - connectionState = PROXY_STATE_WAITING_FOR_AUTH; + connectionState = SPMySQLProxyWaitingForAuth; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } if ([message rangeOfString:@"bind: Address already in use"].location != NSNotFound) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; [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' 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")]; @@ -452,26 +453,26 @@ } if ([message rangeOfString:@"closed by remote host." ].location != NSNotFound) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; [task terminate]; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was closed 'by the remote host'. This may indicate a networking issue or a network timeout.", @"SSH tunnel was closed by remote host message")]; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } if ([message rangeOfString:@"Permission denied (" ].location != NSNotFound || [message rangeOfString:@"No more authentication methods to try" ].location != NSNotFound) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; [task terminate]; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel could not authenticate with the remote host. Please check your password and ensure you still have access.", @"SSH tunnel authentication failed message")]; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } if ([message rangeOfString:@"connect failed: Connection refused" ].location != NSNotFound) { - connectionState = PROXY_STATE_FORWARDING_FAILED; + connectionState = SPMySQLProxyForwardingFailed; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was established successfully, but could not forward data to the remote port as the remote port refused the connection.", @"SSH tunnel forwarding port connection refused message")]; } if ([message rangeOfString:@"Operation timed out" ].location != NSNotFound) { - connectionState = PROXY_STATE_IDLE; + connectionState = SPMySQLProxyIdle; [task terminate]; if (lastError) [lastError release]; lastError = [[NSString alloc] initWithFormat:NSLocalizedString(@"The SSH Tunnel was unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).", @"SSH tunnel failed or timed out message"), sshHost, (long)[[[NSUserDefaults standardUserDefaults] objectForKey:SPConnectionTimeoutValue] integerValue]]; @@ -480,7 +481,7 @@ } } - if (connectionState != PROXY_STATE_IDLE) { + if (connectionState != SPMySQLProxyIdle) { [[standardError fileHandleForReading] waitForDataInBackgroundAndNotify]; } @@ -674,7 +675,7 @@ { delegate = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (connectionState != PROXY_STATE_IDLE) [self disconnect]; + if (connectionState != SPMySQLProxyIdle) [self disconnect]; [sshHost release]; [sshLogin release]; [remoteHost release]; diff --git a/Source/SPServerVariablesController.h b/Source/SPServerVariablesController.h index 3e87609a..2f882df5 100644 --- a/Source/SPServerVariablesController.h +++ b/Source/SPServerVariablesController.h @@ -23,11 +23,11 @@ // // More info at -#import +@class SPMySQLConnection; @interface SPServerVariablesController : NSWindowController { - MCPConnection *connection; + SPMySQLConnection *connection; NSMutableArray *variables, *variablesFiltered; @@ -37,7 +37,7 @@ IBOutlet NSSearchField *filterVariablesSearchField; } -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; - (IBAction)copy:(id)sender; - (IBAction)copyServerVariableName:(id)sender; diff --git a/Source/SPServerVariablesController.m b/Source/SPServerVariablesController.m index 5b9114d8..50f03e31 100644 --- a/Source/SPServerVariablesController.m +++ b/Source/SPServerVariablesController.m @@ -26,6 +26,7 @@ #import "SPServerVariablesController.h" #import "SPDatabaseDocument.h" #import "SPAppController.h" +#import "SPMySQL.h" @interface SPServerVariablesController (PrivateAPI) @@ -287,20 +288,13 @@ */ - (void)_getDatabaseServerVariables { - NSUInteger i = 0; // Get processes - MCPResult *serverVariables = [connection queryString:@"SHOW VARIABLES"]; + SPMySQLResult *serverVariables = [connection queryString:@"SHOW VARIABLES"]; [serverVariables setReturnDataAsStrings:YES]; - if ([serverVariables numOfRows]) [serverVariables dataSeek:0]; - [variables removeAllObjects]; - - for (i = 0; i < [serverVariables numOfRows]; i++) - { - [variables addObject:[serverVariables fetchRowAsDictionary]]; - } + [variables addObjectsFromArray:[serverVariables getAllRows]]; } /** diff --git a/Source/SPTableContent.h b/Source/SPTableContent.h index 90cfc40c..a95dbae3 100644 --- a/Source/SPTableContent.h +++ b/Source/SPTableContent.h @@ -25,9 +25,7 @@ // // More info at -#import - -@class SPDatabaseDocument, SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView, SPFieldEditorController; +@class SPDatabaseDocument, SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult; @class SPTableData, SPDatabaseDocument, SPTablesList, SPTableStructure, SPTableList, SPContentFilterManager; @interface SPTableContent : NSObject @@ -55,7 +53,7 @@ IBOutlet id removeButton; IBOutlet id reloadButton; #ifndef SP_REFACTOR - IBOutlet id multipleLineEditingButton; + IBOutlet NSButton *multipleLineEditingButton; IBOutlet id countText; IBOutlet id limitRowsField; IBOutlet id limitRowsButton; @@ -90,7 +88,7 @@ IBOutlet NSPanel *filterTableSetDefaultOperatorSheet; IBOutlet NSComboBox* filterTableSetDefaultOperatorValue; #endif - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; BOOL _mainNibLoaded; BOOL isWorking; @@ -182,7 +180,7 @@ // Pagination - (IBAction) navigatePaginationFromButton:(id)sender; #ifndef SP_REFACTOR -- (IBAction) togglePagination:(id)sender; +- (IBAction) togglePagination:(NSButton *)sender; #endif - (void) setPaginationViewVisibility:(BOOL)makeVisible; - (void) updatePaginationState; @@ -213,11 +211,11 @@ - (void) endDocumentTaskForTab:(NSNotification *)aNotification; // Additional methods -- (void)setConnection:(MCPConnection *)theConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; - (void)clickLinkArrow:(SPTextAndLinkCell *)theArrowCell; - (void)clickLinkArrowTask:(SPTextAndLinkCell *)theArrowCell; - (IBAction)setCompareTypes:(id)sender; -- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount; +- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount; - (BOOL)saveRowToTable; - (void) addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (NSString *)argumentForRow:(NSInteger)row; diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index a1ff0daa..7549a1f1 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -37,6 +37,7 @@ #import "SPQueryController.h" #import "SPQueryDocumentsController.h" #import "SPTextAndLinkCell.h" +#import "SPMySQL.h" #ifndef SP_REFACTOR #import "QLPreviewPanel.h" #endif @@ -53,6 +54,7 @@ #import "SPAppController.h" #import "SPBundleHTMLOutputController.h" #import "SPCustomQuery.h" +#import @interface SPTableContent () @@ -745,7 +747,7 @@ NSMutableString *queryString; NSString *queryStringBeforeLimit = nil; NSString *filterString; - MCPStreamingResult *streamingResult; + SPMySQLFastStreamingResult *streamingResult; NSInteger rowsToLoad = [[tableDataInstance statusValueForKey:@"Rows"] integerValue]; #ifndef SP_REFACTOR @@ -817,7 +819,7 @@ // Ensure the number of columns are unchanged; if the column count has changed, abort the load // and queue a full table reload. BOOL fullTableReloadRequired = NO; - if (streamingResult && [dataColumns count] != [streamingResult numOfFields]) { + if (streamingResult && [dataColumns count] != [streamingResult numberOfFields]) { [tableDocumentInstance disableTaskCancellation]; [mySQLConnection cancelCurrentQuery]; [streamingResult cancelResultLoad]; @@ -831,7 +833,7 @@ if (streamingResult) [streamingResult release]; // If the result is empty, and a late page is selected, reset the page - if (!fullTableReloadRequired && [prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount && ![mySQLConnection queryCancelled]) { + if (!fullTableReloadRequired && [prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount && ![mySQLConnection lastQueryWasCancelled]) { contentPage = 1; previousTableRowsCount = tableRowsCount; queryString = [NSMutableString stringWithFormat:@"%@ LIMIT 0,%ld", queryStringBeforeLimit, (long)[prefs integerForKey:SPLimitResultsValue]]; @@ -843,7 +845,7 @@ } } - if ([mySQLConnection queryCancelled] || [mySQLConnection queryErrored]) + if ([mySQLConnection lastQueryWasCancelled] || [mySQLConnection queryErrored]) isInterruptedLoad = YES; else isInterruptedLoad = NO; @@ -869,7 +871,7 @@ // Retrieve and cache the column definitions for editing views if (cqColumnDefinition) [cqColumnDefinition release]; - cqColumnDefinition = [[streamingResult fetchResultFieldsStructure] retain]; + cqColumnDefinition = [[streamingResult fieldDefinitions] retain]; // Notify listenters that the query has finished @@ -879,16 +881,16 @@ [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; #endif - if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) { + if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) { #ifndef SP_REFACTOR if(activeFilter == 0) { #endif if(filterString) SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded presumably due to used filter clause. \n\nMySQL said: %@", @"message of panel when loading of table failed and presumably due to used filter argument"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded presumably due to used filter clause. \n\nMySQL said: %@", @"message of panel when loading of table failed and presumably due to used filter argument"), [mySQLConnection lastErrorMessage]]); else SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded.\n\nMySQL said: %@", @"message of panel when loading of table failed"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded.\n\nMySQL said: %@", @"message of panel when loading of table failed"), [mySQLConnection lastErrorMessage]]); } #ifndef SP_REFACTOR // Filter task came from filter table @@ -910,9 +912,8 @@ /** * Processes a supplied streaming result set, loading it into the data array. */ -- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount +- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount { - NSArray *tempRow; NSUInteger i; NSUInteger dataColumnsCount = [dataColumns count]; BOOL *columnBlobStatuses = malloc(dataColumnsCount * sizeof(BOOL)); @@ -949,13 +950,13 @@ // Loop through the result rows as they become available tableRowsCount = 0; - while ((tempRow = [theResult fetchNextRowAsArray])) { + for (NSArray *eachRow in theResult) { pthread_mutex_lock(&tableValuesLock); if (tableRowsCount < previousTableRowsCount) { - SPDataStorageReplaceRow(tableValues, tableRowsCount, tempRow); + SPDataStorageReplaceRow(tableValues, tableRowsCount, eachRow); } else { - SPDataStorageAddRow(tableValues, tempRow); + SPDataStorageAddRow(tableValues, eachRow); } // Alter the values for hidden blob and text fields if appropriate @@ -1569,7 +1570,7 @@ * layer depending on the current state. */ #ifndef SP_REFACTOR -- (IBAction) togglePagination:(id)sender +- (IBAction) togglePagination:(NSButton *)sender { if ([sender state] == NSOnState) [self setPaginationViewVisibility:YES]; else [self setPaginationViewVisibility:NO]; @@ -1660,7 +1661,6 @@ - (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database includeBlobs:(BOOL)includeBlobs { NSArray *dataRow; - NSDictionary *theRow; id field; NSMutableArray *argumentParts = [NSMutableArray array]; @@ -1675,17 +1675,14 @@ dataRow = [tableValues rowContentsAtIndex:rowIndex]; // Get the primary key if there is one, using any columns present within it - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@", + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@", [database backtickQuotedString], [tableForColumn backtickQuotedString]]]; [theResult setReturnDataAsStrings:YES]; - if ([theResult numOfRows]) [theResult dataSeek:0]; NSMutableArray *primaryColumnsInSpecifiedTable = [NSMutableArray array]; - NSUInteger i; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - theRow = [theResult fetchRowAsDictionary]; - if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { + for (NSDictionary *eachRow in theResult) { + if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { for (field in columnsInSpecifiedTable) { - if([[field objectForKey:@"org_name"] isEqualToString:[theRow objectForKey:@"Field"]]) { + if([[field objectForKey:@"org_name"] isEqualToString:[eachRow objectForKey:@"Field"]]) { [primaryColumnsInSpecifiedTable addObject:field]; } } @@ -1698,7 +1695,7 @@ // Build up the argument for (field in columnsToQuery) { id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] integerValue]]; - if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) { + if ([aValue isNSNull]) { [argumentParts addObject:[NSString stringWithFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]]]; } else { NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"]; @@ -1718,14 +1715,14 @@ [argumentParts addObject:[NSString stringWithFormat:@"%@=b'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]]; } else if ([fieldTypeGrouping isEqualToString:@"geometry"]) { - [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:[aValue data]]]]; } // BLOB/TEXT data else if ([aValue isKindOfClass:[NSData class]]) { - [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:aValue]]]; } else { - [argumentParts addObject:[NSString stringWithFormat:@"%@='%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]]; + [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteString:aValue]]]; } } } @@ -1790,7 +1787,7 @@ - (IBAction)duplicateRow:(id)sender { NSMutableArray *tempRow; - MCPResult *queryResult; + SPMySQLResult *queryResult; NSDictionary *row; NSArray *dbDataRow = nil; NSUInteger i; @@ -1819,7 +1816,7 @@ // If we have indexes, use argumentForRow queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@", [selectedTable backtickQuotedString], [self argumentForRow:[tableContentView selectedRow]]]]; - dbDataRow = [queryResult fetchRowAsArray]; + dbDataRow = [queryResult getRowAsArray]; } #endif @@ -1827,12 +1824,10 @@ queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; [queryResult setReturnDataAsStrings:YES]; - - if ([queryResult numOfRows]) [queryResult dataSeek:0]; - - for (i = 0; i < [queryResult numOfRows]; i++) + + for (i = 0; i < [queryResult numberOfRows]; i++) { - row = [queryResult fetchRowAsDictionary]; + row = [queryResult getRowAsDictionary]; if ([[row objectForKey:@"Extra"] isEqualToString:@"auto_increment"]) { [tempRow replaceObjectAtIndex:i withObject:[NSNull null]]; @@ -1904,7 +1899,7 @@ contextInfo = @"removeallrows"; // If table has PRIMARY KEY ask for resetting the auto increment after deletion if given - if(![[tableDataInstance statusValueForKey:@"Auto_increment"] isKindOfClass:[NSNull class]]) { + if(![[tableDataInstance statusValueForKey:@"Auto_increment"] isNSNull]) { [alert setShowsSuppressionButton:YES]; #ifndef SP_REFACTOR [[alert suppressionButton] setState:([prefs boolForKey:SPResetAutoIncrementAfterDeletionOfAllRows]) ? NSOnState : NSOffState]; @@ -1980,7 +1975,7 @@ [self performSelector:@selector(showErrorSheetWith:) withObject:[NSArray arrayWithObjects:NSLocalizedString(@"Error", @"error"), [NSString stringWithFormat:NSLocalizedString(@"Couldn't delete rows.\n\nMySQL said: %@", @"message when deleteing all rows failed"), - [mySQLConnection getLastErrorMessage]], + [mySQLConnection lastErrorMessage]], nil] afterDelay:0.3]; } @@ -2029,18 +2024,17 @@ primaryKeyFieldNames = [tableDataInstance columnNames]; NSInteger numberOfRows = 0; + // Get the number of rows in the table - MCPResult *r; - r = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]]; - if (![mySQLConnection queryErrored]) { - NSArray *a = [r fetchRowAsArray]; - if([a count]) - numberOfRows = [[a objectAtIndex:0] integerValue]; + NSString *returnedCount = [mySQLConnection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]]; + if (returnedCount) { + numberOfRows = [returnedCount integerValue]; } + // Check for uniqueness via LIMIT numberOfRows-1,numberOfRows for speed if(numberOfRows > 0) { [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ GROUP BY %@ LIMIT %ld,%ld", [selectedTable backtickQuotedString], [primaryKeyFieldNames componentsJoinedAndBacktickQuoted], (long)(numberOfRows-1), (long)numberOfRows]]; - if([mySQLConnection affectedRows] == 0) + if ([mySQLConnection rowsAffectedByLastQuery] == 0) primaryKeyFieldNames = nil; } else { primaryKeyFieldNames = nil; @@ -2058,7 +2052,7 @@ [mySQLConnection queryString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", [selectedTable backtickQuotedString], wherePart]]; // Check for errors - if ( ![mySQLConnection affectedRows] || [mySQLConnection queryErrored]) { + if ( ![mySQLConnection rowsAffectedByLastQuery] || [mySQLConnection queryErrored]) { // If error delete that index from selectedRows for reloading table if // "ReloadAfterRemovingRow" is disbaled if(!reloadAfterRemovingRow) @@ -2086,9 +2080,9 @@ id keyValue = [tableValues cellDataAtRow:anIndex column:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(primaryKeyFieldNames,0)] objectForKey:@"datacolumnindex"] integerValue]]; if([keyValue isKindOfClass:[NSData class]]) - [deleteQuery appendFormat:@"X'%@'", [mySQLConnection prepareBinaryData:keyValue]]; + [deleteQuery appendString:[mySQLConnection escapeAndQuoteData:keyValue]]; else - [deleteQuery appendFormat:@"'%@'", [keyValue description]]; + [deleteQuery appendString:[mySQLConnection escapeAndQuoteString:[keyValue description]]]; // Split deletion query into 256k chunks if([deleteQuery length] > 256000) { @@ -2096,7 +2090,7 @@ [mySQLConnection queryString:deleteQuery]; // Remember affected rows for error checking - affectedRows += (NSInteger)[mySQLConnection affectedRows]; + affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery]; // Reinit a new deletion query [deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@ IN (", [selectedTable backtickQuotedString], [NSArrayObjectAtIndex(primaryKeyFieldNames,0) backtickQuotedString]]]; @@ -2115,7 +2109,7 @@ [mySQLConnection queryString:deleteQuery]; // Remember affected rows for error checking - affectedRows += (NSInteger)[mySQLConnection affectedRows]; + affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery]; } errors = (affectedRows > 0) ? [selectedRows count] - affectedRows : [selectedRows count]; @@ -2139,7 +2133,7 @@ [mySQLConnection queryString:deleteQuery]; // Remember affected rows for error checking - affectedRows += (NSInteger)[mySQLConnection affectedRows]; + affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery]; // Reinit a new deletion query [deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE ", [selectedTable backtickQuotedString]]]; @@ -2159,7 +2153,7 @@ [mySQLConnection queryString:deleteQuery]; // Remember affected rows for error checking - affectedRows += (NSInteger)[mySQLConnection affectedRows]; + affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery]; } errors = (affectedRows > 0) ? [selectedRows count] - affectedRows : [selectedRows count]; @@ -2274,7 +2268,7 @@ else if([o isKindOfClass:[NSString class]]) { [tempRow addObject:[o description]]; } - else if([o isKindOfClass:[MCPGeometryData class]]) { + else if([o isKindOfClass:[SPMySQLGeometryData class]]) { SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[o coordinates]]; NSImage *image = [v thumbnailImage]; NSString *imageStr = @""; @@ -2370,7 +2364,7 @@ /** * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once */ -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; @@ -2697,20 +2691,20 @@ // Convert geometry values to their string values } else if ([fieldTypeGroup isEqualToString:@"geometry"]) { - fieldValue = ([rowObject isKindOfClass:[MCPGeometryData class]]) ? [[rowObject wktString] getGeomFromTextString] : [(NSString*)rowObject getGeomFromTextString]; + fieldValue = ([rowObject isKindOfClass:[SPMySQLGeometryData class]]) ? [[rowObject wktString] getGeomFromTextString] : [(NSString*)rowObject getGeomFromTextString]; // Convert the object to a string (here we can add special treatment for date-, number- and data-fields) } else { // I believe these class matches are not ever met at present. if ([rowObject isKindOfClass:[NSCalendarDate class]]) { - fieldValue = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[rowObject description]]]; + fieldValue = [mySQLConnection escapeAndQuoteString:[rowObject description]]; } else if ([rowObject isKindOfClass:[NSNumber class]]) { fieldValue = [rowObject stringValue]; // Convert data to its hex representation } else if ([rowObject isKindOfClass:[NSData class]]) { - fieldValue = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:rowObject]]; + fieldValue = [mySQLConnection escapeAndQuoteData:rowObject]; } else { if ([[rowObject description] isEqualToString:@"CURRENT_TIMESTAMP"]) { @@ -2720,7 +2714,7 @@ } else if ([fieldTypeGroup isEqualToString:@"date"] && [[rowObject description] isEqualToString:@"NOW()"]) { fieldValue = @"NOW()"; } else { - fieldValue = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[rowObject description]]]; + fieldValue = [mySQLConnection escapeAndQuoteString:[rowObject description]]; } } } @@ -2767,7 +2761,7 @@ #endif // If no rows have been changed, show error if appropriate. - if ( ![mySQLConnection affectedRows] && ![mySQLConnection queryErrored] ) { + if ( ![mySQLConnection rowsAffectedByLastQuery] && ![mySQLConnection queryErrored] ) { #ifndef SP_REFACTOR if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) { SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, @@ -2809,7 +2803,7 @@ // Set the insertId for fields with auto_increment for ( i = 0; i < [dataColumns count] ; i++ ) { if ([[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"autoincrement"] integerValue]) { - [tableValues replaceObjectInRow:currentlyEditingRow column:i withObject:[[NSNumber numberWithUnsignedLongLong:[mySQLConnection insertId]] description]]; + [tableValues replaceObjectInRow:currentlyEditingRow column:i withObject:[[NSNumber numberWithUnsignedLongLong:[mySQLConnection lastInsertID]] description]]; } } #ifndef SP_REFACTOR @@ -2837,7 +2831,7 @@ } else { SPBeginAlertSheet(NSLocalizedString(@"Couldn't write row", @"Couldn't write row error"), NSLocalizedString(@"Edit row", @"Edit row button"), NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil, - [NSString stringWithFormat:NSLocalizedString(@"MySQL said:\n\n%@", @"message of panel when error while adding row to db"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"MySQL said:\n\n%@", @"message of panel when error while adding row to db"), [mySQLConnection lastErrorMessage]]); return NO; } } @@ -2942,8 +2936,7 @@ */ - (NSString *)argumentForRow:(NSInteger)row excludingLimits:(BOOL)excludeLimits { - MCPResult *theResult; - NSDictionary *theRow; + SPMySQLResult *theResult; id tempValue; NSMutableString *value = [NSMutableString string]; NSMutableString *argument = [NSMutableString string]; @@ -2963,11 +2956,9 @@ keys = [[NSMutableArray alloc] init]; theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; [theResult setReturnDataAsStrings:YES]; - if ([theResult numOfRows]) [theResult dataSeek:0]; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - theRow = [theResult fetchRowAsDictionary]; - if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { - [keys addObject:[theRow objectForKey:@"Field"]]; + for (NSDictionary *eachRow in theResult) { + if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) { + [keys addObject:[eachRow objectForKey:@"Field"]]; } } } @@ -3015,17 +3006,17 @@ else { // If the field is of type BIT then it needs a binary prefix if ([[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"type"] isEqualToString:@"BIT"]) { - [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection prepareString:tempValue]]]; + [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection escapeString:tempValue includingQuotes:NO]]]; } - else if ([tempValue isKindOfClass:[MCPGeometryData class]]) { - [value setString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:[tempValue data]]]]; + else if ([tempValue isKindOfClass:[SPMySQLGeometryData class]]) { + [value setString:[mySQLConnection escapeAndQuoteData:[tempValue data]]]; } // BLOB/TEXT data else if ([tempValue isKindOfClass:[NSData class]]) { - [value setString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:tempValue]]]; + [value setString:[mySQLConnection escapeAndQuoteData:tempValue]]; } else - [value setString:[NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:tempValue]]]; + [value setString:[mySQLConnection escapeAndQuoteString:tempValue]]; [argument appendFormat:@"%@ = %@", [NSArrayObjectAtIndex(keys, i) backtickQuotedString], value]; } @@ -3120,7 +3111,7 @@ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")]; // Actual check whether field can be identified bijectively - MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", + SPMySQLResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], fieldIDQueryStr]]; @@ -3130,7 +3121,7 @@ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil]; } - NSArray *tempRow = [tempResult fetchRowAsArray]; + NSArray *tempRow = [tempResult getRowAsArray]; if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] > 1) { // try to identify the cell by using blob data @@ -3150,7 +3141,7 @@ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil]; } - tempRow = [tempResult fetchRowAsArray]; + tempRow = [tempResult getRowAsArray]; if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] < 1) { [tableDocumentInstance endTask]; @@ -3309,11 +3300,11 @@ NSString *newObject = nil; if ( [anObject isKindOfClass:[NSCalendarDate class]] ) { - newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]]; + newObject = [mySQLConnection escapeAndQuoteString:[anObject description]]; } else if ( [anObject isKindOfClass:[NSNumber class]] ) { newObject = [anObject stringValue]; } else if ( [anObject isKindOfClass:[NSData class]] ) { - newObject = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:anObject]]; + newObject = [mySQLConnection escapeAndQuoteData:anObject]; } else { if ( [[anObject description] isEqualToString:@"CURRENT_TIMESTAMP"] ) { newObject = @"CURRENT_TIMESTAMP"; @@ -3327,7 +3318,7 @@ && [[anObject description] isEqualToString:@"NOW()"]) { newObject = @"NOW()"; } else { - newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]]; + newObject = [mySQLConnection escapeAndQuoteString:[anObject description]]; } } @@ -3340,7 +3331,7 @@ // Check for errors while UPDATE if ([mySQLConnection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection lastErrorMessage]]); [tableDocumentInstance endTask]; [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; @@ -3349,7 +3340,7 @@ // This shouldn't happen – for safety reasons - if ( ![mySQLConnection affectedRows] ) { + if ( ![mySQLConnection rowsAffectedByLastQuery] ) { #ifndef SP_REFACTOR if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) { SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, @@ -3864,7 +3855,7 @@ */ - (NSInteger)fetchNumberOfRows { - return [[[[mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue]; + return [[mySQLConnection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]] integerValue]; } /** @@ -3951,7 +3942,7 @@ return nil; } } - else if ([theValue isKindOfClass:[MCPGeometryData class]]) { + else if ([theValue isKindOfClass:[SPMySQLGeometryData class]]) { SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[theValue coordinates]]; image = [v thumbnailImage]; if(image) { @@ -4035,7 +4026,7 @@ theValue = SPDataStorageObjectAtRowAndColumn(tableValues, rowIndex, columnIndex); } - if([theValue isKindOfClass:[MCPGeometryData class]]) + if([theValue isKindOfClass:[SPMySQLGeometryData class]]) return [theValue wktString]; if ([theValue isNSNull]) @@ -4242,7 +4233,7 @@ if ([mySQLConnection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't sort table. MySQL said: %@", @"message of panel when sorting of table failed"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't sort table. MySQL said: %@", @"message of panel when sorting of table failed"), [mySQLConnection lastErrorMessage]]); [tableDocumentInstance endTask]; [sortPool drain]; return; @@ -4403,14 +4394,14 @@ // Only get the data for the selected column, not all of them NSString *query = [NSString stringWithFormat:@"SELECT %@ FROM %@ WHERE %@", [[[aTableColumn headerCell] stringValue] backtickQuotedString], [selectedTable backtickQuotedString], wherePart]; - MCPResult *tempResult = [mySQLConnection queryString:query]; - if (![tempResult numOfRows]) { + SPMySQLResult *tempResult = [mySQLConnection queryString:query]; + if (![tempResult numberOfRows]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, NSLocalizedString(@"Couldn't load the row. Reload the table to be sure that the row exists and use a primary key for your table.", @"message of panel when loading of row failed")); return NO; } - NSArray *tempRow = [tempResult fetchRowAsArray]; + NSArray *tempRow = [tempResult getRowAsArray]; [tableValues replaceObjectInRow:rowIndex column:[[tableContentView tableColumns] indexOfObject:aTableColumn] withObject:[tempRow objectAtIndex:0]]; [tableContentView reloadData]; } diff --git a/Source/SPTableCopy.m b/Source/SPTableCopy.m index 5aa55df1..539b83af 100644 --- a/Source/SPTableCopy.m +++ b/Source/SPTableCopy.m @@ -24,6 +24,7 @@ #import "SPDBActionCommons.h" #import "SPTableCopy.h" +#import "SPMySQL.h" @implementation SPTableCopy @@ -31,10 +32,10 @@ { NSString *showCreateTableStatment = [NSString stringWithFormat:@"SHOW CREATE TABLE %@.%@", [sourceDB backtickQuotedString], [tableName backtickQuotedString]]; - MCPResult *theResult = [connection queryString:showCreateTableStatment]; + SPMySQLResult *theResult = [connection queryString:showCreateTableStatment]; - if ([theResult numOfRows] != 0) { - return [[theResult fetchRowAsArray] objectAtIndex:1]; + if ([theResult numberOfRows] != 0) { + return [[theResult getRowAsArray] objectAtIndex:1]; } return @""; diff --git a/Source/SPTableData.h b/Source/SPTableData.h index b4042527..c7ebe37b 100644 --- a/Source/SPTableData.h +++ b/Source/SPTableData.h @@ -23,10 +23,7 @@ // // More info at -#import - -@class SPDatabaseDocument; -@class SPTablesList; +@class SPDatabaseDocument, SPTablesList, SPMySQLConnection; @interface SPTableData : NSObject { @@ -42,7 +39,7 @@ NSString *tableEncoding; NSString *tableCreateSyntax; - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; pthread_mutex_t dataProcessingLock; @@ -51,7 +48,7 @@ @property (readonly, assign) BOOL tableHasAutoIncrementField; -- (void) setConnection:(MCPConnection *)theConnection; +- (void) setConnection:(SPMySQLConnection *)theConnection; - (NSString *) tableEncoding; - (NSString *) tableCreateSyntax; - (NSArray *) columns; diff --git a/Source/SPTableData.m b/Source/SPTableData.m index 297718b9..5f043548 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -30,6 +30,8 @@ #import "SPAlertSheets.h" #import "RegexKitLite.h" #import "SPServerSupport.h" +#import "SPMySQL.h" +#include @interface SPTableData (PrivateAPI) @@ -70,7 +72,7 @@ * * @param theConnection The used connection for the SPDatabaseDocument */ -- (void) setConnection:(MCPConnection *)theConnection +- (void) setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; [mySQLConnection retain]; @@ -476,7 +478,7 @@ [constraints removeAllObjects]; // Retrieve the CREATE TABLE syntax for the table - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]]; [theResult setReturnDataAsStrings:YES]; // Check for any errors, but only display them if a connection still exists @@ -485,10 +487,10 @@ SPBeginAlertSheet(NSLocalizedString(@"Error retrieving table information", @"error retrieving table information message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving the information for table '%@'. Please try again.\n\nMySQL said: %@", @"error retrieving table information informative message"), - tableName, [mySQLConnection getLastErrorMessage]]); + tableName, [mySQLConnection lastErrorMessage]]); // If the current table doesn't exist anymore reload table list - if([mySQLConnection getLastErrorID] == 1146) { + if([mySQLConnection lastErrorID] == 1146) { // Release the table loading lock to allow reselection/reloading to requery the database. pthread_mutex_unlock(&dataProcessingLock); @@ -503,8 +505,8 @@ } // Retrieve the table syntax string - NSArray *syntaxResult = [theResult fetchRowAsArray]; - NSArray *resultFieldNames = [theResult fetchFieldNames]; + NSArray *syntaxResult = [theResult getRowAsArray]; + NSArray *resultFieldNames = [theResult fieldNames]; // Only continue if syntaxResult is not nil. This accommodates causes where the above query caused the // connection reconnect dialog to appear and the user chose to close the connection. @@ -798,7 +800,6 @@ NSMutableArray *tableColumns; NSDictionary *resultRow; NSMutableDictionary *tableColumn, *viewData; - NSUInteger i; BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; // Catch unselected views and return nil @@ -811,7 +812,7 @@ } // Retrieve the CREATE TABLE syntax for the table - MCPResult *theResult = [mySQLConnection queryString: [NSString stringWithFormat: @"SHOW CREATE TABLE %@", + SPMySQLResult *theResult = [mySQLConnection queryString: [NSString stringWithFormat: @"SHOW CREATE TABLE %@", [viewName backtickQuotedString] ]]; [theResult setReturnDataAsStrings:YES]; @@ -822,7 +823,7 @@ 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 getLastErrorMessage]]); + [mySQLConnection lastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } return nil; @@ -830,7 +831,7 @@ // Retrieve the table syntax string if (tableCreateSyntax) [tableCreateSyntax release], tableCreateSyntax = nil; - NSString *syntaxString = [[theResult fetchRowAsArray] objectAtIndex:1]; + NSString *syntaxString = [[theResult getRowAsArray] objectAtIndex:1]; // A NULL value indicates that the user does not have permission to view the syntax if ([syntaxString isNSNull]) { @@ -856,20 +857,18 @@ 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 getLastErrorMessage]]); + [mySQLConnection lastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } return nil; } // Loop through the fields and capture details - if ([theResult numOfRows]) [theResult dataSeek:0]; tableColumns = [[NSMutableArray alloc] init]; tableColumn = [[NSMutableDictionary alloc] init]; fieldParser = [[SPSQLParser alloc] init]; - for ( i = 0; i < [theResult numOfRows] ; i++ ) { + for (resultRow in theResult) { [tableColumn removeAllObjects]; - resultRow = [theResult fetchRowAsDictionary]; // Add the column index and name [tableColumn setObject:[NSString stringWithFormat:@"%llu", (unsigned long long)[tableColumns count]] forKey:@"datacolumnindex"]; @@ -938,7 +937,7 @@ [escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])]; [escapedTableName replaceOccurrencesOfString:@"'" withString:@"\\\'" options:0 range:NSMakeRange(0, [escapedTableName length])]; - MCPResult *tableStatusResult = nil; + SPMySQLResult *tableStatusResult = nil; if ([tableListInstance tableType] == SPTableTypeProc) { NSMutableString *escapedDatabaseName = [NSMutableString stringWithString:[tableDocumentInstance database]]; @@ -967,7 +966,7 @@ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving status data.\nMySQL said: %@", @"message of panel when retrieving view information failed"), - [mySQLConnection getLastErrorMessage]]); + [mySQLConnection lastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } pthread_mutex_unlock(&dataProcessingLock); @@ -975,7 +974,7 @@ } // Retrieve the status as a dictionary and set as the cache - [status setDictionary:[tableStatusResult fetchRowAsDictionary]]; + [status setDictionary:[tableStatusResult getRowAsDictionary]]; if ([tableListInstance tableType] == SPTableTypeTable) { @@ -1001,10 +1000,10 @@ // [status objectForKey:@"Rows"] is NULL then try to get the number of rows via SELECT COUNT(1) FROM `foo` // this happens e.g. for db "information_schema" - if([[status objectForKey:@"Rows"] isKindOfClass:[NSNull class]]) { + if([[status objectForKey:@"Rows"] isNSNull]) { tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [escapedTableName backtickQuotedString] ]]; if (![mySQLConnection queryErrored]) - [status setObject:[[tableStatusResult fetchRowAsArray] objectAtIndex:0] forKey:@"Rows"]; + [status setObject:[[tableStatusResult getRowAsArray] objectAtIndex:0] forKey:@"Rows"]; [status setObject:@"y" forKey:@"RowsCountAccurate"]; } @@ -1042,7 +1041,7 @@ [mySQLConnection setEncoding:@"utf8"]; } - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */", + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */", [[tableListInstance tableName] tickQuotedString]]]; [theResult setReturnDataAsStrings:YES]; @@ -1052,7 +1051,7 @@ SPBeginAlertSheet(NSLocalizedString(@"Error retrieving trigger information", @"error retrieving trigger information message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving the trigger information for table '%@'. Please try again.\n\nMySQL said: %@", @"error retrieving table information informative message"), - [tableListInstance tableName], [mySQLConnection getLastErrorMessage]]); + [tableListInstance tableName], [mySQLConnection lastErrorMessage]]); if (triggers) [triggers release], triggers = nil; if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } @@ -1061,11 +1060,8 @@ return NO; } - if (triggers) [triggers release]; - triggers = [[NSMutableArray alloc] init]; - for (NSUInteger i=0; i<[theResult numOfRows]; i++) { - [triggers addObject:[theResult fetchRowAsDictionary]]; - } + [triggers removeAllObjects]; + [triggers addObjectsFromArray:[theResult getAllRows]]; if (changeEncoding) [mySQLConnection restoreStoredEncoding]; @@ -1298,9 +1294,7 @@ NSString *selectedTable = [tableListInstance tableName]; if(![selectedTable length]) return nil; - MCPResult *r; - NSArray *resultRow; - NSUInteger i; + SPMySQLResult *r; NSMutableArray *keyColumns = [NSMutableArray array]; // select all columns that are primary keys @@ -1308,22 +1302,22 @@ r = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@ /*!50003 WHERE `key` = 'PRI'*/", [selectedTable backtickQuotedString]]]; [r setReturnDataAsStrings:YES]; - if([r numOfRows] < 1) { + if ([r numberOfRows] < 1) { if (changeEncoding && [mySQLConnection isConnected]) [mySQLConnection restoreStoredEncoding]; return nil; } if ([mySQLConnection queryErrored]) { if ([mySQLConnection isConnected]) { - NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the PRIMARY KEY data:\n\n%@",@"message when the query that fetches the primary keys fails"), [mySQLConnection getLastErrorMessage]], @"OK", nil, nil); + NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the PRIMARY KEY data:\n\n%@",@"message when the query that fetches the primary keys fails"), [mySQLConnection lastErrorMessage]], @"OK", nil, nil); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } return nil; } - for( i = 0; i < [r numOfRows]; i++ ) { - resultRow = [r fetchRowAsArray]; + for (NSArray *resultRow in r) { + // check if the row is indeed a key (for MySQL servers before 5.0.3) if ([[NSArrayObjectAtIndex(resultRow ,3) description] isEqualToString:@"PRI"]) { [keyColumns addObject:[NSArrayObjectAtIndex(resultRow ,0) description]]; @@ -1382,4 +1376,4 @@ #endif -@end \ No newline at end of file +@end diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h index 5a8b9c40..99fa251f 100644 --- a/Source/SPTableRelations.h +++ b/Source/SPTableRelations.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPTableView; +@class SPTableView, SPMySQLConnection; @interface SPTableRelations : NSObject { @@ -53,7 +51,7 @@ IBOutlet NSProgressIndicator *dataProgressIndicator; IBOutlet NSTextField *progressStatusTextField; - MCPConnection *connection; + SPMySQLConnection *connection; NSUserDefaults *prefs; NSMutableArray *relationData; @@ -61,7 +59,7 @@ } @property (readonly) NSMutableArray *relationData; -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; // IB action methods - (IBAction)addRelation:(id)sender; diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m index eacdc8f6..44d05ee7 100644 --- a/Source/SPTableRelations.m +++ b/Source/SPTableRelations.m @@ -30,6 +30,7 @@ #import "SPTableView.h" #import "SPAlertSheets.h" #import "RegexKitLite.h" +#import "SPMySQL.h" static NSString *SPRemoveRelation = @"SPRemoveRelation"; @@ -177,12 +178,12 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; if ([connection queryErrored]) { // Retrieve the last connection error message. - NSString *errorText = [connection getLastErrorMessage]; + NSString *errorText = [connection lastErrorMessage]; // An error ID of 1005 indicates a foreign key error. These are thrown for many reasons, but the two // most common are 121 (name probably in use) and 150 (types don't exactly match). // Retrieve the InnoDB status and extract the most recent error for more helpful text. - if ([connection getLastErrorID] == 1005) { + if ([connection lastErrorID] == 1005) { NSString *statusText = [connection getFirstFieldFromQuery:@"SHOW INNODB STATUS"]; NSString *detailErrorString = [statusText stringByMatching:@"latest foreign key error\\s+-----*\\s+[0-9: ]*(.*?)\\s+-----" options:(RKLCaseless | RKLDotAll) inRange:NSMakeRange(0, [statusText length]) capture:1L error:NULL]; if (detailErrorString) { @@ -249,13 +250,10 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; // Get all InnoDB tables in the current database // TODO: MySQL 4 compatibility - MCPResult *result = [connection queryString:[NSString stringWithFormat:@"SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND engine = 'InnoDB' AND table_schema = %@", [[tableDocumentInstance database] tickQuotedString]]]; - - [result dataSeek:0]; - - for (NSUInteger i = 0; i < [result numOfRows]; i++) - { - [refTablePopUpButton addItemWithTitle:[[result fetchRowAsArray] objectAtIndex:0]]; + SPMySQLResult *result = [connection queryString:[NSString stringWithFormat:@"SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND engine = 'InnoDB' AND table_schema = %@", [[tableDocumentInstance database] tickQuotedString]]]; + [result setDefaultRowReturnType:SPMySQLResultRowAsArray]; + for (NSArray *eachRow in result) { + [refTablePopUpButton addItemWithTitle:[eachRow objectAtIndex:0]]; } // Reset other fields @@ -505,7 +503,7 @@ static NSString *SPRelationOnDeleteKey = @"on_delete"; SPBeginAlertSheet(NSLocalizedString(@"Unable to delete relation", @"error deleting relation message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], nil, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"The selected relation couldn't be deleted.\n\nMySQL said: %@", @"error deleting relation informative message"), [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"The selected relation couldn't be deleted.\n\nMySQL said: %@", @"error deleting relation informative message"), [connection lastErrorMessage]]); // Abort loop break; diff --git a/Source/SPTableStructure.h b/Source/SPTableStructure.h index 63ac74b8..a97f70b2 100644 --- a/Source/SPTableStructure.h +++ b/Source/SPTableStructure.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPDatabaseDocument, SPTableFieldValidation, SPTableData, SPDatabaseData, SPTablesList, SPIndexesController, SPTableView; +@class SPDatabaseDocument, SPTableFieldValidation, SPTableData, SPDatabaseData, SPTablesList, SPIndexesController, SPTableView, SPMySQLConnection, SPMySQLResult; @interface SPTableStructure : NSObject #ifdef SP_REFACTOR @@ -70,9 +68,7 @@ #endif IBOutlet NSPopUpButtonCell *encodingPopupCell; - MCPConnection *mySQLConnection; - MCPResult *tableSourceResult; - MCPResult *indexResult; + SPMySQLConnection *mySQLConnection; SPTableFieldValidation *fieldValidation; @@ -123,15 +119,15 @@ - (IBAction)resetAutoIncrement:(id)sender; - (void)resetAutoincrementSheetDidEnd:(NSWindow *)theSheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (IBAction)showOptimizedFieldType:(id)sender; -- (IBAction)toggleColumnView:(id)sender; +- (IBAction)toggleColumnView:(NSMenuItem *)sender; - (BOOL)cancelRowEditing; // Index sheet methods - (IBAction)closeSheet:(id)sender; // Additional methods -- (void)setConnection:(MCPConnection *)theConnection; -- (NSArray *)fetchResultAsArray:(MCPResult *)theResult; +- (void)setConnection:(SPMySQLConnection *)theConnection; +- (NSArray *)convertIndexResultToArray:(SPMySQLResult *)theResult; - (BOOL)saveRowOnDeselect; - (BOOL)addRowToDB; - (void)addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index f9c56eb9..a0fb6ab2 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -36,6 +36,7 @@ #import "SPIndexesController.h" #import "RegexKitLite.h" #import "SPTableFieldValidation.h" +#import "SPMySQL.h" @interface SPTableStructure (PrivateAPI) @@ -232,6 +233,7 @@ { NSArray *theTableIndexes; NSMutableDictionary *theTableEnumLists = [NSMutableDictionary dictionary]; + SPMySQLResult *indexResult; // Check whether a save of the current row is required. if ( ![[self onMainThread] saveRowOnDeselect] ) return; @@ -249,7 +251,7 @@ [theTableFields addObject:[[col mutableCopy] autorelease]]; // Retrieve the indexes for the table - indexResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]] retain]; + indexResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]]; // If an error occurred, reset the interface and abort if ([mySQLConnection queryErrored]) { @@ -264,17 +266,14 @@ 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 getLastErrorMessage]]); + [mySQLConnection lastErrorMessage]]); } - - if (indexResult) [indexResult release]; - + return; } // Process the indexes into a local array of dictionaries - theTableIndexes = [self fetchResultAsArray:indexResult]; - [indexResult release]; + theTableIndexes = [self convertIndexResultToArray:indexResult]; // Set the Key column for (NSDictionary* theIndex in theTableIndexes) @@ -357,7 +356,7 @@ // Normalize default if(![theField objectForKey:@"default"]) [theField setObject:@"" forKey:@"default"]; - else if([[theField objectForKey:@"default"] isKindOfClass:[NSNull class]]) + else if([[theField objectForKey:@"default"] isNSNull]) [theField setObject:[prefs stringForKey:SPNullValue] forKey:@"default"]; // Init Extra field @@ -533,7 +532,7 @@ */ - (IBAction)showOptimizedFieldType:(id)sender { - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT %@ FROM %@ PROCEDURE ANALYSE(0,8192)", + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT %@ FROM %@ PROCEDURE ANALYSE(0,8192)", [[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"] backtickQuotedString], [selectedTable backtickQuotedString]]]; @@ -546,7 +545,7 @@ defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while fetching the optimized field type.\n\nMySQL said:%@",@"an error occurred while fetching the optimized field type.\n\nMySQL said:%@"), [mySQLConnection getLastErrorMessage]]] + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while fetching the optimized field type.\n\nMySQL said:%@",@"an error occurred while fetching the optimized field type.\n\nMySQL said:%@"), [mySQLConnection lastErrorMessage]]] beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:NULL @@ -556,13 +555,10 @@ return; } - NSArray *result = [theResult fetch2DResultAsType:MCPTypeDictionary]; + NSDictionary *analysisResult = [theResult getRowAsDictionary]; - NSString *type = nil; - - if([result count]) - type = [[result objectAtIndex:0] objectForKey:@"Optimal_fieldtype"]; - if(!type || [type isKindOfClass:[NSNull class]] || ![type length]) + NSString *type = [analysisResult objectForKey:@"Optimal_fieldtype"]; + if (!type || [type isNSNull] || ![type length]) type = NSLocalizedString(@"No optimized field type found.", @"no optimized field type found. message"); [[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Optimized type for field '%@'", @"Optimized type for field %@"), [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"]] @@ -580,31 +576,31 @@ /** * Control the visibility of the columns */ -- (IBAction)toggleColumnView:(id)sender +- (IBAction)toggleColumnView:(NSMenuItem *)sender { NSString *columnIdentifierName = nil; - switch([sender tag]) { + switch ([sender tag]) { case 7: - columnIdentifierName = @"Key"; + columnIdentifierName = @"Key"; break; case 10: - columnIdentifierName = @"encoding"; + columnIdentifierName = @"encoding"; break; case 11: - columnIdentifierName = @"collation"; + columnIdentifierName = @"collation"; break; case 12: - columnIdentifierName = @"comment"; + columnIdentifierName = @"comment"; break; default: return; } - for(NSTableColumn *col in [tableSourceView tableColumns]) { + for (NSTableColumn *col in [tableSourceView tableColumns]) { - if([[col identifier] isEqualToString:columnIdentifierName]) { + if ([[col identifier] isEqualToString:columnIdentifierName]) { [col setHidden:([sender state] == NSOffState) ? NO : YES]; [(NSMenuItem *)sender setState:![sender state]]; break; @@ -864,7 +860,7 @@ NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], nil, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to reset AUTO_INCREMENT of table '%@'.\n\nMySQL said: %@", @"error resetting auto_increment informative message"), - selTable, [mySQLConnection getLastErrorMessage]]); + selTable, [mySQLConnection lastErrorMessage]]); } // reload data @@ -884,9 +880,9 @@ /** * Converts the supplied result to an array containing a (mutable) dictionary for each row */ -- (NSArray *)fetchResultAsArray:(MCPResult *)theResult +- (NSArray *)convertIndexResultToArray:(SPMySQLResult *)theResult { - NSUInteger numOfRows = (NSUInteger)[theResult numOfRows]; + NSUInteger numOfRows = (NSUInteger)[theResult numberOfRows]; NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows]; NSMutableDictionary *tempRow; NSArray *keys; @@ -896,9 +892,8 @@ // Ensure table information is returned as strings to avoid problems with some server versions [theResult setReturnDataAsStrings:YES]; - if (numOfRows) [theResult dataSeek:0]; for ( i = 0 ; i < (NSInteger)numOfRows ; i++ ) { - tempRow = [NSMutableDictionary dictionaryWithDictionary:[theResult fetchRowAsDictionary]]; + tempRow = [NSMutableDictionary dictionaryWithDictionary:[theResult getRowAsDictionary]]; // Replace NSNull instances with the NULL string from preferences keys = [tempRow allKeys]; @@ -1028,7 +1023,7 @@ } // Otherwise, use the provided default else { - [queryString appendFormat:@"\n DEFAULT '%@' ", [mySQLConnection prepareString:[theRow objectForKey:@"default"]]]; + [queryString appendFormat:@"\n DEFAULT %@ ", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"default"]]]; } } @@ -1115,7 +1110,7 @@ } // Otherwise, use the provided default else { - [queryString appendFormat:@"\n DEFAULT '%@'", [mySQLConnection prepareString:[theRow objectForKey:@"default"]]]; + [queryString appendFormat:@"\n DEFAULT %@", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"default"]]]; } } @@ -1126,7 +1121,7 @@ // Any column comments if ([(NSString *)[theRow objectForKey:@"comment"] length]) { - [queryString appendFormat:@"\n COMMENT '%@'", [mySQLConnection prepareString:[theRow objectForKey:@"comment"]]]; + [queryString appendFormat:@"\n COMMENT %@", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"comment"]]]; } if (!isEditingNewRow) { @@ -1207,12 +1202,12 @@ } else { alertSheetOpened = YES; - if([mySQLConnection getLastErrorID] == 1146) { // If the current table doesn't exist anymore + if([mySQLConnection lastErrorID] == 1146) { // If the current table doesn't exist anymore SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to alter table '%@'.\n\nMySQL said: %@", @"error while trying to alter table message"), - selectedTable, [mySQLConnection getLastErrorMessage]]); + selectedTable, [mySQLConnection lastErrorMessage]]); isEditingRow = NO; isEditingNewRow = NO; @@ -1237,14 +1232,14 @@ NSLocalizedString(@"Edit row", @"Edit row button"), NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to add the field '%@' via\n\n%@\n\nMySQL said: %@", @"error adding field informative message"), - [theRow objectForKey:@"name"], queryString, [mySQLConnection getLastErrorMessage]]); + [theRow objectForKey:@"name"], queryString, [mySQLConnection lastErrorMessage]]); } else { SPBeginAlertSheet(NSLocalizedString(@"Error changing field", @"error changing field message"), NSLocalizedString(@"Edit row", @"Edit row button"), NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil, [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the field '%@' via\n\n%@\n\nMySQL said: %@", @"error changing field informative message"), - [theRow objectForKey:@"name"], queryString, [mySQLConnection getLastErrorMessage]]); + [theRow objectForKey:@"name"], queryString, [mySQLConnection lastErrorMessage]]); } return NO; @@ -1431,7 +1426,7 @@ /** * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once */ -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; @@ -1449,7 +1444,7 @@ { if ( ![defaultValues objectForKey:field] ) { return [prefs objectForKey:SPNullValue]; - } else if ( [[defaultValues objectForKey:field] isMemberOfClass:[NSNull class]] ) { + } else if ( [[defaultValues objectForKey:field] isNSNull] ) { return [prefs objectForKey:SPNullValue]; } else { return [defaultValues objectForKey:field]; @@ -1502,18 +1497,15 @@ NSString *nullValue = [prefs stringForKey:SPNullValue]; CFStringRef escapedNullValue = CFXMLCreateStringByEscapingEntities(NULL, ((CFStringRef)nullValue), NULL); - MCPResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; - MCPResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]]; + SPMySQLResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; + SPMySQLResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]]; [structureQueryResult setReturnDataAsStrings:YES]; [indexesQueryResult setReturnDataAsStrings:YES]; - if ([structureQueryResult numOfRows]) [structureQueryResult dataSeek:0]; - if ([indexesQueryResult numOfRows]) [indexesQueryResult dataSeek:0]; - - [tempResult addObject:[structureQueryResult fetchFieldNames]]; + [tempResult addObject:[structureQueryResult fieldNames]]; - NSMutableArray *temp = [[indexesQueryResult fetchFieldNames] mutableCopy]; + NSMutableArray *temp = [[indexesQueryResult fieldNames] mutableCopy]; // Remove the 'table' column [temp removeObjectAtIndex:0]; @@ -1522,8 +1514,8 @@ [temp release]; - for (i = 0; i < [structureQueryResult numOfRows]; i++) { - NSMutableArray *row = [[structureQueryResult fetchRowAsArray] mutableCopy]; + for (i = 0; i < [structureQueryResult numberOfRows]; i++) { + NSMutableArray *row = [[structureQueryResult getRowAsArray] mutableCopy]; // For every NULL value replace it with the user's NULL value placeholder so we can actually print it for (j = 0; j < [row count]; j++) @@ -1538,8 +1530,8 @@ [row release]; } - for (i = 0; i < [indexesQueryResult numOfRows]; i++) { - NSMutableArray *eachIndex = [[indexesQueryResult fetchRowAsArray] mutableCopy]; + for (i = 0; i < [indexesQueryResult numberOfRows]; i++) { + NSMutableArray *eachIndex = [[indexesQueryResult getRowAsArray] mutableCopy]; // Remove the 'table' column values [eachIndex removeObjectAtIndex:0]; @@ -1658,10 +1650,10 @@ [mySQLConnection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [selectedTable backtickQuotedString], [relationName backtickQuotedString]]]; // Check for errors, but only if the query wasn't cancelled - if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) { + if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) { NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary]; [errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"]; - [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), relationName, [mySQLConnection getLastErrorMessage]] forKey:@"message"]; + [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), relationName, [mySQLConnection lastErrorMessage]] forKey:@"message"]; [[self onMainThread] showErrorSheetWith:errorDictionary]; } } @@ -1671,12 +1663,12 @@ [selectedTable backtickQuotedString], [[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"] backtickQuotedString]]]; // Check for errors, but only if the query wasn't cancelled - if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) { + if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) { NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary]; [errorDictionary setObject:NSLocalizedString(@"Error", @"error") forKey:@"title"]; [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete field %@.\nMySQL said: %@", @"message of panel when field cannot be deleted"), [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"], - [mySQLConnection getLastErrorMessage]] forKey:@"message"]; + [mySQLConnection lastErrorMessage]] forKey:@"message"]; [[self onMainThread] showErrorSheetWith:errorDictionary]; } else { diff --git a/Source/SPTableStructureDelegate.m b/Source/SPTableStructureDelegate.m index 997bfea2..6493e850 100644 --- a/Source/SPTableStructureDelegate.m +++ b/Source/SPTableStructureDelegate.m @@ -30,6 +30,7 @@ #import "SPTableData.h" #import "SPTableView.h" #import "SPTableFieldValidation.h" +#import "SPMySQL.h" @implementation SPTableStructure (SPTableStructureDelegate) @@ -328,13 +329,13 @@ [queryString appendString:@" DEFAULT CURRENT_TIMESTAMP"]; } else if ([(NSString *)[originalRow objectForKey:@"default"] length]) { - [queryString appendFormat:@" DEFAULT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"default"]]]; + [queryString appendFormat:@" DEFAULT %@", [mySQLConnection escapeAndQuoteString:[originalRow objectForKey:@"default"]]]; } } // Any column comments if ([(NSString *)[originalRow objectForKey:@"comment"] length]) { - [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"comment"]]]; + [queryString appendFormat:@" COMMENT %@", [mySQLConnection escapeAndQuoteString:[originalRow objectForKey:@"comment"]]]; } // Unparsed details - column formats, storage, reference definitions @@ -355,7 +356,7 @@ if ([mySQLConnection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Error moving field", @"error moving field message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to move the field.\n\nMySQL said: %@", @"error moving field informative message"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to move the field.\n\nMySQL said: %@", @"error moving field informative message"), [mySQLConnection lastErrorMessage]]); } else { [tableDataInstance resetAllData]; diff --git a/Source/SPTableTextFieldCell.m b/Source/SPTableTextFieldCell.m index 799cb4c0..ea70b01e 100644 --- a/Source/SPTableTextFieldCell.m +++ b/Source/SPTableTextFieldCell.m @@ -61,7 +61,7 @@ NSSize cellSize = [super cellSize]; cellSize.width = [[self attributedStringValue] size].width + (([self image] != nil) ? [[self image] size].width : 0) + 25; - cellSize.height = [[self attributedStringValue] size].height + 14.0; + cellSize.height = [[self attributedStringValue] size].height + 14.0f; return cellSize; } diff --git a/Source/SPTableTriggers.h b/Source/SPTableTriggers.h index 5cc8d59d..3ffac7fe 100644 --- a/Source/SPTableTriggers.h +++ b/Source/SPTableTriggers.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPTableView; +@class SPTableView, SPMySQLConnection; @interface SPTableTriggers : NSObject { @@ -50,7 +48,7 @@ IBOutlet NSBox *addTriggerTableBox; IBOutlet NSButton *confirmAddTriggerButton; - MCPConnection *connection; + SPMySQLConnection *connection; NSMutableArray *triggerData; @@ -64,7 +62,7 @@ NSString *editTriggerActionTime; } -@property (readwrite, assign) MCPConnection *connection; +@property (readwrite, assign) SPMySQLConnection *connection; - (void)loadTriggers; - (void)resetInterface; diff --git a/Source/SPTableTriggers.m b/Source/SPTableTriggers.m index 59fbb673..715498bb 100644 --- a/Source/SPTableTriggers.m +++ b/Source/SPTableTriggers.m @@ -30,6 +30,7 @@ #import "SPTableView.h" #import "SPAlertSheets.h" #import "SPServerSupport.h" +#import "SPMySQL.h" // Constants static const NSString *SPTriggerName = @"TriggerName"; @@ -189,7 +190,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode"; NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], nil, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), - [connection getLastErrorMessage]]); + [connection lastErrorMessage]]); return; } @@ -229,7 +230,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode"; NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], nil, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"The specified trigger was unable to be created.\n\nMySQL said: %@", @"error creating trigger informative message"), - [connection getLastErrorMessage]]); + [connection lastErrorMessage]]); // In case of error, re-create the original trigger statement if (isEdit) { @@ -346,7 +347,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode"; /** * Double-click action on table cells - for the time being, return NO to disable editing. */ -- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSUInteger)rowIndex +- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { if ([tableDocumentInstance isWorking]) return NO; @@ -427,7 +428,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode"; SPBeginAlertSheet(NSLocalizedString(@"Unable to delete trigger", @"error deleting trigger message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], nil, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), [connection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), [connection lastErrorMessage]]); // Abort loop break; diff --git a/Source/SPTablesList.h b/Source/SPTablesList.h index e5e76548..6da4f6cc 100644 --- a/Source/SPTablesList.h +++ b/Source/SPTablesList.h @@ -23,9 +23,7 @@ // // More info at -#import - -@class SPHistoryController, SPTableView; +@class SPHistoryController, SPTableView, SPMySQLConnection; @class SPDatabaseDocument, SPDatabaseData, SPTableStructure, SPTableContent; #ifdef SP_REFACTOR @@ -103,7 +101,7 @@ IBOutlet NSMenuItem *separatorTableMenuItem3; #endif - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; #ifndef SP_REFACTOR /* ivars */ // Table list context menu items @@ -153,7 +151,7 @@ - (IBAction)togglePaneCollapse:(id)sender; #endif // Additional methods -- (void)setConnection:(MCPConnection *)theConnection; +- (void)setConnection:(SPMySQLConnection *)theConnection; - (void)setSelectionState:(NSDictionary *)selectionDetails; #ifndef SP_REFACTOR /* method decls */ - (void)selectTableAtIndex:(NSNumber *)row; diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index e68bf4f6..09cd8cde 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -27,6 +27,7 @@ #import "SPDatabaseDocument.h" #import "SPTableStructure.h" #import "SPDatabaseViewController.h" +#import "SPMySQL.h" #ifndef SP_REFACTOR /* headers */ #import "SPTableContent.h" @@ -103,9 +104,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; */ - (IBAction)updateTables:(id)sender { - MCPResult *theResult; - NSArray *resultRow; - NSUInteger i; + SPMySQLResult *theResult; NSString *previousSelectedTable = nil; NSString *previousFilterString = nil; BOOL previousTableListIsSelectable = tableListIsSelectable; @@ -150,25 +149,24 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; // Select the table list for the current database. On MySQL versions after 5 this will include // views; on MySQL versions >= 5.0.02 select the "full" list to also select the table type column. theResult = [mySQLConnection queryString:@"SHOW /*!50002 FULL*/ TABLES"]; - if ([theResult numOfRows]) [theResult dataSeek:0]; - if ([theResult numOfFields] == 1) { - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - [tables addObject:[[theResult fetchRowAsArray] objectAtIndex:0]]; + [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray]; + if ([theResult numberOfFields] == 1) { + for (NSArray *eachRow in theResult) { + [tables addObject:[eachRow objectAtIndex:0]]; [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeTable]]; } } else { - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - resultRow = [theResult fetchRowAsArray]; + for (NSArray *eachRow in theResult) { + // Due to encoding problems it can be the case that [resultRow objectAtIndex:0] // return NSNull, thus catch that case for safety reasons - NSString *row = [resultRow objectAtIndex:0]; - NSString *tableName; - if([row isKindOfClass:[NSString class]]) - tableName = [NSString stringWithUTF8String:[row cStringUsingEncoding:[mySQLConnection stringEncoding]]]; - else + id tableName = [eachRow objectAtIndex:0]; + if ([tableName isNSNull]) { tableName = @"..."; + } [tables addObject:tableName]; - if ([[resultRow objectAtIndex:1] isEqualToString:@"VIEW"]) { + + if ([[eachRow objectAtIndex:1] isEqualToString:@"VIEW"]) { [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeView]]; tableListContainsViews = YES; } else { @@ -187,31 +185,31 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; * backward compatibility with pre 4 I believe. I left the other methods below, in case. */ if ([[tableDocumentInstance serverSupport] supportsInformationSchema]) { - NSString *pQuery = [NSString stringWithFormat:@"SELECT * FROM information_schema.routines WHERE routine_schema = '%@' ORDER BY routine_name",[tableDocumentInstance database]]; + NSString *pQuery = [NSString stringWithFormat:@"SELECT * FROM information_schema.routines WHERE routine_schema = %@ ORDER BY routine_name", [[tableDocumentInstance database] tickQuotedString]]; theResult = [mySQLConnection queryString:pQuery]; + [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray]; // Check for mysql errors - if information_schema is not accessible for some reasons // omit adding procedures and functions - if(![mySQLConnection queryErrored] && theResult != nil && [theResult numOfRows] ) { - // add the header row + if(![mySQLConnection queryErrored] && theResult != nil && [theResult numberOfRows] ) { + + // Add the header row [tables addObject:NSLocalizedString(@"PROCS & FUNCS",@"header for procs & funcs list")]; [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeNone]]; - [theResult dataSeek:0]; - if( [theResult numOfFields] == 1 ) { - for( i = 0; i < [theResult numOfRows]; i++ ) { - [tables addObject:NSArrayObjectAtIndex([theResult fetchRowAsArray],3)]; - if( [NSArrayObjectAtIndex([theResult fetchRowAsArray], 4) isEqualToString:@"PROCEDURE"]) { + if( [theResult numberOfFields] == 1 ) { + for (NSArray *eachRow in theResult) { + [tables addObject:NSArrayObjectAtIndex(eachRow, 3)]; + if ([NSArrayObjectAtIndex(eachRow, 4) isEqualToString:@"PROCEDURE"]) { [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeProc]]; } else { [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeFunc]]; } } } else { - for( i = 0; i < [theResult numOfRows]; i++ ) { - resultRow = [theResult fetchRowAsArray]; - [tables addObject:NSArrayObjectAtIndex(resultRow, 3)]; - if( [NSArrayObjectAtIndex(resultRow, 4) isEqualToString:@"PROCEDURE"] ) { + for (NSArray *eachRow in theResult) { + [tables addObject:NSArrayObjectAtIndex(eachRow, 3)]; + if ([NSArrayObjectAtIndex(eachRow, 4) isEqualToString:@"PROCEDURE"]) { [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeProc]]; } else { [tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeFunc]]; @@ -728,7 +726,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; /** * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once */ -- (void)setConnection:(MCPConnection *)theConnection +- (void)setConnection:(SPMySQLConnection *)theConnection { mySQLConnection = theConnection; [self updateTables:self]; @@ -1744,7 +1742,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to import a table via: \n%@\n\n\nMySQL said: %@", @"error importing table informative message"), - query, [mySQLConnection getLastErrorMessage]]]; + query, [mySQLConnection lastErrorMessage]]]; [alert setAlertStyle:NSCriticalAlertStyle]; [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"truncateTableError"]; @@ -2159,7 +2157,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; [alert addButtonWithTitle:NSLocalizedString(@"Stop", @"stop button")]; } [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 getLastErrorMessage]]]; + [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 setAlertStyle:NSWarningAlertStyle]; if ([indexes indexLessThanIndex:currentIndex] == NSNotFound) { [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:nil contextInfo:nil]; @@ -2218,7 +2216,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; alternateButton:nil otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to truncate the table '%@'.\n\nMySQL said: %@", @"error truncating table informative message"), - [filteredTables objectAtIndex:currentIndex], [mySQLConnection getLastErrorMessage]]]; + [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]]; [alert setAlertStyle:NSCriticalAlertStyle]; // NSArray *buttons = [alert buttons]; @@ -2339,7 +2337,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; SPBeginAlertSheet(NSLocalizedString(@"Error adding new table", @"error adding new table message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, @selector(sheetDidEnd:returnCode:contextInfo:), SPAddRow, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@'.\n\nMySQL said: %@", @"error adding new table informative message"), tableName, [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@'.\n\nMySQL said: %@", @"error adding new table informative message"), tableName, [mySQLConnection lastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; [[tablesListView onMainThread] reloadData]; @@ -2393,16 +2391,17 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; } // Get table/view structure - MCPResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", + SPMySQLResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", [tableType uppercaseString], [[filteredTables objectAtIndex:[tablesListView selectedRow]] backtickQuotedString] ]]; [queryResult setReturnDataAsStrings:YES]; - if ( ![queryResult numOfRows] ) { + if ( ![queryResult numberOfRows] ) { + //error while getting table structure SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection lastErrorMessage]]); } else { //insert new table name in create syntax and create new table @@ -2410,14 +2409,14 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; NSString *scanString; if(tblType == SPTableTypeView){ - scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create View"]]; + scanner = [[NSScanner alloc] initWithString:[[queryResult getRowAsDictionary] objectForKey:@"Create View"]]; [scanner scanUpToString:@"AS" intoString:nil]; [scanner scanUpToString:@"" intoString:&scanString]; [scanner release]; [mySQLConnection queryString:[NSString stringWithFormat:@"CREATE VIEW %@ %@", [[copyTableNameField stringValue] backtickQuotedString], scanString]]; } else if(tblType == SPTableTypeTable){ - scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create Table"]]; + scanner = [[NSScanner alloc] initWithString:[[queryResult getRowAsDictionary] objectForKey:@"Create Table"]]; [scanner scanUpToString:@"(" intoString:nil]; [scanner scanUpToString:@"" intoString:&scanString]; [scanner release]; @@ -2436,7 +2435,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; else if(tblType == SPTableTypeFunc || tblType == SPTableTypeProc) { // get the create syntax - MCPResult *theResult; + SPMySQLResult *theResult; if(selectedTableType == SPTableTypeProc) theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE PROCEDURE %@", [selectedTableName backtickQuotedString]]]; else if([self tableType] == SPTableTypeFunc) @@ -2448,20 +2447,20 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; if ([mySQLConnection queryErrored]) { if ([mySQLConnection isConnected]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the create syntax for '%@'.\nMySQL said: %@", @"message of panel when create syntax cannot be retrieved"), selectedTableName, [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the create syntax for '%@'.\nMySQL said: %@", @"message of panel when create syntax cannot be retrieved"), selectedTableName, [mySQLConnection lastErrorMessage]]); } return; } [theResult setReturnDataAsStrings:YES]; - NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; + NSString *tableSyntax = [[theResult getRowAsArray] objectAtIndex:2]; // replace the old name by the new one and drop the old one [mySQLConnection queryString:[tableSyntax stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:@"(?<=%@ )(`[^`]+?`)", [tableType uppercaseString]] withString:[[copyTableNameField stringValue] backtickQuotedString]]]; if ([mySQLConnection queryErrored]) { SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't duplicate '%@'.\nMySQL said: %@", @"message of panel when an item cannot be renamed"), [copyTableNameField stringValue], [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't duplicate '%@'.\nMySQL said: %@", @"message of panel when an item cannot be renamed"), [copyTableNameField stringValue], [mySQLConnection lastErrorMessage]]); } } @@ -2469,7 +2468,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; if ([mySQLConnection queryErrored]) { //error while creating new table SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't create '%@'.\nMySQL said: %@", @"message of panel when table cannot be created"), [copyTableNameField stringValue], [mySQLConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"Couldn't create '%@'.\nMySQL said: %@", @"message of panel when table cannot be created"), [copyTableNameField stringValue], [mySQLConnection lastErrorMessage]]); } else { if (copyTableContent) { @@ -2578,7 +2577,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; [mySQLConnection queryString:[NSString stringWithFormat:@"RENAME TABLE %@ TO %@", [oldTableName backtickQuotedString], [newTableName backtickQuotedString]]]; // check for errors if ([mySQLConnection queryErrored]) { - [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming '%@'.\n\nMySQL said: %@", @"rename table error informative message"), oldTableName, [mySQLConnection getLastErrorMessage]]; + [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming '%@'.\n\nMySQL said: %@", @"rename table error informative message"), oldTableName, [mySQLConnection lastErrorMessage]]; } return; @@ -2597,12 +2596,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; default: break; } - MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", stringTableType, [oldTableName backtickQuotedString] ] ]; + SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", stringTableType, [oldTableName backtickQuotedString] ] ]; if ([mySQLConnection queryErrored]) { - [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't retrieve the syntax for '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't retrieve syntax"), oldTableName, [mySQLConnection getLastErrorMessage]]; + [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't retrieve the syntax for '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't retrieve syntax"), oldTableName, [mySQLConnection lastErrorMessage]]; } [theResult setReturnDataAsStrings:YES]; - NSString *oldCreateSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; + NSString *oldCreateSyntax = [[theResult getRowAsArray] objectAtIndex:2]; // replace the old name with the new name NSRange rangeOfProcedureName = [oldCreateSyntax rangeOfString: [NSString stringWithFormat:@"%@ %@", stringTableType, [oldTableName backtickQuotedString] ] ]; @@ -2613,12 +2612,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable"; withString: [NSString stringWithFormat:@"%@ %@", stringTableType, [newTableName backtickQuotedString] ] ]; [mySQLConnection queryString: newCreateSyntax]; if ([mySQLConnection queryErrored]) { - [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't recreate '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't recreate procedure"), oldTableName, [mySQLConnection getLastErrorMessage]]; + [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't recreate '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't recreate procedure"), oldTableName, [mySQLConnection lastErrorMessage]]; } [mySQLConnection queryString: [NSString stringWithFormat: @"DROP %@ %@", stringTableType, [oldTableName backtickQuotedString]]]; if ([mySQLConnection queryErrored]) { - [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't delete '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't delete old procedure"), oldTableName, [mySQLConnection getLastErrorMessage]]; + [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't delete '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't delete old procedure"), oldTableName, [mySQLConnection lastErrorMessage]]; } return; } diff --git a/Source/SPTextView.h b/Source/SPTextView.h index dc0557f2..ac4391d8 100644 --- a/Source/SPTextView.h +++ b/Source/SPTextView.h @@ -23,14 +23,13 @@ // More info at #import -#import #import "NoodleLineNumberView.h" #import "SPCopyTable.h" #define SP_TEXT_SIZE_TRIGGER_FOR_PARTLY_PARSING 10000 -@class SPNarrowDownCompletion, SPDatabaseDocument, SPTablesList, SPCustomQuery; +@class SPNarrowDownCompletion, SPDatabaseDocument, SPTablesList, SPCustomQuery, SPMySQLConnection; @interface SPTextView : NSTextView #ifdef SP_REFACTOR @@ -65,7 +64,7 @@ NSUserDefaults *prefs; #endif - MCPConnection *mySQLConnection; + SPMySQLConnection *mySQLConnection; NSInteger mySQLmajorVersion; NSInteger snippetControlArray[20][3]; @@ -148,7 +147,7 @@ #endif - (void) doSyntaxHighlighting; - (NSBezierPath*)roundedBezierPathAroundRange:(NSRange)aRange; -- (void) setConnection:(MCPConnection *)theConnection withVersion:(NSInteger)majorVersion; +- (void) setConnection:(SPMySQLConnection *)theConnection withVersion:(NSInteger)majorVersion; - (void) doCompletionByUsingSpellChecker:(BOOL)isDictMode fuzzyMode:(BOOL)fuzzySearch autoCompleteMode:(BOOL)autoCompleteMode; - (void) doAutoCompletion; - (void) refreshCompletion; diff --git a/Source/SPTextView.m b/Source/SPTextView.m index 500e4892..b3db1b30 100644 --- a/Source/SPTextView.m +++ b/Source/SPTextView.m @@ -36,6 +36,7 @@ #import "SPBundleHTMLOutputController.h" #import "SPDatabaseViewController.h" #import "SPAppController.h" +#import "SPMySQL.h" #pragma mark - #pragma mark lex init @@ -227,7 +228,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse) #endif } -- (void) setConnection:(MCPConnection *)theConnection withVersion:(NSInteger)majorVersion +- (void) setConnection:(SPMySQLConnection *)theConnection withVersion:(NSInteger)majorVersion { mySQLConnection = theConnection; mySQLmajorVersion = majorVersion; diff --git a/Source/SPUserMO.h b/Source/SPUserMO.h index b77dfd04..90706ef5 100644 --- a/Source/SPUserMO.h +++ b/Source/SPUserMO.h @@ -38,4 +38,4 @@ - (void)addChildrenObject:(NSManagedObject *)value; - (void)removeChildrenObject:(NSManagedObject *)value; -@end \ No newline at end of file +@end diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h index 3df63a6f..11bb736e 100644 --- a/Source/SPUserManager.h +++ b/Source/SPUserManager.h @@ -22,9 +22,7 @@ // // More info at -#import - -@class SPServerSupport, BWAnchoredButtonBar; +@class SPServerSupport, SPMySQLConnection, BWAnchoredButtonBar; @interface SPUserManager : NSWindowController { @@ -35,7 +33,7 @@ BOOL isInitializing; - MCPConnection *mySqlConnection; + SPMySQLConnection *mySqlConnection; SPServerSupport *serverSupport; IBOutlet NSOutlineView *outlineView; @@ -75,7 +73,7 @@ NSMutableString *errorsString; } -@property (nonatomic, retain) MCPConnection *mySqlConnection; +@property (nonatomic, retain) SPMySQLConnection *mySqlConnection; @property (nonatomic, retain) SPServerSupport *serverSupport; @property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m index 83f0a12f..3b3add1e 100644 --- a/Source/SPUserManager.m +++ b/Source/SPUserManager.m @@ -29,6 +29,7 @@ #import "SPConnectionController.h" #import "SPServerSupport.h" #import "SPAlertSheets.h" +#import "SPMySQL.h" #import static const NSString *SPTableViewNameColumnID = @"NameColumn"; @@ -140,23 +141,11 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; NSMutableString *privKey; NSArray *privRow; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSMutableArray *resultAsArray = [NSMutableArray array]; NSMutableArray *usersResultArray = [NSMutableArray array]; // Select users from the mysql.user table - MCPResult *result = [self.mySqlConnection queryString:@"SELECT * FROM mysql.user ORDER BY user"]; - - NSUInteger rows = (NSUInteger)[result numOfRows]; - - if (rows > 0) [result dataSeek:0]; - - for (NSUInteger i = 0; i < rows; i++) - { - [resultAsArray addObject:[result fetchRowAsDictionary]]; - } - - [usersResultArray addObjectsFromArray:resultAsArray]; + SPMySQLResult *result = [self.mySqlConnection queryString:@"SELECT * FROM mysql.user ORDER BY user"]; + [usersResultArray addObjectsFromArray:[result getAllRows]]; [self _initializeTree:usersResultArray]; @@ -173,8 +162,8 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; [result setReturnDataAsStrings:YES]; } - if (result && [result numOfRows]) { - while ((privRow = [result fetchRowAsArray])) + if (result && [result numberOfRows]) { + while ((privRow = [result getRowAsArray])) { privKey = [NSMutableString stringWithString:[[privRow objectAtIndex:0] lowercaseString]]; @@ -193,7 +182,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; [result setReturnDataAsStrings:YES]; - while ((privRow = [result fetchRowAsArray])) + while ((privRow = [result getRowAsArray])) { privKey = [NSMutableString stringWithString:[privRow objectAtIndex:0]]; @@ -308,15 +297,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; { // Initialize Databases [schemas removeAllObjects]; - - MCPResult *results = [self.mySqlConnection listDBs]; - - if ([results numOfRows]) [results dataSeek:0]; - - for (NSUInteger i = 0; i < [results numOfRows]; i++) - { - [schemas addObject:[results fetchRowAsDictionary]]; - } + [schemas addObjectsFromArray:[self.mySqlConnection databases]]; [schemaController rearrangeObjects]; @@ -377,16 +358,10 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; NSString *queryString = [NSString stringWithFormat:@"SELECT * from mysql.db d WHERE d.user = %@ and d.host = %@", [[[child parent] valueForKey:@"user"] tickQuotedString], [[child valueForKey:@"host"] tickQuotedString]]; - MCPResult *queryResults = [self.mySqlConnection queryString:queryString]; + SPMySQLResult *queryResults = [self.mySqlConnection queryString:queryString]; - if ([queryResults numOfRows] > 0) { - // Go to the beginning - [queryResults dataSeek:0]; - } - - for (NSUInteger i = 0; i < [queryResults numOfRows]; i++) + for (NSDictionary *rowDict in queryResults) { - NSDictionary *rowDict = [queryResults fetchRowAsDictionary]; NSManagedObject *dbPriv = [NSEntityDescription insertNewObjectForEntityForName:@"Privileges" inManagedObjectContext:[self managedObjectContext]]; for (NSString *key in rowDict) @@ -1212,12 +1187,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; [[schemaPriv valueForKeyPath:@"user.host"] tickQuotedString], [dbName tickQuotedString]]; - MCPResult *result = [self.mySqlConnection queryString:statement]; - - NSUInteger rows = (NSUInteger)[result numOfRows]; - BOOL userExists = YES; - - if (rows == 0) userExists = NO; + NSArray *matchingUsers = [self.mySqlConnection getAllRowsFromQuery:statement]; for (NSString *key in self.privsSupportedByServer) { @@ -1228,7 +1198,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; [grantPrivileges addObject:[privilege replaceUnderscoreWithSpace]]; } else { - if (userExists || [grantPrivileges count] > 0) { + if ([matchingUsers count] || [grantPrivileges count] > 0) { [revokePrivileges addObject:[privilege replaceUnderscoreWithSpace]]; } } @@ -1433,11 +1403,11 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn"; { if ([self.mySqlConnection queryErrored]) { if (isSaving) { - [errorsString appendFormat:@"%@\n", [self.mySqlConnection getLastErrorMessage]]; + [errorsString appendFormat:@"%@\n", [self.mySqlConnection lastErrorMessage]]; } else { SPBeginAlertSheet(NSLocalizedString(@"An error occurred", @"mysql error occurred message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"An error occurred whilst trying to perform the operation.\n\nMySQL said: %@", @"mysql error occurred informative message"), [self.mySqlConnection getLastErrorMessage]]); + [NSString stringWithFormat:NSLocalizedString(@"An error occurred whilst trying to perform the operation.\n\nMySQL said: %@", @"mysql error occurred informative message"), [self.mySqlConnection lastErrorMessage]]); } return NO; diff --git a/Source/SPWindowAdditions.m b/Source/SPWindowAdditions.m index 676019ee..ab0b35bc 100644 --- a/Source/SPWindowAdditions.m +++ b/Source/SPWindowAdditions.m @@ -35,7 +35,7 @@ - (CGFloat)toolbarHeight { NSRect windowFrame; - CGFloat toolbarHeight = 0.0; + CGFloat toolbarHeight = 0.0f; if ([self toolbar] && [[self toolbar] isVisible]) { windowFrame = [NSWindow contentRectForFrameRect:[self frame] styleMask:[self styleMask]]; @@ -83,10 +83,12 @@ if( frontDoc && [frontDoc isKindOfClass:[SPDatabaseDocument class]] && [frontDoc valueForKeyPath:@"spHistoryControllerInstance"] && ![frontDoc isWorking]) + { if([anEvent deltaX] == -1.0f) [[frontDoc valueForKeyPath:@"spHistoryControllerInstance"] valueForKey:@"goForwardInHistory"]; else if([anEvent deltaX] == 1.0f) [[frontDoc valueForKeyPath:@"spHistoryControllerInstance"] valueForKey:@"goBackInHistory"]; + } } diff --git a/Source/SPWindowController.m b/Source/SPWindowController.m index 2ef62941..ed538312 100644 --- a/Source/SPWindowController.m +++ b/Source/SPWindowController.m @@ -586,8 +586,8 @@ enum { // Draw the background flipped, which is actually the right way up NSAffineTransform *transform = [NSAffineTransform transform]; - [transform translateXBy:0.0 yBy:[[[self window] contentView] frame].size.height]; - [transform scaleXBy:1.0 yBy:-1.0]; + [transform translateXBy:0.0f yBy:[[[self window] contentView] frame].size.height]; + [transform scaleXBy:1.0f yBy:-1.0f]; [transform concat]; [(id )[[aTabView delegate] style] drawBackgroundInRect:tabFrame]; [viewImage unlockFocus]; @@ -813,4 +813,4 @@ enum { [theDocument addObserver:self forKeyPath:@"isProcessing" options:0 context:nil]; } -@end \ No newline at end of file +@end diff --git a/Source/SPXMLExporter.m b/Source/SPXMLExporter.m index dfd55bf0..8ff99e0d 100644 --- a/Source/SPXMLExporter.m +++ b/Source/SPXMLExporter.m @@ -23,12 +23,11 @@ // // More info at -#import - #import "SPXMLExporter.h" #import "SPExportFile.h" #import "SPFileHandle.h" #import "SPExportUtilities.h" +#import "SPMySQL.h" @implementation SPXMLExporter @@ -73,9 +72,9 @@ NSString *dataConversionString = nil; // Result sets - MCPResult *statusResult = nil; - MCPResult *structureResult = nil; - MCPStreamingResult *streamingResult = nil; + SPMySQLResult *statusResult = nil; + SPMySQLResult *structureResult = nil; + SPMySQLFastStreamingResult *streamingResult = nil; NSMutableArray *xmlTags = [NSMutableArray array]; NSMutableString *xmlString = [NSMutableString string]; @@ -107,7 +106,7 @@ isTableExport = YES; - totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue]; + totalRows = [[connection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] integerValue]; streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self xmlTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]]; // Only include the structure if necessary @@ -118,17 +117,12 @@ [escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])]; statusResult = [connection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE %@", escapedTableName]]; - if ([structureResult numOfRows] && [statusResult numOfRows]) { - - [statusResult dataSeek:0]; - [structureResult dataSeek:0]; - + if ([structureResult numberOfRows] && [statusResult numberOfRows]) { + [xmlString appendFormat:@"\t\n", [self xmlTableName]]; - for (i = 0; i < [structureResult numOfRows]; i++) + for (NSDictionary *row in structureResult) { - NSDictionary *row = [structureResult fetchRowAsDictionary]; - [xmlString appendFormat:@"\t\t\n", [row objectForKey:@"Field"], [row objectForKey:@"Type"], @@ -138,7 +132,7 @@ [row objectForKey:@"Extra"]]; } - NSDictionary *row = [statusResult fetchRowAsDictionary]; + NSDictionary *row = [statusResult getRowAsDictionary]; [xmlString appendFormat:@"\n\t\t\n", [row objectForKey:@"Name"], @@ -175,7 +169,7 @@ if ((!isTableExport) || (isTableExport && [self xmlOutputIncludeContent])) { // Set up an array of encoded field names as opening and closing tags - fieldNames = ([self xmlDataArray]) ? NSArrayObjectAtIndex([self xmlDataArray], 0) : [streamingResult fetchFieldNames]; + fieldNames = ([self xmlDataArray]) ? NSArrayObjectAtIndex([self xmlDataArray], 0) : [streamingResult fieldNames]; for (i = 0; i < [fieldNames count]; i++) { @@ -225,7 +219,7 @@ } // Or by reading an appropriate row from the streaming result else { - xmlRow = [streamingResult fetchNextRowAsArray]; + xmlRow = [streamingResult getRowAsArray]; if (!xmlRow) break; } @@ -265,14 +259,14 @@ [xmlItem setString:[NSString stringWithString:dataConversionString]]; [dataConversionString release]; } - else if ([data isKindOfClass:[NSNull class]]) { + else if (data == [NSNull null]) { dataIsNULL = YES; if ([self xmlFormat] == SPXMLExportPlainFormat) { [xmlItem setString:[self xmlNULLString]]; } } - else if ([data isKindOfClass:[MCPGeometryData class]]) { + else if ([data isKindOfClass:[SPMySQLGeometryData class]]) { [xmlItem setString:[data wktString]]; } else { diff --git a/Source/SPXMLExporterDelegate.m b/Source/SPXMLExporterDelegate.m index 7f286c46..013019b2 100644 --- a/Source/SPXMLExporterDelegate.m +++ b/Source/SPXMLExporterDelegate.m @@ -27,6 +27,7 @@ #import "SPXMLExporter.h" #import "SPDatabaseDocument.h" #import "SPExportFile.h" +#import "SPMySQL.h" @implementation SPExportController (SPXMLExporterDelegate) -- cgit v1.2.3