diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CustomQuery.m | 53 | ||||
-rw-r--r-- | Source/TableContent.m | 116 | ||||
-rw-r--r-- | Source/TableSource.m | 15 |
3 files changed, 100 insertions, 84 deletions
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index eab76897..c07f4d24 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -396,7 +396,7 @@ BOOL suppressErrorSheet = NO; BOOL tableListNeedsReload = NO; BOOL databaseWasChanged = NO; - BOOL queriesSeparatedByDelimiter = NO; + // BOOL queriesSeparatedByDelimiter = NO; NSCharacterSet *whitespaceAndNewlineSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; @@ -415,16 +415,22 @@ } long queryCount = [queries count]; + NSMutableArray *tempQueries = [NSMutableArray arrayWithCapacity:queryCount]; // Perform the supplied queries in series for ( i = 0 ; i < queryCount ; i++ ) { + NSString *query = [NSArrayObjectAtIndex(queries, i) stringByTrimmingCharactersInSet:whitespaceAndNewlineSet]; + // Don't run blank queries, or queries which only contain whitespace. - if ([[NSArrayObjectAtIndex(queries, i) stringByTrimmingCharactersInSet:whitespaceAndNewlineSet] length] == 0) + if (![query length]) continue; + // store trimmed queries for usedQueries and history + [tempQueries addObject:query]; + // Run the query, timing execution (note this also includes network and overhead) - theResult = [mySQLConnection queryString:[queries objectAtIndex:i]]; + theResult = [mySQLConnection queryString:query]; executionTime += [mySQLConnection lastQueryExecutionTime]; totalQueriesRun++; @@ -462,9 +468,9 @@ case NSAlertSecondButtonReturn: break; default: - if(i < [queries count]-1) // output that message only if it was not the last one + if(i < queryCount-1) // output that message only if it was not the last one [errors appendString:NSLocalizedString(@"Execution stopped!\n", @"execution stopped message")]; - i = [queries count]; // break for loop; for safety reasons stop the execution of the following queries + i = queryCount; // break for loop; for safety reasons stop the execution of the following queries } } else { @@ -478,9 +484,9 @@ } else { // Check if table/db list needs an update // The regex is a compromise between speed and usefullness. TODO: further improvements are needed - if(!tableListNeedsReload && [[queries objectAtIndex:i] isMatchedByRegex:@"(?i)\\b(create|alter|drop|rename)\\b\\s+."]) + if(!tableListNeedsReload && [query isMatchedByRegex:@"(?i)\\b(create|alter|drop|rename)\\b\\s+."]) tableListNeedsReload = YES; - if(!databaseWasChanged && [[queries objectAtIndex:i] isMatchedByRegex:@"(?i)\\b(use|drop\\s+database|drop\\s+schema)\\b\\s+."]) + if(!databaseWasChanged && [query isMatchedByRegex:@"(?i)\\b(use|drop\\s+database|drop\\s+schema)\\b\\s+."]) databaseWasChanged = YES; } } @@ -500,13 +506,12 @@ if(usedQuery) [usedQuery release]; - if(!queriesSeparatedByDelimiter) - usedQuery = [[NSString stringWithString:[queries componentsJoinedByString:@";\n"]] retain]; - else // TODO how to combine the query array if “delimiter command” was used? - usedQuery = @""; + + // if(!queriesSeparatedByDelimiter) // TODO: How to combine queries delimited by DELIMITER? + usedQuery = [[NSString stringWithString:[tempQueries componentsJoinedByString:@";\n"]] retain]; //perform empty query if no query is given - if ( [queries count] == 0 ) { + if ( !queryCount ) { theResult = [mySQLConnection queryString:@""]; [errors setString:[mySQLConnection getLastErrorMessage]]; } @@ -525,17 +530,19 @@ } //add query to history - if(!queriesSeparatedByDelimiter) { // TODO only add to history if no “delimiter” command was used - [queryHistoryButton insertItemWithTitle:[queries componentsJoinedByString:@"; "] atIndex:1]; - while ( [queryHistoryButton numberOfItems] > [[prefs objectForKey:@"CustomQueryMaxHistoryItems"] intValue] + 1 ) { - [queryHistoryButton removeItemAtIndex:[queryHistoryButton numberOfItems]-1]; - } - for ( i = 1 ; i < [queryHistoryButton numberOfItems] ; i++ ) - { - [menuItems addObject:[queryHistoryButton itemTitleAtIndex:i]]; - } - [prefs setObject:menuItems forKey:@"queryHistory"]; - } + // if(!queriesSeparatedByDelimiter) { // TODO only add to history if no “delimiter” command was used + [queryHistoryButton insertItemWithTitle:usedQuery atIndex:1]; + + int maxHistoryItems = [[prefs objectForKey:@"CustomQueryMaxHistoryItems"] intValue]; + + while ( [queryHistoryButton numberOfItems] > maxHistoryItems + 1 ) + [queryHistoryButton removeItemAtIndex:[queryHistoryButton numberOfItems]-1]; + + for ( i = 1 ; i < [queryHistoryButton numberOfItems] ; i++ ) + [menuItems addObject:[queryHistoryButton itemTitleAtIndex:i]]; + + [prefs setObject:menuItems forKey:@"queryHistory"]; + // Error checking if ( [errors length] ) { diff --git a/Source/TableContent.m b/Source/TableContent.m index 06f7899a..cd894188 100644 --- a/Source/TableContent.m +++ b/Source/TableContent.m @@ -1472,31 +1472,37 @@ - (NSArray *)fetchResultAsArray:(CMMCPResult *)theResult { NSArray *columns; - NSMutableArray *tempResult = [NSMutableArray array]; + unsigned long numOfRows = [theResult numOfRows]; + NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows]; NSDictionary *tempRow; NSMutableDictionary *modifiedRow = [NSMutableDictionary dictionary]; NSEnumerator *enumerator; id key; int i, j; - + Class nullClass = [NSNull class]; + id prefsNullValue = [prefs objectForKey:@"NullValue"]; + BOOL prefsLoadBlobsAsNeeded = [prefs boolForKey:@"LoadBlobsAsNeeded"]; + columns = [tableDataInstance columns]; - if ([theResult numOfRows]) [theResult dataSeek:0]; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { + long columnsCount = [columns count]; + + if (numOfRows) [theResult dataSeek:0]; + for ( i = 0 ; i < numOfRows ; i++ ) { tempRow = [theResult fetchRowAsDictionary]; enumerator = [tempRow keyEnumerator]; while ( key = [enumerator nextObject] ) { - if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) { - [modifiedRow setObject:[prefs stringForKey:@"NullValue"] forKey:key]; + if ( [[tempRow objectForKey:key] isMemberOfClass:nullClass] ) { + [modifiedRow setObject:prefsNullValue forKey:key]; } else { [modifiedRow setObject:[tempRow objectForKey:key] forKey:key]; } } // Add values for hidden blob and text fields if appropriate - if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] ) { - for ( j = 0 ; j < [columns count] ; j++ ) { + if ( prefsLoadBlobsAsNeeded ) { + for ( j = 0 ; j < columnsCount ; j++ ) { if ( [tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(columns, j) objectForKey:@"name"] ] ) { [modifiedRow setObject:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields") forKey:[NSArrayObjectAtIndex(columns, j) objectForKey:@"name"]]; } @@ -2043,55 +2049,55 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn } - (void)tableView: (CMCopyTable *)aTableView - willDisplayCell: (id)cell - forTableColumn: (NSTableColumn*)aTableColumn - row: (int)row + willDisplayCell: (id)cell + forTableColumn: (NSTableColumn*)aTableColumn + row: (int)row /* - * This function changes the text color of - * text/blob fields which are not yet loaded to gray - */ + * This function changes the text color of + * text/blob fields which are not yet loaded to gray +*/ { - // Check if loading of text/blob fields is disabled - // If not, all text fields are loaded and we don't have to make them gray - if ([prefs boolForKey:@"LoadBlobsAsNeeded"]) - { - // Make sure that the cell actually responds to setTextColor: - // In the future, we might use different cells for the table view - // that don't support this selector - if ([cell respondsToSelector:@selector(setTextColor:)]) - { - NSArray *columns = [tableDataInstance columns]; - NSArray *columnNames = [tableDataInstance columnNames]; - NSString *columnTypeGrouping; - NSUInteger indexOfColumn; - - // We have to find the index of the current column - // Make sure we find it, otherwise return (We might decide in the future - // to add a column to the TableView that doesn't correspond to a column - // of the Mysql table...) - indexOfColumn = [columnNames indexOfObject:[aTableColumn identifier]]; - if (indexOfColumn == NSNotFound) return; - - // Test if the current column is a text or a blob field - columnTypeGrouping = [[columns objectAtIndex:indexOfColumn] objectForKey:@"typegrouping"]; - if ([columnTypeGrouping isEqualToString:@"textdata"] || [columnTypeGrouping isEqualToString:@"blobdata"]) { - - // now check if the field has been loaded already or not - if ([[cell stringValue] isEqualToString:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields")]) - { - // change the text color of the cell to gray - [cell setTextColor: [NSColor grayColor]]; - } - else - { - // Change the text color back to black - // This is necessary because NSTableView reuses - // the NSCell to draw further rows in the column - [cell setTextColor: [NSColor blackColor]]; - } - } - } - } + // Check if loading of text/blob fields is disabled + // If not, all text fields are loaded and we don't have to make them gray + if ([prefs boolForKey:@"LoadBlobsAsNeeded"]) + { + // Make sure that the cell actually responds to setTextColor: + // In the future, we might use different cells for the table view + // that don't support this selector + if ([cell respondsToSelector:@selector(setTextColor:)]) + { + NSArray *columns = [tableDataInstance columns]; + NSArray *columnNames = [tableDataInstance columnNames]; + NSString *columnTypeGrouping; + NSUInteger indexOfColumn; + + // We have to find the index of the current column + // Make sure we find it, otherwise return (We might decide in the future + // to add a column to the TableView that doesn't correspond to a column + // of the Mysql table...) + indexOfColumn = [columnNames indexOfObject:[aTableColumn identifier]]; + if (indexOfColumn == NSNotFound) return; + + // Test if the current column is a text or a blob field + columnTypeGrouping = [[columns objectAtIndex:indexOfColumn] objectForKey:@"typegrouping"]; + if ([columnTypeGrouping isEqualToString:@"textdata"] || [columnTypeGrouping isEqualToString:@"blobdata"]) { + + // now check if the field has been loaded already or not + if ([[cell stringValue] isEqualToString:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields")]) + { + // change the text color of the cell to gray + [cell setTextColor: [NSColor grayColor]]; + } + else + { + // Change the text color back to black + // This is necessary because NSTableView reuses + // the NSCell to draw further rows in the column + [cell setTextColor: [NSColor blackColor]]; + } + } + } + } } - (void)tableView:(NSTableView *)aTableView diff --git a/Source/TableSource.m b/Source/TableSource.m index e9c416cf..24fd13a5 100644 --- a/Source/TableSource.m +++ b/Source/TableSource.m @@ -544,22 +544,25 @@ fetches the result as an array with a dictionary for each row in it */ - (NSArray *)fetchResultAsArray:(CMMCPResult *)theResult { - NSMutableArray *tempResult = [NSMutableArray array]; + unsigned long numOfRows = [theResult numOfRows]; + NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows]; NSMutableDictionary *tempRow; NSArray *keys; id key; int i; + Class nullClass = [NSNull class]; + id prefsNullValue = [prefs objectForKey:@"NullValue"]; - if ([theResult numOfRows]) [theResult dataSeek:0]; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { + if (numOfRows) [theResult dataSeek:0]; + for ( i = 0 ; i < numOfRows ; i++ ) { tempRow = [NSMutableDictionary dictionaryWithDictionary:[theResult fetchRowAsDictionary]]; //use NULL string from preferences instead of the NSNull oject returned by the framework keys = [tempRow allKeys]; for (int i = 0; i < [keys count] ; i++) { - key = [keys objectAtIndex:i]; - if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) - [tempRow setObject:[prefs objectForKey:@"NullValue"] forKey:key]; + key = NSArrayObjectAtIndex(keys, i); + if ( [[tempRow objectForKey:key] isMemberOfClass:nullClass] ) + [tempRow setObject:prefsNullValue forKey:key]; } // change some fields to be more human-readable or GUI compatible if ( [[tempRow objectForKey:@"Extra"] isEqualToString:@""] ) { |