aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/SPCSVExporter.h18
-rw-r--r--Source/SPCSVExporter.m61
-rw-r--r--Source/SPExportController.h19
-rw-r--r--Source/SPExportController.m493
-rw-r--r--Source/SPExporter.h16
-rw-r--r--Source/SPExporter.m30
-rw-r--r--Source/SPSQLExporter.h9
-rw-r--r--Source/SPSQLExporter.m16
8 files changed, 426 insertions, 236 deletions
diff --git a/Source/SPCSVExporter.h b/Source/SPCSVExporter.h
index 3fa6f276..51569838 100644
--- a/Source/SPCSVExporter.h
+++ b/Source/SPCSVExporter.h
@@ -27,9 +27,8 @@
#import "MCPKit.h"
#import "SPExporter.h"
-#import "SPExporterAccess.h"
-@interface SPCSVExporter : SPExporter <SPExporterAccess>
+@interface SPCSVExporter : SPExporter
{
// CSV file
NSFileHandle *csvFileHandle;
@@ -46,13 +45,6 @@
NSString *csvLineEndingString;
NSString *csvNULLString;
NSArray *csvTableColumnNumericStatus;
-
- // CSV encoding
- NSStringEncoding csvOutputEncoding;
-
- // Operational
- BOOL csvExportIsRunning;
- BOOL csvThreadShouldExit;
}
@property (readwrite, retain) NSFileHandle *csvFileHandle;
@@ -68,12 +60,4 @@
@property (readwrite, retain) NSString *csvNULLString;
@property (readwrite, retain) NSArray *csvTableColumnNumericStatus;
-@property (readwrite, assign) NSStringEncoding csvOutputEncoding;
-
-@property (readwrite, assign) BOOL csvExportIsRunning;
-@property (readwrite, assign) BOOL csvThreadShouldExit;
-
-- (BOOL)startExportProcess;
-- (BOOL)stopExportProcess;
-
@end
diff --git a/Source/SPCSVExporter.m b/Source/SPCSVExporter.m
index a157b051..b508172b 100644
--- a/Source/SPCSVExporter.m
+++ b/Source/SPCSVExporter.m
@@ -28,7 +28,7 @@
@interface SPCSVExporter (PrivateAPI)
-- (void)startCSVExportInBackgroundThread;
+- (void)_startCSVExportInBackgroundThread;
@end
@@ -47,24 +47,6 @@
@synthesize csvNULLString;
@synthesize csvTableColumnNumericStatus;
-@synthesize csvOutputEncoding;
-
-@synthesize csvExportIsRunning;
-@synthesize csvThreadShouldExit;
-
-/**
- * Initialize an instance of the exporter setting some default values
- */
-- (id)init
-{
- if ((self == [super init])) {
- [self setCsvExportIsRunning:NO];
- [self setCsvThreadShouldExit:NO];
- }
-
- return self;
-}
-
/**
* Start the CSV export process.
*/
@@ -76,8 +58,7 @@
(![self csvFieldSeparatorString]) ||
(![self csvEscapeString]) ||
(![self csvLineEndingString]) ||
- (![self csvTableColumnNumericStatus]) ||
- (![self csvOutputEncoding]))
+ (![self csvTableColumnNumericStatus]))
{
return NO;
}
@@ -99,12 +80,12 @@
[delegate exportProcessDidStart:self];
}
- [self setCsvExportIsRunning:YES];
+ [self setExportProcessIsRunning:YES];
// Start the export in a new thread
- [NSThread detachNewThreadSelector:@selector(startCSVExportInBackgroundThread) toTarget:self withObject:nil];
+ [NSThread detachNewThreadSelector:@selector(_startCSVExportInBackgroundThread) toTarget:self withObject:nil];
- [self setCsvExportIsRunning:NO];
+ [self setExportProcessIsRunning:NO];
// Tell the delegate that the export process has ended
if (delegate && [delegate respondsToSelector:@selector(exportProcessDidEnd:)]) {
@@ -119,7 +100,7 @@
*/
- (BOOL)stopExportProcess
{
- if (![self csvExportIsRunning]) return NO;
+ if (![self exportProcessIsRunning]) return NO;
// Kill the running thread here
@@ -151,7 +132,7 @@
/**
* Starts the export process in a background thread.
*/
-- (void)startCSVExportInBackgroundThread
+- (void)_startCSVExportInBackgroundThread
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -171,42 +152,38 @@
// Detect and restore special characters being used as terminating or line end strings
NSMutableString *tempSeparatorString = [NSMutableString stringWithString:[self csvFieldSeparatorString]];
-
- NSUInteger tempSeparatorStringLength = [tempSeparatorString length];
-
+
// Escape tabs, line endings and carriage returns
[tempSeparatorString replaceOccurrencesOfString:@"\\t" withString:@"\t"
options:NSLiteralSearch
- range:NSMakeRange(0, tempSeparatorStringLength)];
+ range:NSMakeRange(0, [tempSeparatorString length])];
[tempSeparatorString replaceOccurrencesOfString:@"\\n" withString:@"\n"
options:NSLiteralSearch
- range:NSMakeRange(0, tempSeparatorStringLength)];
+ range:NSMakeRange(0, [tempSeparatorString length])];
[tempSeparatorString replaceOccurrencesOfString:@"\\r" withString:@"\r"
options:NSLiteralSearch
- range:NSMakeRange(0, tempSeparatorStringLength)];
+ range:NSMakeRange(0, [tempSeparatorString length])];
// Set the new field separator string
[self setCsvFieldSeparatorString:[NSString stringWithString:tempSeparatorString]];
NSMutableString *tempLineEndString = [NSMutableString stringWithString:[self csvLineEndingString]];
-
- NSUInteger tempLineEndStringLength = [tempLineEndString length];
-
+
// Escape tabs, line endings and carriage returns
[tempLineEndString replaceOccurrencesOfString:@"\\t" withString:@"\t"
options:NSLiteralSearch
- range:NSMakeRange(0, tempLineEndStringLength)];
+ range:NSMakeRange(0, [tempLineEndString length])];
[tempLineEndString replaceOccurrencesOfString:@"\\n" withString:@"\n"
options:NSLiteralSearch
- range:NSMakeRange(0, tempLineEndStringLength)];
+ range:NSMakeRange(0, [tempLineEndString length])];
[tempLineEndString replaceOccurrencesOfString:@"\\r" withString:@"\r"
options:NSLiteralSearch
- range:NSMakeRange(0, tempLineEndStringLength)];
+ range:NSMakeRange(0, [tempLineEndString length])];
// Set the new line ending string
[self setCsvLineEndingString:[NSString stringWithString:tempLineEndString]];
@@ -231,14 +208,14 @@
for (i = startingRow; i < totalRows; i++)
{
// Check if we should stop and exit the export operation
- if ([self csvThreadShouldExit]) {
+ if ([self exportProcessShouldExit]) {
[pool release];
return;
}
// Update the progress value
- if (totalRows) [self setProgressValue:(((i + 1) * 100) / totalRows)];
+ if (totalRows) [self setExportProgressValue:(((i + 1) * 100) / totalRows)];
// Retrieve the row from the supplied data
if ([self csvDataArray] == nil) {
@@ -264,7 +241,7 @@
// Retrieve the contents of this cell
if ([NSArrayObjectAtIndex(csvRow, j) isKindOfClass:[NSData class]]) {
- dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(csvRow, j) encoding:csvOutputEncoding];
+ dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(csvRow, j) encoding:[self exportOutputEncoding]];
if (dataConversionString == nil) {
dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(csvRow, j) encoding:NSASCIIStringEncoding];
@@ -353,7 +330,7 @@
[csvString appendString:[self csvLineEndingString]];
// Write it to the fileHandle
- [csvFileHandle writeData:[csvString dataUsingEncoding:[self csvOutputEncoding]]];
+ [csvFileHandle writeData:[csvString dataUsingEncoding:[self exportOutputEncoding]]];
}
[pool release];
diff --git a/Source/SPExportController.h b/Source/SPExportController.h
index 61447063..8653c345 100644
--- a/Source/SPExportController.h
+++ b/Source/SPExportController.h
@@ -53,6 +53,9 @@ typedef NSUInteger SPExportSource;
// Tables list
IBOutlet id tablesListInstance;
+ // Table data
+ IBOutlet id tableDataInstance;
+
// Export window
IBOutlet id exportWindow;
IBOutlet id exportToolbar;
@@ -101,20 +104,20 @@ typedef NSUInteger SPExportSource;
IBOutlet id exampleNameLabel;
// Local variables
- MCPConnection *mySQLConnection;
+ BOOL exportCancelled;
NSMutableArray *tables;
+ MCPConnection *connection;
}
-// Export Methods
+@property (readwrite, assign) BOOL exportCancelled;
+@property (readwrite, assign) MCPConnection *connection;
+
+// IB action methods
- (void)export;
- (IBAction)closeSheet:(id)sender;
-- (IBAction)cancelExport:(id)sender;
-- (IBAction)changeExportOutputPath:(id)sender;
-
-// Utility Methods
-- (void)setConnection:(MCPConnection *)theConnection;
-- (void)loadTables;
- (IBAction)switchTab:(id)sender;
- (IBAction)switchInput:(id)sender;
+- (IBAction)cancelExport:(id)sender;
+- (IBAction)changeExportOutputPath:(id)sender;
@end
diff --git a/Source/SPExportController.m b/Source/SPExportController.m
index 5acc40c0..ba6fab79 100644
--- a/Source/SPExportController.m
+++ b/Source/SPExportController.m
@@ -25,17 +25,32 @@
#import "SPExportController.h"
#import "SPCSVExporter.h"
#import "TablesList.h"
+#import "SPTableData.h"
#import "TableDocument.h"
#import "SPArrayAdditions.h"
+#import "SPStringAdditions.h"
+
+@interface SPExportController (PrivateAPI)
+
+- (void)_loadTables;
+- (NSString *)_htmlEscapeString:(NSString *)string;
+- (void)_initializeExportUsingSelectedOptions;
+- (BOOL)_exportTablesAsCSV:(NSArray *)exportTables toFileHandle:(NSFileHandle *)fileHandle usingDataExporter:(SPExporter *)exporter;
+
+@end
@implementation SPExportController
+@synthesize connection;
+@synthesize exportCancelled;
+
/**
* Initializes an instance of SPExportController
*/
- (id)init
{
if ((self = [super init])) {
+ [self setExportCancelled:NO];
tables = [[NSMutableArray alloc] init];
}
@@ -52,7 +67,7 @@
}
#pragma mark -
-#pragma mark Export methods
+#pragma mark IB action methods
/**
* Display the export window allowing the user to select what and of what type to export.
@@ -61,7 +76,7 @@
{
if (!exportWindow) [NSBundle loadNibNamed:@"ExportDialog" owner:self];
- [self loadTables];
+ [self _loadTables];
[exportPathField setStringValue:NSHomeDirectory()];
@@ -73,7 +88,7 @@
}
/**
- * Close the export dialog
+ * Closes the export dialog
*/
- (IBAction)closeSheet:(id)sender
{
@@ -84,145 +99,6 @@
/**
*
*/
-- (IBAction)cancelExport:(id)sender
-{
- // Cancel the export operation here
-}
-
-- (IBAction)changeExportOutputPath:(id)sender
-{
- NSOpenPanel *panel = [NSOpenPanel openPanel];
-
- [panel setCanChooseFiles:NO];
- [panel setCanChooseDirectories:YES];
- [panel setCanCreateDirectories:YES];
-
- [panel beginSheetForDirectory:NSHomeDirectory() file:nil modalForWindow:exportWindow modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
-}
-
-- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
-{
- // Perform the export
- if (returnCode == NSOKButton) {
-
- // First determine what type of export the user selected
- SPExportType exportType = 0;
-
- for (NSToolbarItem *item in [exportToolbar items])
- {
- if ([[item itemIdentifier] isEqualToString:[exportToolbar selectedItemIdentifier]]) {
- exportType = [item tag];
- break;
- }
- }
-
- // Determine what data to use (filtered result, custom query result or selected tables) for the export operation
- SPExportSource exportSource = ([exportInputMatrix selectedRow] + 1);
-
- NSMutableArray *exportTables = [NSMutableArray array];
-
- // Get the data depending on the source
- switch (exportSource)
- {
- case SP_FILTERED_EXPORT:
-
- break;
- case SP_CUSTOM_QUERY_EXPORT:
-
- break;
- case SP_TABLE_EXPORT:
- // Create an array of tables to export
- for (NSMutableArray *table in tables)
- {
- if ([[table objectAtIndex:0] boolValue]) {
- [exportTables addObject:[table objectAtIndex:1]];
- }
- }
-
- break;
- }
-
- // Create the file handle
-
-
- SPExporter *exporter;
- SPCSVExporter *csvExporter;
-
- // Based on the type of export create a new instance of the corresponding exporter and set it's specific options
- switch (exportType)
- {
- case SP_SQL_EXPORT:
-
- break;
- case SP_CSV_EXPORT:
- csvExporter = [[SPCSVExporter alloc] init];
-
- [csvExporter setCsvOutputFieldNames:[exportCSVIncludeFieldNamesCheck state]];
- [csvExporter setCsvFieldSeparatorString:[exportCSVFieldsTerminatedField stringValue]];
- [csvExporter setCsvEnclosingCharacterString:[exportCSVFieldsWrappedField stringValue]];
- [csvExporter setCsvLineEndingString:[exportCSVLinesTerminatedField stringValue]];
- [csvExporter setCsvEscapeString:[exportCSVFieldsEscapedField stringValue]];
-
- [csvExporter setCsvOutputEncoding:[MCPConnection encodingForMySQLEncoding:[[tableDocumentInstance connectionEncoding] UTF8String]]];
- [csvExporter setCsvNULLString:[[NSUserDefaults standardUserDefaults] objectForKey:@"NullValue"]];
-
- exporter = csvExporter;
- break;
- case SP_XML_EXPORT:
-
- break;
- case SP_PDF_EXPORT:
-
- break;
- case SP_HTML_EXPORT:
-
- break;
- case SP_EXCEL_EXPORT:
-
- break;
- }
-
- // Set the exporter's delegate
- [exporter setDelegate:self];
- }
-}
-
-- (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
-{
- if (returnCode == NSOKButton) {
- [exportPathField setStringValue:[panel directory]];
- }
-}
-
-#pragma mark -
-#pragma mark Utility methods
-
-- (void)setConnection:(MCPConnection *)theConnection
-{
- mySQLConnection = theConnection;
-}
-
-- (void)loadTables
-{
- NSUInteger i;
-
- [tables removeAllObjects];
-
- MCPResult *queryResult = (MCPResult *)[mySQLConnection 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];
-}
-
- (IBAction)switchTab:(id)sender
{
if ([sender isKindOfClass:[NSToolbarItem class]]) {
@@ -233,6 +109,9 @@
}
}
+/**
+ *
+ */
- (IBAction)switchInput:(id)sender
{
if ([sender isKindOfClass:[NSMatrix class]]) {
@@ -240,6 +119,28 @@
}
}
+/**
+ *
+ */
+- (IBAction)cancelExport:(id)sender
+{
+ // Cancel the export operation here
+}
+
+/**
+ *
+ */
+- (IBAction)changeExportOutputPath:(id)sender
+{
+ NSOpenPanel *panel = [NSOpenPanel openPanel];
+
+ [panel setCanChooseFiles:NO];
+ [panel setCanChooseDirectories:YES];
+ [panel setCanCreateDirectories:YES];
+
+ [panel beginSheetForDirectory:NSHomeDirectory() file:nil modalForWindow:exportWindow modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
+}
+
#pragma mark -
#pragma mark Table view datasource methods
@@ -294,6 +195,32 @@
#pragma mark -
#pragma mark Other
+/**
+ * Invoked when the user
+ */
+- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
+{
+ // Perform the export
+ if (returnCode == NSOKButton) {
+
+ // Initialize the export after half a second to give the export sheet a chance to close
+ [self performSelector:@selector(_initializeExportUsingSelectedOptions) withObject:nil afterDelay:0.5];
+ }
+}
+
+/**
+ * Invoked when the user dismisses the save panel. Updates the selected directory is they clicked OK.
+ */
+- (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
+{
+ if (returnCode == NSOKButton) {
+ [exportPathField setStringValue:[panel directory]];
+ }
+}
+
+/**
+ * Dealloc
+ */
- (void)dealloc
{
[tables release], tables = nil;
@@ -302,3 +229,285 @@
}
@end
+
+@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
+{
+ NSMutableString *mutableString = [NSMutableString stringWithString:string];
+
+ [mutableString replaceOccurrencesOfString:@"&" withString:@"&amp;"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [mutableString length])];
+
+ [mutableString replaceOccurrencesOfString:@"<" withString:@"&lt;"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [mutableString length])];
+
+ [mutableString replaceOccurrencesOfString:@">" withString:@"&gt;"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [mutableString length])];
+
+ [mutableString replaceOccurrencesOfString:@"\"" withString:@"&quot;"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [mutableString length])];
+
+ return [NSString stringWithString:mutableString];
+}
+
+/**
+ *
+ */
+- (void)_initializeExportUsingSelectedOptions
+{
+ // First determine what type of export the user selected
+ SPExportType exportType = 0;
+
+ for (NSToolbarItem *item in [exportToolbar items])
+ {
+ if ([[item itemIdentifier] isEqualToString:[exportToolbar selectedItemIdentifier]]) {
+ exportType = [item tag];
+ break;
+ }
+ }
+
+ // Determine what data to use (filtered result, custom query result or selected tables) for the export operation
+ SPExportSource exportSource = ([exportInputMatrix selectedRow] + 1);
+
+ NSMutableArray *exportTables = [NSMutableArray array];
+
+ // Get the data depending on the source
+ switch (exportSource)
+ {
+ case SP_FILTERED_EXPORT:
+
+ break;
+ case SP_CUSTOM_QUERY_EXPORT:
+
+ break;
+ case SP_TABLE_EXPORT:
+ // Create an array of tables to export
+ for (NSMutableArray *table in tables)
+ {
+ if ([[table objectAtIndex:0] boolValue]) {
+ [exportTables addObject:[table objectAtIndex:1]];
+ }
+ }
+
+ break;
+ }
+
+ SPExporter *exporter;
+ SPCSVExporter *csvExporter;
+
+ // Based on the type of export create a new instance of the corresponding exporter and set it's specific options
+ switch (exportType)
+ {
+ case SP_SQL_EXPORT:
+
+ break;
+ case SP_CSV_EXPORT:
+ csvExporter = [[SPCSVExporter alloc] init];
+
+ [csvExporter setCsvFileHandle:[NSFileHandle fileHandleForWritingAtPath:@"/Users/stuart/Desktop/output.csv"]];
+
+ [csvExporter setCsvOutputFieldNames:[exportCSVIncludeFieldNamesCheck state]];
+ [csvExporter setCsvFieldSeparatorString:[exportCSVFieldsTerminatedField stringValue]];
+ [csvExporter setCsvEnclosingCharacterString:[exportCSVFieldsWrappedField stringValue]];
+ [csvExporter setCsvLineEndingString:[exportCSVLinesTerminatedField stringValue]];
+ [csvExporter setCsvEscapeString:[exportCSVFieldsEscapedField stringValue]];
+
+ [csvExporter setExportOutputEncoding:[MCPConnection encodingForMySQLEncoding:[[tableDocumentInstance connectionEncoding] UTF8String]]];
+ [csvExporter setCsvNULLString:[[NSUserDefaults standardUserDefaults] objectForKey:@"NullValue"]];
+
+ exporter = csvExporter;
+ break;
+ case SP_XML_EXPORT:
+
+ break;
+ case SP_PDF_EXPORT:
+
+ break;
+ case SP_HTML_EXPORT:
+
+ break;
+ case SP_EXCEL_EXPORT:
+
+ break;
+ }
+
+ // Set the exporter's delegate
+ [exporter setDelegate:self];
+
+ switch (exportSource)
+ {
+ case SP_FILTERED_EXPORT:
+
+ break;
+ case SP_CUSTOM_QUERY_EXPORT:
+
+ break;
+ case SP_TABLE_EXPORT:
+ [self _exportTablesAsCSV:exportTables toFileHandle:[NSFileHandle fileHandleForWritingAtPath:@"/Users/stuart/Desktop/output.csv"] usingDataExporter:exporter];
+ break;
+ }
+}
+
+/**
+ * Exports the contents' of the supplied array of tables using the supplied exporter and export type. Note that
+ * this method currently only supports exporting in CSV and XML formats.
+ */
+- (BOOL)_exportTablesAsCSV:(NSArray *)exportTables toFileHandle:(NSFileHandle *)fileHandle usingDataExporter:(SPExporter *)exporter
+{
+ NSUInteger tableCount, i, j;
+
+ NSMutableString *errors = [NSMutableString string];
+ NSMutableString *infoString = [NSMutableString string];
+
+ NSDictionary *tableDetails;
+ NSMutableArray *tableColumnNumericStatus;
+ NSStringEncoding encoding = [[self connection] encoding];
+
+ // Reset the interface
+ [exportProgressTitle setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Exporting %@", @"text showing that the application is importing a supplied format"), @"CSV"]];
+ [exportProgressText setStringValue:NSLocalizedString(@"Writing...", @"text showing that app is writing text file")];
+ [exportProgressText displayIfNeeded];
+ [exportProgressIndicator setDoubleValue:0];
+ [exportProgressIndicator displayIfNeeded];
+
+ // Open the progress sheet
+ [NSApp beginSheet:exportProgressWindow
+ modalForWindow:tableWindow
+ modalDelegate:self
+ didEndSelector:nil
+ contextInfo:nil];
+
+ // Add a dump header to the dump file
+ NSMutableString *csvLineEnd = [NSMutableString stringWithString:[exportCSVLinesTerminatedField stringValue]];
+
+ [csvLineEnd replaceOccurrencesOfString:@"\\t" withString:@"\t"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [csvLineEnd length])];
+
+ [csvLineEnd replaceOccurrencesOfString:@"\\n" withString:@"\n"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [csvLineEnd length])];
+
+ [csvLineEnd replaceOccurrencesOfString:@"\\r" withString:@"\r"
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [csvLineEnd length])];
+
+ if ([exportTables count] > 1) {
+ [infoString setString:[NSString stringWithFormat:@"Host: %@ Database: %@ Generation Time: %@%@%@",
+ [tableDocumentInstance host], [tableDocumentInstance database], [NSDate date], csvLineEnd, csvLineEnd]];
+ }
+
+ [fileHandle writeData:[infoString dataUsingEncoding:encoding]];
+
+ tableCount = [exportTables count];
+
+ // Loop through the tables
+ for (i = 0 ; i < ((tableCount) && (![self exportCancelled])); i++)
+ {
+ // 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 displayIfNeeded];
+
+ [exportProgressIndicator setIndeterminate:YES];
+ [exportProgressIndicator setUsesThreadedAnimation:YES];
+ [exportProgressIndicator startAnimation:self];
+
+ // For CSV exports of more than one table, output the name of the table
+ if (tableCount > 1) {
+ [fileHandle writeData:[[NSString stringWithFormat:@"Table %@%@%@", tableName, csvLineEnd, csvLineEnd] dataUsingEncoding:encoding]];
+ }
+
+ // Determine whether this table is a table or a view via the create table command, and get the table details
+ MCPResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]];
+
+ if ([queryResult numOfRows]) {
+ tableDetails = [NSDictionary dictionaryWithDictionary:[queryResult fetchRowAsDictionary]];
+
+ tableDetails = [NSDictionary dictionaryWithDictionary:([tableDetails objectForKey:@"Create View"]) ? [tableDataInstance informationForView:tableName] : [tableDataInstance informationForTable:tableName]];
+ }
+
+ // 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++)
+ {
+ NSString *tableColumnTypeGrouping = [[[tableDetails objectForKey:@"columns"] objectAtIndex:j] objectForKey:@"typegrouping"];
+
+ if ([tableColumnTypeGrouping isEqualToString:@"bit"] ||
+ [tableColumnTypeGrouping isEqualToString:@"integer"] ||
+ [tableColumnTypeGrouping isEqualToString:@"float"])
+ {
+ [tableColumnNumericStatus addObject:[NSNumber numberWithBool:YES]];
+ }
+ else {
+ [tableColumnNumericStatus addObject:[NSNumber numberWithBool:NO]];
+ }
+ }
+
+ // Retrieve all the content within this table
+ queryResult = [connection queryString:[NSString stringWithFormat:@"SELECT * FROM %@", [tableName backtickQuotedString]]];
+
+ // Note any errors during retrieval
+ if (![[connection getLastErrorMessage] isEqualToString:@""]) {
+ [errors appendString:[NSString stringWithFormat:@"%@\n", [connection getLastErrorMessage]]];
+ }
+
+ // Update the progress text and set the progress bar back to determinate
+ [exportProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %d of %d (%@): Writing...", @"text showing that app is writing data for table export"), (i + 1), tableCount, tableName]];
+ [exportProgressText displayIfNeeded];
+
+ [exportProgressIndicator stopAnimation:self];
+ [exportProgressIndicator setUsesThreadedAnimation:NO];
+ [exportProgressIndicator setIndeterminate:NO];
+ [exportProgressIndicator setDoubleValue:0];
+ [exportProgressIndicator displayIfNeeded];
+
+ // Start the actual export process in a separate thread using the supplied exporter instance
+ //[exporter startExportProcess];
+
+ // Add a spacer to the file
+ [fileHandle writeData:[[NSString stringWithFormat:@"%@%@%@", csvLineEnd, csvLineEnd, csvLineEnd] dataUsingEncoding:encoding]];
+ }
+
+ // Close the progress sheet
+ [NSApp endSheet:exportProgressWindow returnCode:0];
+ [exportProgressWindow orderOut:self];
+
+ return YES;
+}
+
+@end
diff --git a/Source/SPExporter.h b/Source/SPExporter.h
index 9b0f80fd..d380f94e 100644
--- a/Source/SPExporter.h
+++ b/Source/SPExporter.h
@@ -52,14 +52,24 @@
@end
-@interface SPExporter : NSObject
+@interface SPExporter : NSOperation
{
id delegate;
+
+ double exportProgressValue;
- double progressValue;
+ BOOL exportProcessIsRunning;
+ BOOL exportProcessShouldExit;
+
+ NSStringEncoding exportOutputEncoding;
}
@property (readwrite, assign) id delegate;
-@property (readwrite, assign) double progressValue;
+@property (readwrite, assign) double exportProgressValue;
+
+@property (readwrite, assign) BOOL exportProcessIsRunning;
+@property (readwrite, assign) BOOL exportProcessShouldExit;
+
+@property (readwrite, assign) NSStringEncoding exportOutputEncoding;
@end
diff --git a/Source/SPExporter.m b/Source/SPExporter.m
index f8f2cba0..9cc681d8 100644
--- a/Source/SPExporter.m
+++ b/Source/SPExporter.m
@@ -28,6 +28,34 @@
@implementation SPExporter
@synthesize delegate;
-@synthesize progressValue;
+@synthesize exportProgressValue;
+@synthesize exportProcessIsRunning;
+@synthesize exportProcessShouldExit;
+@synthesize exportOutputEncoding;
+
+/**
+ * Initialize an instance of the exporter setting some default values
+ */
+- (id)init
+{
+ if ((self == [super init])) {
+ [self setExportProgressValue:0];
+ [self setExportProcessIsRunning:NO];
+ [self setExportProcessShouldExit:NO];
+
+ // Default the output encoding to UTF-8
+ [self setExportOutputEncoding:NSUTF8StringEncoding];
+ }
+
+ return self;
+}
+
+/**
+ *
+ */
+- (void)main
+{
+ @throw [NSException exceptionWithName:@"NSOperation main() call" reason:@"Can't call NSOperation's main() method in SPExpoter, must be overriden in subclass." userInfo:nil];
+}
@end
diff --git a/Source/SPSQLExporter.h b/Source/SPSQLExporter.h
index 847a882a..3b5f3be3 100644
--- a/Source/SPSQLExporter.h
+++ b/Source/SPSQLExporter.h
@@ -25,16 +25,11 @@
#import <Cocoa/Cocoa.h>
-#import "MCPKit.h"
#import "SPExporter.h"
-#import "SPExporterAccess.h"
-@interface SPSQLExporter : SPExporter <SPExporterAccess>
+@interface SPSQLExporter : SPExporter
{
-
+
}
-- (BOOL)startExportProcess;
-- (BOOL)stopExportProcess;
-
@end
diff --git a/Source/SPSQLExporter.m b/Source/SPSQLExporter.m
index 73f4ab56..39653abc 100644
--- a/Source/SPSQLExporter.m
+++ b/Source/SPSQLExporter.m
@@ -27,20 +27,4 @@
@implementation SPSQLExporter
-/**
- * Start the SQL export process.
- */
-- (BOOL)startExportProcess
-{
- return YES;
-}
-
-/**
- * Stop the SQL export process by killing the export thread and cleaning up if its running.
- */
-- (BOOL)stopExportProcess
-{
- return YES;
-}
-
@end