diff options
author | stuconnolly <stuart02@gmail.com> | 2009-10-07 00:11:40 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2009-10-07 00:11:40 +0000 |
commit | 6269e47fcf89cf3fb6d01184064dface1d163c05 (patch) | |
tree | 0f1ad826305fc2328fa49f0e5b34a17c52d883d3 | |
parent | 5ec0349424ff8299a25bbf5a538865e752cd9215 (diff) | |
download | sequelpro-6269e47fcf89cf3fb6d01184064dface1d163c05.tar.gz sequelpro-6269e47fcf89cf3fb6d01184064dface1d163c05.tar.bz2 sequelpro-6269e47fcf89cf3fb6d01184064dface1d163c05.zip |
More export redesign work. Note that the current implementation has a major flaw in that exporter instances (NSOperation subclasses) are not reusable and so we have to create a new instance for every 'chunk' of data we want to process.
-rw-r--r-- | Source/SPAppController.m | 8 | ||||
-rw-r--r-- | Source/SPCSVExporter.m | 7 | ||||
-rw-r--r-- | Source/SPExportController.h | 8 | ||||
-rw-r--r-- | Source/SPExportController.m | 122 | ||||
-rw-r--r-- | Source/SPExporter.h | 2 | ||||
-rw-r--r-- | Source/SPExporter.m | 16 | ||||
-rw-r--r-- | Source/SPExporterDataAccess.h | 17 |
7 files changed, 90 insertions, 90 deletions
diff --git a/Source/SPAppController.m b/Source/SPAppController.m index 547d1e9c..f5023643 100644 --- a/Source/SPAppController.m +++ b/Source/SPAppController.m @@ -39,11 +39,13 @@ @implementation SPAppController - -- (id) init +/** + * Inialise the application's main controller, setting itself as the app delegate. + */ +- (id)init { if ((self = [super init])) { - [NSApp setDelegate: self]; + [NSApp setDelegate:self]; } return self; diff --git a/Source/SPCSVExporter.m b/Source/SPCSVExporter.m index 3464b72d..9bbbb4af 100644 --- a/Source/SPCSVExporter.m +++ b/Source/SPCSVExporter.m @@ -269,11 +269,14 @@ [csvData appendString:csvString]; } + // Assign the resulting CSV data to the expoter's export data + [self setExportData:csvData]; + // Mark the process as not running [self setExportProcessIsRunning:NO]; - // Pass the resulting CSV data back to the delegate by calling the specified didEndSelector - [[self delegate] performSelectorOnMainThread:[self didEndSelector] withObject:csvData waitUntilDone:YES]; + // Call the delegate's didEndSelector while passing this exporter to it + [[self delegate] performSelectorOnMainThread:[self didEndSelector] withObject:self waitUntilDone:YES]; [pool release]; } diff --git a/Source/SPExportController.h b/Source/SPExportController.h index 645ade0a..eec8ce63 100644 --- a/Source/SPExportController.h +++ b/Source/SPExportController.h @@ -105,10 +105,16 @@ typedef NSUInteger SPExportSource; IBOutlet id tokenNameTokensField; IBOutlet id exampleNameLabel; - // Local variables + // Cancellation flag BOOL exportCancelled; + + // Current database's tables NSMutableArray *tables; + + // Database connection MCPConnection *connection; + + // Concurrent operation queue NSOperationQueue *operationQueue; } diff --git a/Source/SPExportController.m b/Source/SPExportController.m index f365de75..b6adc58a 100644 --- a/Source/SPExportController.m +++ b/Source/SPExportController.m @@ -32,7 +32,6 @@ @interface SPExportController (PrivateAPI) -- (void)_loadTables; - (NSString *)_htmlEscapeString:(NSString *)string; - (void)_initializeExportUsingSelectedOptions; - (BOOL)_exportTablesAsCSV:(NSArray *)exportTables usingDataExporter:(SPExporter *)exporter; @@ -78,7 +77,23 @@ { if (!exportWindow) [NSBundle loadNibNamed:@"ExportDialog" owner:self]; - [self _loadTables]; + NSUInteger i; + + [tables removeAllObjects]; + + MCPResult *queryResult = (MCPResult *)[[self connection] listTables]; + + if ([queryResult numOfRows]) [queryResult dataSeek:0]; + + for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) + { + [tables addObject:[NSMutableArray arrayWithObjects: + [NSNumber numberWithBool:YES], + NSArrayObjectAtIndex([queryResult fetchRowAsArray], 0), + nil]]; + } + + [exportTableList reloadData]; [exportPathField setStringValue:NSHomeDirectory()]; @@ -99,7 +114,7 @@ } /** - * + * Change the selected toolbar item. */ - (IBAction)switchTab:(id)sender { @@ -122,11 +137,19 @@ } /** - * + * Cancel's the export operation by stopping the current table export loop and marking any current SPExporter + * NSOperation subclasses as cancelled. */ - (IBAction)cancelExport:(id)sender { - // Cancel the export operation here + [self setExportCancelled:YES]; + + // Cancel all of the currently running operations + [operationQueue cancelAllOperations]; + + // Close the progress sheet + [NSApp endSheet:exportProgressWindow returnCode:0]; + [exportProgressWindow orderOut:self]; } /** @@ -195,33 +218,22 @@ } #pragma mark - -#pragma mark Exporter delegate methods - -/** - * Called when CSV data conversion process is complete and the data is available. - */ -- (void)csvDataAvailable:(NSString *)data -{ - -} +#pragma mark SPExporterDataAccess protocol methods /** - * Called when SQL data conversion process is complete and the data is available. + * This method is part of the SPExporterDataAccess protocol. It is called when an expoter complete it's data + * conversion process and the operation is effectively complete. The resulting data can be accessed via + * SPExporter's exportData method. */ -- (void)sqlDataAvailable:(NSString *)data -{ - -} - -/** - * Called when XML data conversion process is complete and the data is available. - */ -- (void)xmlDataAvailable:(NSString *)data -{ - +- (void)exporterDataConversionProcessComplete:(SPExporter *)exporter +{ + // If there are no more operations in the queue, close the progress sheet + if ([[operationQueue operations] count] == 0) { + [NSApp endSheet:exportProgressWindow returnCode:0]; + [exportProgressWindow orderOut:self]; + } } - #pragma mark - #pragma mark Other @@ -248,6 +260,8 @@ } } +#pragma mark - + /** * Dealloc */ @@ -264,30 +278,6 @@ @implementation SPExportController (PrivateAPI) /** - * Loads all the available database tables in table view. - */ -- (void)_loadTables -{ - NSUInteger i; - - [tables removeAllObjects]; - - MCPResult *queryResult = (MCPResult *)[[self connection] listTables]; - - if ([queryResult numOfRows]) [queryResult dataSeek:0]; - - for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) - { - [tables addObject:[NSMutableArray arrayWithObjects: - [NSNumber numberWithBool:YES], - NSArrayObjectAtIndex([queryResult fetchRowAsArray], 0), - nil]]; - } - - [exportTableList reloadData]; -} - -/** * Escapes the supplied HTML string */ - (NSString *)_htmlEscapeString:(NSString *)string @@ -412,7 +402,7 @@ */ - (BOOL)_exportTablesAsCSV:(NSArray *)exportTables usingDataExporter:(SPCSVExporter *)exporter { - NSUInteger tableCount, i, j; + NSUInteger tableCount, i; NSMutableString *errors = [NSMutableString string]; NSMutableString *infoString = [NSMutableString string]; @@ -462,8 +452,8 @@ { // Update the progress text and reset the progress bar to indeterminate status NSString *tableName = [exportTables objectAtIndex:i]; - - [exportProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %i of %i (%@): fetching data...", @"text showing that app is fetching data for table dump"), (i + 1), tableCount, tableName]]; + + [exportProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %d of %d (%@): fetching data...", @"text showing that app is fetching data for table dump"), (i + 1), tableCount, tableName]]; [exportProgressText displayIfNeeded]; [exportProgressIndicator setIndeterminate:YES]; @@ -487,21 +477,15 @@ // Retrieve the table details via the data class, and use it to build an array containing column numeric status tableColumnNumericStatus = [NSMutableArray array]; - for (j = 0; j < [[tableDetails objectForKey:@"columns"] count]; j++) + for (NSDictionary *column in [tableDetails objectForKey:@"columns"]) { - NSString *tableColumnTypeGrouping = [[[tableDetails objectForKey:@"columns"] objectAtIndex:j] objectForKey:@"typegrouping"]; + NSString *tableColumnTypeGrouping = [column objectForKey:@"typegrouping"]; - if ([tableColumnTypeGrouping isEqualToString:@"bit"] || - [tableColumnTypeGrouping isEqualToString:@"integer"] || - [tableColumnTypeGrouping isEqualToString:@"float"]) - { - [tableColumnNumericStatus addObject:[NSNumber numberWithBool:YES]]; - } - else { - [tableColumnNumericStatus addObject:[NSNumber numberWithBool:NO]]; - } + [tableColumnNumericStatus addObject:[NSNumber numberWithBool:([tableColumnTypeGrouping isEqualToString:@"bit"] || + [tableColumnTypeGrouping isEqualToString:@"integer"] || + [tableColumnTypeGrouping isEqualToString:@"float"])]]; } - + [exporter setCsvTableColumnNumericStatus:tableColumnNumericStatus]; // Retrieve all the content within this table @@ -524,7 +508,7 @@ [exportProgressIndicator setIndeterminate:NO]; [exportProgressIndicator setDoubleValue:0]; [exportProgressIndicator displayIfNeeded]; - + // Start the actual data conversion process by placing the exporter on the operation queue. // Note that although it is highly likely there is no guarantee that the operation will executed // as soon as it's placed on the queue. There may be a delay if the queue is already executing it's @@ -535,10 +519,6 @@ //[fileHandle writeData:[[NSString stringWithFormat:@"%@%@%@", csvLineEnd, csvLineEnd, csvLineEnd] dataUsingEncoding:encoding]]; } - // Close the progress sheet - [NSApp endSheet:exportProgressWindow returnCode:0]; - [exportProgressWindow orderOut:self]; - return YES; } diff --git a/Source/SPExporter.h b/Source/SPExporter.h index 685fc597..1f52e5db 100644 --- a/Source/SPExporter.h +++ b/Source/SPExporter.h @@ -56,6 +56,7 @@ BOOL exportProcessIsRunning; + NSString *exportData; NSStringEncoding exportOutputEncoding; } @@ -65,6 +66,7 @@ @property (readwrite, assign) BOOL exportProcessIsRunning; +@property (readwrite, retain) NSString *exportData; @property (readwrite, assign) NSStringEncoding exportOutputEncoding; - (id)initWithDelegate:(id)exportDelegate; diff --git a/Source/SPExporter.m b/Source/SPExporter.m index f99b35c3..a1fe448b 100644 --- a/Source/SPExporter.m +++ b/Source/SPExporter.m @@ -31,6 +31,7 @@ @synthesize didEndSelector; @synthesize exportProgressValue; @synthesize exportProcessIsRunning; +@synthesize exportData; @synthesize exportOutputEncoding; /** @@ -44,10 +45,13 @@ [self setExportProgressValue:0]; [self setExportProcessIsRunning:NO]; + // Default the resulting data to an empty string + [self setExportData:@""]; + // Default the output encoding to UTF-8 [self setExportOutputEncoding:NSUTF8StringEncoding]; - [self setDidEndSelector:@selector(csvDataAvailable:)]; + [self setDidEndSelector:@selector(exporterDataConversionProcessComplete:)]; } return self; @@ -61,4 +65,14 @@ @throw [NSException exceptionWithName:@"NSOperation main() call" reason:@"Can't call NSOperation's main() method in SPExpoter, must be overriden in subclass." userInfo:nil]; } +/** + * Get rid of the export data. + */ +- (void)dealloc +{ + [exportData release], exportData = nil; + + [super dealloc]; +} + @end diff --git a/Source/SPExporterDataAccess.h b/Source/SPExporterDataAccess.h index 1444313d..ab44cd39 100644 --- a/Source/SPExporterDataAccess.h +++ b/Source/SPExporterDataAccess.h @@ -25,21 +25,14 @@ #import <Cocoa/Cocoa.h> -@protocol SPExporterDataAccess - -/** - * Called when CSV data conversion process is complete and the data is available. - */ -- (void)csvDataAvailable:(NSString *)data; +@class SPExporter; -/** - * Called when SQL data conversion process is complete and the data is available. - */ -- (void)sqlDataAvailable:(NSString *)data; +@protocol SPExporterDataAccess /** - * Called when XML data conversion process is complete and the data is available. + * This method called when an expoter complete it's data conversion process and the operation is effectively + * complete. The resulting data can be accessed via SPExporter's exportData method. */ -- (void)xmlDataAvailable:(NSString *)data; +- (void)exporterDataConversionProcessComplete:(SPExporter *)exporter; @end |