From f12e8dfc1453248b843efe9066570206c26bbdd6 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Wed, 22 Sep 2010 14:42:40 +0000 Subject: =?UTF-8?q?=E2=80=A2=C2=A0fixed=20issue836=20by=20avoiding=20the?= =?UTF-8?q?=20fact=20that=20while=20selecting=20a=20new=20table=20the=20CR?= =?UTF-8?q?EATE=20SYNTAX=20will=20be=20parsed=20twice=20under=20certain=20?= =?UTF-8?q?circumstances=20which=20led=20to=20this=20issue=20-=20introduce?= =?UTF-8?q?d=20a=20isWorking=20mechanism=20to=20SPTableData;=20while=20SPT?= =?UTF-8?q?ableData=20is=20updating=20its=20cache=20(ie=20the=20CREATE=20S?= =?UTF-8?q?YNTAX=20is=20being=20parsed)=20each=20request=20for=20values=20?= =?UTF-8?q?will=20return=20nil=20or=20an=20empty=20array;=20the=20caller?= =?UTF-8?q?=20is=20responsible=20to=20decide=20what=20to=20do=20=E2=80=A2?= =?UTF-8?q?=20various=20commenting=20stuff=20=E2=80=A2=20various=20speed?= =?UTF-8?q?=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/SPTableData.h | 4 + Source/SPTableData.m | 279 +++++++++++++++++++++++++++++++--------------- Source/SPTableStructure.m | 33 +++--- 3 files changed, 213 insertions(+), 103 deletions(-) (limited to 'Source') diff --git a/Source/SPTableData.h b/Source/SPTableData.h index 88b0a78f..ade1d30e 100644 --- a/Source/SPTableData.h +++ b/Source/SPTableData.h @@ -41,8 +41,12 @@ NSString *tableCreateSyntax; MCPConnection *mySQLConnection; + + BOOL isWorking; } +@property (readwrite, assign) BOOL isWorking; + - (void) setConnection:(MCPConnection *)theConnection; - (NSString *) tableEncoding; - (NSString *) tableCreateSyntax; diff --git a/Source/SPTableData.m b/Source/SPTableData.m index db9cccfe..edff16b6 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -35,6 +35,11 @@ @implementation SPTableData +@synthesize isWorking; + +/** + * Init class. + */ - (id) init { if ((self = [super init])) { @@ -47,14 +52,17 @@ tableEncoding = nil; tableCreateSyntax = nil; mySQLConnection = nil; + isWorking = NO; } return self; } -/* +/** * Set the connection for use. * Called by the connect sheet methods. + * + * @param theConnection The used connection for the SPDatabaseDocument */ - (void) setConnection:(MCPConnection *)theConnection { @@ -63,11 +71,15 @@ } -/* +/** * Retrieve the encoding for the current table, using or refreshing the cache as appropriate. */ - (NSString *) tableEncoding { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + if (tableEncoding == nil) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -78,11 +90,15 @@ return (tableEncoding == nil) ? nil : [NSString stringWithString:tableEncoding]; } -/* +/** * Retrieve the create syntax for the current table, using or refreshing the cache as appropriate. */ - (NSString *) tableCreateSyntax { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + if (tableCreateSyntax == nil) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -99,11 +115,15 @@ } -/* +/** * Retrieve all columns for the current table as an array, using or refreshing the cache as appropriate. */ - (NSArray *) columns { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return [NSArray array]; + if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -114,14 +134,24 @@ return columns; } +/** + * Retrieve all constraints. + */ - (NSArray *) getConstraints { return constraints; } +/** + * Retrieve all triggers used in the current selected table. + */ - (NSArray *) triggers { + // Return if CREATE SYNTAX is being parsed + if(isWorking) return [NSArray array]; + + // If triggers is nil, the triggers need to be loaded - if a table is selected on MySQL >= 5.0.2 if (!triggers) { if ([tableListInstance tableType] == SPTableTypeTable @@ -137,11 +167,18 @@ return (NSArray *)triggers; } -/* - * Retrieve a column with a specified name, using or refreshing the cache as appropriate. +/** + * Retrieve a NSDictionary containing all parameters of the column with a specified name, using or refreshing the cache as appropriate. + * + * @param colName The column name. */ - (NSDictionary *) columnWithName:(NSString *)colName { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + + if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -155,11 +192,16 @@ } -/* +/** * Retrieve column names for the current table as an array, using or refreshing the cache as appropriate. */ - (NSArray *) columnNames { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return [NSArray array]; + + if ([columnNames count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -171,11 +213,17 @@ } -/* - * Retrieve a specified column for the current table as a dictionary, using or refreshing the cache as appropriate. +/** + * Retrieve a NSDictionary containing all parameters of the column with a specific index, using or refreshing the cache as appropriate. + * + * @param index The index of the column array. */ - (NSDictionary *) columnAtIndex:(NSInteger)index { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -186,13 +234,19 @@ return [columns objectAtIndex:index]; } -/* +/** * Checks if this column is type text or blob. * Used to determine if we have to show a popup when we edit a value from this column. + * + * @param colName The column name which should be checked. */ - (BOOL) columnIsBlobOrText:(NSString *)colName { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return YES; // to be at the safe side + if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { [self updateInformationForCurrentView]; @@ -205,20 +259,30 @@ } -/* +/** * Retrieve the table status value for a supplied key, using or refreshing the cache as appropriate. + * + * @param aKey The key name of the underlying NSDictionary */ - (NSString *) statusValueForKey:(NSString *)aKey { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + if ([status count] == 0) { [self updateStatusInformationForCurrentTable]; } return [status objectForKey:aKey]; } -/* +/** * Set the table status value for the supplied key. This method is useful for when status values are obtained * via other means and are subsequently more accurate than the value currently set. + * + * @param value The string value for the passed key name. + * + * @param key The key name. */ - (void)setStatusValue:(NSString *)value forKey:(NSString *)key { @@ -226,11 +290,15 @@ } -/* +/** * Retrieve all known status values as a dictionary, using or refreshing the cache as appropriate. */ - (NSDictionary *) statusValues { + + // Return if CREATE SYNTAX is being parsed + if(isWorking) return nil; + if ([status count] == 0) { [self updateStatusInformationForCurrentTable]; } @@ -238,7 +306,7 @@ } -/* +/** * Flushes all caches - should be used on major changes, for example table changes. */ - (void) resetAllData @@ -264,7 +332,7 @@ } -/* +/** * Flushes any status-related caches. */ - (void) resetStatusData @@ -273,7 +341,7 @@ } -/* +/** * Flushes any field/column-related caches. */ - (void) resetColumnData @@ -283,12 +351,14 @@ } -/* +/** * Retrieves the information for the current table and stores it in cache. * Returns a boolean indicating success. */ - (BOOL) updateInformationForCurrentTable { + isWorking = YES; + NSDictionary *tableData = nil; NSDictionary *columnData; NSEnumerator *enumerator; @@ -302,6 +372,7 @@ } if (tableData == nil ) { + isWorking = NO; return FALSE; } @@ -317,11 +388,51 @@ } tableEncoding = [[NSString alloc] initWithString:[tableData objectForKey:@"encoding"]]; + isWorking = NO; + return TRUE; } +/** + * Retrieves the information for the current view and stores it in cache. + * Returns a boolean indicating success. + */ +- (BOOL) updateInformationForCurrentView +{ + + isWorking = YES; + + NSDictionary *viewData = [self informationForView:[tableListInstance tableName]]; + NSDictionary *columnData; + NSEnumerator *enumerator; + + if (viewData == nil) { + [columns removeAllObjects]; + [columnNames removeAllObjects]; + [constraints removeAllObjects]; + isWorking = NO; + return FALSE; + } + + [columns addObjectsFromArray:[viewData objectForKey:@"columns"]]; -/* + enumerator = [columns objectEnumerator]; + while (columnData = [enumerator nextObject]) { + [columnNames addObject:[NSString stringWithString:[columnData objectForKey:@"name"]]]; + } + + if (tableEncoding != nil) { + [tableEncoding release]; + } + tableEncoding = [[NSString alloc] initWithString:[viewData objectForKey:@"encoding"]]; + + isWorking = NO; + + return TRUE; +} + + +/** * Retrieve the CREATE TABLE string for a table and analyse it to extract the field * details, primary key, unique keys, and table encoding. * In future this could also be used to retrieve the majority of index information @@ -652,40 +763,8 @@ } -/* - * Retrieves the information for the current view and stores it in cache. - * Returns a boolean indicating success. - */ -- (BOOL) updateInformationForCurrentView -{ - NSDictionary *viewData = [self informationForView:[tableListInstance tableName]]; - NSDictionary *columnData; - NSEnumerator *enumerator; - - if (viewData == nil) { - [columns removeAllObjects]; - [columnNames removeAllObjects]; - [constraints removeAllObjects]; - return FALSE; - } - - [columns addObjectsFromArray:[viewData objectForKey:@"columns"]]; - - enumerator = [columns objectEnumerator]; - while (columnData = [enumerator nextObject]) { - [columnNames addObject:[NSString stringWithString:[columnData objectForKey:@"name"]]]; - } - - if (tableEncoding != nil) { - [tableEncoding release]; - } - tableEncoding = [[NSString alloc] initWithString:[viewData objectForKey:@"encoding"]]; - - return TRUE; -} - -/* +/** * Retrieve information which can be used to display views. Unlike tables, all the information * for views cannot be extracted from the CREATE ALGORITHM syntax without selecting all the info * from the referenced tables. For the time being we therefore use the column information for @@ -815,16 +894,21 @@ -/* +/** * Retrieve the status of a table as a dictionary and add it to the local cache for reuse. */ - (BOOL)updateStatusInformationForCurrentTable { + + isWorking = YES; + BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; // Catch unselected tables and return false - if ([[tableListInstance tableName] isEqualToString:@""] || ![tableListInstance tableName]) + if ([[tableListInstance tableName] isEqualToString:@""] || ![tableListInstance tableName]) { + isWorking = NO; return FALSE; + } // Ensure queries are run as UTF8 if (changeEncoding) { @@ -867,6 +951,7 @@ [mySQLConnection getLastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } + isWorking = NO; return FALSE; } @@ -884,6 +969,7 @@ if ([[status objectForKey:@"Engine"] isNSNull]) { [status setDictionary:[NSDictionary dictionaryWithObjectsAndKeys:@"Error", @"Engine", [NSString stringWithFormat:NSLocalizedString(@"An error occurred retrieving table information. MySQL said: %@", @"MySQL table info retrieval error message"), [status objectForKey:@"Comment"]], @"Comment", [tableListInstance tableName], @"Name", nil]]; if (changeEncoding) [mySQLConnection restoreStoredEncoding]; + isWorking = NO; return FALSE; } @@ -918,6 +1004,8 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; + isWorking = NO; + return TRUE; } @@ -927,6 +1015,8 @@ - (BOOL) updateTriggersForCurrentTable { + isWorking = YES; + // Ensure queries are made in UTF8 BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; if (changeEncoding) { @@ -949,6 +1039,7 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } + isWorking = NO; return NO; } @@ -960,10 +1051,12 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; + isWorking = NO; + return YES; } -/* +/** * Parse an array of field definition parts - not including name but including type and optionally unsigned/zerofill/null * and so forth - into a dictionary of parsed details. Intended for use both with CREATE TABLE syntax - with fuller * details - and with the "type" column from SHOW COLUMNS. @@ -980,13 +1073,15 @@ NSString *detailString; NSInteger i, definitionPartsIndex = 0, partsArrayLength; + NSCharacterSet *whitespaceCharacterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + // Skip blank items within the definition parts while (definitionPartsIndex < [definitionParts count] - && ![[[definitionParts objectAtIndex:definitionPartsIndex] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) + && ![[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex) stringByTrimmingCharactersInSet:whitespaceCharacterSet] length]) definitionPartsIndex++; // The first item is always the data type. - [fieldParser setString:[definitionParts objectAtIndex:definitionPartsIndex]]; + [fieldParser setString:NSArrayObjectAtIndex(definitionParts, definitionPartsIndex)]; definitionPartsIndex++; // If no field length definition is present, store only the type @@ -1003,7 +1098,7 @@ [detailParser setString:[fieldParser stringFromCharacter:'(' toCharacter:')' inclusively:NO]]; detailParts = [[NSMutableArray alloc] initWithArray:[detailParser splitStringByCharacter:',']]; for (i = 0; i < [detailParts count]; i++) { - [detailParser setString:[detailParts objectAtIndex:i]]; + [detailParser setString:NSArrayObjectAtIndex(detailParts, i)]; [detailParts replaceObjectAtIndex:i withObject:[detailParser unquotedString]]; } [fieldDetails setObject:[NSArray arrayWithArray:detailParts] forKey:@"values"]; @@ -1016,7 +1111,7 @@ [detailParser setString:[detailParts objectAtIndex:0]]; [fieldDetails setObject:[detailParser unquotedString] forKey:@"length"]; if ([detailParts count] > 1) { - [detailParser setString:[detailParts objectAtIndex:1]]; + [detailParser setString:NSArrayObjectAtIndex(detailParts, 1)]; [fieldDetails setObject:[detailParser unquotedString] forKey:@"decimals"]; } [detailParts release]; @@ -1060,70 +1155,75 @@ } [detailString release]; + + NSNumber *boolYES = [NSNumber numberWithBool:YES]; + NSNumber *boolNO = [NSNumber numberWithBool:NO]; + // Set up some column defaults for all columns - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"null"]; - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"unsigned"]; - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"binary"]; - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"zerofill"]; - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"autoincrement"]; - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"onupdatetimestamp"]; + [fieldDetails setValue:boolYES forKey:@"null"]; + [fieldDetails setValue:boolNO forKey:@"unsigned"]; + [fieldDetails setValue:boolNO forKey:@"binary"]; + [fieldDetails setValue:boolNO forKey:@"zerofill"]; + [fieldDetails setValue:boolNO forKey:@"autoincrement"]; + [fieldDetails setValue:boolNO forKey:@"onupdatetimestamp"]; [fieldDetails setValue:@"" forKey:@"comment"]; [fieldDetails setValue:[NSMutableString string] forKey:@"unparsed"]; // Walk through the remaining column definition parts storing recognised details partsArrayLength = [definitionParts count]; + id aValue; for ( ; definitionPartsIndex < partsArrayLength; definitionPartsIndex++) { - detailString = [[NSString alloc] initWithString:[[definitionParts objectAtIndex:definitionPartsIndex] uppercaseString]]; + detailString = [[NSString alloc] initWithString:[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex) uppercaseString]]; // Whether numeric fields are unsigned if ([detailString isEqualToString:@"UNSIGNED"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"unsigned"]; + [fieldDetails setValue:boolYES forKey:@"unsigned"]; // Whether numeric fields are zerofill } else if ([detailString isEqualToString:@"ZEROFILL"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"zerofill"]; + [fieldDetails setValue:boolYES forKey:@"zerofill"]; // Whether text types are binary } else if ([detailString isEqualToString:@"BINARY"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"binary"]; + [fieldDetails setValue:boolYES forKey:@"binary"]; // Whether text types have a different encoding to the table } else if ([detailString isEqualToString:@"CHARSET"] && (definitionPartsIndex + 1 < partsArrayLength)) { - if (![[[definitionParts objectAtIndex:definitionPartsIndex+1] uppercaseString] isEqualToString:@"DEFAULT"]) { - [fieldDetails setValue:[definitionParts objectAtIndex:definitionPartsIndex+1] forKey:@"encoding"]; + if (![[aValue = NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1) uppercaseString] isEqualToString:@"DEFAULT"]) { + [fieldDetails setValue:aValue forKey:@"encoding"]; } definitionPartsIndex++; } else if ([detailString isEqualToString:@"CHARACTER"] && (definitionPartsIndex + 2 < partsArrayLength) - && [[[definitionParts objectAtIndex:definitionPartsIndex+1] uppercaseString] isEqualToString:@"SET"]) { - if (![[[definitionParts objectAtIndex:definitionPartsIndex+2] uppercaseString] isEqualToString:@"DEFAULT"]) {; - [fieldDetails setValue:[definitionParts objectAtIndex:definitionPartsIndex+2] forKey:@"encoding"]; + && [[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1) uppercaseString] isEqualToString:@"SET"]) { + if (![[aValue = NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+2) uppercaseString] isEqualToString:@"DEFAULT"]) { + [fieldDetails setValue:aValue forKey:@"encoding"]; } definitionPartsIndex += 2; // Whether text types have a different collation to the table } else if ([detailString isEqualToString:@"COLLATE"] && (definitionPartsIndex + 1 < partsArrayLength)) { - if (![[[definitionParts objectAtIndex:definitionPartsIndex+1] uppercaseString] isEqualToString:@"DEFAULT"]) { - [fieldDetails setValue:[definitionParts objectAtIndex:definitionPartsIndex+1] forKey:@"collation"]; + if (![[aValue = NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1) uppercaseString] isEqualToString:@"DEFAULT"]) { + [fieldDetails setValue:aValue forKey:@"collation"]; } definitionPartsIndex++; // Whether fields are NOT NULL } else if ([detailString isEqualToString:@"NOT"] && (definitionPartsIndex + 1 < partsArrayLength) - && [[[definitionParts objectAtIndex:definitionPartsIndex+1] uppercaseString] isEqualToString:@"NULL"]) { - [fieldDetails setValue:[NSNumber numberWithBool:NO] forKey:@"null"]; + && [[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1) uppercaseString] isEqualToString:@"NULL"]) { + [fieldDetails setValue:boolNO forKey:@"null"]; definitionPartsIndex++; // Whether fields are NULL } else if ([detailString isEqualToString:@"NULL"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"null"]; + [fieldDetails setValue:boolYES forKey:@"null"]; // Whether fields should auto-increment } else if ([detailString isEqualToString:@"AUTO_INCREMENT"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"autoincrement"]; + [fieldDetails setValue:boolYES forKey:@"autoincrement"]; // Field defaults } else if ([detailString isEqualToString:@"DEFAULT"] && (definitionPartsIndex + 1 < partsArrayLength)) { - detailParser = [[SPSQLParser alloc] initWithString:[definitionParts objectAtIndex:definitionPartsIndex+1]]; + detailParser = [[SPSQLParser alloc] initWithString:NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1)]; if([[detailParser unquotedString] isEqualToString:@"NULL"]) [fieldDetails setObject:[NSNull null] forKey:@"default"]; else @@ -1133,14 +1233,14 @@ // Special timestamp case - Whether fields are set to update the current timestamp } else if ([detailString isEqualToString:@"ON"] && (definitionPartsIndex + 2 < partsArrayLength) - && [[[definitionParts objectAtIndex:definitionPartsIndex+1] uppercaseString] isEqualToString:@"UPDATE"] - && [[[definitionParts objectAtIndex:definitionPartsIndex+2] uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"]) { - [fieldDetails setValue:[NSNumber numberWithBool:YES] forKey:@"onupdatetimestamp"]; + && [[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1) uppercaseString] isEqualToString:@"UPDATE"] + && [[NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+2) uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"]) { + [fieldDetails setValue:boolYES forKey:@"onupdatetimestamp"]; definitionPartsIndex += 2; // Column comments } else if ([detailString isEqualToString:@"COMMENT"] && (definitionPartsIndex + 1 < partsArrayLength)) { - detailParser = [[SPSQLParser alloc] initWithString:[definitionParts objectAtIndex:definitionPartsIndex+1]]; + detailParser = [[SPSQLParser alloc] initWithString:NSArrayObjectAtIndex(definitionParts, definitionPartsIndex+1)]; [fieldDetails setValue:[detailParser unquotedString] forKey:@"comment"]; [detailParser release]; definitionPartsIndex++; @@ -1149,7 +1249,7 @@ // TODO: Currently unhandled: [UNIQUE | PRIMARY] KEY | COLUMN_FORMAT bar | STORAGE q | REFERENCES... } else { [[fieldDetails objectForKey:@"unparsed"] appendString:@" "]; - [[fieldDetails objectForKey:@"unparsed"] appendString:[definitionParts objectAtIndex:definitionPartsIndex]]; + [[fieldDetails objectForKey:@"unparsed"] appendString:NSArrayObjectAtIndex(definitionParts, definitionPartsIndex)]; } [detailString release]; @@ -1158,7 +1258,7 @@ return [fieldDetails autorelease]; } -/* +/** * Return the column names which are set to PRIMIARY KEY; returns nil if no PRIMARY KEY is set. */ - (NSArray *)primaryKeyColumnNames @@ -1201,8 +1301,8 @@ for( i = 0; i < [r numOfRows]; i++ ) { resultRow = [r fetchRowAsArray]; // check if the row is indeed a key (for MySQL servers before 5.0.3) - if ([[[resultRow objectAtIndex:3] description] isEqualToString:@"PRI"]) { - [keyColumns addObject:[[resultRow objectAtIndex:0] description]]; + if ([[NSArrayObjectAtIndex(resultRow ,3) description] isEqualToString:@"PRI"]) { + [keyColumns addObject:[NSArrayObjectAtIndex(resultRow ,0) description]]; } } @@ -1215,6 +1315,9 @@ #pragma mark - +/** + * Dealloc the class + */ - (void) dealloc { [columns release]; diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index 410a9bd3..f0556ba8 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -150,7 +150,6 @@ */ - (void)loadTable:(NSString *)aTable { - NSMutableArray *theTableFields = [NSMutableArray array]; NSArray *theTableIndexes; NSMutableDictionary *theTableEnumLists = [NSMutableDictionary dictionary]; NSInteger i; @@ -164,6 +163,9 @@ return; } + NSMutableArray *theTableFields = [[NSMutableArray alloc] init]; + [theTableFields setArray:[NSArray array]]; + // Make a mutable copy out of the cached [tableDataInstance columns] since we're adding infos for(id col in [tableDataInstance columns]) [theTableFields addObject:[[col mutableCopy] autorelease]]; @@ -205,16 +207,15 @@ // Set up the encoding PopUpButtonCell NSArray *encodings = [databaseDataInstance getDatabaseCharacterSetEncodings]; - if (([encodings count] > 0) && ([tableDataInstance tableEncoding])) { + if ([encodings count]) { NSString *selectedTitle = @""; [encodingPopupCell removeAllItems]; [encodingPopupCell addItemWithTitle:@""]; + // Populate encoding popup button for (NSDictionary *encoding in encodings) - { - NSString *menuItemTitle = (![encoding objectForKey:@"DESCRIPTION"]) ? [encoding objectForKey:@"CHARACTER_SET_NAME"] : [NSString stringWithFormat:@"%@ (%@)", [encoding objectForKey:@"DESCRIPTION"], [encoding objectForKey:@"CHARACTER_SET_NAME"]]; - [encodingPopupCell addItemWithTitle:menuItemTitle]; - } + [encodingPopupCell addItemWithTitle:(![encoding objectForKey:@"DESCRIPTION"]) ? [encoding objectForKey:@"CHARACTER_SET_NAME"] : [NSString stringWithFormat:@"%@ (%@)", [encoding objectForKey:@"DESCRIPTION"], [encoding objectForKey:@"CHARACTER_SET_NAME"]]]; + } else { [encodingPopupCell addItemWithTitle:NSLocalizedString(@"Not available", @"not available label")]; @@ -296,6 +297,7 @@ // Send the query finished/work complete notification [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [theTableFields release]; } /** @@ -330,10 +332,10 @@ [indexesController setTable:selectedTable]; // Reset the table store and display + [tableFields removeAllObjects]; [enumFields removeAllObjects]; [tableSourceView deselectAll:self]; [indexesTableView deselectAll:self]; - [tableFields removeAllObjects]; [addFieldButton setEnabled:NO]; [copyFieldButton setEnabled:NO]; [removeFieldButton setEnabled:NO]; @@ -1380,13 +1382,14 @@ returns a dictionary containing enum/set field names as key and possible values if (rowIndex >= [tableFields count]) return @"..."; if([[tableColumn identifier] isEqualToString:@"collation"]) { - if([[[tableFields objectAtIndex:rowIndex] objectForKey:@"encoding"] integerValue] > 0) { - NSString *enc = [[encodingPopupCell itemAtIndex:[[[tableFields objectAtIndex:rowIndex] objectForKey:@"encoding"] integerValue]] title]; + NSInteger idx = 0; + if((idx = [[NSArrayObjectAtIndex(tableFields,rowIndex) objectForKey:@"encoding"] integerValue]) > 0) { + NSString *enc = [[encodingPopupCell itemAtIndex:idx] title]; NSInteger start = [enc rangeOfString:@"("].location+1; NSInteger end = [enc length] - start - 1; collations = [databaseDataInstance getDatabaseCollationsForEncoding:[enc substringWithRange:NSMakeRange(start, end)]]; } else { - if([tableDataInstance tableEncoding]) { + if([tableDataInstance tableEncoding] != nil) { collations = [databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]]; } else { collations = [NSArray array]; @@ -1403,7 +1406,7 @@ returns a dictionary containing enum/set field names as key and possible values } } - return [[tableFields objectAtIndex:rowIndex] objectForKey:[tableColumn identifier]]; + return [NSArrayObjectAtIndex(tableFields, rowIndex) objectForKey:[tableColumn identifier]]; } - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex @@ -1790,10 +1793,10 @@ would result in a position change. } else { // validate cell against current field type - NSDictionary *theRow = [tableFields objectAtIndex:rowIndex]; + NSDictionary *theRow = NSArrayObjectAtIndex(tableFields, rowIndex); NSString *theRowType = @""; - if([theRow objectForKey:@"type"]) - theRowType = [[[theRow objectForKey:@"type"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; + if(theRowType = [theRow objectForKey:@"type"]) + theRowType = [[theRowType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; // Only string fields allow encoding settings if(([[aTableColumn identifier] isEqualToString:@"encoding"])) { @@ -1874,7 +1877,7 @@ would result in a position change. - (id)comboBoxCell:(NSComboBoxCell *)aComboBoxCell objectValueForItemAtIndex:(NSInteger)index { - return [typeSuggestions objectAtIndex:index]; + return NSArrayObjectAtIndex(typeSuggestions, index); } - (NSInteger)numberOfItemsInComboBoxCell:(NSComboBoxCell *)aComboBoxCell -- cgit v1.2.3