aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-09-09 13:48:26 +0000
committerBibiko <bibiko@eva.mpg.de>2010-09-09 13:48:26 +0000
commit0e7ab97ce059e054886288401100586e59188ad3 (patch)
treec8c99fba4787fb5f44e91bc2a053a9defa6253ba /Source
parentcc99469638a22d68a01650bf36adc3b99ae817d1 (diff)
downloadsequelpro-0e7ab97ce059e054886288401100586e59188ad3.tar.gz
sequelpro-0e7ab97ce059e054886288401100586e59188ad3.tar.bz2
sequelpro-0e7ab97ce059e054886288401100586e59188ad3.zip
• TableStructure
- changed: field information are retrieved via [SPTableData columns]; mainly to get all infos like comment, encoding, and collation - added the chance to edit encoding, collation, and comment for each field Note: This is work is progress - not yet optimized but fully workable. Due to GUI I simply added these three columns - improvements will follow
Diffstat (limited to 'Source')
-rw-r--r--Source/SPIndexesController.m206
-rw-r--r--Source/SPTableStructure.h5
-rw-r--r--Source/SPTableStructure.m719
3 files changed, 484 insertions, 446 deletions
diff --git a/Source/SPIndexesController.m b/Source/SPIndexesController.m
index d7a509bd..fdd5b886 100644
--- a/Source/SPIndexesController.m
+++ b/Source/SPIndexesController.m
@@ -47,15 +47,15 @@
- (id)init
{
if ((self = [super initWithWindowNibName:@"IndexesView"])) {
-
+
table = @"";
-
+
fields = [[NSMutableArray alloc] init];
indexes = [[NSMutableArray alloc] init];
-
+
prefs = [NSUserDefaults standardUserDefaults];
}
-
+
return self;
}
@@ -63,18 +63,18 @@
* Nib awakening.
*/
- (void)awakeFromNib
-{
+{
// Set the index tables view's vertical gridlines if required
[indexesTableView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
-
+
// Set the strutcture and index view's font
BOOL useMonospacedFont = [prefs boolForKey:SPUseMonospacedFonts];
-
+
for (NSTableColumn *indexColumn in [indexesTableView tableColumns])
{
[[indexColumn dataCell] setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
}
-
+
[prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:NULL];
}
@@ -85,50 +85,50 @@
* Opens the add new index sheet.
*/
- (IBAction)addIndex:(id)sender
-{
+{
// Check whether a save of the current field row is required.
if (![tableStructure saveRowOnDeselect]) return;
-
+
// Set sheet defaults - key type PRIMARY, key name PRIMARY and disabled
[indexTypePopUpButton selectItemAtIndex:0];
[indexNameTextField setEnabled:NO];
[indexNameTextField setStringValue:@"PRIMARY"];
-
+
[[self window] makeFirstResponder:indexedColumnsComboBox];
-
+
// Check to see whether a primary key already exists for the table, and if so select an INDEX instead
- for (NSDictionary *field in fields)
+ for (NSDictionary *field in fields)
{
if ([[field objectForKey:@"Key"] isEqualToString:@"PRI"]) {
[indexTypePopUpButton selectItemAtIndex:1];
[indexNameTextField setEnabled:YES];
[indexNameTextField setStringValue:@""];
-
+
[[self window] makeFirstResponder:indexNameTextField];
-
+
break;
}
}
-
+
// Update the default values array and the indexed column fields control
[indexedColumnsComboBox removeAllItems];
-
- for (NSDictionary *field in fields)
+
+ for (NSDictionary *field in fields)
{
- [indexedColumnsComboBox addItemWithObjectValue:[field objectForKey:@"Field"]];
+ [indexedColumnsComboBox addItemWithObjectValue:[field objectForKey:@"name"]];
}
-
+
// Only show up to ten items in the indexed column fields combo box
[indexedColumnsComboBox setNumberOfVisibleItems:([fields count] < 10) ? [fields count] : 10];
-
+
// Select the first column
[indexedColumnsComboBox selectItemAtIndex:0];
-
+
// Begin the sheet
[NSApp beginSheet:[self window]
- modalForWindow:[dbDocument parentWindow]
+ modalForWindow:[dbDocument parentWindow]
modalDelegate:self
- didEndSelector:@selector(addIndexSheetDidEnd:returnCode:contextInfo:)
+ didEndSelector:@selector(addIndexSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
@@ -138,20 +138,20 @@
- (IBAction)removeIndex:(id)sender
{
if (![indexesTableView numberOfSelectedRows]) return;
-
+
// Check whether a save of the current fields row is required.
if (![tableStructure saveRowOnDeselect]) return;
-
+
NSInteger index = [indexesTableView selectedRow];
-
+
if ((index == -1) || (index > ([indexes count] - 1))) return;
-
+
NSString *keyName = [[indexes objectAtIndex:index] objectForKey:@"Key_name"];
NSString *columnName = [[indexes objectAtIndex:index] objectForKey:@"Column_name"];
-
+
BOOL hasForeignKey = NO;
NSString *constraintName = @"";
-
+
// Check to see whether the user is attempting to remove an index that a foreign key constraint depends on
// thus would result in an error if not dropped before removing the index.
for (NSDictionary *constraint in [tableData getConstraints])
@@ -165,22 +165,22 @@
}
}
}
-
+
NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete index '%@'?", @"delete index message"), keyName]
defaultButton:NSLocalizedString(@"Delete", @"delete button")
alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
- otherButton:nil
+ otherButton:nil
informativeTextWithFormat:(hasForeignKey) ? [NSString stringWithFormat:NSLocalizedString(@"The foreign key relationship '%@' has a dependency on this index. This relationship must be removed before the index can be deleted.\n\nAre you sure you want to continue to delete the relationship and the index? This action cannot be undone.", @"delete index and foreign key informative message"), constraintName] : [NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete the index '%@'? This action cannot be undone.", @"delete index informative message"), keyName]];
-
+
[alert setAlertStyle:NSCriticalAlertStyle];
-
+
NSArray *buttons = [alert buttons];
-
+
// Change the alert's cancel button to have the key equivalent of return
[[buttons objectAtIndex:0] setKeyEquivalent:@"d"];
[[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask];
[[buttons objectAtIndex:1] setKeyEquivalent:@"\r"];
-
+
[alert beginSheetModalForWindow:[dbDocument parentWindow] modalDelegate:self didEndSelector:@selector(removeIndexSheetDidEnd:returnCode:contextInfo:) contextInfo:(hasForeignKey) ? @"removeIndexAndForeignKey" : @"removeIndex"];
}
@@ -192,10 +192,10 @@
if ([[indexTypePopUpButton titleOfSelectedItem] isEqualToString:@"PRIMARY KEY"] ) {
[indexNameTextField setEnabled:NO];
[indexNameTextField setStringValue:@"PRIMARY"];
- }
+ }
else {
[indexNameTextField setEnabled:YES];
-
+
if ([[indexNameTextField stringValue] isEqualToString:@"PRIMARY"]) {
[indexNameTextField setStringValue:@""];
}
@@ -221,7 +221,7 @@
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
- return [[indexes objectAtIndex:rowIndex] objectForKey:[tableColumn identifier]];
+ return [[indexes objectAtIndex:rowIndex] objectForKey:[tableColumn identifier]];
}
#pragma mark -
@@ -233,11 +233,11 @@
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
if ([notification object] == indexesTableView) {
-
+
// Check if there is currently an index selected and change button state accordingly
[removeIndexButton setEnabled:([indexesTableView numberOfSelectedRows] > 0 && [tablesList tableType] == SPTableTypeTable)];
}
-
+
}
#pragma mark -
@@ -247,9 +247,9 @@
* Only enable the add button if there is at least one indexed column.
*/
- (void)controlTextDidChange:(NSNotification *)notification
-{
+{
if ([notification object] == indexedColumnsComboBox) {
- [addIndexButton setEnabled:([[[indexedColumnsComboBox stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0)];
+ [addIndexButton setEnabled:([[[indexedColumnsComboBox stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0)];
}
}
@@ -262,7 +262,7 @@
- (void)setFields:(NSArray *)tableFields
{
[fields removeAllObjects];
-
+
[fields setArray:tableFields];
}
@@ -272,7 +272,7 @@
- (void)setIndexes:(NSArray *)tableIndexes
{
[indexes removeAllObjects];
-
+
[indexes setArray:tableIndexes];
}
@@ -282,21 +282,21 @@
- (void)addIndexSheetDidEnd:(NSWindow *)theSheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
[theSheet orderOut:nil];
-
+
if (returnCode == NSOKButton) {
[dbDocument startTaskWithDescription:NSLocalizedString(@"Adding index...", @"adding index task status message")];
-
+
NSMutableDictionary *indexDetails = [NSMutableDictionary dictionary];
-
+
[indexDetails setObject:[[indexedColumnsComboBox stringValue] componentsSeparatedByString:@","] forKey:@"IndexedColumns"];
[indexDetails setObject:[indexNameTextField stringValue] forKey:@"IndexName"];
[indexDetails setObject:[indexTypePopUpButton titleOfSelectedItem] forKey:@"IndexType"];
-
+
if ([NSThread isMainThread]) {
[NSThread detachNewThreadSelector:@selector(_addIndexUsingDetails:) toTarget:self withObject:indexDetails];
-
- [dbDocument enableTaskCancellationWithTitle:NSLocalizedString(@"Cancel", @"cancel button") callbackObject:self callbackFunction:NULL];
- }
+
+ [dbDocument enableTaskCancellationWithTitle:NSLocalizedString(@"Cancel", @"cancel button") callbackObject:self callbackFunction:NULL];
+ }
else {
[self _addIndexUsingDetails:indexDetails];
}
@@ -311,20 +311,20 @@
{
// Order out current sheet to suppress overlapping of sheets
[[alert window] orderOut:nil];
-
+
if (returnCode == NSAlertDefaultReturn) {
[dbDocument startTaskWithDescription:NSLocalizedString(@"Removing index...", @"removing index task status message")];
-
+
NSMutableDictionary *indexDetails = [NSMutableDictionary dictionary];
-
+
[indexDetails setObject:[indexes objectAtIndex:[indexesTableView selectedRow]] forKey:@"Index"];
[indexDetails setObject:[NSNumber numberWithBool:[contextInfo hasSuffix:@"AndForeignKey"]] forKey:@"RemoveForeignKey"];
-
+
if ([NSThread isMainThread]) {
[NSThread detachNewThreadSelector:@selector(_removeIndexUsingDeatails:) toTarget:self withObject:indexDetails];
-
+
[dbDocument enableTaskCancellationWithTitle:NSLocalizedString(@"Cancel", @"cancel button") callbackObject:self callbackFunction:NULL];
- }
+ }
else {
[self _removeIndexUsingDeatails:indexDetails];
}
@@ -335,21 +335,21 @@
* 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]) {
[indexesTableView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
}
// Use monospaced fonts preference changed
else if ([keyPath isEqualToString:SPUseMonospacedFonts]) {
-
+
BOOL useMonospacedFont = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
-
+
for (NSTableColumn *indexColumn in [indexesTableView tableColumns])
{
[[indexColumn dataCell] setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
}
-
+
[indexesTableView reloadData];
}
}
@@ -358,19 +358,19 @@
* Menu validation
*/
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
-{
+{
// Remove index
if ([menuItem action] == @selector(removeIndex:)) {
return ([indexesTableView numberOfSelectedRows] == 1);
}
-
+
// Reset AUTO_INCREMENT
- if ([menuItem action] == @selector(resetAutoIncrement:)) {
- return ([indexesTableView numberOfSelectedRows] == 1
- && [[indexes objectAtIndex:[indexesTableView selectedRow]] objectForKey:@"Key_name"]
+ if ([menuItem action] == @selector(resetAutoIncrement:)) {
+ return ([indexesTableView numberOfSelectedRows] == 1
+ && [[indexes objectAtIndex:[indexesTableView selectedRow]] objectForKey:@"Key_name"]
&& [[[indexes objectAtIndex:[indexesTableView selectedRow]] objectForKey:@"Key_name"] isEqualToString:@"PRIMARY"]);
}
-
+
return YES;
}
@@ -383,52 +383,52 @@
- (void)_addIndexUsingDetails:(NSDictionary *)indexDetails
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// Check whether a save of the current fields row is required.
if (![[tableStructure onMainThread] saveRowOnDeselect]) return;
-
+
NSString *indexName = [indexDetails objectForKey:@"IndexName"];
NSString *indexType = [indexDetails objectForKey:@"IndexType"];
NSArray *indexedColumns = [indexDetails objectForKey:@"IndexedColumns"];
-
+
// Interface validation should prevent this
if ([indexedColumns count] > 0) {
-
+
NSMutableArray *tempIndexedColumns = [[NSMutableArray alloc] init];
-
+
if ([indexName isEqualToString:@"PRIMARY"]) {
indexName = @"";
- }
+ }
else {
indexName = ([indexName isEqualToString:@""]) ? @"" : [indexName backtickQuotedString];
}
-
+
// For each column strip leading and trailing whitespace and add it to the temp array
for (NSString *column in indexedColumns)
- {
+ {
[tempIndexedColumns addObject:[column stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
}
-
+
// Execute the query
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ ADD %@ %@ (%@)", [table backtickQuotedString], indexType, indexName, [tempIndexedColumns componentsJoinedAndBacktickQuoted]]];
-
+
[tempIndexedColumns release];
-
+
// Check for errors, but only if the query wasn't cancelled
if ([connection queryErrored] && ![connection queryCancelled]) {
- SPBeginAlertSheet(NSLocalizedString(@"Unable to add index", @"add index error message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [dbDocument parentWindow], self, nil, nil,
+ SPBeginAlertSheet(NSLocalizedString(@"Unable to add index", @"add index error message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [dbDocument parentWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection getLastErrorMessage]]);
}
else {
[tableData resetAllData];
[tablesList setStatusRequiresReload:YES];
-
+
[tableStructure loadTable:table];
}
}
-
+
[dbDocument endTask];
-
+
[pool drain];
}
@@ -438,17 +438,17 @@
- (void)_removeIndexUsingDeatails:(NSDictionary *)indexDetails
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
NSDictionary *index = [indexDetails objectForKey:@"Index"];
BOOL removeForeignKey = [[indexDetails objectForKey:@"RemoveForeignKey"] boolValue];
-
+
// Remove the foreign key dependency before the index if required
if (removeForeignKey) {
-
+
NSString *columnName = [index objectForKey:@"Column_name"];
-
+
NSString *constraintName = @"";
-
+
// Check to see whether the user is attempting to remove an index that a foreign key constraint depends on
// thus would result in an error if not dropped before removing the index.
for (NSDictionary *constraint in [tableData getConstraints])
@@ -461,20 +461,20 @@
}
}
}
-
+
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [table backtickQuotedString], [constraintName backtickQuotedString]]];
-
+
// Check for errors, but only if the query wasn't cancelled
if ([connection queryErrored] && ![connection queryCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
-
+
[errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"];
[errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), constraintName, [connection getLastErrorMessage]] forKey:@"message"];
-
+
[[tableStructure onMainThread] showErrorSheetWith:errorDictionary];
- }
+ }
}
-
+
if ([[index objectForKey:@"Key_name"] isEqualToString:@"PRIMARY"]) {
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP PRIMARY KEY", [table backtickQuotedString]]];
}
@@ -482,25 +482,25 @@
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP INDEX %@",
[table backtickQuotedString], [[index objectForKey:@"Key_name"] backtickQuotedString]]];
}
-
+
// Check for errors, but only if the query wasn't cancelled
if ([connection queryErrored] && ![connection queryCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
-
+
[errorDictionary setObject:NSLocalizedString(@"Unable to delete index", @"error deleting index message") forKey:@"title"];
[errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to delete the index.\n\nMySQL said: %@", @"error deleting index informative message"), [connection getLastErrorMessage]] forKey:@"message"];
-
+
[[tableStructure onMainThread] showErrorSheetWith:errorDictionary];
- }
+ }
else {
[tableData resetAllData];
[tablesList setStatusRequiresReload:YES];
-
+
[tableStructure loadTable:table];
}
-
+
[dbDocument endTask];
-
+
[pool drain];
}
@@ -510,11 +510,11 @@
* Dealloc.
*/
- (void)dealloc
-{
+{
[table release];
[indexes release];
[fields release];
-
+
[super dealloc];
}
diff --git a/Source/SPTableStructure.h b/Source/SPTableStructure.h
index f81078b1..74905e5e 100644
--- a/Source/SPTableStructure.h
+++ b/Source/SPTableStructure.h
@@ -53,7 +53,9 @@
IBOutlet id indexesTableView;
IBOutlet NSSplitView *tablesIndexesSplitView;
IBOutlet NSButton *indexesShowButton;
-
+
+ id databaseDataInstance;
+
MCPConnection *mySQLConnection;
MCPResult *tableSourceResult;
MCPResult *indexResult;
@@ -65,6 +67,7 @@
BOOL isEditingRow, isEditingNewRow, isSavingRow, alertSheetOpened;
NSInteger currentlyEditingRow;
NSUserDefaults *prefs;
+ NSArray *collations;
}
// Table methods
diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m
index ac490b82..2ec324a7 100644
--- a/Source/SPTableStructure.m
+++ b/Source/SPTableStructure.m
@@ -55,14 +55,14 @@
tableFields = [[NSMutableArray alloc] init];
oldRow = [[NSMutableDictionary alloc] init];
enumFields = [[NSMutableDictionary alloc] init];
-
+
currentlyEditingRow = -1;
defaultValues = nil;
selectedTable = nil;
-
+
prefs = [NSUserDefaults standardUserDefaults];
}
-
+
return self;
}
@@ -73,15 +73,17 @@
{
// Set the structure and index view's vertical gridlines if required
[tableSourceView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
-
+
// Set the strutcture and index view's font
BOOL useMonospacedFont = [prefs boolForKey:SPUseMonospacedFonts];
-
+
for (NSTableColumn *fieldColumn in [tableSourceView tableColumns])
{
[[fieldColumn dataCell] setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
}
-
+
+ databaseDataInstance = [tableDocumentInstance valueForKeyPath:@"databaseDataInstance"];
+
// Add observers for document task activity
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
@@ -100,12 +102,10 @@
*/
- (void)loadTable:(NSString *)aTable
{
- NSArray *theTableFields, *theTableIndexes;
+ NSMutableArray *theTableFields = [NSMutableArray array];
+ NSArray *theTableIndexes;
NSMutableDictionary *theTableEnumLists = [NSMutableDictionary dictionary];
- NSArray *extrasArray;
- NSMutableDictionary *tempDefaultValues;
NSInteger i;
- SPSQLParser *fieldParser;
// Check whether a save of the current row is required.
if ( ![[self onMainThread] saveRowOnDeselect] ) return;
@@ -115,32 +115,10 @@
[[self onMainThread] setTableDetails:nil];
return;
}
-
- // Send the query started/working notification
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-
- // Retrieve the column information for this table.
- // TODO: update this and indexes to use TableData at some point - tiny bit more parsing required...
- tableSourceResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [aTable backtickQuotedString]]] retain];
-
- // If an error occurred, reset the interface and abort
- if ([mySQLConnection queryErrored]) {
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
- [[self onMainThread] setTableDetails:nil];
-
- if ([mySQLConnection isConnected]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
- nil, nil, [NSApp mainWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"),
- [mySQLConnection getLastErrorMessage]]);
- }
- if (tableSourceResult) [tableSourceResult release];
- return;
- }
- // Process the field names into a local array of dictionaries
- theTableFields = [self fetchResultAsArray:tableSourceResult];
- [tableSourceResult release];
+ // Make a mutable copy out of the cached [tableDataInstance columns] since we're adding infos
+ for(id col in [tableDataInstance columns])
+ [theTableFields addObject:[col mutableCopy]];
// Retrieve the indexes for the table
indexResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]] retain];
@@ -151,7 +129,7 @@
[[self onMainThread] setTableDetails:nil];
if ([mySQLConnection isConnected]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"),
[mySQLConnection getLastErrorMessage]]);
@@ -164,72 +142,95 @@
theTableIndexes = [self fetchResultAsArray:indexResult];
[indexResult release];
- // Process all the fields to normalise keys and add additional information
- for (id theField in theTableFields) {
- NSString *type;
- NSString *length;
- NSString *extras;
-
- // Set up the field parser with the type definition
- fieldParser = [[SPSQLParser alloc] initWithString:[theField objectForKey:@"Type"]];
-
- // Pull out the field type; if no brackets are found, this returns nil - in which case simple values can be used.
- type = [fieldParser trimAndReturnStringToCharacter:'(' trimmingInclusively:YES returningInclusively:NO];
- if (!type) {
- type = [NSString stringWithString:fieldParser];
- length = @"";
- extras = @"";
- } else {
-
- // Pull out the length, which may include enum/set values
- length = [fieldParser trimAndReturnStringToCharacter:')' trimmingInclusively:YES returningInclusively:NO];
- if (!length) length = @"";
+ // Set the Key column
+ 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"];
+ else
+ [field setObject:(([[theIndex objectForKey:@"Non_unique"] isEqualToString:@"1"]) ? @"MUL" : @"UNI") forKey:@"Key"];
+ break;
+ }
+ }
+ }
- // Separate any remaining extras
- extras = [NSString stringWithString:fieldParser];
- if (!extras) extras = @"";
+ // Set up the encoding PopUpButtonCell
+ NSArray *encodings = [databaseDataInstance getDatabaseCharacterSetEncodings];
+ if (([encodings count] > 0) && ([tableDataInstance tableEncoding])) {
+ NSString *selectedTitle = @"";
+ [[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] removeAllItems];
+ [[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] addItemWithTitle:@""];
+ // Populate encoding popup button
+ for (NSDictionary *encoding in encodings)
+ {
+ NSString *menuItemTitle = (![encoding objectForKey:@"DESCRIPTION"]) ? [encoding objectForKey:@"CHARACTER_SET_NAME"] : [NSString stringWithFormat:@"%@ (%@)", [encoding objectForKey:@"DESCRIPTION"], [encoding objectForKey:@"CHARACTER_SET_NAME"]];
+ [[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] addItemWithTitle:menuItemTitle];
}
+ }
+ else {
+ [[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] addItemWithTitle:NSLocalizedString(@"Not available", @"not available label")];
+ }
- [fieldParser release];
+ // Process all the fields to normalise keys and add additional information
+ for (id theField in theTableFields) {
- // Get possible values if the field is an enum or a set
- if ([type isEqualToString:@"enum"] || [type isEqualToString:@"set"]) {
- SPSQLParser *valueParser = [[SPSQLParser alloc] initWithString:length];
- NSMutableArray *possibleValues = [[NSMutableArray alloc] initWithArray:[valueParser splitStringByCharacter:',']];
- for (i = 0; i < [possibleValues count]; i++) {
- [valueParser setString:[possibleValues objectAtIndex:i]];
- [possibleValues replaceObjectAtIndex:i withObject:[valueParser unquotedString]];
+ // Select and re-map encoding and collation since [self dataSource] stores the choice as NSNumbers
+ NSString *fieldEncoding = @"";
+ NSInteger selectedIndex = 0;
+ if([theField objectForKey:@"encoding"]) {
+ for(id enc in encodings) {
+ if([[enc objectForKey:@"CHARACTER_SET_NAME"] isEqualToString:[theField objectForKey:@"encoding"]]) {
+ fieldEncoding = [theField objectForKey:@"encoding"];
+ break;
+ }
+ selectedIndex++;
}
- [theTableEnumLists setObject:[NSArray arrayWithArray:possibleValues] forKey:[theField objectForKey:@"Field"]];
- [possibleValues release];
- [valueParser release];
+ selectedIndex++; // due to leading @"" in popup list
}
-
- // For timestamps check to see whether "on update CURRENT_TIMESTAMP" - not returned
- // by SHOW COLUMNS - should be set from the table data store
- if ([type isEqualToString:@"timestamp"]
- && [[[tableDataInstance columnWithName:[theField objectForKey:@"Field"]] objectForKey:@"onupdatetimestamp"] integerValue])
- {
- [theField setObject:@"on update CURRENT_TIMESTAMP" forKey:@"Extra"];
+ [theField setObject:[NSNumber numberWithInt:selectedIndex] forKey:@"encoding"];
+ selectedIndex = 0;
+ if([fieldEncoding length] && [theField objectForKey:@"collation"]) {
+ NSArray *theCollations = [databaseDataInstance getDatabaseCollationsForEncoding:fieldEncoding];
+ for(id col in theCollations) {
+ if([[col objectForKey:@"COLLATION_NAME"] isEqualToString:[theField objectForKey:@"collation"]]) {
+ break;
+ }
+ selectedIndex++;
+ }
+ selectedIndex++; // due to leading @"" in popup list
}
+ [theField setObject:[NSNumber numberWithInt:selectedIndex] forKey:@"collation"];
- // Scan extras for values like unsigned, zerofill, binary
- extrasArray = [extras componentsSeparatedByString:@" "];
- for (id extra in extrasArray) {
- if ([extra isEqualToString:@"unsigned"]) {
- [theField setObject:@"1" forKey:@"unsigned"];
- } else if ([extra isEqualToString:@"zerofill"]) {
- [theField setObject:@"1" forKey:@"zerofill"];
- } else if ([extra isEqualToString:@"binary"]) {
- [theField setObject:@"1" forKey:@"binary"];
- } else {
- if (![extra isEqualToString:@""])
- NSLog(@"ERROR: unknown option in field definition: %@", extra);
- }
+ NSString *type = [[theField objectForKey:@"type"] uppercaseString];
+
+ // Get possible values if the field is an enum or a set
+ if (([type isEqualToString:@"ENUM"] || [type isEqualToString:@"SET"]) && [theField objectForKey:@"values"]) {
+ [theTableEnumLists setObject:[NSArray arrayWithArray:[theField objectForKey:@"values"]] forKey:[theField objectForKey:@"name"]];
+ [theField setObject:[NSString stringWithFormat:@"'%@'", [[theField objectForKey:@"values"] componentsJoinedByString:@"','"]] forKey:@"length"];
}
- [theField setObject:type forKey:@"Type"];
- [theField setObject:length forKey:@"Length"];
+ // Join length and decimals if any
+ if ([theField objectForKey:@"decimals"])
+ [theField setObject:[NSString stringWithFormat:@"%@,%@", [theField objectForKey:@"length"], [theField objectForKey:@"decimals"]] forKey:@"length"];
+
+ // Normalize default
+ if(![theField objectForKey:@"default"])
+ [theField setObject:@"" forKey:@"default"];
+ else if([[theField objectForKey:@"default"] isKindOfClass:[NSNull class]])
+ [theField setObject:[prefs stringForKey:SPNullValue] forKey:@"default"];
+
+ // Init Extra field
+ [theField setObject:@"None" forKey:@"Extra"];
+
+ // Check for auto_increment and set Extra accordingly
+ if([[theField objectForKey:@"autoincrement"] integerValue])
+ [theField setObject:@"auto_increment" forKey:@"Extra"];
+
+ // 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
@@ -243,7 +244,7 @@
// Send the query finished/work complete notification
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-
+
}
/**
@@ -274,7 +275,7 @@
// Update the selected table name
if (selectedTable) [selectedTable release], selectedTable = nil;
if (newTableName) selectedTable = [[NSString alloc] initWithString:newTableName];
-
+
[indexesController setTable:selectedTable];
// Reset the table store and display
@@ -301,27 +302,25 @@
// Update the fields and indexes stores
[tableFields setArray:[tableDetails objectForKey:@"tableFields"]];
-
+
[indexesController setFields:tableFields];
[indexesController setIndexes:[tableDetails objectForKey:@"tableIndexes"]];
-
+
if (defaultValues) [defaultValues release], defaultValues = nil;
-
+
newDefaultValues = [NSMutableDictionary dictionaryWithCapacity:[tableFields count]];
-
- for (id theField in tableFields)
- {
- [newDefaultValues setObject:[theField objectForKey:@"Default"] forKey:[theField objectForKey:@"Field"]];
- }
-
+
+ for (id theField in tableFields)
+ [newDefaultValues setObject:[theField objectForKey:@"default"] forKey:[theField objectForKey:@"name"]];
+
defaultValues = [[NSDictionary dictionaryWithDictionary:newDefaultValues] retain];
-
+
// Enable the edit table button
[editTableButton setEnabled:enableInteraction];
// If a view is selected, disable the buttons; otherwise enable.
BOOL editingEnabled = ([tablesListInstance tableType] == SPTableTypeTable) && enableInteraction;
-
+
[addFieldButton setEnabled:editingEnabled];
[addIndexButton setEnabled:editingEnabled];
@@ -342,10 +341,10 @@
if ( ![self saveRowOnDeselect] ) return;
NSInteger insertIndex = ([tableSourceView numberOfSelectedRows] == 0 ? [tableSourceView numberOfRows] : [tableSourceView selectedRow] + 1);
-
- [tableFields insertObject:[NSMutableDictionary
- dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"int", @"", @"0", @"0", @"0", ([prefs boolForKey:SPNewFieldsAllowNulls]) ? @"1" : @"0", @"", [prefs stringForKey:SPNullValue], @"None", nil]
- forKeys:[NSArray arrayWithObjects:@"Field", @"Type", @"Length", @"unsigned", @"zerofill", @"binary", @"Null", @"Key", @"Default", @"Extra", nil]]
+
+ [tableFields insertObject:[NSMutableDictionary
+ dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"INT", @"", @"0", @"0", @"0", ([prefs boolForKey:SPNewFieldsAllowNulls]) ? @"1" : @"0", @"", [prefs stringForKey:SPNullValue], @"None", @"", @"", @"", nil]
+ forKeys:[NSArray arrayWithObjects:@"name", @"type", @"length", @"unsigned", @"zerofill", @"binary", @"null", @"Key", @"default", @"Extra", @"comment", @"encoding", @"collation", nil]]
atIndex:insertIndex];
[tableSourceView reloadData];
@@ -373,10 +372,10 @@
// Check whether a save of the current row is required.
if ( ![self saveRowOnDeselect] ) return;
-
+
//add copy of selected row and go in edit mode
tempRow = [NSMutableDictionary dictionaryWithDictionary:[tableFields objectAtIndex:rowToCopy]];
- [tempRow setObject:[[tempRow objectForKey:@"Field"] stringByAppendingString:@"Copy"] forKey:@"Field"];
+ [tempRow setObject:[[tempRow objectForKey:@"name"] stringByAppendingString:@"Copy"] forKey:@"name"];
[tempRow setObject:@"" forKey:@"Key"];
[tempRow setObject:@"None" forKey:@"Extra"];
[tableFields addObject:tempRow];
@@ -397,31 +396,31 @@
// Check whether a save of the current row is required.
if (![self saveRowOnDeselect]) return;
-
+
NSInteger index = [tableSourceView selectedRow];
-
+
if ((index == -1) || (index > ([tableFields count] - 1))) return;
// Check if the user tries to delete the last defined field in table
// Note that because of better menu item validation, this check will now never evaluate to true.
if ([tableSourceView numberOfRows] < 2) {
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error while deleting field", @"Error while deleting field")
- defaultButton:NSLocalizedString(@"OK", @"OK button")
- alternateButton:nil
- otherButton:nil
+ defaultButton:NSLocalizedString(@"OK", @"OK button")
+ alternateButton:nil
+ otherButton:nil
informativeTextWithFormat:NSLocalizedString(@"You cannot delete the last field in a table. Delete the table instead.", @"You cannot delete the last field in a table. Delete the table instead.")];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"cannotremovefield"];
-
+
}
-
- NSString *field = [[tableFields objectAtIndex:index] objectForKey:@"Field"];
-
+
+ NSString *field = [[tableFields objectAtIndex:index] objectForKey:@"name"];
+
BOOL hasForeignKey = NO;
NSString *referencedTable = @"";
-
+
// Check to see whether the user is attempting to remove a field that has foreign key constraints and thus
// would result in an error if not dropped before removing the field.
for (NSDictionary *constraint in [tableDataInstance getConstraints])
@@ -435,22 +434,22 @@
}
}
}
-
+
NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Delete field '%@'?", @"delete field message"), field]
defaultButton:NSLocalizedString(@"Delete", @"delete button")
- alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
- otherButton:nil
+ alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
+ otherButton:nil
informativeTextWithFormat:(hasForeignKey) ? [NSString stringWithFormat:NSLocalizedString(@"This field is part of a foreign key relationship with the table '%@'. This relationship must be removed before the field can be deleted.\n\nAre you sure you want to continue to delete the relationship and the field? This action cannot be undone.", @"delete field and foreign key informative message"), referencedTable] : [NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete the field '%@'? This action cannot be undone.", @"delete field informative message"), field]];
-
+
[alert setAlertStyle:NSCriticalAlertStyle];
-
+
NSArray *buttons = [alert buttons];
-
+
// Change the alert's cancel button to have the key equivalent of return
[[buttons objectAtIndex:0] setKeyEquivalent:@"d"];
[[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask];
[[buttons objectAtIndex:1] setKeyEquivalent:@"\r"];
-
+
[alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(removeFieldSheetDidEnd:returnCode:contextInfo:) contextInfo:(hasForeignKey) ? @"removeFieldAndForeignKey" : @"removeField"];
}
@@ -460,19 +459,19 @@
- (IBAction)resetAutoIncrement:(id)sender
{
if ([sender tag] == 1) {
-
+
[resetAutoIncrementLine setHidden:YES];
-
+
if ([[tableDocumentInstance valueForKeyPath:@"tableTabView"] indexOfTabViewItem:[[tableDocumentInstance valueForKeyPath:@"tableTabView"] selectedTabViewItem]] == 0)
[resetAutoIncrementLine setHidden:NO];
-
+
// Begin the sheet
[NSApp beginSheet:resetAutoIncrementSheet
- modalForWindow:[tableDocumentInstance parentWindow]
+ modalForWindow:[tableDocumentInstance parentWindow]
modalDelegate:self
- didEndSelector:@selector(resetAutoincrementSheetDidEnd:returnCode:contextInfo:)
+ didEndSelector:@selector(resetAutoincrementSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
-
+
[resetAutoIncrementValue setStringValue:@"1"];
}
else if ([sender tag] == 2) {
@@ -487,7 +486,7 @@
{
// Order out current sheet to suppress overlapping of sheets
[theSheet orderOut:nil];
-
+
if (returnCode == NSAlertDefaultReturn) {
[self setAutoIncrementTo:[[resetAutoIncrementValue stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
@@ -504,14 +503,14 @@
if (returnCode == NSAlertDefaultReturn) {
[tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Removing field...", @"removing field task status message")];
-
+
NSNumber *removeKey = [NSNumber numberWithBool:[contextInfo hasSuffix:@"AndForeignKey"]];
-
+
if ([NSThread isMainThread]) {
[NSThread detachNewThreadSelector:@selector(_removeFieldAndForeignKey:) toTarget:self withObject:removeKey];
-
- [tableDocumentInstance enableTaskCancellationWithTitle:NSLocalizedString(@"Cancel", @"cancel button") callbackObject:self callbackFunction:NULL];
- }
+
+ [tableDocumentInstance enableTaskCancellationWithTitle:NSLocalizedString(@"Cancel", @"cancel button") callbackObject:self callbackFunction:NULL];
+ }
else {
[self _removeFieldAndForeignKey:removeKey];
}
@@ -543,12 +542,12 @@ closes the keySheet
#pragma mark Additional methods
/**
- * Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once
+ * 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];
@@ -586,10 +585,10 @@ closes the keySheet
[mySQLConnection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ AUTO_INCREMENT = %@", [selTable backtickQuotedString], [autoIncValue stringValue]]];
if ([mySQLConnection queryErrored]) {
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"),
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"),
NSLocalizedString(@"OK", @"OK button"),
- nil, nil, [NSApp mainWindow], nil, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to reset AUTO_INCREMENT of table '%@'.\n\nMySQL said: %@", @"error resetting auto_increment informative message"),
+ nil, nil, [NSApp mainWindow], nil, nil, nil,
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to reset AUTO_INCREMENT of table '%@'.\n\nMySQL said: %@", @"error resetting auto_increment informative message"),
selTable, [mySQLConnection getLastErrorMessage]]);
}
@@ -685,181 +684,196 @@ closes the keySheet
if (!isEditingRow || currentlyEditingRow == -1)
return YES;
-
+
if (alertSheetOpened)
return NO;
theRow = [tableFields objectAtIndex:currentlyEditingRow];
-
+
if (isEditingNewRow) {
// ADD syntax
- if ([[theRow objectForKey:@"Length"] isEqualToString:@""] || ![theRow objectForKey:@"Length"]) {
-
+ if ([[theRow objectForKey:@"length"] isEqualToString:@""] || ![theRow objectForKey:@"length"]) {
+
queryString = [NSMutableString stringWithFormat:@"ALTER TABLE %@ ADD %@ %@",
- [selectedTable backtickQuotedString],
- [[theRow objectForKey:@"Field"] backtickQuotedString],
- [theRow objectForKey:@"Type"]];
- }
+ [selectedTable backtickQuotedString],
+ [[theRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"type"] uppercaseString]];
+ }
else {
queryString = [NSMutableString stringWithFormat:@"ALTER TABLE %@ ADD %@ %@(%@)",
- [selectedTable backtickQuotedString],
- [[theRow objectForKey:@"Field"] backtickQuotedString],
- [theRow objectForKey:@"Type"],
- [theRow objectForKey:@"Length"]];
+ [selectedTable backtickQuotedString],
+ [[theRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"type"] uppercaseString],
+ [theRow objectForKey:@"length"]];
}
- }
+ }
else {
// CHANGE syntax
- if (([[theRow objectForKey:@"Length"] isEqualToString:@""]) ||
- (![theRow objectForKey:@"Length"]) ||
- ([[theRow objectForKey:@"Type"] isEqualToString:@"datetime"]))
+ if (([[theRow objectForKey:@"length"] isEqualToString:@""]) ||
+ (![theRow objectForKey:@"length"]) ||
+ ([[[theRow objectForKey:@"type"] lowercaseString] isEqualToString:@"datetime"]))
{
- // If the old row and new row dictionaries are equal then the user didn't actually change anything so don't continue
+ // If the old row and new row dictionaries are equal then the user didn't actually change anything so don't continue
if ([oldRow isEqualToDictionary:theRow]) {
isEditingRow = NO;
currentlyEditingRow = -1;
return YES;
}
-
+
queryString = [NSMutableString stringWithFormat:@"ALTER TABLE %@ CHANGE %@ %@ %@",
- [selectedTable backtickQuotedString],
- [[oldRow objectForKey:@"Field"] backtickQuotedString],
- [[theRow objectForKey:@"Field"] backtickQuotedString],
- [theRow objectForKey:@"Type"]];
- }
+ [selectedTable backtickQuotedString],
+ [[oldRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"type"] uppercaseString]];
+ }
else {
- // If the old row and new row dictionaries are equal then the user didn't actually change anything so don't continue
+ // If the old row and new row dictionaries are equal then the user didn't actually change anything so don't continue
if ([oldRow isEqualToDictionary:theRow]) {
isEditingRow = NO;
currentlyEditingRow = -1;
return YES;
}
-
+
queryString = [NSMutableString stringWithFormat:@"ALTER TABLE %@ CHANGE %@ %@ %@(%@)",
- [selectedTable backtickQuotedString],
- [[oldRow objectForKey:@"Field"] backtickQuotedString],
- [[theRow objectForKey:@"Field"] backtickQuotedString],
- [theRow objectForKey:@"Type"],
- [theRow objectForKey:@"Length"]];
+ [selectedTable backtickQuotedString],
+ [[oldRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"name"] backtickQuotedString],
+ [[theRow objectForKey:@"type"] uppercaseString],
+ [theRow objectForKey:@"length"]];
}
}
-
+
+ NSString *fieldEncoding = @"";
+ if([[theRow objectForKey:@"encoding"] integerValue] > 0) {
+ NSString *enc = [[[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] itemAtIndex:[[theRow objectForKey:@"encoding"] integerValue]] title];
+ NSInteger start = [enc rangeOfString:@"("].location+1;
+ NSInteger end = [enc length] - start - 1;
+ fieldEncoding = [enc substringWithRange:NSMakeRange(start, end)];
+ [queryString appendFormat:@" CHARACTER SET %@", fieldEncoding];
+ }
+ if(![fieldEncoding length] && [tableDataInstance tableEncoding]) {
+ fieldEncoding = [tableDataInstance tableEncoding];
+ }
+ if([fieldEncoding length] && [[theRow objectForKey:@"collation"] integerValue] > 0) {
+ NSArray *theCollations = [databaseDataInstance getDatabaseCollationsForEncoding:fieldEncoding];
+ NSString *col = [[theCollations objectAtIndex:[[theRow objectForKey:@"collation"] integerValue]-1] objectForKey:@"COLLATION_NAME"];
+ [queryString appendFormat:@" COLLATE %@", col];
+ }
+
+
// Field specification
if ([[theRow objectForKey:@"unsigned"] integerValue] == 1) {
[queryString appendString:@" UNSIGNED"];
}
-
+
if ( [[theRow objectForKey:@"zerofill"] integerValue] == 1) {
[queryString appendString:@" ZEROFILL"];
}
-
+
if ( [[theRow objectForKey:@"binary"] integerValue] == 1) {
[queryString appendString:@" BINARY"];
}
- if ([[theRow objectForKey:@"Null"] integerValue] == 0) {
+ if ([[theRow objectForKey:@"null"] integerValue] == 0) {
[queryString appendString:@" NOT NULL"];
} else {
[queryString appendString:@" NULL"];
}
-
+
// Don't provide any defaults for auto-increment fields
if ([[theRow objectForKey:@"Extra"] isEqualToString:@"auto_increment"]) {
[queryString appendString:@" "];
- }
+ }
else {
// If a NULL value has been specified, and NULL is allowed, specify DEFAULT NULL
- if ([[theRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:SPNullValue]]) {
- if ([[theRow objectForKey:@"Null"] integerValue] == 1) {
+ if ([[theRow objectForKey:@"default"] isEqualToString:[prefs objectForKey:SPNullValue]]) {
+ if ([[theRow objectForKey:@"null"] integerValue] == 1) {
[queryString appendString:@" DEFAULT NULL "];
}
- }
+ }
// Otherwise, if CURRENT_TIMESTAMP was specified for timestamps, use that
- else if ([[theRow objectForKey:@"Type"] isEqualToString:@"timestamp"] &&
- [[[theRow objectForKey:@"Default"] uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"])
+ else if ([[theRow objectForKey:@"type"] isEqualToString:@"timestamp"] &&
+ [[[theRow objectForKey:@"default"] uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"])
{
[queryString appendString:@" DEFAULT CURRENT_TIMESTAMP "];
}
// If the field is of type BIT, permit the use of single qoutes and also don't quote the default value.
// For example, use DEFAULT b'1' as opposed to DEFAULT 'b\'1\'' which results in an error.
- else if ([[theRow objectForKey:@"Type"] isEqualToString:@"bit"]) {
- [queryString appendFormat:@" DEFAULT %@ ", [theRow objectForKey:@"Default"]];
+ else if ([[[theRow objectForKey:@"type"] lowercaseString] isEqualToString:@"bit"]) {
+ [queryString appendFormat:@" DEFAULT %@ ", [theRow objectForKey:@"default"]];
}
// Otherwise, use the provided default
else {
- [queryString appendFormat:@" DEFAULT '%@' ", [mySQLConnection prepareString:[theRow objectForKey:@"Default"]]];
+ [queryString appendFormat:@" DEFAULT '%@' ", [mySQLConnection prepareString:[theRow objectForKey:@"default"]]];
}
}
-
+
if (!(
- [[theRow objectForKey:@"Extra"] isEqualToString:@""] ||
+ [[theRow objectForKey:@"Extra"] isEqualToString:@""] ||
[[theRow objectForKey:@"Extra"] isEqualToString:@"None"]
- ) &&
- [theRow objectForKey:@"Extra"] )
+ ) &&
+ [theRow objectForKey:@"Extra"] )
{
[queryString appendString:@" "];
[queryString appendString:[theRow objectForKey:@"Extra"]];
}
-
- if (!isEditingNewRow) {
- // Add details not provided via the SHOW COLUMNS query from the table data cache so column details aren't lost
- NSDictionary *originalColumnDetails = [[tableDataInstance columns] objectAtIndex:currentlyEditingRow];
+ if (!isEditingNewRow) {
// Any column comments
- if ([originalColumnDetails objectForKey:@"comment"] && [(NSString *)[originalColumnDetails objectForKey:@"comment"] length]) {
- [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[originalColumnDetails objectForKey:@"comment"]]];
+ if ([[theRow objectForKey:@"comment"] length]) {
+ [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[theRow objectForKey:@"comment"]]];
}
// Unparsed details - column formats, storage, reference definitions
- if ([originalColumnDetails objectForKey:@"unparsed"]) {
- [queryString appendString:[originalColumnDetails objectForKey:@"unparsed"]];
+ if ([[theRow objectForKey:@"unparsed"] length]) {
+ [queryString appendString:[theRow objectForKey:@"unparsed"]];
}
}
-
+
// Asks the user to add an index to query if auto_increment is set and field isn't indexed
- if ([[theRow objectForKey:@"Extra"] isEqualToString:@"auto_increment"] &&
- ([[theRow objectForKey:@"Key"] isEqualToString:@""] ||
- ![theRow objectForKey:@"Key"]))
+ if ([[theRow objectForKey:@"Extra"] isEqualToString:@"auto_increment"] &&
+ ([[theRow objectForKey:@"Key"] isEqualToString:@""] ||
+ ![theRow objectForKey:@"Key"]))
{
[chooseKeyButton selectItemAtIndex:0];
-
- [NSApp beginSheet:keySheet
- modalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self
- didEndSelector:nil
+
+ [NSApp beginSheet:keySheet
+ modalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self
+ didEndSelector:nil
contextInfo:nil];
-
+
code = [NSApp runModalForWindow:keySheet];
-
+
[NSApp endSheet:keySheet];
[keySheet orderOut:nil];
-
+
if (code) {
// User wants to add PRIMARY KEY
- if ([chooseKeyButton indexOfSelectedItem] == 0 ) {
+ if ([chooseKeyButton indexOfSelectedItem] == 0 ) {
[queryString appendString:@" PRIMARY KEY"];
-
+
// Add AFTER ... only if the user added a new field
if (isEditingNewRow) {
- [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"Field"] backtickQuotedString]];
+ [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"name"] backtickQuotedString]];
}
- }
+ }
else {
// Add AFTER ... only if the user added a new field
if (isEditingNewRow) {
- [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"Field"] backtickQuotedString]];
- }
-
- [queryString appendFormat:@", ADD %@ (%@)", [chooseKeyButton titleOfSelectedItem], [[theRow objectForKey:@"Field"] backtickQuotedString]];
+ [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"name"] backtickQuotedString]];
+ }
+
+ [queryString appendFormat:@", ADD %@ (%@)", [chooseKeyButton titleOfSelectedItem], [[theRow objectForKey:@"name"] backtickQuotedString]];
}
}
- }
+ }
// Add AFTER ... only if the user added a new field
else if (isEditingNewRow) {
- [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"Field"] backtickQuotedString]];
+ [queryString appendFormat:@" AFTER %@", [[[tableFields objectAtIndex:(currentlyEditingRow -1)] objectForKey:@"name"] backtickQuotedString]];
}
-
+
// Execute query
[mySQLConnection queryString:queryString];
@@ -867,7 +881,7 @@ closes the keySheet
isEditingRow = NO;
isEditingNewRow = NO;
currentlyEditingRow = -1;
-
+
[tableDataInstance resetAllData];
[tablesListInstance setStatusRequiresReload:YES];
[self loadTable:selectedTable];
@@ -879,14 +893,14 @@ closes the keySheet
[NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", selectedTable, @"affectedItem", [NSNumber numberWithInt:[tablesListInstance tableType]], @"affectedItemType", nil]];
return YES;
- }
+ }
else {
alertSheetOpened = YES;
if([mySQLConnection getLastErrorID] == 1146) { // If the current table doesn't exist anymore
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"),
- NSLocalizedString(@"OK", @"OK button"),
- nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to alter table '%@'.\n\nMySQL said: %@", @"error while trying to alter table message"),
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"),
+ NSLocalizedString(@"OK", @"OK button"),
+ nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to alter table '%@'.\n\nMySQL said: %@", @"error while trying to alter table message"),
selectedTable, [mySQLConnection getLastErrorMessage]]);
isEditingRow = NO;
@@ -907,20 +921,20 @@ closes the keySheet
}
// Problem: alert sheet doesn't respond to first click
if (isEditingNewRow) {
- SPBeginAlertSheet(NSLocalizedString(@"Error adding field", @"error adding field message"),
- NSLocalizedString(@"Edit row", @"Edit row button"),
- NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to add the field '%@'.\n\nMySQL said: %@", @"error adding field informative message"),
- [theRow objectForKey:@"Field"], [mySQLConnection getLastErrorMessage]]);
- }
+ SPBeginAlertSheet(NSLocalizedString(@"Error adding field", @"error adding field message"),
+ NSLocalizedString(@"Edit row", @"Edit row button"),
+ NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to add the field '%@'.\n\nMySQL said: %@", @"error adding field informative message"),
+ [theRow objectForKey:@"name"], [mySQLConnection getLastErrorMessage]]);
+ }
else {
- SPBeginAlertSheet(NSLocalizedString(@"Error changing field", @"error changing field message"),
- NSLocalizedString(@"Edit row", @"Edit row button"),
- NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the field '%@'.\n\nMySQL said: %@", @"error changing field informative message"),
- [theRow objectForKey:@"Field"], [mySQLConnection getLastErrorMessage]]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error changing field", @"error changing field message"),
+ NSLocalizedString(@"Edit row", @"Edit row button"),
+ NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the field '%@'.\n\nMySQL said: %@", @"error changing field informative message"),
+ [theRow objectForKey:@"name"], [mySQLConnection getLastErrorMessage]]);
}
-
+
return NO;
}
}
@@ -950,7 +964,7 @@ closes the keySheet
[tableFields replaceObjectAtIndex:currentlyEditingRow
withObject:[NSMutableDictionary dictionaryWithDictionary:oldRow]];
isEditingRow = NO;
- }
+ }
else {
[tableFields removeObjectAtIndex:currentlyEditingRow];
isEditingRow = NO;
@@ -965,7 +979,7 @@ closes the keySheet
/**
* 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
+ * be called from within an endSheet selector. This should be called on
* the main thread.
*/
-(void)showErrorSheetWith:(NSDictionary *)errorDictionary
@@ -979,9 +993,9 @@ closes the keySheet
[self performSelector:@selector(showErrorSheetWith:) withObject:delayedErrorDictionary afterDelay:0.3];
return;
}
-
+
// Display the error sheet
- SPBeginAlertSheet([errorDictionary objectForKey:@"title"], NSLocalizedString(@"OK", @"OK button"),
+ SPBeginAlertSheet([errorDictionary objectForKey:@"title"], NSLocalizedString(@"OK", @"OK button"),
nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
[errorDictionary objectForKey:@"message"]);
}
@@ -990,21 +1004,21 @@ closes the keySheet
* 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];
-
+
for (NSTableColumn *fieldColumn in [tableSourceView tableColumns])
{
[[fieldColumn dataCell] setFont:(useMonospacedFont) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
}
-
+
[tableSourceView reloadData];
}
}
@@ -1018,17 +1032,17 @@ closes the keySheet
if ([menuItem action] == @selector(removeField:)) {
return (([tableSourceView numberOfSelectedRows] == 1) && ([tableSourceView numberOfRows] > 1));
}
-
+
// Duplicate field
if ([menuItem action] == @selector(copyField:)) {
return ([tableSourceView numberOfSelectedRows] == 1);
}
-
+
// Reset AUTO_INCREMENT
if ([menuItem action] == @selector(resetAutoIncrement:)) {
return [indexesController validateMenuItem:menuItem];
}
-
+
return YES;
}
@@ -1059,7 +1073,7 @@ get the default value for a specified field
- (NSString *)defaultValueForField:(NSString *)field
{
if ( ![defaultValues objectForKey:field] ) {
- return [prefs objectForKey:SPNullValue];
+ return [prefs objectForKey:SPNullValue];
} else if ( [[defaultValues objectForKey:field] isMemberOfClass:[NSNull class]] ) {
return [prefs objectForKey:SPNullValue];
} else {
@@ -1075,18 +1089,18 @@ returns an array containing the field names of the selected table
NSMutableArray *tempArray = [NSMutableArray array];
NSEnumerator *enumerator;
id field;
-
+
//load table if not already done
if ( ![tablesListInstance structureLoaded] ) {
[self loadTable:[tablesListInstance tableName]];
}
-
+
//get field names
enumerator = [tableFields objectEnumerator];
while ( (field = [enumerator nextObject]) ) {
- [tempArray addObject:[field objectForKey:@"Field"]];
+ [tempArray addObject:[field objectForKey:@"name"]];
}
-
+
return [NSArray arrayWithArray:tempArray];
}
@@ -1100,42 +1114,42 @@ returns a dictionary containing enum/set field names as key and possible values
/**
* Returns a dictionary describing the source of the table to be used for printing purposes. The object accessible
- * via the key 'structure' is an array of the tables fields, where the first element is always the field names
+ * via the key 'structure' is an array of the tables fields, where the first element is always the field names
* and each subsequent element is the field data. This is also true for the table's indexes, which are accessible
* via the key 'indexes'.
*/
- (NSDictionary *)tableSourceForPrinting
-{
+{
NSInteger i, j;
NSMutableArray *tempResult = [NSMutableArray array];
NSMutableArray *tempResult2 = [NSMutableArray array];
-
+
NSString *nullValue = [prefs stringForKey:SPNullValue];
CFStringRef escapedNullValue = CFXMLCreateStringByEscapingEntities(NULL, ((CFStringRef)nullValue), NULL);
-
+
MCPResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
MCPResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]];
-
+
[structureQueryResult setReturnDataAsStrings:YES];
[indexesQueryResult setReturnDataAsStrings:YES];
-
+
if ([structureQueryResult numOfRows]) [structureQueryResult dataSeek:0];
if ([indexesQueryResult numOfRows]) [indexesQueryResult dataSeek:0];
-
+
[tempResult addObject:[structureQueryResult fetchFieldNames]];
-
+
NSMutableArray *temp = [[indexesQueryResult fetchFieldNames] mutableCopy];
-
+
// Remove the 'table' column
[temp removeObjectAtIndex:0];
-
+
[tempResult2 addObject:temp];
-
+
[temp release];
-
+
for (i = 0; i < [structureQueryResult numOfRows]; i++) {
NSMutableArray *row = [[structureQueryResult fetchRowAsArray] mutableCopy];
-
+
// For every NULL value replace it with the user's NULL value placeholder so we can actually print it
for (j = 0; j < [row count]; j++)
{
@@ -1143,18 +1157,18 @@ returns a dictionary containing enum/set field names as key and possible values
[row replaceObjectAtIndex:j withObject:(NSString *)escapedNullValue];
}
}
-
+
[tempResult addObject:row];
-
+
[row release];
}
for (i = 0; i < [indexesQueryResult numOfRows]; i++) {
NSMutableArray *index = [[indexesQueryResult fetchRowAsArray] mutableCopy];
-
+
// Remove the 'table' column values
[index removeObjectAtIndex:0];
-
+
// For every NULL value replace it with the user's NULL value placeholder so we can actually print it
for (j = 0; j < [index count]; j++)
{
@@ -1162,9 +1176,9 @@ returns a dictionary containing enum/set field names as key and possible values
[index replaceObjectAtIndex:j withObject:(NSString *)escapedNullValue];
}
}
-
+
[tempResult2 addObject:index];
-
+
[index release];
}
@@ -1189,7 +1203,7 @@ returns a dictionary containing enum/set field names as key and possible values
[copyFieldButton setEnabled:NO];
[reloadFieldsButton setEnabled:NO];
[editTableButton setEnabled:NO];
-
+
[indexesTableView setEnabled:NO];
[addIndexButton setEnabled:NO];
[removeIndexButton setEnabled:NO];
@@ -1205,22 +1219,22 @@ returns a dictionary containing enum/set field names as key and possible values
if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure]) return;
BOOL editingEnabled = ([tablesListInstance tableType] == SPTableTypeTable);
-
+
[tableSourceView setEnabled:YES];
[tableSourceView displayIfNeeded];
[addFieldButton setEnabled:editingEnabled];
-
+
if (editingEnabled && [tableSourceView numberOfSelectedRows] > 0) {
[removeFieldButton setEnabled:YES];
[copyFieldButton setEnabled:YES];
}
-
+
[reloadFieldsButton setEnabled:YES];
[editTableButton setEnabled:YES];
-
+
[indexesTableView setEnabled:YES];
[indexesTableView displayIfNeeded];
-
+
[addIndexButton setEnabled:editingEnabled];
[removeIndexButton setEnabled:(editingEnabled && ([indexesTableView numberOfSelectedRows] > 0))];
[refreshIndexesButton setEnabled:YES];
@@ -1235,10 +1249,34 @@ returns a dictionary containing enum/set field names as key and possible values
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
-{
+{
// Return a placeholder if the table is reloading
if (rowIndex >= [tableFields count]) return @"...";
+ if([[tableColumn identifier] isEqualToString:@"collation"]) {
+ if([[[tableFields objectAtIndex:rowIndex] objectForKey:@"encoding"] integerValue] > 0) {
+ NSString *enc = [[[[[tableSourceView tableColumns] objectAtIndex:10] dataCell] itemAtIndex:[[[tableFields objectAtIndex:rowIndex] objectForKey:@"encoding"] integerValue]] title];
+ NSInteger start = [enc rangeOfString:@"("].location+1;
+ NSInteger end = [enc length] - start - 1;
+ collations = [databaseDataInstance getDatabaseCollationsForEncoding:[enc substringWithRange:NSMakeRange(start, end)]];
+ } else {
+ if([tableDataInstance tableEncoding]) {
+ collations = [databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]];
+ } else {
+ collations = [NSArray array];
+ }
+ }
+
+ [[tableColumn dataCell] removeAllItems];
+
+ if ([collations count] > 0) {
+ [[tableColumn dataCell] addItemWithTitle:@""];
+ // Populate collation popup button
+ for (NSDictionary *collation in collations)
+ [[tableColumn dataCell] addItemWithTitle:[collation objectForKey:@"COLLATION_NAME"]];
+ }
+ }
+
return [[tableFields objectAtIndex:rowIndex] objectForKey:[tableColumn identifier]];
}
@@ -1252,7 +1290,7 @@ returns a dictionary containing enum/set field names as key and possible values
isEditingRow = YES;
currentlyEditingRow = rowIndex;
}
-
+
[[tableFields objectAtIndex:rowIndex] setObject:(anObject) ? anObject : @"" forKey:[aTableColumn identifier]];
}
@@ -1305,11 +1343,11 @@ would result in a position change.
// Ensure the drop is of the correct type
if (operation == NSTableViewDropAbove && row != -1 && [pboardTypes containsObject:@"SequelProPasteboard"]) {
-
+
// Ensure the drag originated within this table
if ([info draggingSource] == tableView) {
originalRow = [[[info draggingPasteboard] stringForType:@"SequelProPasteboard"] integerValue];
-
+
if (row != originalRow && row != (originalRow+1)) {
return NSDragOperationMove;
}
@@ -1339,58 +1377,55 @@ would result in a position change.
// Begin construction of the reordering query
queryString = [NSMutableString stringWithFormat:@"ALTER TABLE %@ MODIFY COLUMN %@ %@", [selectedTable backtickQuotedString],
- [[originalRow objectForKey:@"Field"] backtickQuotedString],
- [originalRow objectForKey:@"Type"]];
+ [[originalRow objectForKey:@"name"] backtickQuotedString],
+ [[originalRow objectForKey:@"type"] uppercaseString]];
// Add the length parameter if necessary
- if ( [originalRow objectForKey:@"Length"] && ![[originalRow objectForKey:@"Length"] isEqualToString:@""]) {
- [queryString appendFormat:@"(%@)", [originalRow objectForKey:@"Length"]];
+ if ( [originalRow objectForKey:@"length"] && ![[originalRow objectForKey:@"length"] isEqualToString:@""]) {
+ [queryString appendFormat:@"(%@)", [originalRow objectForKey:@"length"]];
}
// Add unsigned, zerofill, binary, not null if necessary
- if ([[originalRow objectForKey:@"unsigned"] isEqualToString:@"1"]) {
+ if ([[originalRow objectForKey:@"unsigned"] integerValue]) {
[queryString appendString:@" UNSIGNED"];
}
- if ([[originalRow objectForKey:@"zerofill"] isEqualToString:@"1"]) {
+ if ([[originalRow objectForKey:@"zerofill"] integerValue]) {
[queryString appendString:@" ZEROFILL"];
}
- if ([[originalRow objectForKey:@"binary"] isEqualToString:@"1"]) {
+ if ([[originalRow objectForKey:@"binary"] integerValue]) {
[queryString appendString:@" BINARY"];
}
- if ([[originalRow objectForKey:@"Null"] isEqualToString:@"0"] ) {
+ if (![[originalRow objectForKey:@"null"] integerValue]) {
[queryString appendString:@" NOT NULL"];
}
if (![[originalRow objectForKey:@"Extra"] isEqualToString:@"None"] ) {
[queryString appendString:@" "];
[queryString appendString:[[originalRow objectForKey:@"Extra"] uppercaseString]];
}
-
- BOOL isTimestampType = [[originalRow objectForKey:@"Type"] isEqualToString:@"timestamp"];
+
+ BOOL isTimestampType = [[[originalRow objectForKey:@"type"] lowercaseString] isEqualToString:@"timestamp"];
// Add the default value
- if ([[originalRow objectForKey:@"Default"] isEqualToString:[prefs objectForKey:SPNullValue]]) {
- if ([[originalRow objectForKey:@"Null"] integerValue] == 1) {
+ if ([[originalRow objectForKey:@"default"] isEqualToString:[prefs objectForKey:SPNullValue]]) {
+ if ([[originalRow objectForKey:@"null"] integerValue] == 1) {
[queryString appendString:(isTimestampType) ? @" NULL DEFAULT NULL" : @" DEFAULT NULL"];
}
- }
- else if (isTimestampType && ([[[originalRow objectForKey:@"Default"] uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"]) ) {
+ }
+ else if (isTimestampType && ([[[originalRow objectForKey:@"default"] uppercaseString] isEqualToString:@"CURRENT_TIMESTAMP"]) ) {
[queryString appendString:@" DEFAULT CURRENT_TIMESTAMP"];
- }
+ }
else {
- [queryString appendFormat:@" DEFAULT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"Default"]]];
+ [queryString appendFormat:@" DEFAULT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"default"]]];
}
- // Add details not provided via the SHOW COLUMNS query from the table data cache so column details aren't lost
- NSDictionary *originalColumnDetails = [[tableDataInstance columns] objectAtIndex:originalRowIndex];
-
// Any column comments
- if ([originalColumnDetails objectForKey:@"comment"] && [(NSString *)[originalColumnDetails objectForKey:@"comment"] length]) {
- [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[originalColumnDetails objectForKey:@"comment"]]];
+ if ([[originalRow objectForKey:@"comment"] length]) {
+ [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"comment"]]];
}
// Unparsed details - column formats, storage, reference definitions
- if ([originalColumnDetails objectForKey:@"unparsed"]) {
- [queryString appendString:[originalColumnDetails objectForKey:@"unparsed"]];
+ if ([originalRow objectForKey:@"unparsed"]) {
+ [queryString appendString:[originalRow objectForKey:@"unparsed"]];
}
// Add the new location
@@ -1398,12 +1433,12 @@ would result in a position change.
[queryString appendString:@" FIRST"];
} else {
[queryString appendFormat:@" AFTER %@",
- [[[tableFields objectAtIndex:destinationRowIndex-1] objectForKey:@"Field"] backtickQuotedString]];
+ [[[tableFields objectAtIndex:destinationRowIndex-1] objectForKey:@"name"] backtickQuotedString]];
}
// Run the query; report any errors, or reload the table on success
[mySQLConnection queryString:queryString];
-
+
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error moving field", @"error moving field message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to move the field.\n\nMySQL said: %@", @"error moving field informative message"), [mySQLConnection getLastErrorMessage]]);
@@ -1423,7 +1458,7 @@ would result in a position change.
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-
+
[originalRow release];
return YES;
}
@@ -1437,13 +1472,13 @@ would result in a position change.
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
id object = [aNotification object];
-
+
// Check for which table view the selection changed
if (object == tableSourceView) {
-
+
// If we are editing a row, attempt to save that row - if saving failed, reselect the edit row.
if (isEditingRow && [tableSourceView selectedRow] != currentlyEditingRow && ![self saveRowOnDeselect]) return;
-
+
[copyFieldButton setEnabled:YES];
// Check if there is currently a field selected and change button state accordingly
@@ -1453,7 +1488,7 @@ would result in a position change.
[removeFieldButton setEnabled:NO];
[copyFieldButton setEnabled:NO];
}
-
+
// If the table only has one field, disable the remove button. This removes the need to check that the user
// is attempting to remove the last field in a table in removeField: above, but leave it in just in case.
if ([tableSourceView numberOfRows] == 1) {
@@ -1495,7 +1530,7 @@ would result in a position change.
}
}
return TRUE;
-
+
// Trap the enter key, triggering a save
}
else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertNewline:)] )
@@ -1503,7 +1538,7 @@ would result in a position change.
[[control window] makeFirstResponder:control];
[self addRowToDB];
return TRUE;
-
+
// Trap escape, aborting the edit and reverting the row
}
else if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(_cancelKey:)] ||
@@ -1532,7 +1567,7 @@ would result in a position change.
* is uneditable.
*/
- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
-
+
//make sure that the message is from the right table view
if (tableView!=tableSourceView) return;
@@ -1558,7 +1593,7 @@ would result in a position change.
}
- (NSRect)splitView:(NSSplitView *)splitView additionalEffectiveRectOfDividerAtIndex:(NSInteger)dividerIndex
-{
+{
return [structureGrabber convertRect:[structureGrabber bounds] toView:splitView];
}
@@ -1569,7 +1604,7 @@ would result in a position change.
if ([tablesIndexesSplitView isSubviewCollapsed:indexesView]) {
[indexesShowButton setHidden:NO];
} else {
- [indexesShowButton setHidden:YES];
+ [indexesShowButton setHidden:YES];
}
}
}
@@ -1583,18 +1618,18 @@ would result in a position change.
#pragma mark Private API methods
/**
- * Removes a field from the current table and the dependent foreign key if specified.
+ * Removes a field from the current table and the dependent foreign key if specified.
*/
- (void)_removeFieldAndForeignKey:(NSNumber *)removeForeignKey
-{
+{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// Remove the foreign key before the field if required
if ([removeForeignKey boolValue]) {
-
+
NSString *relationName = @"";
- NSString *field = [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"Field"];
-
+ NSString *field = [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"];
+
// Get the foreign key name
for (NSDictionary *constraint in [tableDataInstance getConstraints])
{
@@ -1606,42 +1641,42 @@ would result in a position change.
}
}
}
-
+
[mySQLConnection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [selectedTable backtickQuotedString], [relationName backtickQuotedString]]];
-
+
// Check for errors, but only if the query wasn't cancelled
if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"];
[errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), relationName, [mySQLConnection getLastErrorMessage]] forKey:@"message"];
[[self onMainThread] showErrorSheetWith:errorDictionary];
- }
+ }
}
-
+
// Remove field
[mySQLConnection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP %@",
- [selectedTable backtickQuotedString], [[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"Field"] backtickQuotedString]]];
-
+ [selectedTable backtickQuotedString], [[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"] backtickQuotedString]]];
+
// Check for errors, but only if the query wasn't cancelled
if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Error", @"error") forKey:@"title"];
[errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete field %@.\nMySQL said: %@", @"message of panel when field cannot be deleted"),
- [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"Field"],
+ [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"],
[mySQLConnection getLastErrorMessage]] forKey:@"message"];
[[self onMainThread] showErrorSheetWith:errorDictionary];
- }
+ }
else {
[tableDataInstance resetAllData];
[tablesListInstance setStatusRequiresReload:YES];
[self loadTable:selectedTable];
-
+
// Mark the content table cache for refresh
[tablesListInstance setContentRequiresReload:YES];
}
-
+
[tableDocumentInstance endTask];
-
+
[pool drain];
}
@@ -1651,16 +1686,16 @@ would result in a position change.
* Dealloc.
*/
- (void)dealloc
-{
+{
[[NSNotificationCenter defaultCenter] removeObserver:self];
-
+
[tableFields release];
[oldRow release];
[enumFields release];
-
+
if (defaultValues) [defaultValues release];
if (selectedTable) [selectedTable release];
-
+
[super dealloc];
}