From 54ad42a1627e41a0402cfae9fc2a62e5f603e806 Mon Sep 17 00:00:00 2001 From: Stuart Connolly Date: Tue, 9 Oct 2018 21:36:12 +0100 Subject: [PATCH] Fix UI interation from background thread when adding a new table. --- Source/SPTablesList.m | 93 ++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index 4c35f05c3..9837f2faf 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -55,17 +55,26 @@ #import // Constants +// +// Actions static NSString *SPAddRow = @"SPAddRow"; static NSString *SPAddNewTable = @"SPAddNewTable"; static NSString *SPRemoveTable = @"SPRemoveTable"; static NSString *SPTruncateTable = @"SPTruncateTable"; static NSString *SPDuplicateTable = @"SPDuplicateTable"; +// New table +static NSString *SPNewTableName = @"SPNewTableName"; +static NSString *SPNewTableType = @"SPNewTableType"; +static NSString *SPNewTableCharacterSet = @"SPNewTableCharacterSet"; +static NSString *SPNewTableCollation = @"SPNewTableCollation"; + @interface SPTablesList () - (void)_removeTable:(BOOL)force; - (void)_truncateTable; - (void)_addTable; +- (void)_addTableWithDetails:(NSDictionary *)tableDetails; - (void)_copyTable; - (void)_renameTableOfType:(SPTableType)tableType from:(NSString *)oldTableName to:(NSString *)newTableName; - (void)_duplicateConnectionToFrontTab; @@ -734,30 +743,25 @@ - (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSSt } else if ([contextInfo isEqualToString:SPRemoveTable]) { if (returnCode == NSAlertDefaultReturn) { - [self _removeTable:([[(NSAlert *)sheet suppressionButton] state] == NSOnState)]; + [self _removeTable:[[(NSAlert *)sheet suppressionButton] state] == NSOnState]; } } -#ifndef SP_CODA else if ([contextInfo isEqualToString:SPTruncateTable]) { if (returnCode == NSAlertDefaultReturn) { [self _truncateTable]; } } - else -#endif - if ([contextInfo isEqualToString:SPAddNewTable]) { + else if ([contextInfo isEqualToString:SPAddNewTable]) { [addTableCharsetHelper setEnabled:NO]; if (returnCode == NSOKButton) { [self _addTable]; } } -#ifndef SP_CODA else if ([contextInfo isEqualToString:SPDuplicateTable]) { if (returnCode == NSOKButton) { [self _copyTable]; } } -#endif } #pragma mark - @@ -2355,25 +2359,57 @@ - (void)_truncateTable #endif /** - * Adds a new table table to the database using the selected character set encoding and storage engine. + * Adds a new table table to the database using the selected character set encoding and storage engine on a separate thread. + * + * This method *MUST* be called from the UI thread! */ - (void)_addTable { - // Ensure the task is performed on a background thread to group addition and loads - if ([NSThread isMainThread]) { - [NSThread detachNewThreadWithName:SPCtxt(@"SPTablesList table addition task", tableDocumentInstance) target:self selector:@selector(_addTable) object:nil]; - return; + NSString *tableType = [tableTypeButton title]; + NSString *tableName = [tableNameField stringValue]; + NSString *tableCharacterSet = [addTableCharsetHelper selectedCharset]; + NSString *tableColletion = [addTableCharsetHelper selectedCollation]; + + NSMutableDictionary *tableDetails = [NSMutableDictionary dictionaryWithObject:tableName forKey:SPNewTableName]; + + if ([tableTypeButton indexOfSelectedItem] > 0) { + [tableDetails setObject:tableType forKey:SPNewTableType]; } - - @autoreleasepool { - [tableDocumentInstance startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Creating %@...", @"Creating table task string"), [tableNameField stringValue]]]; + if (tableCharacterSet) { + [tableDetails setObject:tableCharacterSet forKey:SPNewTableCharacterSet]; + } + + if (tableColletion) { + [tableDetails setObject:tableColletion forKey:SPNewTableCollation]; + } + + [tableDocumentInstance startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Creating %@...", @"Creating table task string"), tableName]]; + + [NSThread detachNewThreadWithName:SPCtxt(@"SPTablesList table addition task", tableDocumentInstance) + target:self + selector:@selector(_addTableWithDetails:) + object:tableDetails]; + + // Clear table name + [[tableNameField onMainThread] setStringValue:@""]; + + [tableDocumentInstance endTask]; +} + +/** + * Adds a new table table to the database using the selected character set encoding and storage engine. + */ +- (void)_addTableWithDetails:(NSDictionary *)tableDetails +{ + @autoreleasepool + { NSString *charSetStatement = @""; NSString *collationStatement = @""; NSString *engineStatement = @""; - NSString *tableType = [tableTypeButton title]; - NSString *tableName = [tableNameField stringValue]; + NSString *tableName = [tableDetails objectForKey:SPNewTableName]; + NSString *tableType = [tableDetails objectForKey:SPNewTableType]; // Ensure the use of UTF8 when creating new tables BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"]; @@ -2384,15 +2420,17 @@ - (void)_addTable } // If there is an encoding selected other than the default we must specify it in CREATE TABLE statement - NSString *encodingName = [addTableCharsetHelper selectedCharset]; + NSString *encodingName = [tableDetails objectForKey:SPNewTableCharacterSet]; + if (encodingName) charSetStatement = [NSString stringWithFormat:@"DEFAULT CHARACTER SET %@", [encodingName backtickQuotedString]]; // If there is a collation selected other than the default we must specify it in the CREATE TABLE statement - NSString *collationName = [addTableCharsetHelper selectedCollation]; - if (collationName) collationStatement = [NSString stringWithFormat:@"DEFAULT COLLATE %@",[collationName backtickQuotedString]]; + NSString *collationName = [tableDetails objectForKey:SPNewTableCollation]; + + if (collationName) collationStatement = [NSString stringWithFormat:@"DEFAULT COLLATE %@", [collationName backtickQuotedString]]; // If there is a type selected other than the default we must specify it in CREATE TABLE statement - if ([tableTypeButton indexOfSelectedItem] > 0) { + if (tableType) { engineStatement = [NSString stringWithFormat:@"%@ = %@", [[tableDocumentInstance serverSupport] engineTypeQueryName], [[tableDocumentInstance serverSupport] supportsQuotingEngineTypeInCreateSyntax] ? [tableType backtickQuotedString] : tableType]; } @@ -2439,17 +2477,11 @@ - (void)_addTable selectedTableType = SPTableTypeTable; [[self onMainThread] updateFilter:self]; - [[tablesListView onMainThread] scrollRowToVisible:[tablesListView selectedRow]]; + [[tablesListView onMainThread] scrollRowToVisible:[[tablesListView onMainThread] selectedRow]]; // Select the newly created table and switch to the table structure view for easier setup [tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType]; -#ifndef SP_CODA [tableDocumentInstance viewStructure:self]; -#endif - -#ifdef SP_CODA - [sidebarViewController setTableNames:[self allTableNames] selectedTableName:selectedTableName]; -#endif // Query the structure of all databases in the background (mainly for completion) [[tableDocumentInstance databaseStructureRetrieval] queryDbStructureInBackgroundWithUserInfo:@{@"forceUpdate" : @YES}]; @@ -2474,11 +2506,6 @@ - (void)_addTable [[tablesListView onMainThread] reloadData]; } - - // Clear table name - [[tableNameField onMainThread] setStringValue:@""]; - - [tableDocumentInstance endTask]; } }