diff options
author | stuconnolly <stuart02@gmail.com> | 2009-05-27 13:30:34 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2009-05-27 13:30:34 +0000 |
commit | 4cb9f0b6ab99875d487ae9c2c438595978222a3e (patch) | |
tree | be63b305825ba346a73f5bb267bd7113150b61a2 /Source | |
parent | de6f4edd315c319bd7fbc37907176d665aa454dc (diff) | |
download | sequelpro-4cb9f0b6ab99875d487ae9c2c438595978222a3e.tar.gz sequelpro-4cb9f0b6ab99875d487ae9c2c438595978222a3e.tar.bz2 sequelpro-4cb9f0b6ab99875d487ae9c2c438595978222a3e.zip |
Redesigned table information pane.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/MainController.m | 12 | ||||
-rw-r--r-- | Source/SPDatabaseData.h | 51 | ||||
-rw-r--r-- | Source/SPDatabaseData.m | 176 | ||||
-rw-r--r-- | Source/SPExtendedTableInfo.h | 69 | ||||
-rw-r--r-- | Source/SPExtendedTableInfo.m | 358 | ||||
-rw-r--r-- | Source/SPPreferenceController.h | 2 | ||||
-rw-r--r-- | Source/SPPreferenceController.m | 2 | ||||
-rw-r--r-- | Source/SPTableData.h | 9 | ||||
-rw-r--r-- | Source/SPTableData.m | 32 | ||||
-rw-r--r-- | Source/TableDocument.h | 3 | ||||
-rw-r--r-- | Source/TableDocument.m | 18 | ||||
-rw-r--r-- | Source/TableSource.m | 5 | ||||
-rw-r--r-- | Source/TableStatus.h | 63 | ||||
-rw-r--r-- | Source/TableStatus.m | 152 | ||||
-rw-r--r-- | Source/TablesList.h | 2 | ||||
-rw-r--r-- | Source/TablesList.m | 12 |
16 files changed, 729 insertions, 237 deletions
diff --git a/Source/MainController.m b/Source/MainController.m index 283ee032..d446444a 100644 --- a/Source/MainController.m +++ b/Source/MainController.m @@ -23,8 +23,8 @@ // // More info at <http://code.google.com/p/sequel-pro/> -#import "MainController.h" #import "KeyChain.h" +#import "MainController.h" #import "TableDocument.h" #import "SPPreferenceController.h" @@ -176,4 +176,14 @@ return nil; } +/** + * Deallocate prefs controller + */ +- (void)dealloc +{ + [prefsController release], prefsController = nil; + + [super dealloc]; +} + @end diff --git a/Source/SPDatabaseData.h b/Source/SPDatabaseData.h new file mode 100644 index 00000000..3f84705a --- /dev/null +++ b/Source/SPDatabaseData.h @@ -0,0 +1,51 @@ +// +// $Id$ +// +// SPDatabaseData.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on May 20, 2009 +// Copyright (c) 2009 Stuart Connolly. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> + +@class CMMCPConnection; + +@interface SPDatabaseData : NSObject +{ + NSString *characterSetEncoding; + + NSMutableArray *collations; + NSMutableArray *characterSetCollations; + NSMutableArray *storageEngines; + NSMutableArray *characterSetEncodings; + + CMMCPConnection *connection; +} + +@property (readwrite, assign) CMMCPConnection *connection; + +- (void)resetAllData; + +- (NSArray *)getDatabaseCollations; +- (NSArray *)getDatabaseCollationsForEncoding:(NSString *)encoding; +- (NSArray *)getDatabaseStorageEngines; +- (NSArray *)getDatabaseCharacterSetEncodings; + +@end diff --git a/Source/SPDatabaseData.m b/Source/SPDatabaseData.m new file mode 100644 index 00000000..24a0f204 --- /dev/null +++ b/Source/SPDatabaseData.m @@ -0,0 +1,176 @@ +// +// $Id$ +// +// SPDatabaseData.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on May 20, 2009 +// Copyright (c) 2009 Stuart Connolly. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPDatabaseData.h" +#import "CMMCPConnection.h" +#import "CMMCPResult.h" +#import "SPStringAdditions.h" + +@interface SPDatabaseData (PrivateAPI) + +- (NSArray *)_getDatabaseDataForQuery:(NSString *)query; + +@end + +@implementation SPDatabaseData + +@synthesize connection; + +/** + * Initialize cache arrays. + */ +- (id)init +{ + if ((self = [super init])) { + characterSetEncoding = nil; + + collations = [[NSMutableArray alloc] init]; + characterSetCollations = [[NSMutableArray alloc] init]; + storageEngines = [[NSMutableArray alloc] init]; + characterSetEncodings = [[NSMutableArray alloc] init]; + } + + return self; +} + +/** + * Reset all the cached values. + */ +- (void)resetAllData +{ + if (characterSetEncoding != nil) { + [characterSetEncoding release]; + } + + [collations removeAllObjects]; + [characterSetCollations removeAllObjects]; + [storageEngines removeAllObjects]; + [characterSetEncodings removeAllObjects]; +} + +/** + * Returns all of the database's currently available collations by querying information_schema.collations. + */ +- (NSArray *)getDatabaseCollations +{ + if ([collations count] == 0) { + [collations addObjectsFromArray:[self _getDatabaseDataForQuery:@"SELECT * FROM information_schema.collations ORDER BY collation_name ASC"]]; + } + + return collations; +} + +/** + * Returns all of the database's currently available collations allowed for the supplied encoding by + * querying information_schema.collations. + */ +- (NSArray *)getDatabaseCollationsForEncoding:(NSString *)encoding +{ + if ((characterSetEncoding == nil) || (![characterSetEncoding isEqualToString:encoding]) || ([characterSetCollations count] == 0)) { + + [characterSetEncoding release]; + [characterSetCollations removeAllObjects]; + + characterSetEncoding = [[NSString alloc] initWithString:encoding]; + + [characterSetCollations addObjectsFromArray:[self _getDatabaseDataForQuery:[NSString stringWithFormat:@"SELECT * FROM information_schema.collations WHERE character_set_name = '%@' ORDER BY collation_name ASC", characterSetEncoding]]]; + } + + return characterSetCollations; +} + +/** + * Returns all of the database's currently availale storage engines by querying information_schema.engines. + */ +- (NSArray *)getDatabaseStorageEngines +{ + if ([storageEngines count] == 0) { + [storageEngines addObjectsFromArray:[self _getDatabaseDataForQuery:@"SELECT * FROM information_schema.engines"]]; + } + + return storageEngines; +} + +/** + * Returns all of the database's currently available character set encodings by querying + * information_schema.character_sets. + */ +- (NSArray *)getDatabaseCharacterSetEncodings +{ + if ([characterSetEncodings count] == 0) { + [characterSetEncodings addObjectsFromArray:[self _getDatabaseDataForQuery:@"SELECT * FROM information_schema.character_sets ORDER BY character_set_name ASC"]]; + } + + return characterSetEncodings; +} + +/** + * Deallocate ivars. + */ +- (void)dealloc +{ + if (characterSetEncoding != nil) { + [characterSetEncoding release], characterSetEncoding = nil; + } + + [collations release], collations = nil; + [characterSetCollations release], characterSetCollations = nil; + [storageEngines release], storageEngines = nil; + [characterSetEncodings release], characterSetEncodings = nil; + + [super dealloc]; +} + +@end + +@implementation SPDatabaseData (PrivateAPI) + +/** + * Executes the supplied query against the current connection and returns the result as an array of + * NSDictionarys, one for each row. + */ +- (NSArray *)_getDatabaseDataForQuery:(NSString *)query +{ + NSMutableArray *array = [NSMutableArray array]; + + CMMCPResult *result = [connection queryString:query]; + + // Log any errors + if (![[connection getLastErrorMessage] isEqualToString:@""]) { + NSLog(@""); + } + else { + [result dataSeek:0]; + + for (int i = 0; i < [result numOfRows]; i++) + { + [array addObject:[result fetchRowAsDictionary]]; + } + } + + return array; +} + +@end diff --git a/Source/SPExtendedTableInfo.h b/Source/SPExtendedTableInfo.h new file mode 100644 index 00000000..8cdea5e4 --- /dev/null +++ b/Source/SPExtendedTableInfo.h @@ -0,0 +1,69 @@ +// +// $Id$ +// +// SPExtendedTableInfo.h +// sequel-pro +// +// Created by Jason Hallford (jason.hallford@byu.edu) on Th July 08 2004. +// sequel-pro Copyright (c) 2002-2003 Lorenz Textor. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <Cocoa/Cocoa.h> + +@class SPTableData, SPDatabaseData, CMMCPConnection; + +@interface SPExtendedTableInfo : NSObject +{ + IBOutlet SPTableData *tableDataInstance; + IBOutlet SPDatabaseData *databaseDataInstance; + + IBOutlet NSTextField *tableRowNumber; + IBOutlet NSTextField *tableRowFormat; + IBOutlet NSTextField *tableRowAvgLength; + IBOutlet NSTextField *tableRowAutoIncrement; + IBOutlet NSTextField *tableDataSize; + IBOutlet NSTextField *tableSizeFree; + IBOutlet NSTextField *tableIndexSize; + IBOutlet NSTextField *tableMaxDataSize; + IBOutlet NSTextField *tableCreatedAt; + IBOutlet NSTextField *tableUpdatedAt; + + IBOutlet NSTextView *tableCommentsTextView; + IBOutlet NSTextView *tableCreateSyntaxTextView; + + IBOutlet NSPopUpButton *tableTypePopUpButton; + IBOutlet NSPopUpButton *tableEncodingPopUpButton; + IBOutlet NSPopUpButton *tableCollationPopUpButton; + + NSString *selectedTable; + + CMMCPConnection *connection; +} + +@property (readwrite, assign) CMMCPConnection *connection; + +// IBAction methods +- (IBAction)reloadTable:(id)sender; +- (IBAction)updateTableType:(id)sender; +- (IBAction)updateTableEncoding:(id)sender; +- (IBAction)updateTableCollation:(id)sender; + +// Others +- (void)loadTable:(NSString *)table; + +@end diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m new file mode 100644 index 00000000..659f4ae6 --- /dev/null +++ b/Source/SPExtendedTableInfo.m @@ -0,0 +1,358 @@ +// +// $Id$ +// +// SPExtendedTableInfo.m +// sequel-pro +// +// Created by Jason Hallford (jason.hallford@byu.edu) on Th July 08 2004. +// sequel-pro Copyright (c) 2002-2003 Lorenz Textor. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPExtendedTableInfo.h" +#import "SPTableData.h" +#import "RegexKitLite.h" +#import "SPDatabaseData.h" +#import "CMMCPConnection.h" +#import "SPStringAdditions.h" + +@interface SPExtendedTableInfo (PrivateAPI) + +- (NSString *)_formatValueWithKey:(NSString *)key inDictionary:(NSDictionary *)statusDict withLabel:(NSString *)label; + +@end + +@implementation SPExtendedTableInfo + +@synthesize connection; + +/** + * Set the create table syntax textview's font. + */ +- (void)awakeFromNib +{ + [tableCreateSyntaxTextView setFont:[NSUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] dataForKey:@"CustomQueryEditorFont"]]]; +} + +#pragma mark - +#pragma mark IBAction methods + +/** + * Reloads the info for the currently selected table. + */ +- (IBAction)reloadTable:(id)sender +{ + // Reset the table data's cache + [tableDataInstance resetAllData]; + + // Load the new table info + [self loadTable:selectedTable]; +} + +/** + * Update the table type (storage engine) of the currently selected table. + */ +- (IBAction)updateTableType:(id)sender +{ + NSString *newType = [sender titleOfSelectedItem]; + NSString *currentType = [tableDataInstance statusValueForKey:@"Engine"]; + + // Check if the user selected the same type + if ([currentType isEqualToString:newType]) { + return; + } + + // Alter table's storage type + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ TYPE = %@", [selectedTable backtickQuotedString], newType]]; + + if ([connection getLastErrorID] == 0) { + // Reload the table's data + [self reloadTable:self]; + } + else { + [sender selectItemWithTitle:currentType]; + + NSBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table type to '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), newType, [connection getLastErrorMessage]]); + } +} + +/** + * Update the character set encoding of the currently selected table. + */ +- (IBAction)updateTableEncoding:(id)sender +{ + NSString *currentEncoding = [tableDataInstance tableEncoding]; + NSString *newEncoding = [[sender titleOfSelectedItem] stringByMatching:@"^.+\\((.+)\\)$" capture:1L]; + + // Check if the user selected the same encoding + if ([currentEncoding isEqualToString:newEncoding]) { + return; + } + + // Alter table's character set encoding + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ CHARACTER SET = %@", [selectedTable backtickQuotedString], newEncoding]]; + + if ([connection getLastErrorID] == 0) { + // Reload the table's data + [self reloadTable:self]; + } + else { + [sender selectItemWithTitle:currentEncoding]; + + NSBeginAlertSheet(NSLocalizedString(@"Error changing table encoding", @"error changing table encoding message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table encoding to '%@'.\n\nMySQL said: %@", @"error changing table encoding informative message"), newEncoding, [connection getLastErrorMessage]]); + } +} + +/** + * Update the character set collation of the currently selected table. + */ +- (IBAction)updateTableCollation:(id)sender +{ + NSString *newCollation = [sender titleOfSelectedItem]; + NSString *currentCollation = [tableDataInstance statusValueForKey:@"Collation"]; + + // Check if the user selected the same collation + if ([currentCollation isEqualToString:newCollation]) { + return; + } + + // Alter table's character set collation + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COLLATE = %@", [selectedTable backtickQuotedString], newCollation]]; + + if ([connection getLastErrorID] == 0) { + // Reload the table's data + [self reloadTable:self]; + } + else { + [sender selectItemWithTitle:currentCollation]; + + NSBeginAlertSheet(NSLocalizedString(@"Error changing table collation", @"error changing table collation message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table collation to '%@'.\n\nMySQL said: %@", @"error changing table collation informative message"), newCollation, [connection getLastErrorMessage]]); + } +} + +#pragma mark - +#pragma mark Other + +/** + * Load all the info for the supplied table by querying the table data instance and updaing the interface + * elements accordingly. + */ +- (void)loadTable:(NSString *)table +{ + // Store the table name away for future use + selectedTable = table; + + // Retrieve the table status information via the table data cache + NSDictionary *statusFields = [tableDataInstance statusValues]; + + [tableTypePopUpButton removeAllItems]; + [tableEncodingPopUpButton removeAllItems]; + [tableCollationPopUpButton removeAllItems]; + + // No table selected or view selected + if ([table isEqualToString:@""] || (!table) || [[statusFields objectForKey:@"Engine"] isEqualToString:@"View"]) { + + [tableTypePopUpButton setEnabled:NO]; + [tableEncodingPopUpButton setEnabled:NO]; + [tableCollationPopUpButton setEnabled:NO]; + + if ([[statusFields objectForKey:@"Engine"] isEqualToString:@"View"]) { + [tableTypePopUpButton addItemWithTitle:@"View"]; + } + + [tableCreatedAt setStringValue:@"Created at: "]; + [tableUpdatedAt setStringValue:@"Updated at: "]; + + // Set row values + [tableRowNumber setStringValue:@"Number of rows: "]; + [tableRowFormat setStringValue:@"Row format: "]; + [tableRowAvgLength setStringValue:@"Avg. row length: "]; + [tableRowAutoIncrement setStringValue:@"Auto increment: "]; + + // Set size values + [tableDataSize setStringValue:@"Data size: "]; + [tableMaxDataSize setStringValue:@"Max data size: "]; + [tableIndexSize setStringValue:@"Index size: "]; + [tableSizeFree setStringValue:@"Free data size: "]; + + // Set comments + [tableCommentsTextView setString:@""]; + + // Set create syntax + [tableCreateSyntaxTextView setString:@""]; + + return; + } + + NSArray *engines = [databaseDataInstance getDatabaseStorageEngines]; + NSArray *encodings = [databaseDataInstance getDatabaseCharacterSetEncodings]; + NSArray *collations = [databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]]; + + if ([engines count] > 0) { + // Populate type popup button + for (NSDictionary *engine in engines) + { + [tableTypePopUpButton addItemWithTitle:[engine objectForKey:@"ENGINE"]]; + } + + [tableTypePopUpButton selectItemWithTitle:[statusFields objectForKey:@"Engine"]]; + [tableTypePopUpButton setEnabled:YES]; + } + + if ([encodings count] > 0) { + NSString *selectedTitle = @""; + + // Populate encoding popup button + for (NSDictionary *encoding in encodings) + { + NSString *menuItemTitle = [NSString stringWithFormat:@"%@ (%@)", [encoding objectForKey:@"DESCRIPTION"], [encoding objectForKey:@"CHARACTER_SET_NAME"]]; + + [tableEncodingPopUpButton addItemWithTitle:menuItemTitle]; + + if ([[tableDataInstance tableEncoding] isEqualToString:[encoding objectForKey:@"CHARACTER_SET_NAME"]]) { + selectedTitle = menuItemTitle; + } + } + + [tableEncodingPopUpButton selectItemWithTitle:selectedTitle]; + [tableEncodingPopUpButton setEnabled:YES]; + } + + if ([collations count] > 0) { + // Populate collation popup button + for (NSDictionary *collation in collations) + { + [tableCollationPopUpButton addItemWithTitle:[collation objectForKey:@"COLLATION_NAME"]]; + } + + [tableCollationPopUpButton selectItemWithTitle:[statusFields objectForKey:@"Collation"]]; + [tableCollationPopUpButton setEnabled:YES]; + } + + [tableCreatedAt setStringValue:[self _formatValueWithKey:@"Create_time" inDictionary:statusFields withLabel:@"Created at"]]; + [tableUpdatedAt setStringValue:[self _formatValueWithKey:@"Update_time" inDictionary:statusFields withLabel:@"Updated at"]]; + + // Set row values + [tableRowNumber setStringValue:[self _formatValueWithKey:@"Rows" inDictionary:statusFields withLabel:@"Number of rows"]]; + [tableRowFormat setStringValue:[self _formatValueWithKey:@"Row_format" inDictionary:statusFields withLabel:@"Row format"]]; + [tableRowAvgLength setStringValue:[self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields withLabel:@"Avg. row length"]]; + [tableRowAutoIncrement setStringValue:[self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields withLabel:@"Auto increment"]]; + + // Set size values + [tableDataSize setStringValue:[self _formatValueWithKey:@"Data_length" inDictionary:statusFields withLabel:@"Data size"]]; + [tableMaxDataSize setStringValue:[self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields withLabel:@"Max data size"]]; + [tableIndexSize setStringValue:[self _formatValueWithKey:@"Index_length" inDictionary:statusFields withLabel:@"Index size"]]; + [tableSizeFree setStringValue:[self _formatValueWithKey:@"Data_free" inDictionary:statusFields withLabel:@"Free data size"]]; + + // Set comments + [tableCommentsTextView setString:[statusFields objectForKey:@"Comment"]]; + + // Set create syntax + [tableCreateSyntaxTextView setEditable:YES]; + [tableCreateSyntaxTextView setString:@""]; + [tableCreateSyntaxTextView insertText:[tableDataInstance tableCreateSyntax]]; + [tableCreateSyntaxTextView setEditable:NO]; +} + +/** + * NSTextView delegate. Used to change the selected table's comment. + */ +- (void)textDidEndEditing:(NSNotification *)notification +{ + if (([notification object] == tableCommentsTextView) && ([selectedTable length] > 0)) { + + NSString *currentComment = [tableDataInstance statusValueForKey:@"Comment"]; + NSString *newComment = [[tableCommentsTextView string] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + // Check that the user actually changed the tables comment + if (![currentComment isEqualToString:newComment]) { + + // Alter table's comment + [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COMMENT = '%@'", [selectedTable backtickQuotedString], newComment]]; + + if ([connection getLastErrorID] == 0) { + // Reload the table's data + [self reloadTable:self]; + } + else { + NSBeginAlertSheet(NSLocalizedString(@"Error changing table comment", @"error changing table comment message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table's comment to '%@'.\n\nMySQL said: %@", @"error changing table comment informative message"), newComment, [connection getLastErrorMessage]]); + } + } + } +} + +/** + * Release connection. + */ +- (void)dealloc +{ + [connection release], connection = nil; + + [super dealloc]; +} + +@end + +@implementation SPExtendedTableInfo (PrivateAPI) + +/** + * Format and returns the value within the info dictionary with the associated key. + */ +- (NSString *)_formatValueWithKey:(NSString *)key inDictionary:(NSDictionary *)infoDict withLabel:(NSString *)label +{ + NSString *value = [infoDict objectForKey:key]; + + if ([value isKindOfClass:[NSNull class]]) { + value = @""; + } + else { + // Format size strings + if ([key isEqualToString:@"Data_length"] || + [key isEqualToString:@"Max_data_length"] || + [key isEqualToString:@"Index_length"] || + [key isEqualToString:@"Data_free"]) { + + value = [NSString stringForByteSize:[value intValue]]; + } + // Format date strings to the user's long date format + else if ([key isEqualToString:@"Create_time"] || + [key isEqualToString:@"Update_time"]) { + + // Create date formatter + NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; + + [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; + + [dateFormatter setDateStyle:NSDateFormatterLongStyle]; + [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; + + value = [dateFormatter stringFromDate:[NSDate dateWithNaturalLanguageString:value]]; + } + } + + return [NSString stringWithFormat:@"%@: %@", label, ([value length] > 0) ? value : @"Not available"]; +} + +@end diff --git a/Source/SPPreferenceController.h b/Source/SPPreferenceController.h index 1147351e..7fb849a0 100644 --- a/Source/SPPreferenceController.h +++ b/Source/SPPreferenceController.h @@ -39,8 +39,6 @@ IBOutlet NSView *networkView; IBOutlet NSView *editorView; - - IBOutlet NSPopUpButton *defaultFavoritePopup; IBOutlet NSTableView *favoritesTableView; diff --git a/Source/SPPreferenceController.m b/Source/SPPreferenceController.m index 64f29004..829f887c 100644 --- a/Source/SPPreferenceController.m +++ b/Source/SPPreferenceController.m @@ -809,7 +809,7 @@ // Action receiver for a font change in the font panel - (void)changeFont:(id)sender { - NSFont *nf = [[NSFontPanel sharedFontPanel] panelConvertFont:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:@"CustomQueryEditorFont"]]]; + NSFont *nf = [[NSFontPanel sharedFontPanel] panelConvertFont:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:@"CustomQueryEditorFont"]]]; [prefs setObject:[NSArchiver archivedDataWithRootObject:nf] forKey:@"CustomQueryEditorFont"]; [editorFontName setStringValue:[NSString stringWithFormat:@"%@, %.1f pt", [nf displayName], [nf pointSize]]]; } diff --git a/Source/SPTableData.h b/Source/SPTableData.h index 8f2e0a54..02179852 100644 --- a/Source/SPTableData.h +++ b/Source/SPTableData.h @@ -25,8 +25,8 @@ #import <Cocoa/Cocoa.h> - -@interface SPTableData : NSObject { +@interface SPTableData : NSObject +{ IBOutlet id tableDocumentInstance; IBOutlet id tableListInstance; @@ -34,13 +34,16 @@ NSMutableArray *columnNames; NSMutableArray *constraints; NSMutableDictionary *status; + NSString *tableEncoding; - + NSString *tableCreateSyntax; + CMMCPConnection *mySQLConnection; } - (void) setConnection:(CMMCPConnection *)theConnection; - (NSString *) tableEncoding; +- (NSString *) tableCreateSyntax; - (NSArray *) columns; - (NSDictionary *) columnWithName:(NSString *)colName; - (NSArray *) columnNames; diff --git a/Source/SPTableData.m b/Source/SPTableData.m index 7a989d0c..bedc9dc1 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -43,7 +43,9 @@ columnNames = [[NSMutableArray alloc] init]; constraints = [[NSMutableArray alloc] init]; status = [[NSMutableDictionary alloc] init]; + tableEncoding = nil; + tableCreateSyntax = nil; mySQLConnection = nil; } @@ -76,6 +78,23 @@ return [NSString stringWithString:tableEncoding]; } +/* + * Retrieve the create syntax for the current table, using or refreshing the cache as appropriate. + */ +- (NSString *) tableCreateSyntax +{ + if (tableCreateSyntax == nil) { + if ([tableListInstance tableType] == SP_TABLETYPE_VIEW) { + [self updateInformationForCurrentView]; + } + else { + [self updateInformationForCurrentTable]; + } + } + + return [NSString stringWithString:tableCreateSyntax]; +} + /* * Retrieve all columns for the current table as an array, using or refreshing the cache as appropriate. @@ -189,10 +208,16 @@ [columns removeAllObjects]; [columnNames removeAllObjects]; [status removeAllObjects]; + if (tableEncoding != nil) { [tableEncoding release]; tableEncoding = nil; } + + if (tableCreateSyntax != nil) { + [tableCreateSyntax release]; + tableCreateSyntax = nil; + } } @@ -272,6 +297,8 @@ [columnNames removeAllObjects]; [constraints removeAllObjects]; + if (tableCreateSyntax != nil) [tableCreateSyntax release]; + // Catch unselected tables and return nil if ([tableName isEqualToString:@""] || !tableName) return nil; @@ -290,9 +317,12 @@ // Retrieve the table syntax string NSArray *syntaxResult = [theResult fetchRowAsArray]; + if ([[syntaxResult objectAtIndex:1] isKindOfClass:[NSData class]]) { + tableCreateSyntax = [[NSString alloc] initWithData:[syntaxResult objectAtIndex:1] encoding:[mySQLConnection encoding]]; createTableParser = [[SPSQLParser alloc] initWithData:[syntaxResult objectAtIndex:1] encoding:[mySQLConnection encoding]]; } else { + tableCreateSyntax = [[NSString alloc] initWithString:[syntaxResult objectAtIndex:1]]; createTableParser = [[SPSQLParser alloc] initWithString:[syntaxResult objectAtIndex:1]]; } @@ -837,7 +867,9 @@ [columnNames release]; [constraints release]; [status release]; + if (tableEncoding != nil) [tableEncoding release]; + if (tableCreateSyntax != nil) [tableCreateSyntax release]; [super dealloc]; } diff --git a/Source/TableDocument.h b/Source/TableDocument.h index 53458230..738acdfb 100644 --- a/Source/TableDocument.h +++ b/Source/TableDocument.h @@ -45,7 +45,8 @@ IBOutlet id customQueryInstance; IBOutlet id tableDumpInstance; IBOutlet id tableDataInstance; - IBOutlet id tableStatusInstance; + IBOutlet id extendedTableInfoInstance; + IBOutlet id databaseDataInstance; IBOutlet id spExportControllerInstance; IBOutlet id tableWindow; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index 9b15dced..aedf9d34 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -32,21 +32,22 @@ #import "TableContent.h" #import "CustomQuery.h" #import "TableDump.h" -#import "TableStatus.h" #import "ImageAndTextCell.h" #import "SPGrowlController.h" #import "SPExportController.h" #import "SPQueryConsole.h" #import "SPSQLParser.h" #import "SPTableData.h" +#import "SPDatabaseData.h" #import "SPStringAdditions.h" #import "SPQueryConsole.h" #import "CMMCPConnection.h" #import "CMMCPResult.h" #import "MainController.h" +#import "SPExtendedTableInfo.h" #import "SPPreferenceController.h" -//used for printing +// Used for printing #import "MGTemplateEngine.h" #import "ICUTemplateMatcher.h" @@ -341,17 +342,24 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum } else { mySQLVersion = [[NSString stringWithString:version] retain]; } + [self setDatabases:self]; + + // For each of the main controllers assigned the current connection [tablesListInstance setConnection:mySQLConnection]; [tableSourceInstance setConnection:mySQLConnection]; [tableContentInstance setConnection:mySQLConnection]; [tableRelationsInstance setConnection:mySQLConnection]; [customQueryInstance setConnection:mySQLConnection]; - [customQueryInstance setMySQLversion:mySQLVersion]; [tableDumpInstance setConnection:mySQLConnection]; [spExportControllerInstance setConnection:mySQLConnection]; - [tableStatusInstance setConnection:mySQLConnection]; [tableDataInstance setConnection:mySQLConnection]; + [extendedTableInfoInstance setConnection:mySQLConnection]; + [databaseDataInstance setConnection:mySQLConnection]; + + // Set the cutom query editor's MySQL version + [customQueryInstance setMySQLversion:mySQLVersion]; + [self setFileName:[NSString stringWithFormat:@"(MySQL %@) %@@%@ %@", mySQLVersion, [userField stringValue], [hostField stringValue], [databaseField stringValue]]]; [tableWindow setTitle:[NSString stringWithFormat:@"(MySQL %@) %@/%@", mySQLVersion, [self name], [databaseField stringValue]]]; @@ -782,7 +790,7 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum if (reloadViews) { if ([tablesListInstance structureLoaded]) [tableSourceInstance reloadTable:self]; if ([tablesListInstance contentLoaded]) [tableContentInstance reloadTable:self]; - if ([tablesListInstance statusLoaded]) [tableStatusInstance reloadTable:self]; + if ([tablesListInstance statusLoaded]) [extendedTableInfoInstance reloadTable:self]; } } diff --git a/Source/TableSource.m b/Source/TableSource.m index 8a09b0ab..afadf50e 100644 --- a/Source/TableSource.m +++ b/Source/TableSource.m @@ -413,8 +413,9 @@ reloads the table (performing a new mysql-query) [tableDataInstance resetColumnData]; } else { [sender selectItemWithTitle:tableType]; - NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, - [NSString stringWithFormat:NSLocalizedString(@"Couldn't change table type.\nMySQL said: %@", @"message of panel when table type cannot be removed"), [mySQLConnection getLastErrorMessage]]); + NSBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table to '%@' from '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), selectedItem, tableType, [mySQLConnection getLastErrorMessage]]); } } } diff --git a/Source/TableStatus.h b/Source/TableStatus.h deleted file mode 100644 index ee8a279f..00000000 --- a/Source/TableStatus.h +++ /dev/null @@ -1,63 +0,0 @@ -// -// $Id$ -// -// TableStatus.h -// sequel-pro -// -// Created by Jason Hallford (jason.hallford@byu.edu) on Th July 08 2004. -// sequel-pro Copyright (c) 2002-2003 Lorenz Textor. All rights reserved. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Cocoa/Cocoa.h> -#import <MCPKit_bundled/MCPKit_bundled.h> -#import "CMMCPConnection.h" -#import "CMMCPResult.h" - -@interface TableStatus : NSObject -{ - IBOutlet id tableDataInstance; - - IBOutlet id commentsBox; - IBOutlet id rowsNumber; - IBOutlet id rowsFormat; - IBOutlet id rowsAvgLength; - IBOutlet id rowsAutoIncrement; - IBOutlet id sizeData; - IBOutlet id sizeFree; - IBOutlet id sizeIndex; - IBOutlet id sizeMaxData; - IBOutlet id tableCreatedAt; - IBOutlet id tableName; - IBOutlet id tableType; - IBOutlet id tableUpdatedAt; - - CMMCPConnection *mySQLConnection; - CMMCPResult *tableStatusResult; - - NSString *selectedTable; - NSDictionary *statusFields; -} - -// Table methods -- (void)loadTable:(NSString *)aTable; -- (IBAction)reloadTable:(id)sender; - -// Additional methods -- (void)setConnection:(CMMCPConnection *)theConnection; - -@end diff --git a/Source/TableStatus.m b/Source/TableStatus.m deleted file mode 100644 index d5bc5da4..00000000 --- a/Source/TableStatus.m +++ /dev/null @@ -1,152 +0,0 @@ -// -// $Id$ -// -// TableStatus.m -// sequel-pro -// -// Created by Jason Hallford (jason.hallford@byu.edu) on Th July 08 2004. -// sequel-pro Copyright (c) 2002-2003 Lorenz Textor. All rights reserved. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://code.google.com/p/sequel-pro/> - -#import "TableStatus.h" -#import "SPTableData.h" -#import "SPStringAdditions.h" - -@implementation TableStatus - -- (void)setConnection:(CMMCPConnection *)theConnection -{ - mySQLConnection = theConnection; - [mySQLConnection retain]; -} - -- (NSString*)formatValueWithKey:(NSString *)aKey inDictionary:(NSDictionary*)statusDict withLabel:(NSString*)label -{ - NSString *value = [statusDict objectForKey:aKey]; - - if ([value isKindOfClass:[NSNull class]]) { - value = @"--"; - } - else { - // Format size strings - if ([aKey isEqualToString:@"Data_length"] || - [aKey isEqualToString:@"Max_data_length"] || - [aKey isEqualToString:@"Index_length"] || - [aKey isEqualToString:@"Data_free"]) { - - value = [NSString stringForByteSize:[value intValue]]; - } - // Format date strings to the user's long date format - else if ([aKey isEqualToString:@"Create_time"] || - [aKey isEqualToString:@"Update_time"]) { - - // Create date formatter - NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; - - [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; - - [dateFormatter setDateStyle:NSDateFormatterLongStyle]; - [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; - - value = [dateFormatter stringFromDate:[NSDate dateWithNaturalLanguageString:value]]; - } - } - - NSString *labelVal = [NSString stringWithFormat:@"%@: %@", label, value]; - - return labelVal; -} - -- (void)loadTable:(NSString *)aTable -{ - // Store the table name away for future use... - selectedTable = aTable; - - // Retrieve the table status information via the table data cache - statusFields = [tableDataInstance statusValues]; - - // No table selected or view selected - if([aTable isEqualToString:@""] || !aTable || [[statusFields objectForKey:@"Engine"] isEqualToString:@"View"]) { - - if ([[statusFields objectForKey:@"Engine"] isEqualToString:@"View"]) { - [tableName setStringValue:[NSString stringWithFormat:@"Name: %@", selectedTable]]; - [tableType setStringValue:@"Type: View"]; - } else { - [tableName setStringValue:@"Name: --"]; - [tableType setStringValue:@"Type: --"]; - } - - [tableCreatedAt setStringValue:@"Created At: --"]; - [tableUpdatedAt setStringValue:@"Updated At: --"]; - - // Assign the row values... - [rowsNumber setStringValue:@"Number Of: --"]; - [rowsFormat setStringValue:@"Format: --"]; - [rowsAvgLength setStringValue:@"Avg. Length: --"]; - [rowsAutoIncrement setStringValue:@"Auto Increment: --"]; - - // Assign the size values... - [sizeData setStringValue:@"Data: --"]; - [sizeMaxData setStringValue:@"Max Data: --"]; - [sizeIndex setStringValue:@"Index: --"]; - [sizeFree setStringValue:@"Free: --"]; - - // Finally, set the value of the comments box - [commentsBox setStringValue:@"--"]; - - return; - } - - // Assign the table values... - [tableName setStringValue:[NSString stringWithFormat:@"Name: %@",selectedTable]]; - [tableType setStringValue:[self formatValueWithKey:@"Engine" inDictionary:statusFields withLabel:@"Type"]]; - [tableCreatedAt setStringValue:[self formatValueWithKey:@"Create_time" inDictionary:statusFields withLabel:@"Created At"]]; - [tableUpdatedAt setStringValue:[self formatValueWithKey:@"Update_time" inDictionary:statusFields withLabel:@"Updated At"]]; - - // Assign the row values... - [rowsNumber setStringValue:[self formatValueWithKey:@"Rows" inDictionary:statusFields withLabel:@"Approx. Number"]]; - [rowsFormat setStringValue:[self formatValueWithKey:@"Row_format" inDictionary:statusFields withLabel:@"Format"]]; - [rowsAvgLength setStringValue:[self formatValueWithKey:@"Avg_row_length" inDictionary:statusFields withLabel:@"Avg. Length"]]; - [rowsAutoIncrement setStringValue:[self formatValueWithKey:@"Auto_increment" inDictionary:statusFields withLabel:@"Auto Increment"]]; - - // Assign the size values... - [sizeData setStringValue:[self formatValueWithKey:@"Data_length" inDictionary:statusFields withLabel:@"Data"]]; - [sizeMaxData setStringValue:[self formatValueWithKey:@"Max_data_length" inDictionary:statusFields withLabel:@"Max Data"]]; - [sizeIndex setStringValue:[self formatValueWithKey:@"Index_length" inDictionary:statusFields withLabel:@"Index"]]; - [sizeFree setStringValue:[self formatValueWithKey:@"Data_free" inDictionary:statusFields withLabel:@"Free"]]; - - // Finally, assign the comments... - [commentsBox setStringValue:[statusFields objectForKey:@"Comment"]]; - - return; -} - -- (IBAction)reloadTable:(id)sender -{ - [tableDataInstance resetStatusData]; - [self loadTable:selectedTable]; -} - -- (id)init -{ - self = [super init]; - - return self; -} - -@end diff --git a/Source/TablesList.h b/Source/TablesList.h index a745f9ba..6fd86c56 100644 --- a/Source/TablesList.h +++ b/Source/TablesList.h @@ -45,7 +45,7 @@ enum sp_table_types IBOutlet id customQueryInstance; IBOutlet id tableDumpInstance; IBOutlet id tableDataInstance; - IBOutlet id tableStatusInstance; + IBOutlet id extendedTableInfoInstance; IBOutlet id tableWindow; IBOutlet id copyTableSheet; diff --git a/Source/TablesList.m b/Source/TablesList.m index 0029aac1..fa4db07a 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -276,7 +276,7 @@ statusLoaded = NO; } else if (selectedIndex == 3) { - [tableStatusInstance loadTable:tableName]; + [extendedTableInfoInstance loadTable:tableName]; structureLoaded = NO; contentLoaded = NO; statusLoaded = YES; @@ -1011,7 +1011,7 @@ statusLoaded = NO; } else if (selectedIndex == 3) { - [tableStatusInstance loadTable:anObject]; + [extendedTableInfoInstance loadTable:anObject]; structureLoaded = NO; contentLoaded = NO; statusLoaded = YES; @@ -1123,7 +1123,7 @@ contentLoaded = YES; statusLoaded = NO; } else if ( [tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 3 ) { - [tableStatusInstance loadTable:[tables objectAtIndex:[tablesListView selectedRow]]]; + [extendedTableInfoInstance loadTable:[tables objectAtIndex:[tablesListView selectedRow]]]; structureLoaded = NO; contentLoaded = NO; statusLoaded = YES; @@ -1136,7 +1136,7 @@ // if we are not looking at a table or view, clear these [tableSourceInstance loadTable:nil]; [tableContentInstance loadTable:nil]; - [tableStatusInstance loadTable:nil]; + [extendedTableInfoInstance loadTable:nil]; structureLoaded = NO; contentLoaded = NO; statusLoaded = NO; @@ -1229,7 +1229,7 @@ } else { [tableSourceInstance loadTable:nil]; [tableContentInstance loadTable:nil]; - [tableStatusInstance loadTable:nil]; + [extendedTableInfoInstance loadTable:nil]; structureLoaded = NO; contentLoaded = NO; statusLoaded = NO; @@ -1360,7 +1360,7 @@ } if ( ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 3) && !statusLoaded ) { - [tableStatusInstance loadTable:[tables objectAtIndex:[tablesListView selectedRow]]]; + [extendedTableInfoInstance loadTable:[tables objectAtIndex:[tablesListView selectedRow]]]; statusLoaded = YES; } } |