diff options
author | stuconnolly <stuart02@gmail.com> | 2008-12-10 16:52:52 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2008-12-10 16:52:52 +0000 |
commit | fab9a6506cd04ec8f840c98772a80c44a79c74a7 (patch) | |
tree | 3cd483487bef381c934717f10df71d306c7eaf97 /TableDump.m | |
parent | 4c3b208fad0572d8d1a79bba1bd1b8147fd0f8a6 (diff) | |
download | sequelpro-fab9a6506cd04ec8f840c98772a80c44a79c74a7.tar.gz sequelpro-fab9a6506cd04ec8f840c98772a80c44a79c74a7.tar.bz2 sequelpro-fab9a6506cd04ec8f840c98772a80c44a79c74a7.zip |
MERGED r262:266 from branches/stuart02 to trunk to include new project structure.
Diffstat (limited to 'TableDump.m')
-rw-r--r-- | TableDump.m | 1892 |
1 files changed, 0 insertions, 1892 deletions
diff --git a/TableDump.m b/TableDump.m deleted file mode 100644 index 277ed3e7..00000000 --- a/TableDump.m +++ /dev/null @@ -1,1892 +0,0 @@ -// -// TableDump.m -// sequel-pro -// -// Created by lorenz textor (lorenz@textor.ch) on Wed May 01 2002. -// Copyright (c) 2002-2003 Lorenz Textor. All rights reserved. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://code.google.com/p/sequel-pro/> -// Or mail to <lorenz@textor.ch> - -#import "TableDump.h" -#import "TableDocument.h" -#import "TablesList.h" -#import "TableSource.h" -#import "TableContent.h" -#import "CustomQuery.h" -#import "SPGrowlController.h" - -@implementation TableDump - -//IBAction methods -- (IBAction)reloadTables:(id)sender -/* - get the tables in db - */ -{ - CMMCPResult *queryResult; - int i; - - //get tables - [tables removeAllObjects]; - queryResult = (CMMCPResult *)[mySQLConnection listTables]; - - if ([queryResult numOfRows]) [queryResult dataSeek:0]; - for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) { - [tables addObject:[NSMutableArray arrayWithObjects: - [NSNumber numberWithBool:YES], [[queryResult fetchRowAsArray] objectAtIndex:0], nil]]; - } - - [exportDumpTableView reloadData]; - [exportMultipleCSVTableView reloadData]; - [exportMultipleXMLTableView reloadData]; - -} - -- (IBAction)selectTables:(id)sender -/* - selects or deselects all tables - */ -{ - NSEnumerator *enumerator; - id theObject; - - [self reloadTables:self]; - - enumerator = [tables objectEnumerator]; - while ( (theObject = [enumerator nextObject]) ) { - if ( [sender tag] ) { - [theObject replaceObjectAtIndex:0 withObject:[NSNumber numberWithBool:YES]]; - } else { - [theObject replaceObjectAtIndex:0 withObject:[NSNumber numberWithBool:NO]]; - } - } - - [exportDumpTableView reloadData]; - [exportMultipleCSVTableView reloadData]; - [exportMultipleXMLTableView reloadData]; -} - -- (IBAction)closeSheet:(id)sender -/* - ends the modal session - */ -{ - [NSApp stopModalWithCode:[sender tag]]; -} - -#pragma mark - -#pragma mark export methods - -- (void)exportFile:(int)tag -/* - invoked when user clicks on an export menuItem - */ -{ - NSString *file; - NSString *contextInfo; - NSSavePanel *savePanel = [NSSavePanel savePanel]; - NSString *currentDate = [[NSDate date] descriptionWithCalendarFormat:@"%d.%m.%Y" timeZone:nil locale:nil]; - - switch ( tag ) { - case 5: - // export dump - [self reloadTables:self]; - file = [NSString stringWithFormat:@"%@_dump %@.sql", [tableDocumentInstance database], currentDate]; - [savePanel setAccessoryView:exportDumpView]; - contextInfo = @"exportDump"; - break; - - // Export the full resultset for the currently selected table to a file in CSV format - case 6: - file = [NSString stringWithFormat:@"%@.csv", [tableDocumentInstance table]]; - [savePanel setAccessoryView:exportCSVView]; - contextInfo = @"exportTableContentAsCSV"; - break; - - // Export the full resultset for the currently selected table to a file in XML format - case 7: - file = [NSString stringWithFormat:@"%@.xml", [tableDocumentInstance table]]; - contextInfo = @"exportTableContentAsXML"; - break; - - // Export the current "browse" view to a file in CSV format - case 8: - file = [NSString stringWithFormat:@"%@ view.csv", [tableDocumentInstance table]]; - [savePanel setAccessoryView:exportCSVView]; - contextInfo = @"exportBrowseViewAsCSV"; - break; - - // Export the current "browse" view to a file in XML format - case 9: - file = [NSString stringWithFormat:@"%@ view.xml", [tableDocumentInstance table]]; - contextInfo = @"exportBrowseViewAsXML"; - break; - - // Export the current custom query result set to a file in CSV format - case 10: - file = @"customresult.csv"; - [savePanel setAccessoryView:exportCSVView]; - contextInfo = @"exportCustomResultAsCSV"; - break; - - // Export the current custom query result set to a file in XML format - case 11: - file = @"customresult.xml"; - contextInfo = @"exportCustomResultAsXML"; - break; - - // Export multiple tables to a file in CSV format - case 12: - [self reloadTables:self]; - file = [NSString stringWithFormat:@"%@.csv", [tableDocumentInstance database]]; - [savePanel setAccessoryView:exportMultipleCSVView]; - contextInfo = @"exportMultipleTablesAsCSV"; - break; - - // Export multiple tables to a file in XML format - case 13: - [self reloadTables:self]; - file = [NSString stringWithFormat:@"%@.xml", [tableDocumentInstance database]]; - [savePanel setAccessoryView:exportMultipleXMLView]; - contextInfo = @"exportMultipleTablesAsXML"; - break; - default: - NSLog(@"ERROR: unknown export item with tag %d", tag); - return; - break; - } - - // Open the savePanel - [savePanel beginSheetForDirectory:[prefs objectForKey:@"savePath"] - file:file modalForWindow:tableWindow modalDelegate:self - didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:contextInfo]; -} - -/* - Save the export file; open a file handle, pass it to the appropriate data-writing function for streaming the export, and close the handle. - */ -- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo -{ - NSFileHandle *fileHandle = nil; - BOOL success; - - [sheet orderOut:self]; - - if ( returnCode != NSOKButton ) - return; - - // Save path to preferences - [prefs setObject:[sheet directory] forKey:@"savePath"]; - - // Error if the file already exists and is not writable, and get a fileHandle to it. - if ( [[NSFileManager defaultManager] fileExistsAtPath:[sheet filename]] ) { - if ( ![[NSFileManager defaultManager] isWritableFileAtPath:[sheet filename]] - || !(fileHandle = [NSFileHandle fileHandleForWritingAtPath:[sheet filename]]) ) { - NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, - NSLocalizedString(@"Couldn't replace the file. Be sure that you have the necessary privileges.", @"message of panel when file cannot be replaced")); - return; - } - - // Truncate the file to zero bytes - [fileHandle truncateFileAtOffset:0]; - - // Otherwise attempt to create a file - } else { - if ( ![[NSFileManager defaultManager] createFileAtPath:[sheet filename] contents:[NSData data] attributes:nil] ) { - NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, - NSLocalizedString(@"Couldn't write to file. Be sure that you have the necessary privileges.", @"message of panel when file cannot be written")); - return; - } - - // Retrieve a filehandle for the file, attempting to delete it on failure. - fileHandle = [NSFileHandle fileHandleForWritingAtPath:[sheet filename]]; - if ( !fileHandle ) { - [[NSFileManager defaultManager] removeFileAtPath:[sheet filename] handler:nil]; - NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, - NSLocalizedString(@"Couldn't write to file. Be sure that you have the necessary privileges.", @"message of panel when file cannot be written")); - return; - } - } - - // Export the tables selected in the MySQL export sheet to a file - if ( [contextInfo isEqualToString:@"exportDump"] ) { - success = [self dumpSelectedTablesAsSqlToFileHandle:fileHandle]; - - // Export the full resultset for the currently selected table to a file in CSV format - } else if ( [contextInfo isEqualToString:@"exportTableContentAsCSV"] ) { - success = [self exportTables:[NSArray arrayWithObject:[tableDocumentInstance table]] toFileHandle:fileHandle usingFormat:@"csv"]; - - // Export the full resultset for the currently selected table to a file in XML format - } else if ( [contextInfo isEqualToString:@"exportTableContentAsXML"] ) { - success = [self exportTables:[NSArray arrayWithObject:[tableDocumentInstance table]] toFileHandle:fileHandle usingFormat:@"xml"]; - - // Export the current "browse" view to a file in CSV format - } else if ( [contextInfo isEqualToString:@"exportBrowseViewAsCSV"] ) { - success = [self writeCsvForArray:[tableContentInstance currentResult] orQueryResult:nil - toFileHandle:fileHandle - outputFieldNames:[exportFieldNamesSwitch state] - terminatedBy:[exportFieldsTerminatedField stringValue] - enclosedBy:[exportFieldsEnclosedField stringValue] - escapedBy:[exportFieldsEscapedField stringValue] - lineEnds:[exportLinesTerminatedField stringValue] - silently:NO]; - - // Export the current "browse" view to a file in XML format - } else if ( [contextInfo isEqualToString:@"exportBrowseViewAsXML"] ) { - success = [self writeXmlForArray:[tableContentInstance currentResult] orQueryResult:nil - toFileHandle:fileHandle - tableName:[tableDocumentInstance table] - withHeader:YES - silently:NO]; - - // Export the current custom query result set to a file in CSV format - } else if ( [contextInfo isEqualToString:@"exportCustomResultAsCSV"] ) { - success = [self writeCsvForArray:[customQueryInstance currentResult] orQueryResult:nil - toFileHandle:fileHandle - outputFieldNames:[exportFieldNamesSwitch state] - terminatedBy:[exportFieldsTerminatedField stringValue] - enclosedBy:[exportFieldsEnclosedField stringValue] - escapedBy:[exportFieldsEscapedField stringValue] - lineEnds:[exportLinesTerminatedField stringValue] - silently:NO]; - - // Export the current custom query result set to a file in XML format - } else if ( [contextInfo isEqualToString:@"exportCustomResultAsXML"] ) { - success = [self writeXmlForArray:[customQueryInstance currentResult] orQueryResult:nil - toFileHandle:fileHandle - tableName:@"custom" - withHeader:YES - silently:NO]; - - // Export multiple tables to a file in CSV format - } else if ( [contextInfo isEqualToString:@"exportMultipleTablesAsCSV"] ) { - success = [self exportSelectedTablesToFileHandle:fileHandle usingFormat:@"csv"]; - - // Export multiple tables to a file in XML format - } else if ( [contextInfo isEqualToString:@"exportMultipleTablesAsXML"] ) { - success = [self exportSelectedTablesToFileHandle:fileHandle usingFormat:@"xml"]; - - // Unknown operation - } else { - NSLog(@"Unknown export operation: %@", [contextInfo description]); - return; - } - - // Close the file handle - [fileHandle closeFile]; - - if ( !success ) { - NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, - NSLocalizedString(@"Couldn't write to file. Be sure that you have the necessary privileges.", @"message of panel when file cannot be written")); - } - - // Export finished Growl notification - [[SPGrowlController sharedGrowlController] notifyWithTitle:@"Export Finished" - description:[NSString stringWithFormat:NSLocalizedString(@"Finished exporting to %@",@"description for finished exporting growl notification"), [[sheet filename] lastPathComponent]] - notificationName:@"Export Finished"]; -} - -#pragma mark - -#pragma mark import methods - -- (void)importFile -/* - invoked when user clicks on an import menuItem - */ -{ - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; - [openPanel setAccessoryView:importCSVView]; - - // Show openPanel - [openPanel beginSheetForDirectory:[prefs objectForKey:@"openPath"] - file:nil - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (IBAction)changeFormat:(id)sender -{ - [importCSVBox setHidden:![[[importFormatPopup selectedItem] title] isEqualToString:@"CSV"]]; -} - -- (IBAction)changeTable:(id)sender -{ - [tableListView selectRowIndexes:[NSIndexSet indexSetWithIndex:[[tablesListInstance tables] indexOfObject:[fieldMappingPopup titleOfSelectedItem]]] byExtendingSelection:NO]; - - //set up tableView - currentRow = 0; - fieldMappingArray = nil; - [self setupFieldMappingArray]; - [rowDownButton setEnabled:NO]; - [rowUpButton setEnabled:([importArray count] > 1)]; - [recordCountLabel setStringValue:[NSString stringWithFormat:@"%i of %i records", currentRow+1, [importArray count]]]; - - [self updateFieldMappingButtonCell]; - [fieldMappingTableView reloadData]; -} - -- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo -/* - reads mysql-dumpfile - */ -{ - NSString *dumpFile; - NSError **errorStr; - NSMutableString *errors = [NSMutableString string]; - NSString *fileType = [[importFormatPopup selectedItem] title]; - - [sheet orderOut:self]; - - if ( returnCode != NSOKButton ) - return; - - //save path to preferences - [prefs setObject:[sheet directory] forKey:@"openPath"]; - - //load file into string - if ( [NSString respondsToSelector:@selector(stringWithContentsOfFile:encoding:error:)] ) { - // mac os 10.4 or later - dumpFile = [NSString stringWithContentsOfFile:[sheet filename] - encoding:[CMMCPConnection encodingForMySQLEncoding:[[tableDocumentInstance encoding] cString]] - error:errorStr]; - } else { - // mac os pre 10.4 - dumpFile = [NSString stringWithContentsOfFile:[sheet filename]]; - } - - if ( !dumpFile ) { - NSBeginAlertSheet(NSLocalizedString(@"Error", @"Title of error alert"), - NSLocalizedString(@"OK", @"OK button"), - nil, nil, - tableWindow, self, - nil, nil, nil, - NSLocalizedString(@"Couldn't open file. Be sure that the path is correct and that you have the necessary privileges.", @"Message of panel when file cannot be opened")); - return; - } - - // reset interface - [errorsView setString:@""]; - [errorsView displayIfNeeded]; - [singleProgressText setStringValue:NSLocalizedString(@"Reading...", @"text showing that app is reading dump")]; - [singleProgressText displayIfNeeded]; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - if ( [fileType isEqualToString:@"SQL"] ) { - - //import dump file - NSArray *queries; - int i; - - //open progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - [singleProgressBar setIndeterminate:YES]; - [singleProgressBar setUsesThreadedAnimation:YES]; - [singleProgressBar startAnimation:self]; - - //get array with an object for each mysql-query - queries = [self splitQueries:dumpFile]; - - [singleProgressBar stopAnimation:self]; - [singleProgressBar setUsesThreadedAnimation:NO]; - [singleProgressBar setIndeterminate:NO]; - - //perform all mysql-queries - for ( i = 0 ; i < [queries count] ; i++ ) { - [singleProgressBar setDoubleValue:((i+1)*100/[queries count])]; - [singleProgressBar displayIfNeeded]; - [mySQLConnection queryString:[queries objectAtIndex:i]]; - - if (![[mySQLConnection getLastErrorMessage] isEqualToString:@""] && ![[mySQLConnection getLastErrorMessage] isEqualToString:@"Query was empty"]) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"[ERROR in query %d] %@\n", @"error text when multiple custom query failed"), (i+1),[mySQLConnection getLastErrorMessage]]]; - } - } - - //close progress sheet - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - - //display errors - if ( [errors length] ) { - [errorsView setString:errors]; - [NSApp beginSheet:errorsSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - [NSApp runModalForWindow:errorsSheet]; - - [NSApp endSheet:errorsSheet]; - [errorsSheet orderOut:nil]; - } - - //////////////// - // IMPORT CSV // - //////////////// - - } else if ( [fileType isEqualToString:@"CSV"] ) { - //import csv file - int code; - NSPopUpButtonCell *buttonCell = [[NSPopUpButtonCell alloc] init]; - - //open progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - [singleProgressBar setIndeterminate:YES]; - [singleProgressBar setUsesThreadedAnimation:YES]; - [singleProgressBar startAnimation:self]; - - //put file in array - if ( importArray ) - [importArray release]; - - importArray = [[self arrayForCSV:dumpFile - terminatedBy:[importFieldsTerminatedField stringValue] - enclosedBy:[importFieldsEnclosedField stringValue] - escapedBy:[importFieldsEscapedField stringValue] - lineEnds:[importLinesTerminatedField stringValue]] retain]; - - //close progress sheet - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - [singleProgressBar stopAnimation:self]; - [singleProgressBar setUsesThreadedAnimation:NO]; - [singleProgressBar setIndeterminate:NO]; - - - CMMCPResult *theResult; - int i; - theResult = (CMMCPResult *) [mySQLConnection listTables]; - if ([theResult numOfRows]) [theResult dataSeek:0]; - for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { - [fieldMappingPopup addItemWithTitle:[[theResult fetchRowAsArray] objectAtIndex:0]]; - } - - if ([tableDocumentInstance table] != nil && ![(NSString *)[tableDocumentInstance table] isEqualToString:@""]) { - [fieldMappingPopup selectItemWithTitle:[(TableDocument *)tableDocumentInstance table]]; - } else { - [fieldMappingPopup selectItemAtIndex:0]; - } - - [tableListView selectRowIndexes:[NSIndexSet indexSetWithIndex:[[tablesListInstance tables] indexOfObject:[fieldMappingPopup titleOfSelectedItem]]] byExtendingSelection:NO]; - - //set up tableView - currentRow = 0; - fieldMappingArray = nil; - [self setupFieldMappingArray]; - [rowDownButton setEnabled:NO]; - [rowUpButton setEnabled:([importArray count] > 1)]; - [recordCountLabel setStringValue:[NSString stringWithFormat:@"%i of %i records", currentRow+1, [importArray count]]]; - - //set up tableView buttons - [buttonCell setControlSize:NSSmallControlSize]; - [buttonCell setFont:[NSFont labelFontOfSize:[NSFont smallSystemFontSize]]]; - [buttonCell setBordered:NO]; - [[fieldMappingTableView tableColumnWithIdentifier:@"value"] setDataCell:buttonCell]; - [self updateFieldMappingButtonCell]; - [fieldMappingTableView reloadData]; - - // show fieldMapping sheet - [NSApp beginSheet:fieldMappingSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - code = [NSApp runModalForWindow:fieldMappingSheet]; - - [NSApp endSheet:fieldMappingSheet]; - [fieldMappingSheet orderOut:nil]; - - if ( code ) { - //import array into db - NSMutableString *fNames = [NSMutableString string]; - //NSMutableArray *fValuesIndexes = [NSMutableArray array]; - NSMutableString *fValues = [NSMutableString string]; - int i,j; - - //open progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - // get fields to be imported - for (i = 0; i < [fieldMappingArray count] ; i++ ) { - if ([[fieldMappingArray objectAtIndex:i] intValue] > 0) { - if ( [fNames length] ) - [fNames appendString:@","]; - - [fNames appendString:[NSString stringWithFormat:@"`%@`", [[tableSourceInstance fieldNames] objectAtIndex:i]]]; - } - } - - //import array - for ( i = 0 ; i < [importArray count] ; i++ ) { - //show progress bar - [singleProgressBar setDoubleValue:((i+1)*100/[importArray count])]; - [singleProgressBar displayIfNeeded]; - - if ( !([importFieldNamesSwitch state] && (i == 0)) ) { - //put values in string - [fValues setString:@""]; - - for ( j = 0 ; j < [fieldMappingArray count] ; j++ ) { - - if ([[fieldMappingArray objectAtIndex:j] intValue] > 0) { - if ( [fValues length] ) - [fValues appendString:@","]; - - if ([[[importArray objectAtIndex:i] objectAtIndex:([[fieldMappingArray objectAtIndex:j] intValue] - 1)] isMemberOfClass:[NSNull class]] ) { - [fValues appendString:@"NULL"]; - } else { - [fValues appendString:[NSString stringWithFormat:@"'%@'",[mySQLConnection prepareString:[[importArray objectAtIndex:i] objectAtIndex:([[fieldMappingArray objectAtIndex:j] intValue] - 1)]]]]; - } - } - } - - //perform query - [mySQLConnection queryString:[NSString stringWithFormat:@"INSERT INTO `%@` (%@) VALUES (%@)", - [fieldMappingPopup titleOfSelectedItem], - fNames, - fValues]]; - - if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"[ERROR in line %d] %@\n", @"error text when reading of csv file gave errors"), (i+1),[mySQLConnection getLastErrorMessage]]]; - } - } - } - - //close progress sheet - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - } - - [tableContentInstance reloadTableValues:self]; - - //display errors - if ( [errors length] ) { - [errorsView setString:errors]; - [NSApp beginSheet:errorsSheet - modalForWindow:tableWindow - modalDelegate:self - didEndSelector:nil - contextInfo:nil]; - - [NSApp runModalForWindow:errorsSheet]; - - [NSApp endSheet:errorsSheet]; - [errorsSheet orderOut:nil]; - } - - //free arrays - fieldMappingArray = nil; - importArray = nil; - } - - // Import finished Growl notification - [[SPGrowlController sharedGrowlController] notifyWithTitle:@"Import Finished" - description:[NSString stringWithFormat:NSLocalizedString(@"Finished importing %@",@"description for finished importing growl notification"), [[sheet filename] lastPathComponent]] - notificationName:@"Import Finished"]; -} - -- (void)setupFieldMappingArray -/* - sets up the fieldMapping array to be shown in the tableView - */ -{ - int i, value; - - if ( fieldMappingArray ) { - - // for ( i = 0 ; i < [fieldMappingArray count] ; i++ ) { - // - // if ( [[[importArray objectAtIndex:currentRow] objectAtIndex:i] isKindOfClass:[NSNull class]] ) { - // [fieldMappingArray replaceObjectAtIndex:i withObject:0]; - // - // } else { - // [fieldMappingArray replaceObjectAtIndex:i withObject:[[importArray objectAtIndex:currentRow] objectAtIndex:0]]; - // } - // } - - } else { - fieldMappingArray = [NSMutableArray array]; - - for (i = 0; i < [[tableSourceInstance fieldNames] count]; i++) { - if (i < [[importArray objectAtIndex:currentRow] count] && ![[[importArray objectAtIndex:currentRow] objectAtIndex:i] isKindOfClass:[NSNull class]]) { - value = i + 1; - } else { - value = 0; - } - - [fieldMappingArray addObject:[NSNumber numberWithInt:value]]; - } - - [fieldMappingArray retain]; - } - - [fieldMappingTableView reloadData]; -} - -/* - * Update the NSButtonCell items for use in the field mapping display - */ -- (void)updateFieldMappingButtonCell -{ - int i; - - [fieldMappingButtonOptions setArray:[importArray objectAtIndex:currentRow]]; - for (i = 0; i < [fieldMappingButtonOptions count]; i++) { - if ([[fieldMappingButtonOptions objectAtIndex:i] isNSNull]) { - [fieldMappingButtonOptions replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%i. %@", i+1, [prefs objectForKey:@"nullValue"]]]; - } else { - [fieldMappingButtonOptions replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%i. %@", i+1, [fieldMappingButtonOptions objectAtIndex:i]]]; - } - } -} - -- (IBAction)stepRow:(id)sender -/* - displays next/previous row in fieldMapping tableView - */ -{ - if ( [sender tag] == 0 ) { - currentRow--; - } else { - currentRow++; - } - [self updateFieldMappingButtonCell]; - - //-----------[self setupFieldMappingArray]; - [fieldMappingTableView reloadData]; - - [recordCountLabel setStringValue:[NSString stringWithFormat:@"%i of %i records", currentRow+1, [importArray count]]]; - - // enable/disable buttons - [rowDownButton setEnabled:(currentRow != 0)]; - [rowUpButton setEnabled:(currentRow != ([importArray count]-1))]; -} - -#pragma mark - -#pragma mark format methods - - -/* - Dump the selected tables to a file handle in SQL format. - */ -- (BOOL)dumpSelectedTablesAsSqlToFileHandle:(NSFileHandle *)fileHandle -{ - int i,j,t,rowCount, progressBarWidth, lastProgressValue, queryLength; - CMMCPResult *queryResult; - NSString *tableName; - NSArray *fieldNames; - NSArray *theRow; - NSMutableArray *selectedTables = [NSMutableArray array]; - NSMutableString *headerString = [NSMutableString string]; - NSMutableString *cellValue = [NSMutableString string]; - NSMutableString *sqlString = [NSMutableString string]; - NSMutableString *errors = [NSMutableString string]; - NSStringEncoding connectionEncoding = [mySQLConnection encoding]; - NSScanner *sqlNumericTester; - id createTableSyntax; - - // Reset the interface - [errorsView setString:@""]; - [errorsView displayIfNeeded]; - [singleProgressText setStringValue:NSLocalizedString(@"Dumping...", @"text showing that app is writing dump")]; - [singleProgressText displayIfNeeded]; - progressBarWidth = (int)[singleProgressBar bounds].size.width; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - // Open the progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - - // Copy over the selected table names into a table in preparation for iteration - for ( i = 0 ; i < [tables count] ; i++ ) { - if ( [[[tables objectAtIndex:i] objectAtIndex:0] boolValue] ) { - [selectedTables addObject:[NSString stringWithString:[[tables objectAtIndex:i] objectAtIndex:1]]]; - } - } - - // Add the dump header to the dump file. - [headerString setString:@"# Sequel Pro dump\n"]; - [headerString appendString:[NSString stringWithFormat:@"# Version %@\n", - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]]; - [headerString appendString:@"# http://code.google.com/p/sequel-pro\n#\n"]; - [headerString appendString:[NSString stringWithFormat:@"# Host: %@ (MySQL %@)\n", - [tableDocumentInstance host], [tableDocumentInstance mySQLVersion]]]; - [headerString appendString:[NSString stringWithFormat:@"# Database: %@\n", [tableDocumentInstance database]]]; - [headerString appendString:[NSString stringWithFormat:@"# Generation Time: %@\n", [NSDate date]]]; - [headerString appendString:@"# ************************************************************\n\n"]; - [fileHandle writeData:[headerString dataUsingEncoding:connectionEncoding]]; - - // Loop through the selected tables - for ( i = 0 ; i < [selectedTables count] ; i++ ) { - lastProgressValue = 0; - - // Update the progress text and reset the progress bar to indeterminate status while fetching data - tableName = [selectedTables objectAtIndex:i]; - [singleProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %i of %i (%@): Fetching data...", @"text showing that app is fetching data for table dump"), (i+1), [selectedTables count], tableName]]; - [singleProgressText displayIfNeeded]; - [singleProgressBar setIndeterminate:YES]; - [singleProgressBar setUsesThreadedAnimation:YES]; - [singleProgressBar startAnimation:self]; - - // Add the name of table - [fileHandle writeData:[[NSString stringWithFormat:@"# Dump of table %@\n# ------------------------------------------------------------\n\n", tableName] - dataUsingEncoding:connectionEncoding]]; - - - // Add a "drop table" command if specified in the export dialog - if ( [addDropTableSwitch state] == NSOnState ) - [fileHandle writeData:[[NSString stringWithFormat:@"DROP TABLE IF EXISTS `%@`;\n\n", tableName] - dataUsingEncoding:connectionEncoding]]; - - // Add the create syntax for the table if specified in the export dialog - if ( [addCreateTableSwitch state] == NSOnState ) { - queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE `%@`", tableName]]; - if ( [queryResult numOfRows] ) { - createTableSyntax = [[queryResult fetchRowAsDictionary] objectForKey:@"Create Table"]; - if ( [createTableSyntax isKindOfClass:[NSData class]] ) { - createTableSyntax = [[[NSString alloc] initWithData:createTableSyntax encoding:connectionEncoding] autorelease]; - } - [fileHandle writeData:[createTableSyntax dataUsingEncoding:connectionEncoding]]; - [fileHandle writeData:[[NSString stringWithString:@";\n\n"] dataUsingEncoding:connectionEncoding]]; - } - if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { - [errors appendString:[NSString stringWithFormat:@"%@\n", [mySQLConnection getLastErrorMessage]]]; - if ( [addErrorsSwitch state] == NSOnState ) { - [fileHandle writeData:[[NSString stringWithFormat:@"# Error: %@\n", [mySQLConnection getLastErrorMessage]] dataUsingEncoding:connectionEncoding]]; - } - } - } - - // Add the table content if required - if ( [addTableContentSwitch state] == NSOnState ) { - queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM `%@`", tableName]]; - fieldNames = [queryResult fetchFieldNames]; - rowCount = [queryResult numOfRows]; - - // Update the progress text and set the progress bar back to determinate - [singleProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %i of %i (%@): Dumping...", @"text showing that app is writing data for table dump"), (i+1), [selectedTables count], tableName]]; - [singleProgressText displayIfNeeded]; - [singleProgressBar stopAnimation:self]; - [singleProgressBar setUsesThreadedAnimation:NO]; - [singleProgressBar setIndeterminate:NO]; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - if (rowCount) { - [queryResult dataSeek:0]; - queryLength = 0; - - // Construct the start of the insertion command - [fileHandle writeData:[[NSString stringWithFormat:@"INSERT INTO `%@` (`%@`)\nVALUES\n\t(", - tableName, [fieldNames componentsJoinedByString:@"`,`"]] dataUsingEncoding:connectionEncoding]]; - - // Iterate through the rows to construct a VALUES group for each - for ( j = 0 ; j < rowCount ; j++ ) { - theRow = [queryResult fetchRowAsArray]; - [sqlString setString:@""]; - - // Update the progress bar - [singleProgressBar setDoubleValue:((j+1)*100/rowCount)]; - if ((int)[singleProgressBar doubleValue] > lastProgressValue) { - lastProgressValue = (int)[singleProgressBar doubleValue]; - [singleProgressBar displayIfNeeded]; - } - - for ( t = 0 ; t < [theRow count] ; t++ ) { - - // Add NULL values directly to the output row - if ( [[theRow objectAtIndex:t] isMemberOfClass:[NSNull class]] ) { - [sqlString appendString:@"NULL"]; - - // Add data types directly as hex data - } else if ( [[theRow objectAtIndex:t] isKindOfClass:[NSData class]] ) { - [sqlString appendString:@"X'"]; - [sqlString appendString:[mySQLConnection prepareBinaryData:[theRow objectAtIndex:t]]]; - [sqlString appendString:@"'"]; - - } else { - [cellValue setString:[[theRow objectAtIndex:t] description]]; - - // Add empty strings as a pair of quotes - if ([cellValue length] == 0) { - [sqlString appendString:@"''"]; - - } else { - - // Test whether this cell contains a number - sqlNumericTester = [NSScanner scannerWithString:cellValue]; - - // If it does contain a number, add the number directly - if ([sqlNumericTester scanFloat:nil] && [sqlNumericTester isAtEnd]) { - [sqlString appendString:cellValue]; - - // Otherwise add a quoted string with special characters escaped - } else { - [sqlString appendString:@"'"]; - [sqlString appendString:[mySQLConnection prepareString:cellValue]]; - [sqlString appendString:@"'"]; - } - } - } - - // Add the field separator if this isn't the last cell in the row - if (t != [theRow count] - 1) [sqlString appendString:@","]; - } - - queryLength += [sqlString length]; - - // Close this VALUES group and set up the next one if appropriate - if (j != rowCount - 1) { - - // Add a new INSERT starter command every ~250k of data. - if (queryLength > 250000) { - [sqlString appendString:[NSString stringWithFormat:@");\n\nINSERT INTO `%@` (`%@`)\nVALUES\n\t(", - tableName, [fieldNames componentsJoinedByString:@"`,`"]]]; - queryLength = 0; - } else { - [sqlString appendString:@"),\n\t("]; - } - } else { - [sqlString appendString:@")"]; - } - - // Write this row to the file - [fileHandle writeData:[sqlString dataUsingEncoding:connectionEncoding]]; - } - - // Complete the command - [fileHandle writeData:[[NSString stringWithString:@";\n\n"] dataUsingEncoding:connectionEncoding]]; - - if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { - [errors appendString:[NSString stringWithFormat:@"%@\n", [mySQLConnection getLastErrorMessage]]]; - if ( [addErrorsSwitch state] == NSOnState ) { - [fileHandle writeData:[[NSString stringWithFormat:@"# Error: %@\n", [mySQLConnection getLastErrorMessage]] - dataUsingEncoding:connectionEncoding]]; - } - } - } - } - - // Add an additional separator between tables - [fileHandle writeData:[[NSString stringWithString:@"\n\n"] dataUsingEncoding:connectionEncoding]]; - } - - // Close the progress sheet - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - - // Show errors sheet if there have been errors - if ( [errors length] ) { - [errorsView setString:errors]; - [NSApp beginSheet:errorsSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - [NSApp runModalForWindow:errorsSheet]; - - [NSApp endSheet:errorsSheet]; - [errorsSheet orderOut:nil]; - } - - return TRUE; -} - -/* - Takes an array and writes it in CSV format to the supplied NSFileHandle - */ -- (BOOL)writeCsvForArray:(NSArray *)array orQueryResult:(CMMCPResult *)queryResult toFileHandle:(NSFileHandle *)fileHandle outputFieldNames:(BOOL)outputFieldNames terminatedBy:(NSString *)fieldSeparatorString - enclosedBy:(NSString *)enclosingString escapedBy:(NSString *)escapeString lineEnds:(NSString *)lineEndString silently:(BOOL)silently; -{ - NSStringEncoding tableEncoding = [CMMCPConnection encodingForMySQLEncoding:[[tableDocumentInstance encoding] cString]]; - NSMutableString *csvCell = [NSMutableString string]; - NSMutableArray *csvRow = [NSMutableArray array]; - NSMutableString *csvString = [NSMutableString string]; - NSString *nullString = [NSString stringWithString:[prefs objectForKey:@"nullValue"]]; - NSString *escapedEscapeString, *escapedFieldSeparatorString, *escapedEnclosingString, *escapedLineEndString; - NSString *dataConversionString; - NSScanner *csvNumericTester; - BOOL quoteFieldSeparators = [enclosingString isEqualToString:@""]; - BOOL csvCellIsNumeric; - int i, j, startingRow, totalRows, progressBarWidth, lastProgressValue; - - if (queryResult != nil && [queryResult numOfRows]) [queryResult dataSeek:0]; - - // Detect and restore special characters being used as terminating or line end strings - NSMutableString *tempSeparatorString = [NSMutableString stringWithString:fieldSeparatorString]; - [tempSeparatorString replaceOccurrencesOfString:@"\\t" withString:@"\t" - options:NSLiteralSearch - range:NSMakeRange(0, [tempSeparatorString length])]; - [tempSeparatorString replaceOccurrencesOfString:@"\\n" withString:@"\n" - options:NSLiteralSearch - range:NSMakeRange(0, [tempSeparatorString length])]; - [tempSeparatorString replaceOccurrencesOfString:@"\\r" withString:@"\r" - options:NSLiteralSearch - range:NSMakeRange(0, [tempSeparatorString length])]; - fieldSeparatorString = [NSString stringWithString:tempSeparatorString]; - NSMutableString *tempLineEndString = [NSMutableString stringWithString:lineEndString]; - [tempLineEndString replaceOccurrencesOfString:@"\\t" withString:@"\t" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEndString length])]; - [tempLineEndString replaceOccurrencesOfString:@"\\n" withString:@"\n" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEndString length])]; - [tempLineEndString replaceOccurrencesOfString:@"\\r" withString:@"\r" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEndString length])]; - lineEndString = [NSString stringWithString:tempLineEndString]; - - // Updating the progress bar can take >20% of processing time - store details to only update when required - progressBarWidth = (int)[singleProgressBar bounds].size.width; - lastProgressValue = 0; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - if ( !silently ) { - - // Set the progress text - [singleProgressText setStringValue:NSLocalizedString(@"Exporting...", @"text showing that app is exporting to text file")]; - [singleProgressText displayIfNeeded]; - - - // Open progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - } - - // Set up escaped versions of strings for substitution within the loop - escapedEscapeString = [NSString stringWithFormat:@"%@%@", escapeString, escapeString]; - escapedFieldSeparatorString = [NSString stringWithFormat:@"%@%@", escapeString, fieldSeparatorString]; - escapedEnclosingString = [NSString stringWithFormat:@"%@%@", escapeString, enclosingString]; - escapedLineEndString = [NSString stringWithFormat:@"%@%@", escapeString, lineEndString]; - - // Determine the total number of rows and starting row depending on supplied data format - if (array == nil) { - startingRow = outputFieldNames ? -1 : 0; - totalRows = [queryResult numOfRows]; - } else { - startingRow = outputFieldNames ? 0 : 1; - totalRows = [array count]; - } - - // Walk through the supplied data constructing the CSV string - for ( i = startingRow ; i < totalRows ; i++ ) { - - // Update the progress bar - [singleProgressBar setDoubleValue:((i+1)*100/totalRows)]; - if ((int)[singleProgressBar doubleValue] > lastProgressValue) { - lastProgressValue = (int)[singleProgressBar doubleValue]; - [singleProgressBar displayIfNeeded]; - } - - // Retrieve the row from the supplied data - if (array == nil) { - - // Header row - if (i == -1) { - [csvRow setArray:[queryResult fetchFieldNames]]; - } else { - [csvRow setArray:[queryResult fetchRowAsArray]]; - } - } else { - [csvRow setArray:[array objectAtIndex:i]]; - } - - [csvString setString:@""]; - for ( j = 0 ; j < [csvRow count] ; j++ ) { - - // For NULL objects supplied from a queryResult, add an unenclosed null string as per prefs - if ([[csvRow objectAtIndex:j] isKindOfClass:[NSNull class]]) { - [csvString appendString:nullString]; - if (j < [csvRow count] - 1) [csvString appendString:fieldSeparatorString]; - continue; - } - - // Retrieve the contents of this cell - if ([[csvRow objectAtIndex:j] isKindOfClass:[NSData class]]) { - dataConversionString = [[NSString alloc] initWithData:[csvRow objectAtIndex:j] encoding:tableEncoding]; - [csvCell setString:[NSString stringWithString:dataConversionString]]; - [dataConversionString release]; - } else { - [csvCell setString:[[csvRow objectAtIndex:j] description]]; - } - - // For NULL values supplied via an array add the unenclosed null string as set in preferences - if ( [csvCell isEqualToString:nullString] ) { - [csvString appendString:nullString]; - - // Add empty strings as a pair of enclosing characters. - } else if ( [csvCell length] == 0 ) { - [csvString appendString:enclosingString]; - [csvString appendString:enclosingString]; - - } else { - - // Test whether this cell contains a number - if ([[csvRow objectAtIndex:j] isKindOfClass:[NSData class]]) { - csvCellIsNumeric = FALSE; - } else { - csvNumericTester = [NSScanner scannerWithString:csvCell]; - csvCellIsNumeric = [csvNumericTester scanFloat:nil] && [csvNumericTester isAtEnd]; - } - - // Escape any occurrences of the escaping character - [csvCell replaceOccurrencesOfString:escapeString - withString:escapedEscapeString - options:NSLiteralSearch - range:NSMakeRange(0,[csvCell length])]; - - // Escape any occurrences of the enclosure string - if ( ![escapeString isEqualToString:enclosingString] ) { - [csvCell replaceOccurrencesOfString:enclosingString - withString:escapedEnclosingString - options:NSLiteralSearch - range:NSMakeRange(0,[csvCell length])]; - } - - // Escape occurrences of the line end character - [csvCell replaceOccurrencesOfString:lineEndString - withString:escapedLineEndString - options:NSLiteralSearch - range:NSMakeRange(0,[csvCell length])]; - - // If the string isn't quoted or otherwise enclosed, escape occurrences of the - // field separators - if ( quoteFieldSeparators || csvCellIsNumeric ) { - [csvCell replaceOccurrencesOfString:fieldSeparatorString - withString:escapedFieldSeparatorString - options:NSLiteralSearch - range:NSMakeRange(0,[csvCell length])]; - } - - // Write out the cell data by appending strings - this is significantly faster than stringWithFormat. - if (csvCellIsNumeric) { - [csvString appendString:csvCell]; - } else { - [csvString appendString:enclosingString]; - [csvString appendString:csvCell]; - [csvString appendString:enclosingString]; - } - } - if (j < [csvRow count] - 1) [csvString appendString:fieldSeparatorString]; - } - - // Append the line ending to the string for this row - [csvString appendString:lineEndString]; - - // Write it to the fileHandle - [fileHandle writeData:[csvString dataUsingEncoding:tableEncoding]]; - } - - // Close the progress sheet if it's present - if ( !silently ) { - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - } - - return TRUE; -} - -- (NSArray *)arrayForCSV:(NSString *)csv terminatedBy:(NSString *)terminated - enclosedBy:(NSString *)enclosed escapedBy:(NSString *)escaped lineEnds:(NSString *)lineEnds -/* - loads a csv string into an array - */ -{ - NSMutableString *tempTerminated, *tempLineEnds; - NSMutableArray *tempArray = [NSMutableArray array]; - NSMutableArray *tempRowArray = [NSMutableArray array]; - NSMutableString *mutableField; - NSScanner *scanner; - NSString *scanString; - NSMutableString *tempString = [NSMutableString string]; - NSMutableArray *linesArray = [NSMutableArray array]; - BOOL isEscaped, br; - int fieldCount = nil; - int x,i,j; - - //repare tabs and line ends - tempTerminated = [NSMutableString stringWithString:terminated]; - [tempTerminated replaceOccurrencesOfString:@"\\t" withString:@"\t" - options:NSLiteralSearch - range:NSMakeRange(0, [tempTerminated length])]; - [tempTerminated replaceOccurrencesOfString:@"\\n" withString:@"\n" - options:NSLiteralSearch - range:NSMakeRange(0, [tempTerminated length])]; - [tempTerminated replaceOccurrencesOfString:@"\\r" withString:@"\r" - options:NSLiteralSearch - range:NSMakeRange(0, [tempTerminated length])]; - terminated = [NSString stringWithString:tempTerminated]; - tempLineEnds = [NSMutableString stringWithString:lineEnds]; - [tempLineEnds replaceOccurrencesOfString:@"\\t" withString:@"\t" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEnds length])]; - [tempLineEnds replaceOccurrencesOfString:@"\\n" withString:@"\n" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEnds length])]; - [tempLineEnds replaceOccurrencesOfString:@"\\r" withString:@"\r" - options:NSLiteralSearch - range:NSMakeRange(0, [tempLineEnds length])]; - lineEnds = [NSString stringWithString:tempLineEnds]; - - //array with one line per object - scanner = [NSScanner scannerWithString:csv]; - [scanner setCharactersToBeSkipped:nil]; - - while ( ![scanner isAtEnd] ) { - [tempString setString:@""]; - br = NO; - - while ( !br ) { - scanString = @""; - [scanner scanUpToString:lineEnds intoString:&scanString]; - [tempString appendString:scanString]; - [scanner scanString:lineEnds intoString:&scanString]; - - //test if lineEnds-character is escaped - isEscaped = NO; - j = 1; - if ( ![escaped isEqualToString:enclosed] && ![escaped isEqualToString:@""] ) { - while ( ((j*[escaped length])<=[tempString length]) && - ([[tempString substringWithRange:NSMakeRange(([tempString length]-(j*[escaped length])),[escaped length])] isEqualToString:escaped]) ) { - isEscaped = !isEscaped; - j++; - } - } - if ( !isEscaped || [scanner isAtEnd] ) { - //end of row - br = YES; - } else { - //lineEnds-character was escaped - [tempString appendString:scanString]; - } - } - - // Skip blank lines - if (![tempString length]) continue; - - // Add the line to the array - [linesArray addObject:[NSString stringWithString:tempString]]; - } - - for ( x = 0 ; x < [linesArray count] ; x++ ) { - - //separate fields - [tempRowArray removeAllObjects]; - [tempRowArray addObjectsFromArray:[self arrayForString:[linesArray objectAtIndex:x] enclosed:enclosed escaped:escaped terminated:terminated]]; - if ( x == 0 ) { - fieldCount = [tempRowArray count]; - } else { - while ( [tempRowArray count] < fieldCount ) { - [tempRowArray addObject:[NSString stringWithString:[prefs objectForKey:@"nullValue"]]]; - } - } - for ( i = 0 ; i < [tempRowArray count] ; i++ ) { - - // Insert a NSNull object if the cell contains an unescaped null character or an unescaped string - // which matches the NULL string set in preferences. - if ( [[tempRowArray objectAtIndex:i] isEqualToString:@"\\N"] || [[tempRowArray objectAtIndex:i] isEqualToString:[prefs objectForKey:@"nullValue"]] ) { - [tempRowArray replaceObjectAtIndex:i withObject:[NSNull null]]; - - } else { - - //strip enclosed and escaped characters - mutableField = [NSMutableString stringWithString:[tempRowArray objectAtIndex:i]]; - - //strip enclosed characters - if ( [mutableField length] >= (2*[enclosed length]) ) { - if ( [[mutableField substringToIndex:[enclosed length]] isEqualToString:enclosed] ) { - [mutableField deleteCharactersInRange:NSMakeRange(0,[enclosed length])]; - } - if ( [[mutableField substringFromIndex:([mutableField length]-[enclosed length])] isEqualToString:enclosed] ) { - [mutableField deleteCharactersInRange:NSMakeRange(([mutableField length]-[enclosed length]),[enclosed length])]; - } - } - if ( [mutableField length] >= [enclosed length] ) { - if ( [[mutableField substringFromIndex:([mutableField length]-[enclosed length])] isEqualToString:enclosed] ) { - [mutableField deleteCharactersInRange:NSMakeRange(([mutableField length]-[enclosed length]),[enclosed length])]; - } - } - //strip escaped characters - if ( ![enclosed isEqualToString:@""] ) { - [mutableField replaceOccurrencesOfString:[NSString stringWithFormat:@"%@%@", escaped, enclosed] withString:enclosed options:NSLiteralSearch range:NSMakeRange(0, [mutableField length])]; - } else { - [mutableField replaceOccurrencesOfString:[NSString stringWithFormat:@"%@%@", escaped, terminated] withString:terminated options:NSLiteralSearch range:NSMakeRange(0, [mutableField length])]; - } - if ( ![lineEnds isEqualToString:@""] ) { - [mutableField replaceOccurrencesOfString:[NSString stringWithFormat:@"%@%@", escaped, lineEnds] withString:lineEnds options:NSLiteralSearch range:NSMakeRange(0, [mutableField length])]; - } - if ( ![escaped isEqualToString:@""] && ![escaped isEqualToString:enclosed] ) { - [mutableField replaceOccurrencesOfString:[NSString stringWithFormat:@"%@%@", escaped, escaped] withString:escaped options:NSLiteralSearch range:NSMakeRange(0, [mutableField length])]; - } - //add field to tempRowArray - [tempRowArray replaceObjectAtIndex:i withObject:[NSString stringWithString:mutableField]]; - } - } - //add row to tempArray - [tempArray addObject:[NSArray arrayWithArray:tempRowArray]]; - } - - return [NSArray arrayWithArray:tempArray]; -} - - -/* - Takes an array and writes it in XML format to the supplied NSFileHandle - */ -- (BOOL)writeXmlForArray:(NSArray *)array orQueryResult:(CMMCPResult *)queryResult toFileHandle:(NSFileHandle *)fileHandle tableName:(NSString *)table withHeader:(BOOL)header silently:(BOOL)silently -{ - NSStringEncoding tableEncoding = [CMMCPConnection encodingForMySQLEncoding:[[tableDocumentInstance encoding] cString]]; - NSMutableArray *xmlTags = [NSMutableArray array]; - NSMutableArray *xmlRow = [NSMutableArray array]; - NSMutableString *xmlString = [NSMutableString string]; - NSMutableString *xmlItem = [NSMutableString string]; - NSString *dataConversionString; - int i,j, startingRow, totalRows, progressBarWidth, lastProgressValue; - - if (queryResult != nil && [queryResult numOfRows]) [queryResult dataSeek:0]; - - // Updating the progress bar can take >20% of processing time - store details to only update when required - progressBarWidth = (int)[singleProgressBar bounds].size.width; - lastProgressValue = 0; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - // Set up an array of encoded field names as opening and closing tags - if (array == nil) { - [xmlRow setArray:[queryResult fetchFieldNames]]; - } else { - [xmlRow setArray:[array objectAtIndex:0]]; - } - for ( j = 0; j < [xmlRow count]; j++ ) { - [xmlTags addObject:[NSMutableArray array]]; - [[xmlTags objectAtIndex:j] addObject:[NSString stringWithFormat:@"\t\t<%@>", - [self htmlEscapeString:[[xmlRow objectAtIndex:j] description]]]]; - [[xmlTags objectAtIndex:j] addObject:[NSString stringWithFormat:@"</%@>\n", - [self htmlEscapeString:[[xmlRow objectAtIndex:j] description]]]]; - } - - if ( !silently ) { - - // Set the progress text - [singleProgressText setStringValue:NSLocalizedString(@"Writing...", @"text showing that app is writing text file")]; - [singleProgressText displayIfNeeded]; - - // Open progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - } - - // Output the XML header if required - if ( header ) { - [xmlString setString:@"<?xml version=\"1.0\"?>\n\n"]; - [xmlString appendString:@"<!--\n-\n"]; - [xmlString appendString:@"- Sequel Pro dump\n"]; - [xmlString appendString:[NSString stringWithFormat:@"- Version %@\n", - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]]; - [xmlString appendString:@"- http://code.google.com/p/sequel-pro\n-\n"]; - [xmlString appendString:[NSString stringWithFormat:@"- Host: %@ (MySQL %@)\n", - [tableDocumentInstance host], [tableDocumentInstance mySQLVersion]]]; - [xmlString appendString:[NSString stringWithFormat:@"- Database: %@\n", [tableDocumentInstance database]]]; - [xmlString appendString:[NSString stringWithFormat:@"- Generation Time: %@\n", [NSDate date]]]; - [xmlString appendString:@"-\n-->\n\n"]; - [fileHandle writeData:[xmlString dataUsingEncoding:tableEncoding]]; - } - - // Write an opening tag in the form of the table name - [fileHandle writeData:[[NSString stringWithFormat:@"\t<%@>\n", - [self htmlEscapeString:table]] - dataUsingEncoding:tableEncoding]]; - - // Determine the total number of rows and starting row depending on supplied data format - if (array == nil) { - startingRow = 0; - totalRows = [queryResult numOfRows]; - } else { - startingRow = 1; - totalRows = [array count]; - } - - // Walk through the array, contructing the XML string. - for ( i = 1 ; i < totalRows ; i++ ) { - - // Update the progress bar - [singleProgressBar setDoubleValue:((i+1)*100/totalRows)]; - if ((int)[singleProgressBar doubleValue] > lastProgressValue) { - lastProgressValue = (int)[singleProgressBar doubleValue]; - [singleProgressBar displayIfNeeded]; - } - - // Retrieve the row from the supplied data - if (array == nil) { - [xmlRow setArray:[queryResult fetchRowAsArray]]; - } else { - [xmlRow setArray:[array objectAtIndex:i]]; - } - - // Construct the row - [xmlString setString:@"\t<row>\n"]; - for ( j = 0 ; j < [xmlRow count] ; j++ ) { - - // Retrieve the contents of this tag - if ([[xmlRow objectAtIndex:j] isKindOfClass:[NSData class]]) { - dataConversionString = [[NSString alloc] initWithData:[xmlRow objectAtIndex:j] encoding:tableEncoding]; - [xmlItem setString:[NSString stringWithString:dataConversionString]]; - [dataConversionString release]; - } else { - [xmlItem setString:[[xmlRow objectAtIndex:j] description]]; - } - - // Add the opening and closing tag and the contents to the XML string - [xmlString appendString:[[xmlTags objectAtIndex:j] objectAtIndex:0]]; - [xmlString appendString:[self htmlEscapeString:xmlItem]]; - [xmlString appendString:[[xmlTags objectAtIndex:j] objectAtIndex:1]]; - } - [xmlString appendString:@"\t</row>\n"]; - - // Write the row to the filehandle - [fileHandle writeData:[xmlString dataUsingEncoding:tableEncoding]]; - } - - // Write the closing tag for the table - [fileHandle writeData:[[NSString stringWithFormat:@"\t</%@>", - [self htmlEscapeString:table]] - dataUsingEncoding:tableEncoding]]; - - // Close the progress sheet if appropriate - if ( !silently ) { - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - } - - return TRUE; -} - -/* - Processes the selected tables within the multiple table export accessory view and passes them - to be exported. - */ -- (BOOL)exportSelectedTablesToFileHandle:(NSFileHandle *)fileHandle usingFormat:(NSString *)type -{ - int i; - NSMutableArray *selectedTables = [NSMutableArray array]; - - // Extract the table names of the selected tables - for ( i = 0 ; i < [tables count] ; i++ ) { - if ( [[[tables objectAtIndex:i] objectAtIndex:0] boolValue] ) { - [selectedTables addObject:[NSString stringWithString:[[tables objectAtIndex:i] objectAtIndex:1]]]; - } - } - - return [self exportTables:selectedTables toFileHandle:fileHandle usingFormat:type]; -} - -/* - Walks through the selected tables and exports them to a file handle. The export type must be - "csv" for CSV format, and "xml" for XML format. - */ -- (BOOL)exportTables:(NSArray *)selectedTables toFileHandle:(NSFileHandle *)fileHandle usingFormat:(NSString *)type -{ - int i; - CMMCPResult *queryResult; - NSString *tableName; - NSMutableString *infoString = [NSMutableString string]; - NSMutableString *errors = [NSMutableString string]; - NSStringEncoding connectionEncoding = [mySQLConnection encoding]; - NSMutableString *csvLineEnd; - - // Reset the interface - [errorsView setString:@""]; - [errorsView displayIfNeeded]; - [singleProgressText setStringValue:NSLocalizedString(@"Writing...", @"text showing that app is writing text file")]; - [singleProgressText displayIfNeeded]; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - // Open the progress sheet - [NSApp beginSheet:singleProgressSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - - - // Add a dump header to the dump file, dependant on export type. - if ( [type isEqualToString:@"csv"] ) { - csvLineEnd = [NSMutableString stringWithString:[exportMultipleLinesTerminatedField 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 ([selectedTables count] > 1) { - [infoString setString:[NSString stringWithFormat:@"Host: %@ Database: %@ Generation Time: %@%@%@", - [tableDocumentInstance host], [tableDocumentInstance database], [NSDate date], csvLineEnd, csvLineEnd]]; - } - } else if ( [type isEqualToString:@"xml"] ) { - [infoString setString:@"<?xml version=\"1.0\"?>\n\n"]; - [infoString appendString:@"<!--\n-\n"]; - [infoString appendString:@"- Sequel Pro dump\n"]; - [infoString appendString:[NSString stringWithFormat:@"- Version %@\n", - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]]; - [infoString appendString:@"- http://code.google.com/p/sequel-pro\n-\n"]; - [infoString appendString:[NSString stringWithFormat:@"- Host: %@ (MySQL %@)\n", - [tableDocumentInstance host], [tableDocumentInstance mySQLVersion]]]; - [infoString appendString:[NSString stringWithFormat:@"- Database: %@\n", [tableDocumentInstance database]]]; - [infoString appendString:[NSString stringWithFormat:@"- Generation Time: %@\n", [NSDate date]]]; - [infoString appendString:@"-\n-->\n\n\n"]; - [infoString appendString:[NSString stringWithFormat:@"<%@>\n\n\n", - [self htmlEscapeString:[tableDocumentInstance database]]]]; - } - [fileHandle writeData:[infoString dataUsingEncoding:connectionEncoding]]; - - // Loop through the selected tables - for ( i = 0 ; i < [selectedTables count] ; i++ ) { - - // Update the progress text and reset the progress bar to indeterminate status - tableName = [selectedTables objectAtIndex:i]; - [singleProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %i of %i (%@): fetching data...", @"text showing that app is fetching data for table dump"), (i+1), [selectedTables count], tableName]]; - [singleProgressText displayIfNeeded]; - [singleProgressBar setIndeterminate:YES]; - [singleProgressBar setUsesThreadedAnimation:YES]; - [singleProgressBar startAnimation:self]; - - // For CSV exports of more than one table, output the name of the table - if ( [type isEqualToString:@"csv"] && [selectedTables count] > 1) { - [fileHandle writeData:[[NSString stringWithFormat:@"Table %@%@%@", tableName, csvLineEnd, csvLineEnd] dataUsingEncoding:connectionEncoding]]; - } - - // Retrieve all the content within this table - queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM `%@`", tableName]]; - - // Note any errors during retrieval - if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) { - [errors appendString:[NSString stringWithFormat:@"%@\n", [mySQLConnection getLastErrorMessage]]]; - } - - // Update the progress text and set the progress bar back to determinate - [singleProgressText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"Table %i of %i (%@): Writing...", @"text showing that app is writing data for table export"), (i+1), [selectedTables count], tableName]]; - [singleProgressText displayIfNeeded]; - [singleProgressBar stopAnimation:self]; - [singleProgressBar setUsesThreadedAnimation:NO]; - [singleProgressBar setIndeterminate:NO]; - [singleProgressBar setDoubleValue:0]; - [singleProgressBar displayIfNeeded]; - - // Use the appropriate export method to write the data to file - if ( [type isEqualToString:@"csv"] ) { - [self writeCsvForArray:nil orQueryResult:queryResult - toFileHandle:fileHandle - outputFieldNames:[exportMultipleFieldNamesSwitch state] - terminatedBy:[exportMultipleFieldsTerminatedField stringValue] - enclosedBy:[exportMultipleFieldsEnclosedField stringValue] - escapedBy:[exportMultipleFieldsEscapedField stringValue] - lineEnds:[exportMultipleLinesTerminatedField stringValue] - silently:YES]; - - // Add a spacer to the file - [fileHandle writeData:[[NSString stringWithFormat:@"%@%@%@", csvLineEnd, csvLineEnd, csvLineEnd] dataUsingEncoding:connectionEncoding]]; - } else if ( [type isEqualToString:@"xml"] ) { - [self writeXmlForArray:nil orQueryResult:queryResult - toFileHandle:fileHandle - tableName:tableName - withHeader:NO - silently:YES]; - - // Add a spacer to the file - [fileHandle writeData:[[NSString stringWithString:@"\n\n\n"] dataUsingEncoding:connectionEncoding]]; - } - - } - - // For XML output, close the database tag - if ( [type isEqualToString:@"xml"] ) { - [fileHandle writeData:[[NSString stringWithFormat:@"</%@>", - [self htmlEscapeString:[tableDocumentInstance database]]] - dataUsingEncoding:connectionEncoding]]; - } - - // Close the progress sheet - [NSApp endSheet:singleProgressSheet]; - [singleProgressSheet orderOut:nil]; - - // Show the errors sheet if there have been errors - if ( [errors length] ) { - [errorsView setString:errors]; - [NSApp beginSheet:errorsSheet - modalForWindow:tableWindow modalDelegate:self - didEndSelector:nil contextInfo:nil]; - [NSApp runModalForWindow:errorsSheet]; - - [NSApp endSheet:errorsSheet]; - [errorsSheet orderOut:nil]; - } - - return TRUE; -} - -- (NSString *)htmlEscapeString:(NSString *)string -/* - html escapes a string - */ -{ - NSMutableString *mutableString = [NSMutableString stringWithString:string]; - - [mutableString replaceOccurrencesOfString:@"&" withString:@"&" - options:NSLiteralSearch - range:NSMakeRange(0, [mutableString length])]; - [mutableString replaceOccurrencesOfString:@"<" withString:@"<" - options:NSLiteralSearch - range:NSMakeRange(0, [mutableString length])]; - [mutableString replaceOccurrencesOfString:@">" withString:@">" - options:NSLiteralSearch - range:NSMakeRange(0, [mutableString length])]; - [mutableString replaceOccurrencesOfString:@"\"" withString:@""" - options:NSLiteralSearch - range:NSMakeRange(0, [mutableString length])]; - - return [NSString stringWithString:mutableString]; -} - -- (NSArray *)arrayForString:(NSString *)string enclosed:(NSString *)enclosed - escaped:(NSString *)escaped terminated:(NSString *)terminated -/* - split a string by the terminated-character if this is not escaped - if enclosed-character is given, ignores characters inside enclosed-characters - */ -{ - NSMutableArray *tempArray = [NSMutableArray array]; - BOOL inString = NO; - BOOL isEscaped = NO; - BOOL br = NO; - unsigned i, j, start; - char enc = nil; - char esc = nil; - char ter = nil; - - //we take only first character by now (too complicated otherwise) - if ( [enclosed length] ) { - enc = [enclosed characterAtIndex:0]; - } - if ( [escaped length] ) { - esc = [escaped characterAtIndex:0]; - } - if ( [terminated length] ) { - ter = [terminated characterAtIndex:0]; - } - - start = 0; - - for ( i = 0 ; i < [string length] ; i++ ) { - if ( inString ) { - //we are in a string - br = NO; - while ( !br ) { - if ( i >= [string length] ) { - //end of string -> no second enclose character found - br = YES; - } else if ( [string characterAtIndex:i] == enc ) { - //second enclose-character found - //enclose-character escaped? - isEscaped = NO; - j = 1; - while ( (i-j>0) && ([string characterAtIndex:(i-j)] == esc) ) { - isEscaped = !isEscaped; - j++; - } - if ( !isEscaped ) { - inString = NO; - br = YES; - } - } - if ( !br ) - i++; - } - } else if ( [string characterAtIndex:i] == ter ) { - //terminated-character found - if ( [enclosed isEqualToString:@""] ) { - //check if terminated character is escaped - isEscaped = NO; - j = 1; - while ( (i-j>0) && ([string characterAtIndex:(i-j)] == esc) ) { - isEscaped = !isEscaped; - j++; - } - if ( !isEscaped ) { - [tempArray addObject:[string substringWithRange:NSMakeRange(start,(i-start))]]; - start = i + 1; - } - } else { - //add object to array - //NSLog([string substringWithRange:NSMakeRange(start,(i-start))]); - [tempArray addObject:[string substringWithRange:NSMakeRange(start,(i-start))]]; - start = i + 1; - } - } else if ( [string characterAtIndex:i] == enc ) { - //enclosed-character found - inString = YES; - } - } - - //add rest of string to array - [tempArray addObject:[string substringWithRange:NSMakeRange(start,([string length]-start))]]; - - return [NSArray arrayWithArray:tempArray]; -} - -- (NSArray *)splitQueries:(NSString *)query -/* - splits the queries by ;'s which aren't inside any ", ' or ` characters - */ -{ - NSMutableString *queries = [NSMutableString stringWithString:query]; - NSMutableArray *queryArray = [NSMutableArray array]; - char stringType = nil; - BOOL inString = NO; - BOOL escaped; - unsigned lineStart = 0; - unsigned i, j, x, currentLineLength; - - //parse string - for ( i = 0 ; i < [queries length] ; i++ ) { - if ( inString ) { - //we are in a string - //look for end of string - for ( ; i < [queries length] ; i++ ) { - - // For the backtick character treat the string as ended - if ( ([queries characterAtIndex:i] == '`') && (stringType == '`') ) { - - inString = NO; - break; - - // Otherwise, prepare to treat the string as ended after a stringType.... - } else if ( [queries characterAtIndex:i] == stringType ) { - - // ...but only if the stringType isn't escaped with an *odd* number of escaping characters. - escaped = NO; - j = 1; - currentLineLength = i - lineStart; - while ( ((currentLineLength-j) > 0) && ([queries characterAtIndex:i-j] == '\\') ) { - escaped = !escaped; - j++; - } - - // If an odd number have been found, it really is the end of the string. - if ( !escaped ) { - inString = NO; - break; - } - } - } - } else if ( ([queries characterAtIndex:i] == '#') || - ((i+2<[queries length]) && - ([queries characterAtIndex:i] == '-') && - ([queries characterAtIndex:i+1] == '-') && - ([queries characterAtIndex:i+2] == ' ')) ) { - //it's a comment -> delete it - x = i; - while ( (x<[queries length]) && ([queries characterAtIndex:x] != '\r') && ([queries characterAtIndex:x] != '\n') ) { - x++; - } - [queries deleteCharactersInRange:NSMakeRange(i,x-i)]; - } else if ( [queries characterAtIndex:i] == ';' ) { - //we are at the end of a query - [queryArray addObject:[queries substringWithRange:NSMakeRange(lineStart, (i-lineStart))]]; - while ( ((i+1)<[queries length]) && (([queries characterAtIndex:i+1]=='\n') || ([queries characterAtIndex:i+1]=='\r') || ([queries characterAtIndex:i+1]==' ')) ) { - i++; - } - lineStart = i + 1; - } else if ( ([queries characterAtIndex:i] == '\'') || - ([queries characterAtIndex:i] == '"') || - ([queries characterAtIndex:i] == '`') ) { - //we are entering a string - inString = YES; - stringType = [queries characterAtIndex:i]; - } - } - - //add rest of string to array (if last line has not ended with a ";") - if ( lineStart < [queries length] ) { - [queryArray addObject:[queries substringWithRange:NSMakeRange(lineStart, ([queries length]-lineStart))]]; - } - - //return array - return [NSArray arrayWithArray:queryArray]; -} - - -//additional methods -- (void)setConnection:(CMMCPConnection *)theConnection -/* - sets the connection (received from TableDocument) and makes things that have to be done only once - */ -{ - NSButtonCell *switchButton = [[NSButtonCell alloc] init]; - - prefs = [[NSUserDefaults standardUserDefaults] retain]; - - mySQLConnection = theConnection; - - //set up the interface - [switchButton setButtonType:NSSwitchButton]; - [switchButton setControlSize:NSSmallControlSize]; - [[exportDumpTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; - [[exportMultipleCSVTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; - [[exportMultipleXMLTableView tableColumnWithIdentifier:@"switch"] setDataCell:switchButton]; - if ( [prefs boolForKey:@"useMonospacedFonts"] ) { - [[[exportDumpTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - [[[exportMultipleCSVTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - [[[exportMultipleXMLTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - [[[fieldMappingTableView tableColumnWithIdentifier:@"0"] dataCell] - setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - [errorsView setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - } else { - [[[exportDumpTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [[[exportMultipleCSVTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [[[exportMultipleXMLTableView tableColumnWithIdentifier:@"tables"] dataCell] - setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [[[fieldMappingTableView tableColumnWithIdentifier:@"0"] dataCell] - setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [errorsView setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - } - // [self reloadTables:self]; -} - -#pragma mark - -#pragma mark tableView datasource methods - -- (int)numberOfRowsInTableView:(NSTableView *)aTableView; -{ - if ( aTableView == fieldMappingTableView ) { - return [[tableSourceInstance fieldNames] count]; - } else { - return [tables count]; - } -} - -- (void)tableView:(NSTableView *)aTableView - willDisplayCell:(id)aCell - forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ - if ( [[NSUserDefaults standardUserDefaults] boolForKey:@"useMonospacedFonts"] ) { - [aCell setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]]; - } - else - { - [aCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - } -} - -- (id)tableView:(NSTableView *)aTableView -objectValueForTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ - if ( aTableView == fieldMappingTableView ) { - if ([[aTableColumn identifier] isEqualToString:@"field"]) { - return [[tableSourceInstance fieldNames] objectAtIndex:rowIndex]; - - } else if ([[aTableColumn identifier] isEqualToString:@"value"]) { - if ([[[aTableColumn dataCell] class] isEqualTo:[NSPopUpButtonCell class]]) { - [(NSPopUpButtonCell *)[aTableColumn dataCell] removeAllItems]; - [(NSPopUpButtonCell *)[aTableColumn dataCell] addItemWithTitle:NSLocalizedString(@"Do not import", @"text for csv import drop downs")]; - [(NSPopUpButtonCell *)[aTableColumn dataCell] addItemsWithTitles:fieldMappingButtonOptions]; - } - - return [fieldMappingArray objectAtIndex:rowIndex]; - } - } else { - if ( [[aTableColumn identifier] isEqualToString:@"switch"] ) { - return [[tables objectAtIndex:rowIndex] objectAtIndex:0]; - } else { - return [[tables objectAtIndex:rowIndex] objectAtIndex:1]; - } - } -} - -- (void)tableView:(NSTableView *)aTableView - setObjectValue:(id)anObject - forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ - if ( aTableView == fieldMappingTableView ) { - [fieldMappingArray replaceObjectAtIndex:rowIndex withObject:anObject]; - - } else { - [[tables objectAtIndex:rowIndex] replaceObjectAtIndex:0 withObject:anObject]; - } -} - -#pragma mark - -#pragma mark other -//last but not least -- (id)init; -{ - self = [super init]; - - tables = [[NSMutableArray alloc] init]; - fieldMappingButtonOptions = [[NSMutableArray alloc] init]; - - return self; -} - -- (void)dealloc -{ - // NSLog(@"TableDump dealloc"); - - [tables release]; - [importArray release]; - [fieldMappingButtonOptions release]; - [fieldMappingArray release]; - [savePath release]; - [openPath release]; - [prefs release]; - - [super dealloc]; -} - - -@end |