aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/MainController.m12
-rw-r--r--Source/SPDatabaseData.h51
-rw-r--r--Source/SPDatabaseData.m176
-rw-r--r--Source/SPExtendedTableInfo.h69
-rw-r--r--Source/SPExtendedTableInfo.m358
-rw-r--r--Source/SPPreferenceController.h2
-rw-r--r--Source/SPPreferenceController.m2
-rw-r--r--Source/SPTableData.h9
-rw-r--r--Source/SPTableData.m32
-rw-r--r--Source/TableDocument.h3
-rw-r--r--Source/TableDocument.m18
-rw-r--r--Source/TableSource.m5
-rw-r--r--Source/TableStatus.h63
-rw-r--r--Source/TableStatus.m152
-rw-r--r--Source/TablesList.h2
-rw-r--r--Source/TablesList.m12
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;
}
}