aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2010-06-07 13:44:45 +0000
committerrowanbeentje <rowan@beent.je>2010-06-07 13:44:45 +0000
commit4c7cbdf882ad1e1bb1a5a11dc59dc53b90bee686 (patch)
treeffa901519ec9b970a76f6437feb39de65e04498a
parent42781adb6cfa7f01f3763aade1b5043995930756 (diff)
downloadsequelpro-4c7cbdf882ad1e1bb1a5a11dc59dc53b90bee686.tar.gz
sequelpro-4c7cbdf882ad1e1bb1a5a11dc59dc53b90bee686.tar.bz2
sequelpro-4c7cbdf882ad1e1bb1a5a11dc59dc53b90bee686.zip
A number of exporter improvements:
- Improve interface validation on the SQL view, including fixing no-content toggling - Fix the export of views to correctly construct placeholder tables and fix view syntax export (this addresses Issue #707) - Fix logic controlling Stored Procedure and Function export - fix hangs and allow correct export - Handle permission errors when retrieving Stored Pro/Function syntax - Improve export of linebreaks in CSV quoted cells for improved Excel compatibility - SQL export now retrieves table syntax as it progresses through the tables - more accurate progress bar and removes initial pause when exporting lots of tables - Alter filename construction to use centralised filename string: fixes end export Growl notification - Improve dump comments
-rw-r--r--Source/SPCSVExporter.m12
-rw-r--r--Source/SPExportController.h4
-rw-r--r--Source/SPExportController.m13
-rw-r--r--Source/SPExportInitializer.m75
-rw-r--r--Source/SPSQLExporter.h8
-rw-r--r--Source/SPSQLExporter.m166
-rw-r--r--Source/SPTableData.m3
7 files changed, 144 insertions, 137 deletions
diff --git a/Source/SPCSVExporter.m b/Source/SPCSVExporter.m
index b465b4e2..49d6ade6 100644
--- a/Source/SPCSVExporter.m
+++ b/Source/SPCSVExporter.m
@@ -330,18 +330,16 @@
range:NSMakeRange(0, [csvCellString length])];
}
- // Escape occurrences of the line end character
- [csvCellString replaceOccurrencesOfString:[self csvLineEndingString]
- withString:escapedLineEndString
- options:NSLiteralSearch
- range:NSMakeRange(0, [csvCellString length])];
-
- // If the string isn't quoted or otherwise enclosed, escape occurrences of the field separators
+ // If the string isn't quoted or otherwise enclosed, escape occurrences of the field separators and line end character
if (quoteFieldSeparators || csvCellIsNumeric) {
[csvCellString replaceOccurrencesOfString:[self csvFieldSeparatorString]
withString:escapedFieldSeparatorString
options:NSLiteralSearch
range:NSMakeRange(0, [csvCellString length])];
+ [csvCellString replaceOccurrencesOfString:[self csvLineEndingString]
+ withString:escapedLineEndString
+ options:NSLiteralSearch
+ range:NSMakeRange(0, [csvCellString length])];
}
// Write out the cell data by appending strings - this is significantly faster than stringWithFormat.
diff --git a/Source/SPExportController.h b/Source/SPExportController.h
index 32541d19..8d0a6969 100644
--- a/Source/SPExportController.h
+++ b/Source/SPExportController.h
@@ -131,7 +131,7 @@
/**
* Number of tables being exported
*/
- NSUInteger exportTableCount;
+ NSUInteger exportTableCount;
/**
* Index of the current table being exported
@@ -146,7 +146,7 @@
/**
* Export filename
*/
- NSString *exportFilename;
+ NSMutableString *exportFilename;
/**
* Current database's tables
diff --git a/Source/SPExportController.m b/Source/SPExportController.m
index 6da5b544..ca4f1ac8 100644
--- a/Source/SPExportController.m
+++ b/Source/SPExportController.m
@@ -67,7 +67,7 @@
exportTableCount = 0;
currentTableExportIndex = 0;
- exportFilename = @"";
+ exportFilename = [[NSMutableString alloc] init];
exportTypeLabel = @"";
createCustomFilename = NO;
@@ -520,9 +520,7 @@
*/
- (IBAction)toggleSQLIncludeContent:(id)sender
{
- [sender setTag:[sender state]];
-
- [self selectDeselectAllTables:sender];
+ [[exportTableList tableColumnWithIdentifier:@"content"] setHidden:(![sender state])];
[self _toggleExportButtonOnBackgroundThread];
}
@@ -640,6 +638,7 @@
[tables release], tables = nil;
[exporters release], exporters = nil;
[operationQueue release], operationQueue = nil;
+ [exportFilename release], exportFilename = nil;
if (sqlPreviousConnectionEncoding) [sqlPreviousConnectionEncoding release], sqlPreviousConnectionEncoding = nil;
@@ -678,9 +677,9 @@
}
}
else if (isSQL) {
- BOOL structureEnabled = [uiStateDict objectForKey:@"SQLExportStructureEnabled"];
- BOOL contentEnabled = [uiStateDict objectForKey:@"SQLExportContentEnabled"];
- BOOL dropEnabled = [uiStateDict objectForKey:@"SQLExportDropEnabled"];
+ BOOL structureEnabled = [[uiStateDict objectForKey:@"SQLExportStructureEnabled"] integerValue];
+ BOOL contentEnabled = [[uiStateDict objectForKey:@"SQLExportContentEnabled"] integerValue];
+ BOOL dropEnabled = [[uiStateDict objectForKey:@"SQLExportDropEnabled"] integerValue];
// Disable if all are unchecked
if ((!contentEnabled) && (!structureEnabled) && (!dropEnabled)) {
diff --git a/Source/SPExportInitializer.m b/Source/SPExportInitializer.m
index 0cfa88b1..c5779dc6 100644
--- a/Source/SPExportInitializer.m
+++ b/Source/SPExportInitializer.m
@@ -178,30 +178,28 @@
// If the user has selected to only export to a single file or this is a filtered or custom query
// export, create the single file now and assign it to all subsequently created exporters.
if ((![self exportToMultipleFiles]) || (exportSource == SPFilteredExport) || (exportSource == SPQueryExport)) {
-
- NSString *filename = @"";
-
+
// Create custom filename if required
if (createCustomFilename) {
- filename = [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil];
+ [exportFilename setString:[self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil]];
}
else {
// Determine what the file name should be
switch (exportSource)
{
case SPFilteredExport:
- filename = [NSString stringWithFormat:@"%@_view", [tableDocumentInstance table]];
+ [exportFilename setString:[NSString stringWithFormat:@"%@_view", [tableDocumentInstance table]]];
break;
case SPQueryExport:
- filename = @"query_result";
+ [exportFilename setString:@"query_result"];
break;
case SPTableExport:
- filename = [tableDocumentInstance database];
+ [exportFilename setString:[tableDocumentInstance database]];
break;
}
}
- singleFileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:filename]];
+ singleFileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:exportFilename]];
}
// Start the export process depending on the data source
@@ -294,17 +292,7 @@
sqlPreviousConnectionEncodingViaLatin1 = [tableDocumentInstance connectionEncodingViaLatin1:nil];
[tableDocumentInstance setConnectionEncoding:@"utf8" reloadingViews:NO];
-
- NSMutableArray *tableTypes = [[NSMutableArray alloc] init];
- NSMutableDictionary *infoDict = [[NSMutableDictionary alloc] init];
-
- // Build the table information dictionary as well as the table array with item type
- for (NSArray *table in exportTables)
- {
- [infoDict setObject:[tableDataInstance informationForTable:[table objectAtIndex:0]] forKey:[table objectAtIndex:0]];
- }
-
- [sqlExporter setSqlTableInformation:infoDict];
+
[sqlExporter setSqlExportTables:exportTables];
// Set the exporter's max progress
@@ -313,15 +301,11 @@
// Set the progress bar's max value
[exportProgressIndicator setMaxValue:[sqlExporter exportMaxProgress]];
- [infoDict release];
- [tableTypes release];
-
- NSString *filename = @"";
-
// Create custom filename if required
- filename = (createCustomFilename) ? [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil] : [NSString stringWithFormat:@"%@_%@", [tableDocumentInstance database], [[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d" timeZone:nil locale:nil]];
+ [exportFilename setString:(createCustomFilename) ? [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil] : [NSString stringWithFormat:@"%@_%@", [tableDocumentInstance database], [[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d" timeZone:nil locale:nil]]];
+ [exportFilename setString:[exportFilename stringByAppendingPathExtension:([exportCompressOutputFile state]) ? @"sql.gz" : @"sql"]];
- SPFileHandle *fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:[filename stringByAppendingPathExtension:([exportCompressOutputFile state]) ? @"sql.gz" : @"sql"]]];
+ SPFileHandle *fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:exportFilename]];
[sqlExporter setExportOutputFileHandle:fileHandle];
@@ -338,29 +322,28 @@
// export, create the single file now and assign it to all subsequently created exporters.
if ((![self exportToMultipleFiles]) || (exportSource == SPFilteredExport) || (exportSource == SPQueryExport)) {
- NSString *filename = @"";
-
// Create custom filename if required
if (createCustomFilename) {
- filename = [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil];
+ [exportFilename setString:[self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil]];
}
else {
// Determine what the file name should be
switch (exportSource)
{
case SPFilteredExport:
- filename = [NSString stringWithFormat:@"%@_view", [tableDocumentInstance table]];
+ [exportFilename setString:[NSString stringWithFormat:@"%@_view", [tableDocumentInstance table]]];
break;
case SPQueryExport:
- filename = @"query_result";
+ [exportFilename setString:@"query_result"];
break;
case SPTableExport:
- filename = [tableDocumentInstance database];
+ [exportFilename setString:[tableDocumentInstance database]];
break;
}
}
+ [exportFilename setString:[exportFilename stringByAppendingPathExtension:@"xml"]];
- singleFileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:[filename stringByAppendingPathExtension:@"xml"]]];
+ singleFileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:exportFilename]];
}
// Start the export process depending on the data source
@@ -431,17 +414,16 @@
// Set the progress bar's max value
[exportProgressIndicator setMaxValue:[dotExporter exportMaxProgress]];
- NSString *filename = @"";
-
// Create custom filename if required
if (createCustomFilename) {
- filename = [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil];
+ [exportFilename setString:[self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:nil]];
}
else {
- filename = [tableDocumentInstance database];
+ [exportFilename setString:[tableDocumentInstance database]];
}
-
- SPFileHandle *fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:[filename stringByAppendingPathExtension:@"dot"]]];
+ [exportFilename setString:[exportFilename stringByAppendingPathExtension:@"dot"]];
+
+ SPFileHandle *fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:exportFilename]];
[dotExporter setExportOutputFileHandle:fileHandle];
@@ -463,7 +445,6 @@
*/
- (SPCSVExporter *)initializeCSVExporterForTable:(NSString *)table orDataArray:(NSArray *)dataArray
{
- NSString *filename = @"";
SPFileHandle *fileHandle = nil;
SPCSVExporter *csvExporter = [[SPCSVExporter alloc] initWithDelegate:self];
@@ -491,17 +472,17 @@
if (createCustomFilename) {
// Create custom filename based on the selected format
- filename = [self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:table];
+ [exportFilename setString:[self expandCustomFilenameFormatFromString:[exportCustomFilenameTokenField stringValue] usingTableName:table]];
// If the user chose to use a custom filename format and we exporting to multiple files, make
// sure the table name is included to ensure the output files are unique.
- filename = ([[exportCustomFilenameTokenField stringValue] rangeOfString:@"table" options:NSLiteralSearch].location == NSNotFound) ? [filename stringByAppendingFormat:@"_%@", table] : filename;
+ [exportFilename setString:([[exportCustomFilenameTokenField stringValue] rangeOfString:@"table" options:NSLiteralSearch].location == NSNotFound) ? [exportFilename stringByAppendingFormat:@"_%@", table] : exportFilename];
}
else {
- filename = table;
+ [exportFilename setString:table];
}
- fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:filename]];
+ fileHandle = [self getFileHandleForFilePath:[[exportPathField stringValue] stringByAppendingPathComponent:exportFilename]];
[csvExporter setExportOutputFileHandle:fileHandle];
}
@@ -523,7 +504,6 @@
*/
- (SPXMLExporter *)initializeXMLExporterForTable:(NSString *)table orDataArray:(NSArray *)dataArray
{
- NSString *filename = @"";
SPFileHandle *fileHandle = nil;
SPXMLExporter *xmlExporter = [[SPXMLExporter alloc] initWithDelegate:self];
@@ -544,9 +524,10 @@
// If required create separate files
if ((exportSource == SPTableExport) && exportToMultipleFiles && (exportTableCount > 0)) {
- filename = [[exportPathField stringValue] stringByAppendingPathComponent:table];
+ [exportFilename setString:[[exportPathField stringValue] stringByAppendingPathComponent:table]];
+ [exportFilename setString:[exportFilename stringByAppendingPathExtension:@"xml"]];
- fileHandle = [self getFileHandleForFilePath:[filename stringByAppendingPathExtension:@"xml"]];
+ fileHandle = [self getFileHandleForFilePath:exportFilename];
// Write the file header
[self writeXMLHeaderToFileHandle:fileHandle];
diff --git a/Source/SPSQLExporter.h b/Source/SPSQLExporter.h
index 735056aa..12ed686e 100644
--- a/Source/SPSQLExporter.h
+++ b/Source/SPSQLExporter.h
@@ -28,6 +28,8 @@
#import "SPExporter.h"
#import "SPSQLExporterProtocol.h"
+@class SPTableData;
+
/**
* @class SPSQLExporter SPSQLExporter.m
*
@@ -95,9 +97,9 @@
NSUInteger sqlCurrentTableExportIndex;
/**
- * Table information
+ * Table information fetcher and parser
*/
- NSDictionary *sqlTableInformation;
+ SPTableData *sqlTableDataInstance;
}
@property(readwrite, assign) NSObject *delegate;
@@ -118,8 +120,6 @@
@property(readwrite, assign) NSUInteger sqlCurrentTableExportIndex;
-@property(readwrite, retain) NSDictionary *sqlTableInformation;
-
/**
* Initialise an instance of SPSQLExporter using the supplied delegate.
*
diff --git a/Source/SPSQLExporter.m b/Source/SPSQLExporter.m
index eda13741..1c1ebadc 100644
--- a/Source/SPSQLExporter.m
+++ b/Source/SPSQLExporter.m
@@ -32,6 +32,7 @@
#import "SPStringAdditions.h"
#import "SPFileHandle.h"
#import "SPExportUtilities.h"
+#import "SPTableData.h"
@interface SPSQLExporter (PrivateAPI)
@@ -53,7 +54,6 @@
@synthesize sqlOutputIncludeErrors;
@synthesize sqlOutputCompressFile;
@synthesize sqlCurrentTableExportIndex;
-@synthesize sqlTableInformation;
/**
* Initialise an instance of SPSQLExporter using the supplied delegate.
@@ -77,6 +77,9 @@
- (void)main
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ sqlTableDataInstance = [[[SPTableData alloc] init] autorelease];
+ [sqlTableDataInstance setConnection:connection];
+
NSAutoreleasePool *sqlExportPool = [[NSAutoreleasePool alloc] init];
MCPResult *queryResult;
@@ -108,7 +111,6 @@
// Check that we have all the required info before starting the export
if ((![self sqlExportTables]) || ([[self sqlExportTables] count] == 0) ||
- (![self sqlTableInformation]) || ([[self sqlTableInformation] count] == 0) ||
(![self sqlDatabaseHost]) || ([[self sqlDatabaseHost] isEqualToString:@""]) ||
(![self sqlDatabaseName]) || ([[self sqlDatabaseName] isEqualToString:@""]) ||
(![self sqlDatabaseVersion] || ([[self sqlDatabaseName] isEqualToString:@""])))
@@ -192,7 +194,7 @@
[[self exportOutputFileHandle] writeData:[metaString dataUsingEncoding:[self exportOutputEncoding]]];
// Loop through the selected tables
- for (NSArray *table in [self sqlExportTables])
+ for (NSArray *table in tables)
{
// Check for cancellation flag
if ([self isCancelled]) {
@@ -268,7 +270,7 @@
if (sqlOutputIncludeContent && (tableType == SPTableTypeTable)) {
// Retrieve the table details via the data class, and use it to build an array containing column numeric status
- tableDetails = [NSDictionary dictionaryWithDictionary:[[self sqlTableInformation] objectForKey:tableName]];
+ tableDetails = [NSDictionary dictionaryWithDictionary:[sqlTableDataInstance informationForTable:tableName]];
NSUInteger colCount = [[tableDetails objectForKey:@"columns"] count];
@@ -461,63 +463,62 @@
// Release the result set
[streamingResult release];
+ }
- queryResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */;", [tableName tickQuotedString]]];
+ queryResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */;", [tableName tickQuotedString]]];
+
+ [queryResult setReturnDataAsStrings:YES];
+
+ if ([queryResult numOfRows]) {
- [queryResult setReturnDataAsStrings:YES];
+ [metaString setString:@"\n"];
+ [metaString appendString:@"DELIMITER ;;\n"];
- if ([queryResult numOfRows]) {
+ for (s = 0; s < [queryResult numOfRows]; s++)
+ {
+ // Check for cancellation flag
+ if ([self isCancelled]) {
+ [pool release];
+ return;
+ }
- [metaString setString:@"\n"];
- [metaString appendString:@"DELIMITER ;;\n"];
+ NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
- for (s = 0; s < [queryResult numOfRows]; s++)
- {
- // Check for cancellation flag
- if ([self isCancelled]) {
- [pool release];
- return;
- }
-
- NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
-
- // Definer is user@host but we need to escape it to `user`@`host`
- NSArray *triggersDefiner = [[triggers objectForKey:@"Definer"] componentsSeparatedByString:@"@"];
-
- NSString *escapedDefiner = [NSString stringWithFormat:@"%@@%@",
- [NSArrayObjectAtIndex(triggersDefiner, 0) backtickQuotedString],
- [NSArrayObjectAtIndex(triggersDefiner, 1) backtickQuotedString]
- ];
-
- [metaString appendString:[NSString stringWithFormat:@"/*!50003 SET SESSION SQL_MODE=\"%@\" */;;\n", [triggers objectForKey:@"sql_mode"]]];
- [metaString appendString:@"/*!50003 CREATE */ "];
- [metaString appendString:[NSString stringWithFormat:@"/*!50017 DEFINER=%@ */ ", escapedDefiner]];
- [metaString appendString:[NSString stringWithFormat:@"/*!50003 TRIGGER %@ %@ %@ ON %@ FOR EACH ROW %@ */;;\n",
- [[triggers objectForKey:@"Trigger"] backtickQuotedString],
- [triggers objectForKey:@"Timing"],
- [triggers objectForKey:@"Event"],
- [[triggers objectForKey:@"Table"] backtickQuotedString],
- [triggers objectForKey:@"Statement"]
- ]];
-
- [triggers release];
- }
+ // Definer is user@host but we need to escape it to `user`@`host`
+ NSArray *triggersDefiner = [[triggers objectForKey:@"Definer"] componentsSeparatedByString:@"@"];
- [metaString appendString:@"DELIMITER ;\n"];
- [metaString appendString:@"/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n"];
+ NSString *escapedDefiner = [NSString stringWithFormat:@"%@@%@",
+ [NSArrayObjectAtIndex(triggersDefiner, 0) backtickQuotedString],
+ [NSArrayObjectAtIndex(triggersDefiner, 1) backtickQuotedString]
+ ];
- [[self exportOutputFileHandle] writeData:[metaString dataUsingEncoding:NSUTF8StringEncoding]];
+ [metaString appendString:[NSString stringWithFormat:@"/*!50003 SET SESSION SQL_MODE=\"%@\" */;;\n", [triggers objectForKey:@"sql_mode"]]];
+ [metaString appendString:@"/*!50003 CREATE */ "];
+ [metaString appendString:[NSString stringWithFormat:@"/*!50017 DEFINER=%@ */ ", escapedDefiner]];
+ [metaString appendString:[NSString stringWithFormat:@"/*!50003 TRIGGER %@ %@ %@ ON %@ FOR EACH ROW %@ */;;\n",
+ [[triggers objectForKey:@"Trigger"] backtickQuotedString],
+ [triggers objectForKey:@"Timing"],
+ [triggers objectForKey:@"Event"],
+ [[triggers objectForKey:@"Table"] backtickQuotedString],
+ [triggers objectForKey:@"Statement"]
+ ]];
+
+ [triggers release];
}
- if ([connection queryErrored]) {
- [errors appendString:[NSString stringWithFormat:@"%@\n", [connection getLastErrorMessage]]];
-
- if ([self sqlOutputIncludeErrors]) {
- [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]]
- dataUsingEncoding:NSUTF8StringEncoding]];
- }
- }
+ [metaString appendString:@"DELIMITER ;\n"];
+ [metaString appendString:@"/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n"];
+
+ [[self exportOutputFileHandle] writeData:[metaString dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+
+ if ([connection queryErrored]) {
+ [errors appendString:[NSString stringWithFormat:@"%@\n", [connection getLastErrorMessage]]];
+ if ([self sqlOutputIncludeErrors]) {
+ [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]]
+ dataUsingEncoding:NSUTF8StringEncoding]];
+ }
}
// Add an additional separator between tables
@@ -534,6 +535,8 @@
}
[metaString setString:@"\n\n"];
+ // Add the name of table
+ [metaString appendFormat:@"# Replace placeholder table for %@ with correct view syntax\n# ------------------------------------------------------------\n\n", tableName];
[metaString appendFormat:@"DROP TABLE %@;\n", [tableName backtickQuotedString]];
[metaString appendFormat:@"%@;\n", [viewSyntaxes objectForKey:tableName]];
@@ -571,7 +574,7 @@
[[self sqlDatabaseName] tickQuotedString]]];
[metaString appendString:@"--\n"];
- [metaString appendString:@"DELIMITER ;;\n"];
+ [metaString appendString:@"DELIMITER ;;\n\n"];
// Loop through the definitions, exporting if enabled
for (s = 0; s < [queryResult numOfRows]; s++)
@@ -581,32 +584,37 @@
[pool release];
return;
}
-
+
NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
NSString *procedureName = [NSString stringWithFormat:@"%@", [proceduresList objectForKey:@"Name"]];
-
- // Only proceed if the item was selected for export
- if (![items containsObject:procedureName]) {
- [proceduresList release];
- continue;
- }
-
+
// Only proceed if the item is in the list of items
+ BOOL itemFound = NO;
for (NSArray *item in items)
{
// Check for cancellation flag
if ([self isCancelled]) {
+ [proceduresList release];
[pool release];
return;
}
if ([NSArrayObjectAtIndex(item, 0) isEqualToString:procedureName]) {
+ itemFound = YES;
sqlOutputIncludeStructure = [NSArrayObjectAtIndex(item, 1) boolValue];
sqlOutputIncludeContent = [NSArrayObjectAtIndex(item, 2) boolValue];
sqlOutputIncludeDropSyntax = [NSArrayObjectAtIndex(item, 3) boolValue];
+ break;
}
}
-
+ if (!itemFound) {
+ [proceduresList release];
+ continue;
+ }
+
+ if (sqlOutputIncludeStructure || sqlOutputIncludeDropSyntax)
+ [metaString appendFormat:@"# Dump of %@ %@\n# ------------------------------------------------------------\n\n", procedureType, procedureName];
+
// Add the 'DROP' command if required
if (sqlOutputIncludeDropSyntax) {
[metaString appendString:[NSString stringWithFormat:@"/*!50003 DROP %@ IF EXISTS %@ */;;\n", procedureType,
@@ -614,7 +622,7 @@
}
// Only continue if the 'CREATE SYNTAX' is required
- if (sqlOutputIncludeStructure) {
+ if (!sqlOutputIncludeStructure) {
[proceduresList release];
continue;
}
@@ -629,14 +637,35 @@
MCPResult *createProcedureResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW CREATE %@ %@ */;;", procedureType,
[procedureName backtickQuotedString]]];
-
[createProcedureResult setReturnDataAsStrings:YES];
+ if ([connection queryErrored]) {
+ [errors appendString:[NSString stringWithFormat:@"%@\n", [connection getLastErrorMessage]]];
+
+ if ([self sqlOutputIncludeErrors]) {
+ [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+ [proceduresList release];
+ continue;
+ }
NSDictionary *procedureInfo = [[NSDictionary alloc] initWithDictionary:[createProcedureResult fetchRowAsDictionary]];
[metaString appendString:[NSString stringWithFormat:@"/*!50003 SET SESSION SQL_MODE=\"%@\"*/;;\n", [procedureInfo objectForKey:@"sql_mode"]]];
- NSString *createProcedure = [procedureInfo objectForKey:[NSString stringWithFormat:@"Create %@", [procedureType capitalizedString]]];
+ NSString *createProcedure = [procedureInfo objectForKey:[NSString stringWithFormat:@"Create %@", [procedureType capitalizedString]]];
+
+ // A NULL result indicates a permission problem
+ if ([createProcedure isNSNull]) {
+ NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Could not export the %@ '%@' because of a permisions error.\n", @"Procedure/function export permission error"), procedureType, procedureName];
+ [errors appendString:errorString];
+ if ([self sqlOutputIncludeErrors]) {
+ [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"# Error: %@\n", errorString] dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+ [proceduresList release];
+ [procedureInfo release];
+ continue;
+ }
+
NSRange procedureRange = [createProcedure rangeOfString:procedureType options:NSCaseInsensitiveSearch];
NSString *procedureBody = [createProcedure substringFromIndex:procedureRange.location];
@@ -646,7 +675,7 @@
// END */;;
//
// Build the CREATE PROCEDURE string to include MySQL Version limiters
- [metaString appendString:[NSString stringWithFormat:@"/*!50003 CREATE*/ /*!50020 DEFINER=%@*/ /*!50003 %@ */;;\n", escapedDefiner, procedureBody]];
+ [metaString appendString:[NSString stringWithFormat:@"/*!50003 CREATE*/ /*!50020 DEFINER=%@*/ /*!50003 %@ */;;\n\n", escapedDefiner, procedureBody]];
[procedureInfo release];
[proceduresList release];
@@ -723,12 +752,12 @@
NSMutableString *placeholderSyntax;
// Get structured information for the view via the SPTableData parsers
- NSDictionary *viewInformation = [[self sqlTableInformation] objectForKey:viewName];
+ NSDictionary *viewInformation = [sqlTableDataInstance informationForView:viewName];
if (!viewInformation) return nil;
NSArray *viewColumns = [viewInformation objectForKey:@"columns"];
-
+
// Set up the start of the placeholder string and initialise an empty field string
placeholderSyntax = [[NSMutableString alloc] initWithFormat:@"CREATE TABLE %@ (\n", [viewName backtickQuotedString]];
@@ -788,7 +817,7 @@
}
// Append the remainder of the table string
- [placeholderSyntax appendString:@") ENGINE=MyISAM;"];
+ [placeholderSyntax appendString:@") ENGINE=MyISAM"];
// Clean up and return
[fieldString release];
@@ -806,7 +835,6 @@
[sqlDatabaseName release], sqlDatabaseName = nil;
[sqlExportCurrentTable release], sqlExportCurrentTable = nil;
[sqlDatabaseVersion release], sqlDatabaseVersion = nil;
- [sqlTableInformation release], sqlTableInformation = nil;
[super dealloc];
}
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index 35d7060b..6e169e09 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -781,7 +781,8 @@
// The character set has to be guessed at via the database encoding.
// Add the details to the data object.
viewData = [NSMutableDictionary dictionary];
- [viewData setObject:[NSString stringWithString:[tableDocumentInstance databaseEncoding]] forKey:@"encoding"];
+ if (tableDocumentInstance)
+ [viewData setObject:[NSString stringWithString:[tableDocumentInstance databaseEncoding]] forKey:@"encoding"];
[viewData setObject:[NSArray arrayWithArray:tableColumns] forKey:@"columns"];
[tableColumns release];