aboutsummaryrefslogtreecommitdiffstats
path: root/TableDump.m
diff options
context:
space:
mode:
Diffstat (limited to 'TableDump.m')
-rw-r--r--TableDump.m502
1 files changed, 247 insertions, 255 deletions
diff --git a/TableDump.m b/TableDump.m
index de7b30db..3d9b6857 100644
--- a/TableDump.m
+++ b/TableDump.m
@@ -110,55 +110,55 @@
[savePanel setAccessoryView:exportDumpView];
contextInfo = @"exportDump";
break;
-
- // Export the full resultset for the currently selected table to a file in CSV format
+
+ // 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
+
+ // 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
+
+ // 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
+
+ // 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
+
+ // 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
+
+ // 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
+
+ // 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
+
+ // Export multiple tables to a file in XML format
case 13:
[self reloadTables:self];
file = [NSString stringWithFormat:@"%@.xml", [tableDocumentInstance database]];
@@ -173,8 +173,8 @@
// Open the savePanel
[savePanel beginSheetForDirectory:[prefs objectForKey:@"savePath"]
- file:file modalForWindow:tableWindow modalDelegate:self
- didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
+ file:file modalForWindow:tableWindow modalDelegate:self
+ didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
}
/*
@@ -189,10 +189,10 @@
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]]
@@ -204,21 +204,21 @@
// Truncate the file to zero bytes
[fileHandle truncateFileAtOffset:0];
-
- // Otherwise attempt to create a file
+
+ // 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"));
+ NSLocalizedString(@"Couldn't write to file. Be sure that you have the necessary privileges.", @"message of panel when file cannot be written"));
return;
}
}
@@ -226,62 +226,62 @@
// 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
+
+ // 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
+
+ // 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
+
+ // 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]
+ 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
+ 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
+ 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]
+ 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
+ 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
+ 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
+
+ // Export multiple tables to a file in XML format
} else if ( [contextInfo isEqualToString:@"exportMultipleTablesAsXML"] ) {
success = [self exportSelectedTablesToFileHandle:fileHandle usingFormat:@"xml"];
-
- // Unknown operation
+
+ // Unknown operation
} else {
NSLog(@"Unknown export operation: %@", [contextInfo description]);
return;
@@ -289,10 +289,10 @@
// 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"));
+ 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
@@ -403,7 +403,7 @@
//import dump file
NSArray *queries;
int i;
-
+
//open progress sheet
[NSApp beginSheet:singleProgressSheet
modalForWindow:tableWindow
@@ -417,7 +417,7 @@
//get array with an object for each mysql-query
queries = [self splitQueries:dumpFile];
-
+
[singleProgressBar stopAnimation:self];
[singleProgressBar setUsesThreadedAnimation:NO];
[singleProgressBar setIndeterminate:NO];
@@ -452,9 +452,9 @@
[errorsSheet orderOut:nil];
}
- ////////////////
- // IMPORT CSV //
- ////////////////
+ ////////////////
+ // IMPORT CSV //
+ ////////////////
} else if ( [fileType isEqualToString:@"CSV"] ) {
//import csv file
@@ -522,7 +522,7 @@
[buttonCell addItemsWithTitles:[importArray objectAtIndex:currentRow]];
[[fieldMappingTableView tableColumnWithIdentifier:@"value"] setDataCell:buttonCell];
-
+
// show fieldMapping sheet
[NSApp beginSheet:fieldMappingSheet
modalForWindow:tableWindow
@@ -574,7 +574,7 @@
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 {
@@ -637,15 +637,15 @@
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]];
-// }
-// }
+ // 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];
@@ -656,7 +656,7 @@
} else {
value = 0;
}
-
+
[fieldMappingArray addObject:[NSNumber numberWithInt:value]];
}
@@ -722,23 +722,23 @@
// Open the progress sheet
[NSApp beginSheet:singleProgressSheet
- modalForWindow:tableWindow modalDelegate:self
- didEndSelector:nil contextInfo:nil];
-
+ 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"]]];
+ [[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]]];
+ [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"];
@@ -747,7 +747,7 @@
// 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]];
@@ -755,17 +755,17 @@
[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]];
-
-
+ 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]];
-
+ 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]];
@@ -784,7 +784,7 @@
}
}
}
-
+
// Add the table content if required
if ( [addTableContentSwitch state] == NSOnState ) {
queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM `%@`", tableName]];
@@ -799,56 +799,56 @@
[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]];
+ 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
+
+ // 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
+
+ // Otherwise add a quoted string with special characters escaped
} else {
[sqlString appendString:@"'"];
[sqlString appendString:[mySQLConnection prepareString:cellValue]];
@@ -860,16 +860,16 @@
// 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:@"`,`"]]];
+ tableName, [fieldNames componentsJoinedByString:@"`,`"]]];
queryLength = 0;
} else {
[sqlString appendString:@"),\n\t("];
@@ -881,24 +881,24 @@
// 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]];
+ 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];
@@ -922,7 +922,7 @@
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;
+ enclosedBy:(NSString *)enclosingString escapedBy:(NSString *)escapeString lineEnds:(NSString *)lineEndString silently:(BOOL)silently;
{
NSStringEncoding tableEncoding = [CMMCPConnection encodingForMySQLEncoding:[[tableDocumentInstance encoding] cString]];
NSMutableString *csvCell = [NSMutableString string];
@@ -935,31 +935,31 @@
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])];
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [tempSeparatorString length])];
[tempSeparatorString replaceOccurrencesOfString:@"\\n" withString:@"\n"
- options:NSLiteralSearch
- range:NSMakeRange(0, [tempSeparatorString length])];
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [tempSeparatorString length])];
[tempSeparatorString replaceOccurrencesOfString:@"\\r" withString:@"\r"
- options:NSLiteralSearch
- range:NSMakeRange(0, [tempSeparatorString length])];
+ 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])];
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [tempLineEndString length])];
[tempLineEndString replaceOccurrencesOfString:@"\\n" withString:@"\n"
- options:NSLiteralSearch
- range:NSMakeRange(0, [tempLineEndString length])];
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [tempLineEndString length])];
[tempLineEndString replaceOccurrencesOfString:@"\\r" withString:@"\r"
- options:NSLiteralSearch
- range:NSMakeRange(0, [tempLineEndString length])];
+ 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
@@ -967,13 +967,13 @@
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
@@ -986,7 +986,7 @@
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;
@@ -998,17 +998,17 @@
// 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]];
@@ -1018,16 +1018,16 @@
} else {
[csvRow setArray:[array objectAtIndex:i]];
}
-
+
[csvString setString:@""];
for ( j = 0 ; j < [csvRow count] ; j++ ) {
-
+
// For NULL objects supplied from a queryResult, no data is added to the cell
if ([[csvRow objectAtIndex:j] isKindOfClass:[NSNull class]]) {
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];
@@ -1036,15 +1036,15 @@
} else {
[csvCell setString:[[csvRow objectAtIndex:j] description]];
}
-
+
// For NULL values supplied via an array no cell needs to be written.
if ( [csvCell isEqualToString:nullString] ) {
-
- // Add empty strings as a pair of enclosing characters.
+
+ // 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
@@ -1057,31 +1057,31 @@
// Escape any occurrences of the escaping character
[csvCell replaceOccurrencesOfString:escapeString
- withString:escapedEscapeString
- options:NSLiteralSearch
- range:NSMakeRange(0,[csvCell length])];
-
+ 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])];
+ withString:escapedEnclosingString
+ options:NSLiteralSearch
+ range:NSMakeRange(0,[csvCell length])];
}
-
+
// If the string isn't quoted or otherwise enclosed, escape occurrences of the
// field separators and the line ending separator.
if ( quoteFieldSeparators || csvCellIsNumeric ) {
[csvCell replaceOccurrencesOfString:fieldSeparatorString
- withString:escapedFieldSeparatorString
- options:NSLiteralSearch
- range:NSMakeRange(0,[csvCell length])];
+ withString:escapedFieldSeparatorString
+ options:NSLiteralSearch
+ range:NSMakeRange(0,[csvCell length])];
[csvCell replaceOccurrencesOfString:lineEndString
- withString:escapedLineEndString
- options:NSLiteralSearch
- range:NSMakeRange(0,[csvCell length])];
+ withString:escapedLineEndString
+ 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];
@@ -1093,10 +1093,10 @@
}
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]];
}
@@ -1202,40 +1202,32 @@
}
}
for ( i = 0 ; i < [tempRowArray count] ; i++ ) {
- if ( [[tempRowArray objectAtIndex:i] isEqualToString:@"NULL"] || [[tempRowArray objectAtIndex:i] isEqualToString:@""] || [[tempRowArray objectAtIndex:i] isEqualToString:@"\\N"] || [[tempRowArray objectAtIndex:i] isEqualToString:[prefs objectForKey:@"nullValue"]] ) {
-
- //put nsnull object to array if field contains un-enclosed NULL string
- [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])];
- }
- }
- //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])];
+ //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 ( ![escaped isEqualToString:@""] && ![escaped isEqualToString:enclosed] ) {
- [mutableField replaceOccurrencesOfString:[NSString stringWithFormat:@"%@%@", escaped, escaped] withString:escaped options:NSLiteralSearch range:NSMakeRange(0, [mutableField length])];
+ if ( [[mutableField substringFromIndex:([mutableField length]-[enclosed length])] isEqualToString:enclosed] ) {
+ [mutableField deleteCharactersInRange:NSMakeRange(([mutableField length]-[enclosed length]),[enclosed length])];
}
- //add field to tempRowArray
- [tempRowArray replaceObjectAtIndex:i withObject:[NSString stringWithString:mutableField]];
}
+ //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]];
@@ -1259,13 +1251,13 @@
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]];
@@ -1275,17 +1267,17 @@
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]]]];
+ [self htmlEscapeString:[[xmlRow objectAtIndex:j] description]]]];
[[xmlTags objectAtIndex:j] addObject:[NSString stringWithFormat:@"</%@>\n",
- [self htmlEscapeString:[[xmlRow objectAtIndex:j] description]]]];
+ [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
@@ -1298,21 +1290,21 @@
[xmlString appendString:@"<!--\n-\n"];
[xmlString appendString:@"- Sequel Pro dump\n"];
[xmlString appendString:[NSString stringWithFormat:@"- Version %@\n",
- [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];
+ [[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]]];
+ [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]];
-
+ [self htmlEscapeString:table]]
+ dataUsingEncoding:tableEncoding]];
+
// Determine the total number of rows and starting row depending on supplied data format
if (array == nil) {
startingRow = 0;
@@ -1321,28 +1313,28 @@
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];
@@ -1351,7 +1343,7 @@
} 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]];
@@ -1362,12 +1354,12 @@
// 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]];
-
+ [self htmlEscapeString:table]]
+ dataUsingEncoding:tableEncoding]];
+
// Close the progress sheet if appropriate
if ( !silently ) {
[NSApp endSheet:singleProgressSheet];
@@ -1385,14 +1377,14 @@
{
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];
}
@@ -1409,7 +1401,7 @@
NSMutableString *errors = [NSMutableString string];
NSStringEncoding connectionEncoding = [mySQLConnection encoding];
NSMutableString *csvLineEnd;
-
+
// Reset the interface
[errorsView setString:@""];
[errorsView displayIfNeeded];
@@ -1417,13 +1409,13 @@
[singleProgressText displayIfNeeded];
[singleProgressBar setDoubleValue:0];
[singleProgressBar displayIfNeeded];
-
+
// Open the progress sheet
[NSApp beginSheet:singleProgressSheet
- modalForWindow:tableWindow modalDelegate:self
- didEndSelector:nil contextInfo:nil];
-
-
+ 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]];
@@ -1438,28 +1430,28 @@
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]];
+ [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"]]];
+ [[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]]];
+ [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]]]];
+ [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]];
@@ -1467,20 +1459,20 @@
[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];
@@ -1489,40 +1481,40 @@
[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]];
+ 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]];
+ 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]];
+ dataUsingEncoding:connectionEncoding]];
}
-
+
// Close the progress sheet
[NSApp endSheet:singleProgressSheet];
[singleProgressSheet orderOut:nil];
@@ -1673,13 +1665,13 @@
// 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....
+
+ // 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;
@@ -1816,7 +1808,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
[(NSPopUpButtonCell *)[aTableColumn dataCell] addItemsWithTitles:[importArray objectAtIndex:currentRow]];
//[(NSPopUpButtonCell *)[aTableColumn dataCell] selectItemAtIndex:[fieldMappingArray objectAtIndex:rowIndex]];
}
-
+
return [fieldMappingArray objectAtIndex:rowIndex];
}
} else {