aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPXMLExporter.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPXMLExporter.m')
-rw-r--r--Source/SPXMLExporter.m291
1 files changed, 144 insertions, 147 deletions
diff --git a/Source/SPXMLExporter.m b/Source/SPXMLExporter.m
index de43560e..0c060a55 100644
--- a/Source/SPXMLExporter.m
+++ b/Source/SPXMLExporter.m
@@ -58,73 +58,104 @@
*/
- (void)main
{
- @try {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSArray *xmlRow = nil;
- NSString *dataConversionString = nil;
- MCPStreamingResult *streamingResult = nil;
-
- NSMutableArray *xmlTags = [NSMutableArray array];
- NSMutableString *xmlString = [NSMutableString string];
- NSMutableString *xmlItem = [NSMutableString string];
-
- NSUInteger xmlRowCount = 0;
- NSUInteger i, totalRows, currentRowIndex, lastProgressValue, currentPoolDataLength;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSArray *xmlRow = nil;
+ NSString *dataConversionString = nil;
+ MCPStreamingResult *streamingResult = nil;
+
+ NSMutableArray *xmlTags = [NSMutableArray array];
+ NSMutableString *xmlString = [NSMutableString string];
+ NSMutableString *xmlItem = [NSMutableString string];
+
+ NSUInteger xmlRowCount = 0;
+ NSUInteger i, totalRows, currentRowIndex, lastProgressValue, currentPoolDataLength;
+
+ // Check to see if we have at least a table name or data array
+ if ((![self xmlTableName]) && (![self xmlDataArray]) ||
+ ([[self xmlTableName] isEqualToString:@""]) && ([[self xmlDataArray] count] == 0))
+ {
+ [pool release];
+ return;
+ }
+
+ // Inform the delegate that the export process is about to begin
+ [delegate performSelectorOnMainThread:@selector(xmlExportProcessWillBegin:) withObject:self waitUntilDone:NO];
+
+ // Mark the process as running
+ [self setExportProcessIsRunning:YES];
+
+ lastProgressValue = 0;
+
+ // Make a streaming request for the data if the data array isn't set
+ if ((![self xmlDataArray]) && [self xmlTableName]) {
+ totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue];
+ streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self xmlTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]];
+ }
+ else {
+ totalRows = [[self xmlDataArray] count];
+ }
+
+ // Set up an array of encoded field names as opening and closing tags
+ xmlRow = ([self xmlDataArray]) ? [[self xmlDataArray] objectAtIndex:0] : [streamingResult fetchFieldNames];
+
+ for (i = 0; i < [xmlRow count]; i++)
+ {
+ [xmlTags addObject:[NSMutableArray array]];
- // Check to see if we have at least a table name or data array
- if ((![self xmlTableName]) && (![self xmlDataArray]) ||
- ([[self xmlTableName] isEqualToString:@""]) && ([[self xmlDataArray] count] == 0))
- {
+ [[xmlTags objectAtIndex:i] addObject:[NSString stringWithFormat:@"\t\t<%@>", [[[xmlRow objectAtIndex:i] description] HTMLEscapeString]]];
+ [[xmlTags objectAtIndex:i] addObject:[NSString stringWithFormat:@"</%@>\n", [[[xmlRow objectAtIndex:i] description] HTMLEscapeString]]];
+ }
+
+ [[self exportOutputFileHandle] writeData:[xmlString dataUsingEncoding:[self exportOutputEncoding]]];
+
+ // Write an opening tag in the form of the table name
+ [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"\t<%@>\n", ([self xmlTableName]) ? [[self xmlTableName] HTMLEscapeString] : @"custom"] dataUsingEncoding:[self exportOutputEncoding]]];
+
+ // Set up the starting row, which is 0 for streaming result sets and
+ // 1 for supplied arrays which include the column headers as the first row.
+ currentRowIndex = 0;
+
+ if ([self xmlDataArray]) currentRowIndex++;
+
+ // Drop into the processing loop
+ NSAutoreleasePool *xmlExportPool = [[NSAutoreleasePool alloc] init];
+
+ currentPoolDataLength = 0;
+
+ while (1)
+ {
+ // Check for cancellation flag
+ if ([self isCancelled]) {
+ if (streamingResult) {
+ [connection cancelCurrentQuery];
+ [streamingResult cancelResultLoad];
+ }
+
+ [xmlExportPool release];
[pool release];
+
return;
}
-
- // Inform the delegate that the export process is about to begin
- [delegate performSelectorOnMainThread:@selector(xmlExportProcessWillBegin:) withObject:self waitUntilDone:NO];
- // Mark the process as running
- [self setExportProcessIsRunning:YES];
-
- lastProgressValue = 0;
-
- // Make a streaming request for the data if the data array isn't set
- if ((![self xmlDataArray]) && [self xmlTableName]) {
- totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue];
- streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self xmlTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]];
- }
+ // Retrieve the next row from the supplied data, either directly from the array...
+ if ([self xmlDataArray]) {
+ xmlRow = NSArrayObjectAtIndex([self xmlDataArray], currentRowIndex);
+ }
+ // Or by reading an appropriate row from the streaming result
else {
- totalRows = [[self xmlDataArray] count];
- }
-
- // Set up an array of encoded field names as opening and closing tags
- xmlRow = ([self xmlDataArray]) ? [[self xmlDataArray] objectAtIndex:0] : [streamingResult fetchFieldNames];
-
- for (i = 0; i < [xmlRow count]; i++)
- {
- [xmlTags addObject:[NSMutableArray array]];
+ xmlRow = [streamingResult fetchNextRowAsArray];
- [[xmlTags objectAtIndex:i] addObject:[NSString stringWithFormat:@"\t\t<%@>", [[[xmlRow objectAtIndex:i] description] HTMLEscapeString]]];
- [[xmlTags objectAtIndex:i] addObject:[NSString stringWithFormat:@"</%@>\n", [[[xmlRow objectAtIndex:i] description] HTMLEscapeString]]];
+ if (!xmlRow) break;
}
- [[self exportOutputFileHandle] writeData:[xmlString dataUsingEncoding:[self exportOutputEncoding]]];
-
- // Write an opening tag in the form of the table name
- [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"\t<%@>\n", ([self xmlTableName]) ? [[self xmlTableName] HTMLEscapeString] : @"custom"] dataUsingEncoding:[self exportOutputEncoding]]];
+ // Get the cell count if we don't already have it stored
+ if (!xmlRowCount) xmlRowCount = [xmlRow count];
- // Set up the starting row, which is 0 for streaming result sets and
- // 1 for supplied arrays which include the column headers as the first row.
- currentRowIndex = 0;
+ // Construct the row
+ [xmlString setString:@"\t<row>\n"];
- if ([self xmlDataArray]) currentRowIndex++;
-
- // Drop into the processing loop
- NSAutoreleasePool *xmlExportPool = [[NSAutoreleasePool alloc] init];
-
- currentPoolDataLength = 0;
-
- while (1)
+ for (i = 0; i < xmlRowCount; i++)
{
// Check for cancellation flag
if ([self isCancelled]) {
@@ -139,109 +170,75 @@
return;
}
- // Retrieve the next row from the supplied data, either directly from the array...
- if ([self xmlDataArray]) {
- xmlRow = NSArrayObjectAtIndex([self xmlDataArray], currentRowIndex);
- }
- // Or by reading an appropriate row from the streaming result
- else {
- xmlRow = [streamingResult fetchNextRowAsArray];
-
- if (!xmlRow) break;
- }
-
- // Get the cell count if we don't already have it stored
- if (!xmlRowCount) xmlRowCount = [xmlRow count];
-
- // Construct the row
- [xmlString setString:@"\t<row>\n"];
-
- for (i = 0; i < xmlRowCount; i++)
- {
- // Check for cancellation flag
- if ([self isCancelled]) {
- if (streamingResult) {
- [connection cancelCurrentQuery];
- [streamingResult cancelResultLoad];
- }
-
- [xmlExportPool release];
- [pool release];
-
- return;
- }
+ // Retrieve the contents of this tag
+ if ([NSArrayObjectAtIndex(xmlRow, i) isKindOfClass:[NSData class]]) {
+ dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(xmlRow, i) encoding:[self exportOutputEncoding]];
- // Retrieve the contents of this tag
- if ([NSArrayObjectAtIndex(xmlRow, i) isKindOfClass:[NSData class]]) {
- dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(xmlRow, i) encoding:[self exportOutputEncoding]];
-
- if (dataConversionString == nil) {
- dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(xmlRow, i) encoding:NSASCIIStringEncoding];
- }
-
- [xmlItem setString:[NSString stringWithString:dataConversionString]];
- [dataConversionString release];
- }
- else {
- [xmlItem setString:[NSArrayObjectAtIndex(xmlRow, i) description]];
+ if (dataConversionString == nil) {
+ dataConversionString = [[NSString alloc] initWithData:NSArrayObjectAtIndex(xmlRow, i) encoding:NSASCIIStringEncoding];
}
- // Add the opening and closing tag and the contents to the XML string
- [xmlString appendString:NSArrayObjectAtIndex(NSArrayObjectAtIndex(xmlTags, i), 0)];
- [xmlString appendString:[xmlItem HTMLEscapeString]];
- [xmlString appendString:NSArrayObjectAtIndex(NSArrayObjectAtIndex(xmlTags, i), 1)];
- }
-
- [xmlString appendString:@"\t</row>\n"];
-
- // Record the total length for use with pool flushing
- currentPoolDataLength += [xmlString length];
-
- // Write the row to the filehandle
- [[self exportOutputFileHandle] writeData:[xmlString dataUsingEncoding:[self exportOutputEncoding]]];
-
- // Update the progress counter and progress bar
- currentRowIndex++;
-
- // Update the progress
- if (totalRows && (currentRowIndex * ([self exportMaxProgress] / totalRows)) > lastProgressValue) {
-
- NSInteger progress = (currentRowIndex * ([self exportMaxProgress] / totalRows));
-
- [self setExportProgressValue:progress];
-
- lastProgressValue = progress;
- }
-
- // Inform the delegate that the export's progress has been updated
- [delegate performSelectorOnMainThread:@selector(xmlExportProcessProgressUpdated:) withObject:self waitUntilDone:NO];
-
- // Drain the autorelease pool as required to keep memory usage low
- if (currentPoolDataLength > 250000) {
- [xmlExportPool release];
- xmlExportPool = [[NSAutoreleasePool alloc] init];
+ [xmlItem setString:[NSString stringWithString:dataConversionString]];
+ [dataConversionString release];
+ }
+ else {
+ [xmlItem setString:[NSArrayObjectAtIndex(xmlRow, i) description]];
}
- // If an array was supplied and we've processed all rows, break
- if ([self xmlDataArray] && totalRows == currentRowIndex) break;
+ // Add the opening and closing tag and the contents to the XML string
+ [xmlString appendString:NSArrayObjectAtIndex(NSArrayObjectAtIndex(xmlTags, i), 0)];
+ [xmlString appendString:[xmlItem HTMLEscapeString]];
+ [xmlString appendString:NSArrayObjectAtIndex(NSArrayObjectAtIndex(xmlTags, i), 1)];
}
- // Write the closing tag for the table
- [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"\t</%@>\n\n", ([self xmlTableName]) ? [[self xmlTableName] HTMLEscapeString] : @"custom"] dataUsingEncoding:[self exportOutputEncoding]]];
+ [xmlString appendString:@"\t</row>\n"];
- // Write data to disk
- [[self exportOutputFileHandle] synchronizeFile];
+ // Record the total length for use with pool flushing
+ currentPoolDataLength += [xmlString length];
- // Mark the process as not running
- [self setExportProcessIsRunning:NO];
+ // Write the row to the filehandle
+ [[self exportOutputFileHandle] writeData:[xmlString dataUsingEncoding:[self exportOutputEncoding]]];
- // Inform the delegate that the export process is complete
- [delegate performSelectorOnMainThread:@selector(xmlExportProcessComplete:) withObject:self waitUntilDone:NO];
+ // Update the progress counter and progress bar
+ currentRowIndex++;
- [xmlExportPool release];
- [pool release];
+ // Update the progress
+ if (totalRows && (currentRowIndex * ([self exportMaxProgress] / totalRows)) > lastProgressValue) {
+
+ NSInteger progress = (currentRowIndex * ([self exportMaxProgress] / totalRows));
+
+ [self setExportProgressValue:progress];
+
+ lastProgressValue = progress;
+ }
+
+ // Inform the delegate that the export's progress has been updated
+ [delegate performSelectorOnMainThread:@selector(xmlExportProcessProgressUpdated:) withObject:self waitUntilDone:NO];
+
+ // Drain the autorelease pool as required to keep memory usage low
+ if (currentPoolDataLength > 250000) {
+ [xmlExportPool release];
+ xmlExportPool = [[NSAutoreleasePool alloc] init];
+ }
+
+ // If an array was supplied and we've processed all rows, break
+ if ([self xmlDataArray] && totalRows == currentRowIndex) break;
}
- @catch (NSException *e) { }
+
+ // Write the closing tag for the table
+ [[self exportOutputFileHandle] writeData:[[NSString stringWithFormat:@"\t</%@>\n\n", ([self xmlTableName]) ? [[self xmlTableName] HTMLEscapeString] : @"custom"] dataUsingEncoding:[self exportOutputEncoding]]];
+
+ // Write data to disk
+ [[self exportOutputFileHandle] synchronizeFile];
+
+ // Mark the process as not running
+ [self setExportProcessIsRunning:NO];
+
+ // Inform the delegate that the export process is complete
+ [delegate performSelectorOnMainThread:@selector(xmlExportProcessComplete:) withObject:self waitUntilDone:NO];
+
+ [xmlExportPool release];
+ [pool release];
}
/**