diff options
author | rowanbeentje <rowan@beent.je> | 2009-11-15 23:58:21 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2009-11-15 23:58:21 +0000 |
commit | 50a283b6d1f3ce48e3a06eceeed3a466c6259fe7 (patch) | |
tree | 98596427c436f4735ec9baee45da66248e83291c /Source/CustomQuery.m | |
parent | 69a4fbc7cf11a35e5bf609cf7a16d2844559997c (diff) | |
download | sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.tar.gz sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.tar.bz2 sequelpro-50a283b6d1f3ce48e3a06eceeed3a466c6259fe7.zip |
Implement query cancellation support within MCPKit, and add it to the task functionality:
- MCPKit now supports cancelling the active query; for MySQL servers >= 5.0.0 a query kill is attempted from a new connection, and if that fails or for MySQL < 5 a reconnect is triggered.
- TableDocument now supports enabling a cancel task button on the task interface, including an optional callback
- Implement query cancellation for custom queries. This addresses Issue #86.
- Implement query cancellation for table content loads, filters, and sorts.
Diffstat (limited to 'Source/CustomQuery.m')
-rw-r--r-- | Source/CustomQuery.m | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index f515f335..dc0d9b76 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -388,6 +388,7 @@ MCPStreamingResult *streamingResult = nil; NSMutableString *errors = [NSMutableString string]; SEL callbackMethod = NULL; + NSString *taskButtonString; int i, totalQueriesRun = 0, totalAffectedRows = 0; double executionTime = 0; @@ -425,6 +426,13 @@ long queryCount = [queries count]; NSMutableArray *tempQueries = [NSMutableArray arrayWithCapacity:queryCount]; + // Enable task cancellation + if (queryCount > 1) + taskButtonString = NSLocalizedString(@"Stop queries", @"Stop queries string"); + else + taskButtonString = NSLocalizedString(@"Stop query", @"Stop query string"); + [tableDocumentInstance enableTaskCancellationWithTitle:taskButtonString callbackObject:nil callbackFunction:NULL]; + // Perform the supplied queries in series for ( i = 0 ; i < queryCount ; i++ ) { @@ -450,7 +458,7 @@ // If this is the last query, retrieve and store the result; otherwise, // discard the result without fully loading. - if (totalQueriesRun == queryCount) { + if (totalQueriesRun == queryCount || [mySQLConnection queryCancelled]) { // get column definitions for the result array if (cqColumnDefinition) [cqColumnDefinition release]; @@ -507,7 +515,17 @@ totalAffectedRows += [streamingResult numOfRows]; // Store any error messages - if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { + if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] || [mySQLConnection queryCancelled]) { + + NSString *errorString; + if ([mySQLConnection queryCancelled]) { + if ([mySQLConnection queryCancellationUsedReconnect]) + errorString = NSLocalizedString(@"Query cancelled. Please note that to cancel the query the connection had to be reset; transactions and connection variables were reset.", @"Query cancel by resetting connection error"); + else + errorString = NSLocalizedString(@"Query cancelled.", @"Query cancelled error"); + } else { + errorString = [mySQLConnection getLastErrorMessage]; + } // If the query errored, append error to the error log for display at the end if ( queryCount > 1 ) { @@ -519,35 +537,37 @@ // Update error text for the user [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"[ERROR in query %d] %@\n", @"error text when multiple custom query failed"), i+1, - [mySQLConnection getLastErrorMessage]]]; + errorString]]; [errorText setStringValue:errors]; + // ask the user to continue after detecting an error - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; - [alert addButtonWithTitle:NSLocalizedString(@"Run All", @"run all button")]; - [alert addButtonWithTitle:NSLocalizedString(@"Continue", @"continue button")]; - [alert addButtonWithTitle:NSLocalizedString(@"Stop", @"stop button")]; - [alert setMessageText:NSLocalizedString(@"MySQL Error", @"mysql error message")]; - [alert setInformativeText:[mySQLConnection getLastErrorMessage]]; - [alert setAlertStyle:NSWarningAlertStyle]; - int choice = [alert runModal]; - switch (choice){ - case NSAlertFirstButtonReturn: - suppressErrorSheet = YES; - case NSAlertSecondButtonReturn: - break; - default: - 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 = queryCount; // break for loop; for safety reasons stop the execution of the following queries + if (![mySQLConnection queryCancelled]) { + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + [alert addButtonWithTitle:NSLocalizedString(@"Run All", @"run all button")]; + [alert addButtonWithTitle:NSLocalizedString(@"Continue", @"continue button")]; + [alert addButtonWithTitle:NSLocalizedString(@"Stop", @"stop button")]; + [alert setMessageText:NSLocalizedString(@"MySQL Error", @"mysql error message")]; + [alert setInformativeText:[mySQLConnection getLastErrorMessage]]; + [alert setAlertStyle:NSWarningAlertStyle]; + int choice = [alert runModal]; + switch (choice){ + case NSAlertFirstButtonReturn: + suppressErrorSheet = YES; + case NSAlertSecondButtonReturn: + break; + default: + 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 = queryCount; // break for loop; for safety reasons stop the execution of the following queries + } } - } else { [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"[ERROR in query %d] %@\n", @"error text when multiple custom query failed"), i+1, - [mySQLConnection getLastErrorMessage]]]; + errorString]]; } } else { - [errors setString:[mySQLConnection getLastErrorMessage]]; + [errors setString:errorString]; } } else { // Check if table/db list needs an update @@ -557,6 +577,9 @@ if(!databaseWasChanged && [query isMatchedByRegex:@"(?i)\\b(use|drop\\s+database|drop\\s+schema)\\b\\s+."]) databaseWasChanged = YES; } + + // If the query was cancelled, end all queries. + if ([mySQLConnection queryCancelled]) break; } // Reload table list if at least one query began with drop, alter, rename, or create @@ -605,7 +628,7 @@ } // Error checking - if ( [errors length] && !queryIsTableSorter ) { + if ( [mySQLConnection queryCancelled] || ([errors length] && !queryIsTableSorter)) { // set the error text [errorText setStringValue:errors]; // select the line x of the first error if error message contains "at line x" @@ -656,7 +679,18 @@ } // Set up the status string - if ( totalQueriesRun > 1 ) { + if ( [mySQLConnection queryCancelled] ) { + if (totalQueriesRun > 1) { + [affectedRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Cancelled in query %i, after %@", @"text showing multiple queries were cancelled"), + totalQueriesRun, + [NSString stringForTimeInterval:executionTime] + ]]; + } else { + [affectedRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Cancelled after %@", @"text showing a query was cancelled"), + [NSString stringForTimeInterval:executionTime] + ]]; + } + } else if ( totalQueriesRun > 1 ) { if (totalAffectedRows==1) { [affectedRowsText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"1 row affected in total, by %i queries taking %@", @"text showing one row has been affected by multiple queries"), totalQueriesRun, |