From 44cdc2f18931a6d5a7571b2dc485120a73b33b57 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sun, 3 Jan 2010 13:37:54 +0000 Subject: - Ensure all results for server variable requests are returned as strings, to avoid binary-mode result issues with certain versions of MySQL (including 4.1.14). This should address Issue #509. - TableDocument now requests the server version string from MCPConnection, aiding caching --- Source/CustomQuery.m | 1 + Source/SPDatabaseData.m | 1 + Source/SPExportController.m | 1 + Source/SPProcessListController.m | 1 + Source/SPServerVariablesController.m | 1 + Source/SPTableData.m | 23 ++++++++------------- Source/SPUserManager.m | 2 ++ Source/TableContent.m | 2 ++ Source/TableDocument.m | 39 +++++++++++++++--------------------- Source/TableDump.m | 2 ++ Source/TableSource.m | 3 +++ Source/TablesList.m | 27 ++++++++++--------------- 12 files changed, 49 insertions(+), 54 deletions(-) (limited to 'Source') diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index 17763ddd..71ed2ec4 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -1278,6 +1278,7 @@ // Get the primary key if there is one MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@", [database backtickQuotedString], [tableForColumn backtickQuotedString]]]; + [theResult setReturnDataAsStrings:YES]; if ([theResult numOfRows]) [theResult dataSeek:0]; int i; for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { diff --git a/Source/SPDatabaseData.m b/Source/SPDatabaseData.m index 98fedd4f..07220f59 100644 --- a/Source/SPDatabaseData.m +++ b/Source/SPDatabaseData.m @@ -299,6 +299,7 @@ const CHAR_SETS charsets[] = // Check if InnoDB support is enabled MCPResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'have_innodb'"]; + [result setReturnDataAsStrings:YES]; if ([result numOfRows] == 1) { if ([[[result fetchRowAsDictionary] objectForKey:@"Value"] isEqualToString:@"YES"]) { diff --git a/Source/SPExportController.m b/Source/SPExportController.m index d7c0882f..c4fa682c 100644 --- a/Source/SPExportController.m +++ b/Source/SPExportController.m @@ -418,6 +418,7 @@ // Determine whether this table is a table or a view via the create table command, and get the table details MCPResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]]; + [queryResult setReturnDataAsStrings:YES]; if ([queryResult numOfRows]) { tableDetails = [NSDictionary dictionaryWithDictionary:[queryResult fetchRowAsDictionary]]; diff --git a/Source/SPProcessListController.m b/Source/SPProcessListController.m index 5087ef2a..63529a29 100644 --- a/Source/SPProcessListController.m +++ b/Source/SPProcessListController.m @@ -418,6 +418,7 @@ // Get processes MCPResult *processList = [connection queryString:@"SHOW PROCESSLIST"]; + [processList setReturnDataAsStrings:YES]; if ([processList numOfRows]) [processList dataSeek:0]; diff --git a/Source/SPServerVariablesController.m b/Source/SPServerVariablesController.m index 3046c2dd..dd3632e5 100644 --- a/Source/SPServerVariablesController.m +++ b/Source/SPServerVariablesController.m @@ -289,6 +289,7 @@ // Get processes MCPResult *serverVariables = [connection queryString:@"SHOW VARIABLES"]; + [serverVariables setReturnDataAsStrings:YES]; if ([serverVariables numOfRows]) [serverVariables dataSeek:0]; diff --git a/Source/SPTableData.m b/Source/SPTableData.m index fb777b9d..0ccac919 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -320,6 +320,7 @@ // Retrieve the CREATE TABLE syntax for the table MCPResult *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 if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) { @@ -339,13 +340,8 @@ if (tableCreateSyntax != nil) [tableCreateSyntax release]; - if ([[syntaxResult objectAtIndex:1] isKindOfClass:[NSData class]]) { - tableCreateSyntax = [[NSString alloc] initWithData:[syntaxResult objectAtIndex:1] encoding:[mySQLConnection encoding]]; - createTableParser = [[SPSQLParser alloc] initWithData:[syntaxResult objectAtIndex:1] encoding:[mySQLConnection encoding]]; - } else { - tableCreateSyntax = [[NSString alloc] initWithString:[syntaxResult objectAtIndex:1]]; - createTableParser = [[SPSQLParser alloc] initWithString:[syntaxResult objectAtIndex:1]]; - } + tableCreateSyntax = [[NSString alloc] initWithString:[syntaxResult objectAtIndex:1]]; + createTableParser = [[SPSQLParser alloc] initWithString:[syntaxResult objectAtIndex:1]]; // Extract the fields definition string from the CREATE TABLE syntax fieldsParser = [[SPSQLParser alloc] initWithString:[createTableParser trimAndReturnStringFromCharacter:'(' toCharacter:')' trimmingInclusively:YES returningInclusively:NO skippingBrackets:YES]]; @@ -632,6 +628,7 @@ MCPResult *theResult = [mySQLConnection queryString: [NSString stringWithFormat: @"SHOW CREATE TABLE %@", [viewName backtickQuotedString] ]]; + [theResult setReturnDataAsStrings:YES]; // Check for any errors, but only display them if a connection still exists if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) { @@ -645,17 +642,11 @@ } // Retrieve the table syntax string - NSArray *syntaxResult = [theResult fetchRowAsArray]; - - if ([[syntaxResult objectAtIndex:1] isKindOfClass:[NSData class]]) { - tableCreateSyntax = [[NSString alloc] initWithData:[syntaxResult objectAtIndex:1] encoding:[mySQLConnection encoding]]; - } else { - tableCreateSyntax = [[NSString alloc] initWithString:[syntaxResult objectAtIndex:1]]; - } - + tableCreateSyntax = [[NSString alloc] initWithString:[[theResult fetchRowAsArray] objectAtIndex:1]]; // Retrieve the SHOW COLUMNS syntax for the table theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [viewName backtickQuotedString]]]; + [theResult setReturnDataAsStrings:YES]; // Check for any errors, but only display them if a connection still exists if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) { @@ -757,6 +748,7 @@ } else if ([tableListInstance tableType] == SP_TABLETYPE_TABLE) { tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE '%@'", escapedTableName ]]; + [tableStatusResult setReturnDataAsStrings:YES]; } // Check for any errors, only displaying them if the connection hasn't been terminated @@ -1008,6 +1000,7 @@ NSMutableArray *keyColumns = [NSMutableArray array]; r = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@ WHERE `key` = 'PRI'", [selectedTable backtickQuotedString]]]; + [r setReturnDataAsStrings:YES]; if([r numOfRows] < 1) return nil; diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m index 811e353e..83ffa52d 100644 --- a/Source/SPUserManager.m +++ b/Source/SPUserManager.m @@ -148,6 +148,7 @@ // Attempt to use SHOW PRIVILEGES syntax - supported since 4.1.0 result = [self.mySqlConnection queryString:@"SHOW PRIVILEGES"]; + [result setReturnDataAsStrings:YES]; if ([result numOfRows]) { while (privRow = [result fetchRowAsArray]) { privKey = [NSMutableString stringWithString:[[privRow objectAtIndex:0] lowercaseString]]; @@ -159,6 +160,7 @@ // If that fails, base privilege support on the mysql.users columns } else { result = [self.mySqlConnection queryString:@"SHOW COLUMNS FROM `mysql`.`user`"]; + [result setReturnDataAsStrings:YES]; while (privRow = [result fetchRowAsArray]) { privKey = [NSMutableString stringWithString:[privRow objectAtIndex:0]]; if (![privKey hasSuffix:@"_priv"]) continue; diff --git a/Source/TableContent.m b/Source/TableContent.m index 4cc301c2..c4f60029 100644 --- a/Source/TableContent.m +++ b/Source/TableContent.m @@ -1279,6 +1279,7 @@ //set autoincrement fields to NULL 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++ ) { row = [queryResult fetchRowAsDictionary]; @@ -1899,6 +1900,7 @@ setLimit = NO; 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]; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index 0bd76f6f..c7ab7105 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -648,15 +648,7 @@ } // Get the mysql version - theResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE 'version'"]; - version = [[theResult fetchRowAsArray] objectAtIndex:1]; - if (mySQLVersion) [mySQLVersion release], mySQLVersion = nil; - if ( [version isKindOfClass:[NSData class]] ) { - // starting with MySQL 4.1.14 the mysql variables are returned as nsdata - mySQLVersion = [[NSString alloc] initWithData:version encoding:[mySQLConnection encoding]]; - } else { - mySQLVersion = [[NSString alloc] initWithString:version]; - } + mySQLVersion = [[NSString alloc] initWithString:[mySQLConnection serverVersionString]]; // Update the selected database if appropriate if ([connectionController database] && ![[connectionController database] isEqualToString:@""]) { @@ -1640,17 +1632,22 @@ */ - (NSString *)databaseEncoding { + MCPResult *charSetResult; + NSString *mysqlEncoding; + // MySQL > 4.0 - id mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set_connection'"] fetchRowAsDictionary] objectForKey:@"Value"]; + charSetResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set_connection'"]; + [charSetResult setReturnDataAsStrings:YES]; + mysqlEncoding = [[charSetResult fetchRowAsDictionary] objectForKey:@"Value"]; _supportsEncoding = (mysqlEncoding != nil); - if ( [mysqlEncoding isKindOfClass:[NSData class]] ) { // MySQL 4.1.14 returns the mysql variables as nsdata - mysqlEncoding = [mySQLConnection stringWithText:mysqlEncoding]; - } - if ( !mysqlEncoding ) { // mysql 4.0 or older -> only default character set possible, cannot choose others using "set names xy" + // mysql 4.0 or older -> only default character set possible, cannot choose others using "set names xy" + if ( !mysqlEncoding ) { mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] fetchRowAsDictionary] objectForKey:@"Value"]; } - if ( !mysqlEncoding ) { // older version? -> set encoding to mysql default encoding latin1 + + // older version? -> set encoding to mysql default encoding latin1 + if ( !mysqlEncoding ) { NSLog(@"Error: no character encoding found, mysql version is %@", [self mySQLVersion]); mysqlEncoding = @"latin1"; } @@ -1709,6 +1706,7 @@ if (query == nil) return; MCPResult *theResult = [mySQLConnection queryString:query]; + [theResult setReturnDataAsStrings:YES]; // Check for errors, only displaying if the connection hasn't been terminated if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) { @@ -1719,10 +1717,7 @@ return; } - id tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs]; - - if ([tableSyntax isKindOfClass:[NSData class]]) - tableSyntax = [[[NSString alloc] initWithData:tableSyntax encoding:[mySQLConnection encoding]] autorelease]; + NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs]; [createTableSyntaxTextField setStringValue:[NSString stringWithFormat:@"Create syntax for %@ '%@'", typeString, [self table]]]; @@ -1767,6 +1762,7 @@ return; MCPResult *theResult = [mySQLConnection queryString:query]; + [theResult setReturnDataAsStrings:YES]; // Check for errors, only displaying if the connection hasn't been terminated if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) { @@ -1776,10 +1772,7 @@ return; } - id tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs]; - - if ([tableSyntax isKindOfClass:[NSData class]]) - tableSyntax = [[[NSString alloc] initWithData:tableSyntax encoding:[mySQLConnection encoding]] autorelease]; + NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs]; // copy to the clipboard NSPasteboard *pb = [NSPasteboard generalPasteboard]; diff --git a/Source/TableDump.m b/Source/TableDump.m index de782dd6..39bc6d0f 100644 --- a/Source/TableDump.m +++ b/Source/TableDump.m @@ -1420,6 +1420,7 @@ // Determine whether this table is a table or a view via the create table command, and keep the create table syntax queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]]; + [queryResult setReturnDataAsStrings:YES]; if ( [queryResult numOfRows] ) { tableDetails = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]]; if ([tableDetails objectForKey:@"Create View"]) { @@ -2353,6 +2354,7 @@ // Determine whether this table is a table or a view via the create table command, and get the table details queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]]; + [queryResult setReturnDataAsStrings:YES]; if ( [queryResult numOfRows] ) { tableDetails = [NSDictionary dictionaryWithDictionary:[queryResult fetchRowAsDictionary]]; if ([tableDetails objectForKey:@"Create View"]) { diff --git a/Source/TableSource.m b/Source/TableSource.m index 6f73e9a5..bf431326 100644 --- a/Source/TableSource.m +++ b/Source/TableSource.m @@ -98,6 +98,7 @@ loads aTable, put it in an array, update the tableViewColumns and reload the tab //perform queries and load results in array (each row as a dictionary) tableSourceResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]] retain]; + [tableSourceResult setReturnDataAsStrings:YES]; // listFieldsFromTable is broken in the current version of the framework (no back-ticks for table name)! // tableSourceResult = [[mySQLConnection listFieldsFromTable:selectedTable] retain]; @@ -106,6 +107,7 @@ loads aTable, put it in an array, update the tableViewColumns and reload the tab [tableSourceResult release]; indexResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [selectedTable backtickQuotedString]]] retain]; + [indexResult setReturnDataAsStrings:YES]; // [indexes setArray:[[self fetchResultAsArray:indexResult] retain]]; [indexes setArray:[self fetchResultAsArray:indexResult]]; [indexResult release]; @@ -972,6 +974,7 @@ returns a dictionary containing enum/set field names as key and possible values int i; queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; + [queryResult setReturnDataAsStrings:YES]; if ([queryResult numOfRows]) [queryResult dataSeek:0]; [tempResult addObject:[queryResult fetchFieldNames]]; diff --git a/Source/TablesList.m b/Source/TablesList.m index 6d60faed..3a6462a7 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -1242,10 +1242,8 @@ return; } - id tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; - - if ([tableSyntax isKindOfClass:[NSData class]]) - tableSyntax = [[[NSString alloc] initWithData:tableSyntax encoding:[mySQLConnection encoding]] autorelease]; + [theResult setReturnDataAsStrings:YES]; + NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; // replace the old name by the new one and drop the old one [mySQLConnection queryString:[tableSyntax stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:@"(?<=%@ )(`[^`]+?`)", tableType] withString:[anObject backtickQuotedString]]]; @@ -1991,7 +1989,8 @@ [tableType uppercaseString], [[filteredTables objectAtIndex:[tablesListView selectedRow]] backtickQuotedString] ]]; - + [queryResult setReturnDataAsStrings:YES]; + if ( ![queryResult numOfRows] ) { //error while getting table structure NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, @@ -2044,10 +2043,8 @@ return; } - id tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; - - if ([tableSyntax isKindOfClass:[NSData class]]) - tableSyntax = [[[NSString alloc] initWithData:tableSyntax encoding:[mySQLConnection encoding]] autorelease]; + [theResult setReturnDataAsStrings:YES]; + NSString *tableSyntax = [[theResult fetchRowAsArray] 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]]]; @@ -2173,14 +2170,12 @@ } return; } - - id tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; - - if ([tableSyntax isKindOfClass:[NSData class]]) - tableSyntax = [[[NSString alloc] initWithData:tableSyntax encoding:[mySQLConnection encoding]] autorelease]; - + + [theResult setReturnDataAsStrings:YES]; + NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2]; + NSString *tableType; - + switch([self tableType]){ case SP_TABLETYPE_TABLE: tableType = NSLocalizedString(@"table",@"table"); -- cgit v1.2.3