diff options
Diffstat (limited to 'Source/SPExportFile.m')
-rw-r--r-- | Source/SPExportFile.m | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/Source/SPExportFile.m b/Source/SPExportFile.m new file mode 100644 index 00000000..e102b28e --- /dev/null +++ b/Source/SPExportFile.m @@ -0,0 +1,210 @@ +// +// $Id$ +// +// SPExportFile.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on July 31, 2010 +// Copyright (c) 2010 Stuart Connolly. 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/> + +#import "SPExportFile.h" + +@interface SPExportFile (PrivateAPI) + +- (SPExportFileHandleStatus)_createFileHandle; + +@end + +@implementation SPExportFile + +@synthesize exportFilePath; +@synthesize exportFileHandle; +@synthesize exportFileNeedsCSVHeader; +@synthesize exportFileNeedsXMLHeader; +@synthesize exportFileHandleStatus; + +#pragma mark - +#pragma mark Initialization + +/** + * Initialise an autoreleased instance of SPExport using the supplied path. + * + * @param path The path of the export file + * + * @return The initialised instance + */ ++ (SPExportFile *)exportFileAtPath:(NSString *)path +{ + return [[[SPExportFile alloc] initWithFilePath:path] autorelease]; +} + +/** + * Initialise an instance of SPExportFile using the supplied path. + * + * @param path The path of the export file + * + * @return The initialised instance + */ +- (id)initWithFilePath:(NSString *)path +{ + if ((self = [super init])) { + + [self setExportFilePath:path]; + + exportFileHandleStatus = -1; + + [self setExportFileNeedsCSVHeader:NO]; + [self setExportFileNeedsXMLHeader:NO]; + } + + return self; +} + +#pragma mark - +#pragma mark General Methods + +/** + * Closes the export file to writing. + */ +- (void)close +{ + if (![self exportFileHandle]) return; + + [[self exportFileHandle] closeFile]; +} + +/** + * Deletes the export file on disk. + * + * @return A BOOL indicating the success of attempting to delete the file + */ +- (BOOL)delete +{ + if ((![self exportFilePath]) || (![self exportFileHandle]) || ([[self exportFilePath] length] == 0)) return NO; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if ([fileManager fileExistsAtPath:[self exportFilePath]]) { + return [[NSFileManager defaultManager] removeItemAtPath:[self exportFilePath] error:nil]; + } +} + +/** + * This is a convenience method provided in order to write the supplied data to the underlying filehandle + * without having to directly access it. Throws an exception if attempting to write data when no file + * handle exists. + * + * @param data The data to be written + */ +- (void)writeData:(NSData *)data +{ + if (![self exportFileHandle]) { + [NSException raise:NSInternalInconsistencyException format:@"Attempting to write to an uninitialized file handle."]; + + return; + } + + [[self exportFileHandle] writeData:data]; +} + +/** + * Creates the underlying export file handle and thus the actual file on disk. + * + * @param overwrite If true and a file already exists at this file's location, then it'll be overwritten. + * + * @return One of SPExportFileHandleStatus indicating the status of its creation. + */ +- (SPExportFileHandleStatus)createExportFileHandle:(BOOL)overwrite +{ + // The file path must be set before attempting to create the file handle + if ((![self exportFilePath]) || ([[self exportFilePath] length] == 0)) { + [NSException raise:NSInternalInconsistencyException + format:@"Attempting to create an export filehandle for a path that is either not set or has zero length: %@." + arguments:[self exportFilePath]]; + + return; + } + + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if ([fileManager fileExistsAtPath:[self exportFilePath]]) { + + // If specified attempt to overwrite the file + if (overwrite) { + // Check that it's writable first + if ([fileManager isWritableFileAtPath:[self exportFilePath]]) { + exportFileHandleStatus = [self _createFileHandle]; + } + // The file is not writable, so return that we failed. + else { + exportFileHandleStatus = SPExportFileHandleFailed; + } + } + else { + exportFileHandleStatus = SPExportFileHandleExists; + } + } + // Otherwise attempt to create a file + else { + exportFileHandleStatus = [self _createFileHandle]; + } + + return exportFileHandleStatus; +} + +#pragma mark - +#pragma mark Private API + +/** + * Creates the actual empty file handle and establishes a file handle to it. + * + * @return The status of the file handle's creation. See SPExportFileHandleStatus constants. + */ +- (SPExportFileHandleStatus)_createFileHandle +{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if (![fileManager createFileAtPath:[self exportFilePath] contents:[NSData data] attributes:nil]) { + return SPExportFileHandleFailed; + } + + // Retrieve a filehandle for the file, attempting to delete it on failure. + exportFileHandle = [[SPFileHandle fileHandleForWritingAtPath:[self exportFilePath]] retain]; + + if (!exportFileHandle) { + [[NSFileManager defaultManager] removeFileAtPath:[self exportFilePath] handler:nil]; + + return SPExportFileHandleFailed; + } + + return SPExportFileHandleCreated; +} + +#pragma mark - +#pragma mark Other + +/** + * Dealloc. + */ +- (void)dealloc +{ + if (exportFileHandle) [exportFileHandle release], exportFileHandle = nil; +} + +@end |