From 886ee90ca1047fdef2c6bfd52ea28ffc0345aca4 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Thu, 28 Oct 2010 20:18:32 +0000 Subject: Tidy up SPTableStructure including moving all the private field type validation methods to their own class, SPTableFieldValidation. --- Source/SPTableFieldValidation.h | 42 ++++++ Source/SPTableFieldValidation.m | 142 +++++++++++++++++ Source/SPTableStructure.h | 6 +- Source/SPTableStructure.m | 285 ++++++++++++++--------------------- Source/SPTableStructureDelegate.m | 14 +- sequel-pro.xcodeproj/project.pbxproj | 22 ++- 6 files changed, 330 insertions(+), 181 deletions(-) create mode 100644 Source/SPTableFieldValidation.h create mode 100644 Source/SPTableFieldValidation.m diff --git a/Source/SPTableFieldValidation.h b/Source/SPTableFieldValidation.h new file mode 100644 index 00000000..b9d973dd --- /dev/null +++ b/Source/SPTableFieldValidation.h @@ -0,0 +1,42 @@ +// +// $Id$ +// +// SPTableFieldValidation.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on October 28, 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 + +@interface SPTableFieldValidation : NSObject +{ + NSArray *fieldTypes; +} + +/** + * @property fieldTypes Field types array + */ +@property (readwrite, retain) NSArray *fieldTypes; + +- (BOOL)isFieldTypeNumeric:(NSString *)fieldType; +- (BOOL)isFieldTypeDate:(NSString *)fieldType; +- (BOOL)isFieldTypeGeometry:(NSString *)fieldType; +- (BOOL)isFieldTypeString:(NSString *)fieldType; +- (BOOL)isFieldTypeAllowBinary:(NSString *)fieldType; + +@end diff --git a/Source/SPTableFieldValidation.m b/Source/SPTableFieldValidation.m new file mode 100644 index 00000000..ceee9b3b --- /dev/null +++ b/Source/SPTableFieldValidation.m @@ -0,0 +1,142 @@ +// +// $Id$ +// +// SPTableFieldValidation.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on October 28, 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 + +#import "SPTableFieldValidation.h" + +@interface SPTableFieldValidation (PrivateAPI) + +- (NSString *)_formatType:(NSString *)type; + +@end + +@implementation SPTableFieldValidation + +@synthesize fieldTypes; + +#pragma mark - +#pragma mark Public API + +/** + * Returns whether or not the supplied field type is numeric according to it's position within the currnet + * field types array. + * + * @param fieldType The field type to test + */ +- (BOOL)isFieldTypeNumeric:(NSString *)fieldType +{ + NSString *type = [self _formatType:fieldType]; + + if (![fieldTypes containsObject:type]) return YES; + + return ([fieldTypes indexOfObject:type] < 17); +} + +/** + * Returns whether or not the supplied field type is a date according to it's position within the currnet + * field types array. + * + * @param fieldType The field type to test + */ +- (BOOL)isFieldTypeDate:(NSString *)fieldType +{ + NSString *type = [self _formatType:fieldType]; + + if (![fieldTypes containsObject:type]) return YES; + + return (([fieldTypes indexOfObject:type] > 32) && ([fieldTypes indexOfObject:type] < 38)); +} + +/** + * Returns whether or not the supplied field type is geometry according to it's position within the currnet + * field types array. + * + * @param fieldType The field type to test + */ +- (BOOL)isFieldTypeGeometry:(NSString *)fieldType +{ + NSString *type = [self _formatType:fieldType]; + + if (![fieldTypes containsObject:type]) return YES; + + return ([fieldTypes indexOfObject:type] > 38); +} + +/** + * Returns whether or not the supplied field type is a string according to it's position within the currnet + * field types array. + * + * @param fieldType The field type to test + */ +- (BOOL)isFieldTypeString:(NSString *)fieldType +{ + NSString *type = [self _formatType:fieldType]; + + if (![fieldTypes containsObject:type]) return YES; + + return (([fieldTypes indexOfObject:type] > 17) && ([fieldTypes indexOfObject:type] < 32)); +} + +/** + * Returns whether or not the supplied field type allows binary according to it's position within the currnet + * field types array. + * + * @param fieldType The field type to test + */ +- (BOOL)isFieldTypeAllowBinary:(NSString *)fieldType +{ + NSString *type = [self _formatType:fieldType]; + + if (![fieldTypes containsObject:type]) return YES; + + return (([fieldTypes indexOfObject:type] > 17) && ([fieldTypes indexOfObject:type] < 24)); +} + +#pragma mark - +#pragma mark Private API + +/** + * Formats, i.e. removes whitespace and newlines as well as uppercases the supplied field type string. + * + * @param type The field type string to format + */ +- (NSString *)_formatType:(NSString *)type +{ + return [[type stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; +} + +#pragma mark - +#pragma mark Other + +/** + * Dealloc. + */ +- (void)dealloc +{ + [fieldTypes release], fieldTypes = nil; + + [super dealloc]; +} + +@end diff --git a/Source/SPTableStructure.h b/Source/SPTableStructure.h index 68225fab..1ae392f4 100644 --- a/Source/SPTableStructure.h +++ b/Source/SPTableStructure.h @@ -25,6 +25,8 @@ #import +@class SPTableFieldValidation; + @interface SPTableStructure : NSObject { IBOutlet id tablesListInstance; @@ -60,6 +62,8 @@ MCPConnection *mySQLConnection; MCPResult *tableSourceResult; MCPResult *indexResult; + + SPTableFieldValidation *fieldValidation; NSString *selectedTable; NSMutableArray *tableFields; @@ -100,7 +104,7 @@ - (BOOL)addRowToDB; - (void)setAutoIncrementTo:(NSString*)valueAsString; -// Getter methods +// Accessors - (NSString *)defaultValueForField:(NSString *)field; - (NSArray *)fieldNames; - (NSDictionary *)enumFields; diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index 86644319..14ae632c 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -36,11 +36,6 @@ @interface SPTableStructure (PrivateAPI) - (void)_removeFieldAndForeignKey:(NSNumber *)removeForeignKey; -- (BOOL)_isFieldTypeNumeric:(NSString*)aType; -- (BOOL)_isFieldTypeDate:(NSString*)aType; -- (BOOL)_isFieldTypeString:(NSString*)aType; -- (BOOL)_isFieldTypeGeometry:(NSString*)aType; -- (BOOL)_isFieldTypeAllowBinary:(NSString*)aType; @end @@ -55,15 +50,18 @@ - (id)init { if ((self = [super init])) { + tableFields = [[NSMutableArray alloc] init]; oldRow = [[NSMutableDictionary alloc] init]; enumFields = [[NSMutableDictionary alloc] init]; - typeSuggestions = nil; - - currentlyEditingRow = -1; + defaultValues = nil; selectedTable = nil; + typeSuggestions = nil; + currentlyEditingRow = -1; + fieldValidation = [[SPTableFieldValidation alloc] init]; + prefs = [NSUserDefaults standardUserDefaults]; } @@ -82,6 +80,8 @@ [tableSourceView setFont:([prefs boolForKey:SPUseMonospacedFonts]) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; [indexesTableView setFont:([prefs boolForKey:SPUseMonospacedFonts]) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + // Note that changing the contents or ordering of this array will affect the implementation of + // SPTableFieldValidation. See it's implementation file for more details. typeSuggestions = [[NSArray arrayWithObjects: @"TINYINT", @"SMALLINT", @@ -131,7 +131,8 @@ @"MULTIPOLYGON", @"GEOMETRYCOLLECTION", nil] retain]; - // Hint: _isFieldTypeDate and _isFieldTypeNumeric must be changed if typeSuggestions was changed! + + [fieldValidation setFieldTypes:typeSuggestions]; // Add observers for document task activity [[NSNotificationCenter defaultCenter] addObserver:self @@ -148,21 +149,23 @@ // Init the view column submenu according to saved hidden status; // menu items are identified by their tag number which represents the initial column index - for(NSMenuItem *item in [viewColumnsMenu itemArray]) [item setState:NSOnState]; // Set all items to NSOnState - for(NSTableColumn *col in [tableSourceView tableColumns]) { - if([col isHidden]) { - if([[col identifier] isEqualToString:@"Key"]) + for (NSMenuItem *item in [viewColumnsMenu itemArray]) [item setState:NSOnState]; // Set all items to NSOnState + + for (NSTableColumn *col in [tableSourceView tableColumns]) + { + if ([col isHidden]) { + if ([[col identifier] isEqualToString:@"Key"]) [[viewColumnsMenu itemWithTag:7] setState:NSOffState]; - else if([[col identifier] isEqualToString:@"encoding"]) + else if ([[col identifier] isEqualToString:@"encoding"]) [[viewColumnsMenu itemWithTag:10] setState:NSOffState]; - else if([[col identifier] isEqualToString:@"collation"]) + else if ([[col identifier] isEqualToString:@"collation"]) [[viewColumnsMenu itemWithTag:11] setState:NSOffState]; - else if([[col identifier] isEqualToString:@"comment"]) + else if ([[col identifier] isEqualToString:@"comment"]) [[viewColumnsMenu itemWithTag:12] setState:NSOffState]; } } + [tableSourceView reloadData]; - } #pragma mark - @@ -207,7 +210,9 @@ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"), [mySQLConnection getLastErrorMessage]]); } + if (indexResult) [indexResult release]; + return; } @@ -216,8 +221,10 @@ [indexResult release]; // Set the Key column - for(NSDictionary* theIndex in theTableIndexes) { - for(id field in theTableFields) { + for (NSDictionary* theIndex in theTableIndexes) + { + for (id field in theTableFields) + { if([[field objectForKey:@"name"] isEqualToString:[theIndex objectForKey:@"Column_name"]]) { if([[theIndex objectForKey:@"Key_name"] isEqualToString:@"PRIMARY"]) [field setObject:@"PRI" forKey:@"Key"]; @@ -308,7 +315,6 @@ // For timestamps check to see whether "on update CURRENT_TIMESTAMP" and set Extra accordingly else if ([type isEqualToString:@"TIMESTAMP"] && [[theField objectForKey:@"onupdatetimestamp"] integerValue]) [theField setObject:@"on update CURRENT_TIMESTAMP" forKey:@"Extra"]; - } // Set up the table details for the new table, and request an data/interface update @@ -705,6 +711,14 @@ return YES; } +#pragma mark - +#pragma mark Other IB action methods + +- (IBAction)unhideIndexesView:(id)sender +{ + [tablesIndexesSplitView setPosition:[tablesIndexesSplitView frame].size.height-130 ofDividerAtIndex:0]; +} + #pragma mark - #pragma mark Index sheet methods @@ -728,20 +742,6 @@ #pragma mark - #pragma mark Additional methods -/** - * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once - */ -- (void)setConnection:(MCPConnection *)theConnection -{ - mySQLConnection = theConnection; - - // Set the indexes controller connection - [indexesController setConnection:mySQLConnection]; - - // Set up tableView - [tableSourceView registerForDraggedTypes:[NSArray arrayWithObjects:SPDefaultPasteboardDragType, nil]]; -} - /** * Try table's auto_increment to a specific value * @@ -749,19 +749,17 @@ */ - (void)setAutoIncrementTo:(NSString*)valueAsString { - NSString *selTable = nil; // if selectedTable is nil try to get the name from SPTablesList - if(selectedTable == nil || ![selectedTable length]) + if (selectedTable == nil || ![selectedTable length]) selTable = [tablesListInstance tableName]; else selTable = [NSString stringWithString:selectedTable]; - if(selTable == nil || ![selTable length]) - return; + if (selTable == nil || ![selTable length]) return; - if(valueAsString == nil || ![valueAsString length]) { + if (valueAsString == nil || ![valueAsString length]) { // reload data and bail [tableDataInstance resetAllData]; [extendedTableInfoInstance loadTable:selTable]; @@ -792,7 +790,6 @@ } [tableInfoInstance tableChanged:nil]; - } /** @@ -943,7 +940,7 @@ if(!specialFieldTypes) { - if([self _isFieldTypeString:theRowType]) { + if ([fieldValidation isFieldTypeString:theRowType]) { // Add CHARSET NSString *fieldEncoding = @""; if([[theRow objectForKey:@"encoding"] integerValue] > 0) { @@ -970,7 +967,7 @@ } } - else if ([self _isFieldTypeNumeric:theRowType] && (![theRowType isEqualToString:@"BIT"])) { + else if ([fieldValidation isFieldTypeNumeric:theRowType] && (![theRowType isEqualToString:@"BIT"])) { if ([[theRow objectForKey:@"unsigned"] integerValue] == 1) { [queryString appendString:@"\n UNSIGNED"]; @@ -1010,7 +1007,7 @@ [queryString appendFormat:@"\n DEFAULT %@", [theRow objectForKey:@"default"]]; } // Suppress appending DEFAULT clause for any numerics, date, time fields if default is empty to avoid error messages - else if (![[theRow objectForKey:@"default"] length] && ([self _isFieldTypeNumeric:theRowType] || [self _isFieldTypeDate:theRowType])) { + else if (![[theRow objectForKey:@"default"] length] && ([fieldValidation isFieldTypeNumeric:theRowType] || [fieldValidation isFieldTypeDate:theRowType])) { ; } // Otherwise, use the provided default @@ -1160,41 +1157,13 @@ } } -/** - * Perform the action requested in the Add Row error sheet. - */ -- (void)addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo -{ - - // Order out current sheet to suppress overlapping of sheets - [[alert window] orderOut:nil]; - - alertSheetOpened = NO; - - // Remain in edit mode - reselect the row and resume editing - if (returnCode == NSAlertDefaultReturn) { - - // Problem: reentering edit mode for first cell doesn't function - [tableSourceView selectRowIndexes:[NSIndexSet indexSetWithIndex:currentlyEditingRow] byExtendingSelection:NO]; - [tableSourceView performSelector:@selector(keyDown:) withObject:[NSEvent keyEventWithType:NSKeyDown location:NSMakePoint(0,0) modifierFlags:0 timestamp:0 windowNumber:[[tableDocumentInstance parentWindow] windowNumber] context:[NSGraphicsContext currentContext] characters:nil charactersIgnoringModifiers:nil isARepeat:NO keyCode:0x24] afterDelay:0.0]; - } - - // Discard changes and cancel editing - else { - [self cancelRowEditing]; - } - - [tableSourceView reloadData]; -} - /** * A method to show an error sheet after a short delay, so that it can * be called from within an endSheet selector. This should be called on * the main thread. */ --(void)showErrorSheetWith:(NSDictionary *)errorDictionary +- (void)showErrorSheetWith:(NSDictionary *)errorDictionary { - // If this method has been called directly, invoke a delay. Invoking the delay // on the main thread ensures the timer fires on the main thread. if (![errorDictionary objectForKey:@"delayed"]) { @@ -1210,28 +1179,6 @@ [errorDictionary objectForKey:@"message"]); } -/** - * This method is called as part of Key Value Observing which is used to watch for preference changes which effect the interface. - */ -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - // Display table veiew vertical gridlines preference changed - if ([keyPath isEqualToString:SPDisplayTableViewVerticalGridlines]) { - [tableSourceView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; - } - // Use monospaced fonts preference changed - else if ([keyPath isEqualToString:SPUseMonospacedFonts]) { - - BOOL useMonospacedFont = [[change objectForKey:NSKeyValueChangeNewKey] boolValue]; - - [tableSourceView setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [indexesTableView setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - - [tableSourceView reloadData]; - [indexesTableView reloadData]; - } -} - /** * Menu validation. */ @@ -1273,12 +1220,77 @@ alertSheetOpened = NO; } +/** + * Perform the action requested in the Add Row error sheet. + */ +- (void)addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + // Order out current sheet to suppress overlapping of sheets + [[alert window] orderOut:nil]; + + alertSheetOpened = NO; + + // Remain in edit mode - reselect the row and resume editing + if (returnCode == NSAlertDefaultReturn) { + + // Problem: reentering edit mode for first cell doesn't function + [tableSourceView selectRowIndexes:[NSIndexSet indexSetWithIndex:currentlyEditingRow] byExtendingSelection:NO]; + [tableSourceView performSelector:@selector(keyDown:) withObject:[NSEvent keyEventWithType:NSKeyDown location:NSMakePoint(0,0) modifierFlags:0 timestamp:0 windowNumber:[[tableDocumentInstance parentWindow] windowNumber] context:[NSGraphicsContext currentContext] characters:nil charactersIgnoringModifiers:nil isARepeat:NO keyCode:0x24] afterDelay:0.0]; + } + + // Discard changes and cancel editing + else { + [self cancelRowEditing]; + } + + [tableSourceView reloadData]; +} + +#pragma mark - +#pragma mark KVO methods + +/** + * This method is called as part of Key Value Observing which is used to watch for preference changes which effect the interface. + */ +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // Display table veiew vertical gridlines preference changed + if ([keyPath isEqualToString:SPDisplayTableViewVerticalGridlines]) { + [tableSourceView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; + } + // Use monospaced fonts preference changed + else if ([keyPath isEqualToString:SPUseMonospacedFonts]) { + + BOOL useMonospacedFont = [[change objectForKey:NSKeyValueChangeNewKey] boolValue]; + + [tableSourceView setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + [indexesTableView setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + + [tableSourceView reloadData]; + [indexesTableView reloadData]; + } +} + #pragma mark - -#pragma mark Getter methods +#pragma mark Accessors /** -get the default value for a specified field -*/ + * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once + */ +- (void)setConnection:(MCPConnection *)theConnection +{ + mySQLConnection = theConnection; + + // Set the indexes controller connection + [indexesController setConnection:mySQLConnection]; + + // Set up tableView + [tableSourceView registerForDraggedTypes:[NSArray arrayWithObjects:SPDefaultPasteboardDragType, nil]]; +} + +/** + * Get the default value for a specified field + */ - (NSString *)defaultValueForField:(NSString *)field { if ( ![defaultValues objectForKey:field] ) { @@ -1291,8 +1303,8 @@ get the default value for a specified field } /** -returns an array containing the field names of the selected table -*/ + * Returns an array containing the field names of the selected table + */ - (NSArray *)fieldNames { NSMutableArray *tempArray = [NSMutableArray array]; @@ -1314,8 +1326,8 @@ returns an array containing the field names of the selected table } /** -returns a dictionary containing enum/set field names as key and possible values as array -*/ + * Returns a dictionary containing enum/set field names as key and possible values as array + */ - (NSDictionary *)enumFields { return [NSDictionary dictionaryWithDictionary:enumFields]; @@ -1449,75 +1461,8 @@ returns a dictionary containing enum/set field names as key and possible values [refreshIndexesButton setEnabled:YES]; } -- (IBAction)unhideIndexesView:(id)sender -{ - [tablesIndexesSplitView setPosition:[tablesIndexesSplitView frame].size.height-130 ofDividerAtIndex:0]; -} - #pragma mark - -#pragma mark Private API methods - -/** - * Return if aType is numeric according to typeSuggestions's position - * Hint: This must be changed if typeSuggestions was changed! - */ -- (BOOL)_isFieldTypeNumeric:(NSString*)aType -{ - NSString *type = [[aType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - if(![typeSuggestions containsObject:type]) return YES; // for safety reasons - - return ([typeSuggestions indexOfObject:type] < 17); -} - -/** - * Return if aType is a date or time according to typeSuggestions's position - * Hint: This must be changed if typeSuggestions was changed! - */ -- (BOOL)_isFieldTypeDate:(NSString*)aType -{ - NSString *type = [[aType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - if(![typeSuggestions containsObject:type]) return YES; // for safety reasons - - return ([typeSuggestions indexOfObject:type] > 32 && [typeSuggestions indexOfObject:type] < 38); -} - -/** - * Return if aType is a geometry to typeSuggestions's position - * Hint: This must be changed if typeSuggestions was changed! - */ -- (BOOL)_isFieldTypeGeometry:(NSString*)aType -{ - NSString *type = [[aType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - if(![typeSuggestions containsObject:type]) return YES; // for safety reasons - - return ([typeSuggestions indexOfObject:type] > 38); -} - -/** - * Return if aType is a string type - */ -- (BOOL)_isFieldTypeString:(NSString*)aType -{ - NSString *type = [[aType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - if(![typeSuggestions containsObject:type]) return YES; // for safety reasons - - return ([typeSuggestions indexOfObject:type] > 17 && [typeSuggestions indexOfObject:type] < 32); -} -/** - * Return if aType is a string type - */ -- (BOOL)_isFieldTypeAllowBinary:(NSString*)aType -{ - NSString *type = [[aType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; - - if(![typeSuggestions containsObject:type]) return YES; // for safety reasons - - return ([typeSuggestions indexOfObject:type] > 17 && [typeSuggestions indexOfObject:type] < 24); -} +#pragma mark Private API /** * Removes a field from the current table and the dependent foreign key if specified. @@ -1598,6 +1543,8 @@ returns a dictionary containing enum/set field names as key and possible values [oldRow release]; [enumFields release]; [typeSuggestions release]; + + [fieldValidation release], fieldValidation = nil; if (defaultValues) [defaultValues release]; if (selectedTable) [selectedTable release]; diff --git a/Source/SPTableStructureDelegate.m b/Source/SPTableStructureDelegate.m index d3954df7..b3246ca2 100644 --- a/Source/SPTableStructureDelegate.m +++ b/Source/SPTableStructureDelegate.m @@ -123,7 +123,7 @@ if(anObject && [(NSString*)anObject length] && ![(NSString*)anObject hasPrefix:@"--"]) { [currentRow setObject:[(NSString*)anObject uppercaseString] forKey:@"type"]; // If type is BLOB or TEXT reset DEFAULT since these field types don't allow a default - if([[currentRow objectForKey:@"type"] hasSuffix:@"TEXT"] || [[currentRow objectForKey:@"type"] hasSuffix:@"BLOB"] || [self _isFieldTypeGeometry:[currentRow objectForKey:@"type"]]) { + if([[currentRow objectForKey:@"type"] hasSuffix:@"TEXT"] || [[currentRow objectForKey:@"type"] hasSuffix:@"BLOB"] || [fieldValidation isFieldTypeGeometry:[currentRow objectForKey:@"type"]]) { [currentRow setObject:@"" forKey:@"default"]; [currentRow setObject:@"" forKey:@"length"]; } @@ -465,23 +465,23 @@ // Only string fields allow encoding settings if(([[aTableColumn identifier] isEqualToString:@"encoding"])) { - [aCell setEnabled:([self _isFieldTypeString:theRowType] && ![theRowType hasSuffix:@"BINARY"] && ![theRowType hasSuffix:@"BLOB"])]; + [aCell setEnabled:([fieldValidation isFieldTypeString:theRowType] && ![theRowType hasSuffix:@"BINARY"] && ![theRowType hasSuffix:@"BLOB"])]; } // Only string fields allow collation settings and string field is not set to BINARY since BINARY sets the collation to *_bin else if([[aTableColumn identifier] isEqualToString:@"collation"]){ - [aCell setEnabled:([self _isFieldTypeString:theRowType] && [[theRow objectForKey:@"binary"] integerValue] == 0 && ![theRowType hasSuffix:@"BINARY"] && ![theRowType hasSuffix:@"BLOB"])]; + [aCell setEnabled:([fieldValidation isFieldTypeString:theRowType] && [[theRow objectForKey:@"binary"] integerValue] == 0 && ![theRowType hasSuffix:@"BINARY"] && ![theRowType hasSuffix:@"BLOB"])]; } // Check if UNSIGNED and ZEROFILL is allowed else if([[aTableColumn identifier] isEqualToString:@"zerofill"] || [[aTableColumn identifier] isEqualToString:@"unsigned"]) { - [aCell setEnabled:([self _isFieldTypeNumeric:theRowType])]; + [aCell setEnabled:([fieldValidation isFieldTypeNumeric:theRowType])]; } // Check if BINARY is allowed else if([[aTableColumn identifier] isEqualToString:@"binary"]) { - [aCell setEnabled:([self _isFieldTypeAllowBinary:theRowType])]; + [aCell setEnabled:([fieldValidation isFieldTypeAllowBinary:theRowType])]; } // TEXT, BLOB, and GEOMETRY fields don't allow a DEFAULT else if([[aTableColumn identifier] isEqualToString:@"default"]) { - [aCell setEnabled:([theRowType hasSuffix:@"TEXT"] || [theRowType hasSuffix:@"BLOB"] || [self _isFieldTypeGeometry:theRowType]) ? NO : YES]; + [aCell setEnabled:([theRowType hasSuffix:@"TEXT"] || [theRowType hasSuffix:@"BLOB"] || [fieldValidation isFieldTypeGeometry:theRowType]) ? NO : YES]; } // Check allow NULL else if([[aTableColumn identifier] isEqualToString:@"null"]) { @@ -489,7 +489,7 @@ } // TEXT, BLOB, date, and GEOMETRY fields don't allow a length else if([[aTableColumn identifier] isEqualToString:@"length"]) { - [aCell setEnabled:([theRowType hasSuffix:@"TEXT"] || [theRowType hasSuffix:@"BLOB"] || [self _isFieldTypeDate:theRowType] || [self _isFieldTypeGeometry:theRowType]) ? NO : YES]; + [aCell setEnabled:([theRowType hasSuffix:@"TEXT"] || [theRowType hasSuffix:@"BLOB"] || [fieldValidation isFieldTypeDate:theRowType] || [fieldValidation isFieldTypeGeometry:theRowType]) ? NO : YES]; } else { [aCell setEnabled:YES]; diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 1039488b..c9b87bf0 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -110,6 +110,7 @@ 17CC97F710B4AC6C0034CD7A /* AboutPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17CC97F510B4AC6C0034CD7A /* AboutPanel.xib */; }; 17CC993B10B4C9C80034CD7A /* License.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 17CC993A10B4C9C80034CD7A /* License.rtf */; }; 17D38EBC12771A1C00672B13 /* SPTableStructureDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D38EBB12771A1C00672B13 /* SPTableStructureDelegate.m */; }; + 17D38F701279E23A00672B13 /* SPTableFieldValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D38F6F1279E23A00672B13 /* SPTableFieldValidation.m */; }; 17DC8E75126F4AB600E9AAEC /* MCPConnectionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 17DC8E74126F4AB600E9AAEC /* MCPConnectionDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17DCC5C7115C202700F89A00 /* MCPStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 17DCC5C5115C202700F89A00 /* MCPStringAdditions.h */; }; 17DD52B7115071D0007D8950 /* SPPrintTemplate.html in Resources */ = {isa = PBXBuildFile; fileRef = 17DD52B6115071D0007D8950 /* SPPrintTemplate.html */; }; @@ -665,6 +666,8 @@ 17CC993A10B4C9C80034CD7A /* License.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = License.rtf; sourceTree = ""; }; 17D38EBA12771A1C00672B13 /* SPTableStructureDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTableStructureDelegate.h; sourceTree = ""; }; 17D38EBB12771A1C00672B13 /* SPTableStructureDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTableStructureDelegate.m; sourceTree = ""; }; + 17D38F6E1279E23A00672B13 /* SPTableFieldValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTableFieldValidation.h; sourceTree = ""; }; + 17D38F6F1279E23A00672B13 /* SPTableFieldValidation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTableFieldValidation.m; sourceTree = ""; }; 17DA04EA0FC1A7DA00D66140 /* Unit Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Unit Tests-Info.plist"; path = "Plists/Unit Tests-Info.plist"; sourceTree = ""; }; 17DC8E74126F4AB600E9AAEC /* MCPConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCPConnectionDelegate.h; sourceTree = ""; }; 17DCC5C5115C202700F89A00 /* MCPStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCPStringAdditions.h; sourceTree = ""; }; @@ -1356,10 +1359,7 @@ 17E6414F0EF01EF6001BC333 /* SPTableContent.m */, 17E641500EF01EF6001BC333 /* SPDatabaseDocument.h */, 17E641510EF01EF6001BC333 /* SPDatabaseDocument.m */, - 17E641540EF01EF6001BC333 /* SPTableStructure.h */, - 17E641550EF01EF6001BC333 /* SPTableStructure.m */, - 17D38EBA12771A1C00672B13 /* SPTableStructureDelegate.h */, - 17D38EBB12771A1C00672B13 /* SPTableStructureDelegate.m */, + 17D38F691279E17D00672B13 /* Table Structure */, 1792C28910AE1C7200ABE758 /* Controller Categories */, ); name = "Main View Controllers"; @@ -1607,6 +1607,19 @@ name = "Data Import"; sourceTree = ""; }; + 17D38F691279E17D00672B13 /* Table Structure */ = { + isa = PBXGroup; + children = ( + 17E641540EF01EF6001BC333 /* SPTableStructure.h */, + 17E641550EF01EF6001BC333 /* SPTableStructure.m */, + 17D38EBA12771A1C00672B13 /* SPTableStructureDelegate.h */, + 17D38EBB12771A1C00672B13 /* SPTableStructureDelegate.m */, + 17D38F6E1279E23A00672B13 /* SPTableFieldValidation.h */, + 17D38F6F1279E23A00672B13 /* SPTableFieldValidation.m */, + ); + name = "Table Structure"; + sourceTree = ""; + }; 17DC8825126B222D00E9AAEC /* Third Party */ = { isa = PBXGroup; children = ( @@ -2932,6 +2945,7 @@ 1798AB911267924D000D946A /* SPAppleScriptSupport.m in Sources */, 175EC63512733B36009A7C0F /* SPExportControllerDelegate.m in Sources */, 17D38EBC12771A1C00672B13 /* SPTableStructureDelegate.m in Sources */, + 17D38F701279E23A00672B13 /* SPTableFieldValidation.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- cgit v1.2.3