diff options
author | rowanbeentje <rowan@beent.je> | 2011-02-11 02:06:18 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2011-02-11 02:06:18 +0000 |
commit | e3ac547a6fb5b73581e61bb35ac2f3f7fca67a96 (patch) | |
tree | 8ed159102057d9a26a5dd13e303cf1ce37da7c3b /Source/SPTableData.m | |
parent | f5a99e49839174bdfa2364fbba1c963da4a3481b (diff) | |
download | sequelpro-e3ac547a6fb5b73581e61bb35ac2f3f7fca67a96.tar.gz sequelpro-e3ac547a6fb5b73581e61bb35ac2f3f7fca67a96.tar.bz2 sequelpro-e3ac547a6fb5b73581e61bb35ac2f3f7fca67a96.zip |
- Revert r3187, which only masked an underlying bug and caused double columns in views
- In SPTableStructureDelete, don't request the encoding if the table is reloading; this prevents multithreaded data fetches and race conditions causing Issue #974.
- Alter SPTableData to use thread mutexes instead of a boolean to prevent threading issues, which also fixes Issue #974 in a different way. Alter race condition checks to block their threads instead of returning bogus information to prevent state issues.
- Alter table loading to no longer load trigger information until required, speeding up use of other views and cleaning up the console log.
Diffstat (limited to 'Source/SPTableData.m')
-rw-r--r-- | Source/SPTableData.m | 110 |
1 files changed, 53 insertions, 57 deletions
diff --git a/Source/SPTableData.m b/Source/SPTableData.m index 28717864..c63d10ff 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -31,11 +31,13 @@ #import "RegexKitLite.h" #import "SPServerSupport.h" +@interface SPTableData (PrivateAPI) +- (void)_loopWhileWorking; +@end + @implementation SPTableData -@synthesize isWorking; @synthesize tableHasAutoIncrementField; -; /** * Init class. @@ -52,9 +54,9 @@ tableEncoding = nil; tableCreateSyntax = nil; mySQLConnection = nil; - isWorking = NO; tableHasAutoIncrementField = NO; + pthread_mutex_init(&dataProcessingLock, NULL); } return self; @@ -79,8 +81,8 @@ - (NSString *) tableEncoding { - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if (tableEncoding == nil) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -98,8 +100,8 @@ - (NSString *) tableCreateSyntax { - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if (tableCreateSyntax == nil) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -123,8 +125,8 @@ - (NSArray *) columns { - // Return if CREATE SYNTAX is being parsed - if(isWorking) return [NSArray array]; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -149,9 +151,8 @@ */ - (NSArray *) triggers { - // Return if CREATE SYNTAX is being parsed - if (isWorking) return [NSArray array]; - + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; // If triggers is nil, the triggers need to be loaded - if a table is selected on MySQL >= 5.0.2 if (!triggers) { @@ -173,10 +174,8 @@ */ - (NSDictionary *) columnWithName:(NSString *)colName { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; - + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -196,10 +195,8 @@ */ - (NSArray *) columnNames { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return [NSArray array]; - + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columnNames count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -219,9 +216,8 @@ */ - (NSDictionary *) columnAtIndex:(NSInteger)index { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -242,9 +238,8 @@ - (BOOL) columnIsBlobOrText:(NSString *)colName { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return YES; // to be at the safe side + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -266,9 +261,8 @@ - (BOOL) columnIsGeometry:(NSString *)colName { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return YES; // to be at the safe side + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([columns count] == 0) { if ([tableListInstance tableType] == SPTableTypeView) { @@ -289,9 +283,8 @@ */ - (NSString *) statusValueForKey:(NSString *)aKey { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([status count] == 0) { [self updateStatusInformationForCurrentTable]; @@ -318,9 +311,8 @@ */ - (NSDictionary *) statusValues { - - // Return if CREATE SYNTAX is being parsed - if(isWorking) return nil; + // If processing is already in action, wait for it to complete + [self _loopWhileWorking]; if ([status count] == 0) { [self updateStatusInformationForCurrentTable]; @@ -380,7 +372,7 @@ */ - (BOOL) updateInformationForCurrentTable { - isWorking = YES; + pthread_mutex_lock(&dataProcessingLock); NSDictionary *tableData = nil; NSDictionary *columnData; @@ -396,7 +388,7 @@ } if (tableData == nil ) { - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return FALSE; } @@ -412,7 +404,7 @@ } tableEncoding = [[NSString alloc] initWithString:[tableData objectForKey:@"encoding"]]; - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return TRUE; } @@ -423,8 +415,7 @@ */ - (BOOL) updateInformationForCurrentView { - - isWorking = YES; + pthread_mutex_lock(&dataProcessingLock); NSDictionary *viewData = [self informationForView:[tableListInstance tableName]]; NSDictionary *columnData; @@ -436,7 +427,7 @@ [columns removeAllObjects]; [columnNames removeAllObjects]; [constraints removeAllObjects]; - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return FALSE; } @@ -452,7 +443,7 @@ } tableEncoding = [[NSString alloc] initWithString:[viewData objectForKey:@"encoding"]]; - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return TRUE; } @@ -476,10 +467,6 @@ unichar quoteCharacter; BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; - [columns removeAllObjects]; - [columnNames removeAllObjects]; - [constraints removeAllObjects]; - // Catch unselected tables and return nil if ([tableName isEqualToString:@""] || !tableName) return nil; @@ -925,14 +912,13 @@ */ - (BOOL)updateStatusInformationForCurrentTable { - - isWorking = YES; + pthread_mutex_lock(&dataProcessingLock); BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; // Catch unselected tables and return false if ([[tableListInstance tableName] isEqualToString:@""] || ![tableListInstance tableName]) { - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return FALSE; } @@ -979,7 +965,7 @@ [mySQLConnection getLastErrorMessage]]); if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return FALSE; } @@ -997,7 +983,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; + pthread_mutex_unlock(&dataProcessingLock); return FALSE; } @@ -1032,7 +1018,7 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return TRUE; } @@ -1042,8 +1028,7 @@ */ - (BOOL) updateTriggersForCurrentTable { - - isWorking = YES; + pthread_mutex_lock(&dataProcessingLock); // Ensure queries are made in UTF8 BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; @@ -1067,7 +1052,7 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; } - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return NO; } @@ -1079,7 +1064,7 @@ if (changeEncoding) [mySQLConnection restoreStoredEncoding]; - isWorking = NO; + pthread_mutex_unlock(&dataProcessingLock); return YES; } @@ -1364,7 +1349,18 @@ if (tableCreateSyntax) [tableCreateSyntax release]; if (mySQLConnection) [mySQLConnection release]; + pthread_mutex_destroy(&dataProcessingLock); + [super dealloc]; } -@end +#pragma mark - +#pragma mark Private API + +- (void)_loopWhileWorking +{ + while (pthread_mutex_trylock(&dataProcessingLock)) usleep(10000); + pthread_mutex_unlock(&dataProcessingLock); +} + +@end
\ No newline at end of file |