//
// TableDocument.m
// sequel-pro
//
// Created by lorenz textor (lorenz@textor.ch) on Wed May 01 2002.
// 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
// Or mail to
#import "TableDocument.h"
#import "KeyChain.h"
#import "TablesList.h"
#import "TableSource.h"
#import "TableContent.h"
#import "CustomQuery.h"
#import "TableDump.h"
#import "TableStatus.h"
NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocumentFavoritesControllerSelectionIndexDidChange";
@implementation TableDocument
- (void)awakeFromNib
{
[favoritesController addObserver:self forKeyPath:@"selectionIndex" options:NSKeyValueChangeInsertion context:TableDocumentFavoritesControllerSelectionIndexDidChange];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == TableDocumentFavoritesControllerSelectionIndexDidChange) {
[self chooseFavorite:self];
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
//start sheet
- (IBAction)toggleUseSSH:(id)sender
/*
enables/disables ssh tunneling
*/
{
if ([sshCheckbox state] == NSOnState) {
[sshUserField setEnabled:YES];
[sshPasswordField setEnabled:YES];
[sshHostField setEnabled:YES];
[sshPortField setEnabled:YES];
} else {
[sshUserField setEnabled:NO];
[sshPasswordField setEnabled:NO];
[sshHostField setEnabled:NO];
[sshPortField setEnabled:NO];
}
}
- (IBAction)connectToDB:(id)sender
/*
tries to connect to the db
alert-sheets when no success
*/
{
CMMCPResult *theResult;
NSString *encoding;
int code;
id version;
[self setFavorites];
[NSApp beginSheet:connectSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
code = [NSApp runModalForWindow:connectSheet];
[NSApp endSheet:connectSheet];
[connectSheet orderOut:nil];
if ( code == 1) {
//connected with success
//register as delegate
[mySQLConnection setDelegate:self];
// set encoding
encoding = [prefs objectForKey:@"encoding"];
if ( [encoding isEqualToString:@"Autodetect"] ) {
[self detectEncoding];
} else {
[chooseEncodingButton selectItemWithTitle:encoding];
[self setEncoding:[self getSelectedEncoding]];
}
// get selected db
if ( ![[databaseField stringValue] isEqualToString:@""] )
selectedDatabase = [[databaseField stringValue] retain];
//get mysql version
// theResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE \"version\""];
theResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE 'version'"];
version = [[theResult fetchRowAsArray] objectAtIndex:1];
if ( [version isKindOfClass:[NSData class]] ) {
// starting with MySQL 4.1.14 the mysql variables are returned as nsdata
mySQLVersion = [[NSString alloc] initWithData:version encoding:[mySQLConnection encoding]];
} else {
mySQLVersion = [[NSString stringWithString:version] retain];
}
[self setDatabases:self];
[tablesListInstance setConnection:mySQLConnection];
[tableSourceInstance setConnection:mySQLConnection];
[tableContentInstance setConnection:mySQLConnection];
[customQueryInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
[tableStatusInstance setConnection:mySQLConnection];
[self setFileName:[NSString stringWithFormat:@"(MySQL %@) %@@%@ %@", mySQLVersion, [userField stringValue],
[hostField stringValue], [databaseField stringValue]]];
[tableWindow setTitle:[NSString stringWithFormat:@"(MySQL %@) %@@%@/%@", mySQLVersion, [userField stringValue],
[hostField stringValue], [databaseField stringValue]]];
} else if (code == 2) {
//can't connect to host
NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil,
@selector(sheetDidEnd:returnCode:contextInfo:), @"connect",
[NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@.\nBe sure that the address is correct and that you have the necessary privileges.\nMySQL said: %@", @"message of panel when connection to host failed"), [hostField stringValue], [mySQLConnection getLastErrorMessage]]);
} else if (code == 3) {
//can't connect to db
NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil,
@selector(sheetDidEnd:returnCode:contextInfo:), @"connect",
[NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that the database exists and that you have the necessary privileges.\nMySQL said: %@", @"message of panel when connection to db failed"), [databaseField stringValue], [mySQLConnection getLastErrorMessage]]);
} else if (code == 4) {
//no host is given
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil,
@selector(sheetDidEnd:returnCode:contextInfo:), @"connect", NSLocalizedString(@"Please enter at least a host or socket.", @"message of panel when host/socket are missing"));
} else {
//cancel button was pressed
//since the window is getting ready to be toast ignore events for awhile
//so as not to crash, this happens to me when hitten esc key instead of
//cancel button, but with this code it does not crash
[[NSApplication sharedApplication] discardEventsMatchingMask:NSAnyEventMask
beforeEvent:[[NSApplication sharedApplication] nextEventMatchingMask:NSLeftMouseDownMask | NSLeftMouseUpMask |NSRightMouseDownMask | NSRightMouseUpMask | NSFlagsChangedMask | NSKeyDownMask | NSKeyUpMask untilDate:[NSDate distantPast] inMode:NSEventTrackingRunLoopMode dequeue:YES]];
[tableWindow close];
}
}
/*
invoked when user hits the connect-button of the connectSheet
stops modal session with code:
1 when connected with success
2 when no connection to host
3 when no connection to db
4 when hostField and socketField are empty
*/
- (IBAction)connect:(id)sender
{
int code;
[connectProgressBar startAnimation:self];
[connectProgressStatusText setHidden:NO];
[connectProgressStatusText display];
code = 0;
if ( [[hostField stringValue] isEqualToString:@""] && [[socketField stringValue] isEqualToString:@""] ) {
code = 4;
} else {
if ( ![[socketField stringValue] isEqualToString:@""] ) {
//connect to socket
mySQLConnection = [[CMMCPConnection alloc] initToSocket:[socketField stringValue]
withLogin:[userField stringValue]
password:[passwordField stringValue]];
[hostField setStringValue:@"localhost"];
} else {
//connect to host
mySQLConnection = [[CMMCPConnection alloc] initToHost:[hostField stringValue]
withLogin:[userField stringValue]
password:[passwordField stringValue]
usingPort:[portField intValue]];
}
if ( ![mySQLConnection isConnected] )
code = 2;
if ( !code && ![[databaseField stringValue] isEqualToString:@""] )
if ( ![mySQLConnection selectDB:[databaseField stringValue]] )
code = 3;
if ( !code )
code = 1;
}
[NSApp stopModalWithCode:code];
[connectProgressBar stopAnimation:self];
[connectProgressStatusText setHidden:YES];
}
- (IBAction)closeSheet:(id)sender
/*
invoked when user hits the cancel button of the connectSheet
stops modal session with code 0
reused when user hits the close button of the variablseSheet or of the createTableSyntaxSheet
*/
{
[NSApp stopModalWithCode:0];
}
- (IBAction)chooseFavorite:(id)sender
/*
sets fields for the choosen favorite
*/
{
/*
BOOL useSSH = NO;
if ( [favoritesButton indexOfSelectedItem] == 0 ) {
[hostField setStringValue:@""];
[socketField setStringValue:@""];
[userField setStringValue:@""];
[portField setStringValue:@""];
[databaseField setStringValue:@""];
[passwordField setStringValue:@""];
[sshCheckbox setState:NSOffState];
[sshUserField setEnabled:NO];
[sshPasswordField setEnabled:NO];
[sshHostField setEnabled:NO];
[sshPortField setEnabled:NO];
[sshHostField setStringValue:@""];
[sshUserField setStringValue:@""];
[sshPasswordField setStringValue:@""];
[sshPortField setStringValue:@"8888"];
[hostField selectText:self];
[selectedFavorite release];
selectedFavorite = [[favoritesButton titleOfSelectedItem] retain];
} else if ( [favoritesButton indexOfSelectedItem] == 1 ) {
if ( ![[socketField stringValue] isEqualToString:@""] ) {
[hostField setStringValue:@"localhost"];
}
if ( [sshCheckbox state] == NSOnState ) {
useSSH = YES;
} else {
useSSH = NO;
}
[self addToFavoritesHost:[hostField stringValue]
socket:[socketField stringValue]
user:[userField stringValue]
password:[passwordField stringValue]
port:[portField stringValue]
database:[databaseField stringValue]
useSSH:useSSH
sshHost:[sshHostField stringValue]
sshUser:[sshUserField stringValue]
sshPassword:[sshPasswordField stringValue]
sshPort:[sshPortField stringValue]];
// } else if ( [favoritesButton indexOfSelectedItem] == 2 ) {
// [favoritesButton selectItemWithTitle:selectedFavorite];
} else {*/
if ([[prefs objectForKey:@"favorites"] count] == 0)
return;
NSDictionary *favorite = [[prefs objectForKey:@"favorites"] objectAtIndex:[favoritesController selectionIndex]];
NSString *name = [favorite objectForKey:@"name"];
NSString *host = [favorite objectForKey:@"host"];
NSString *socket = [favorite objectForKey:@"socket"];
NSString *user = [favorite objectForKey:@"user"];
NSString *port = [favorite objectForKey:@"port"];
NSString *database = [favorite objectForKey:@"database"];
int useSSH = [[favorite objectForKey:@"useSSH"] intValue];
NSString *sshHost = [favorite objectForKey:@"sshHost"];
NSString *sshUser = [favorite objectForKey:@"sshUser"];
NSString *sshPort = [favorite objectForKey:@"sshPort"];
[hostField setStringValue:host];
[socketField setStringValue:socket];
[userField setStringValue:user];
[portField setStringValue:port];
[databaseField setStringValue:database];
[passwordField setStringValue:[keyChainInstance
getPasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@", name]
account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]];
if ( useSSH ) {
[sshCheckbox setState:NSOnState];
[sshHostField setStringValue:sshHost];
[sshUserField setStringValue:sshUser];
[sshPortField setStringValue:sshPort];
[sshPasswordField setStringValue:[keyChainInstance
getPasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", name]
account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]];
[sshUserField setEnabled:YES];
[sshPasswordField setEnabled:YES];
[sshHostField setEnabled:YES];
[sshPortField setEnabled:YES];
} else {
[sshCheckbox setState:NSOffState];
[sshHostField setStringValue:@""];
[sshUserField setStringValue:@""];
[sshPortField setStringValue:@""];
[sshPasswordField setStringValue:@""];
[sshUserField setEnabled:NO];
[sshPasswordField setEnabled:NO];
[sshHostField setEnabled:NO];
[sshPortField setEnabled:NO];
}
[selectedFavorite release];
selectedFavorite = [[favoritesButton titleOfSelectedItem] retain];
/*}*/
}
- (NSArray *)favorites
{
return favorites;
}
- (void)setFavorites
/*
set up the favorites popUpButton and notifiy bindings that it's changed
*/
{
[self willChangeValueForKey:@"favorites"];
[self didChangeValueForKey:@"favorites"];
NSEnumerator *enumerator = [favorites objectEnumerator];
id favorite;
[favoritesButton removeAllItems];
[favoritesButton addItemWithTitle:NSLocalizedString(@"Custom", @"menu item for custom connection")];
[favoritesButton addItemWithTitle:NSLocalizedString(@"Save to favorites...", @"menu item for saving connection to favorites")];
// [favoritesButton addItemWithTitle:@""];
[[favoritesButton menu] addItem:[NSMenuItem separatorItem]];
while ( (favorite = [enumerator nextObject]) ) {
[favoritesButton addItemWithTitle:[favorite objectForKey:@"name"]];
}
}
- (void)addToFavoritesHost:(NSString *)host socket:(NSString *)socket
user:(NSString *)user password:(NSString *)password
port:(NSString *)port database:(NSString *)database
useSSH:(BOOL)useSSH sshHost:(NSString *)sshHost
sshUser:(NSString *)sshUser sshPassword:(NSString *)sshPassword
sshPort:(NSString *)sshPort
/*
add actual connection to favorites
*/
{
NSEnumerator *enumerator = [favorites objectEnumerator];
id favorite;
NSString *favoriteName = [NSString stringWithFormat:@"%@@%@/%@", user, host, database];
NSNumber *ssh;
//test if host and socket are not nil
if ( [host isEqualToString:@""] && [socket isEqualToString:@""] )
{
NSRunAlertPanel(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"Please enter at least a host or socket.", @"message of panel when host/socket are missing"), NSLocalizedString(@"OK", @"OK button"), nil, nil);
[favoritesButton selectItemWithTitle:selectedFavorite];
return;
}
//test if all fields are specified for ssh tunnel
if ( useSSH ) {
if ( [sshHost isEqualToString:@""] ) {
sshHost = host;
}
if ( [sshUser isEqualToString:@""] ) {
sshUser = user;
}
if ( [sshPassword isEqualToString:@""] ) {
sshPassword = password;
}
if ( [sshPort isEqualToString:@""] ) {
sshPort = port;
}
ssh = [NSNumber numberWithInt:1];
} else {
sshHost = @"";
sshUser = @"";
sshPassword = @"";
sshPort = @"";
ssh = [NSNumber numberWithInt:0];
}
//test if favorite name isn't used by another favorite and if no favorite with the same host, user and db exists
while ( (favorite = [enumerator nextObject]) ) {
if ( [[favorite objectForKey:@"name"] isEqualToString:favoriteName] )
{
NSRunAlertPanel(NSLocalizedString(@"Error", @"error"), [NSString stringWithFormat:NSLocalizedString(@"Favorite %@ has already been saved!\nOpen Preferences to change the names of the favorites.", @"message of panel when favorite name has already been used"), favoriteName], NSLocalizedString(@"OK", @"OK button"), nil, nil);
[favoritesButton selectItemWithTitle:selectedFavorite];
return;
}
/*
if ( [[favorite objectForKey:@"host"] isEqualToString:host] &&
[[favorite objectForKey:@"user"] isEqualToString:user] &&
[[favorite objectForKey:@"database"] isEqualToString:database] ) {
NSRunAlertPanel(@"Error", @"There is already a favorite with the same host, user and database!", @"OK", nil, nil);
[favoritesButton selectItemWithTitle:selectedFavorite];
return;
}
*/
}
//write favorites and password
NSDictionary *newFavorite = [NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:favoriteName, host, socket, user, port, database, ssh, sshHost, sshUser, sshPort, nil]
forKeys:[NSArray arrayWithObjects:@"name", @"host", @"socket", @"user", @"port", @"database", @"useSSH", @"sshHost", @"sshUser", @"sshPort", nil]];
favorites = [[favorites arrayByAddingObject:newFavorite] retain];
if ( ![password isEqualToString:@""] )
[keyChainInstance addPassword:password forName:[NSString stringWithFormat:@"Sequel Pro : %@", favoriteName]
account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]];
if ( ![sshPassword isEqualToString:@""] )
[keyChainInstance addPassword:sshPassword forName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@", favoriteName]
account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]];
[prefs setObject:favorites forKey:@"favorites"];
//reload favorites and select new favorite
[self setFavorites];
[favoritesButton selectItemWithTitle:favoriteName];
selectedFavorite = [favoriteName retain];
}
//alert sheets method
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo
/*
invoked when alertSheet get closed
if contextInfo == connect -> reopens the connectSheet
if contextInfo == removedatabase -> tries to remove the selected database
*/
{
[sheet orderOut:self];
if ( [contextInfo isEqualToString:@"connect"] ) {
[self connectToDB:nil];
} else if ( [contextInfo isEqualToString:@"removedatabase"] ) {
if ( returnCode == NSAlertDefaultReturn ) {
[mySQLConnection queryString:[NSString stringWithFormat:@"DROP DATABASE `%@`", [self database]]];
if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
//db deleted with success
selectedDatabase = nil;
[self setDatabases:self];
[tablesListInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
[tableWindow setTitle:[NSString stringWithFormat:@"(MySQL %@) %@@%@/",
mySQLVersion, [userField stringValue], [hostField stringValue]]];
} else {
//error while deleting db
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Couldn't remove database.\nMySQL said: %@", @"message of panel when removing db failed"), [mySQLConnection getLastErrorMessage]]);
}
}
}
}
//database methods
- (IBAction)setDatabases:(id)sender;
/*
sets up the chooseDatabaseButton (adds all databases)
*/
{
CMMCPResult *queryResult;
int i;
[chooseDatabaseButton removeAllItems];
[chooseDatabaseButton addItemWithTitle:NSLocalizedString(@"Choose database...", @"menu item for choose db")];
queryResult = [mySQLConnection listDBs];
for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) {
[queryResult dataSeek:i];
[chooseDatabaseButton addItemWithTitle:[[queryResult fetchRowAsArray] objectAtIndex:0]];
}
if ( ![self database] ) {
[chooseDatabaseButton selectItemWithTitle:NSLocalizedString(@"Choose database...", @"menu item for choose db")];
} else {
[chooseDatabaseButton selectItemWithTitle:[self database]];
}
}
- (IBAction)chooseDatabase:(id)sender
/*
selects the database choosen by the user
errorsheet if connection failed
*/
{
if ( ![tablesListInstance selectionShouldChangeInTableView:nil] ) {
[chooseDatabaseButton selectItemWithTitle:[self database]];
return;
}
if ( [chooseDatabaseButton indexOfSelectedItem] == 0 ) {
if ( ![self database] ) {
[chooseDatabaseButton selectItemWithTitle:NSLocalizedString(@"Choose database...", @"menu item for choose db")];
} else {
[chooseDatabaseButton selectItemWithTitle:[self database]];
}
return;
}
if ( ![mySQLConnection selectDB:[chooseDatabaseButton titleOfSelectedItem]] ) {
//connection failed
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"),
[chooseDatabaseButton titleOfSelectedItem]]);
[self setDatabases:self];
} else {
//changed database with success
//setConnection of TablesList and TablesDump to reload tables in db
[selectedDatabase release];
selectedDatabase = nil;
selectedDatabase = [[chooseDatabaseButton titleOfSelectedItem] retain];
[tablesListInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
[tableWindow setTitle:[NSString stringWithFormat:@"(MySQL %@) %@@%@/%@", mySQLVersion, [userField stringValue],
[hostField stringValue], [self database]]];
}
}
- (IBAction)addDatabase:(id)sender
/*
opens the add-db sheet and creates the new db
*/
{
int code = 0;
if ( ![tablesListInstance selectionShouldChangeInTableView:nil] )
return;
[databaseNameField setStringValue:@""];
[NSApp beginSheet:databaseSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
code = [NSApp runModalForWindow:databaseSheet];
[NSApp endSheet:databaseSheet];
[databaseSheet orderOut:nil];
if ( code ) {
if ( [[databaseNameField stringValue] isEqualToString:@""] ) {
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil, NSLocalizedString(@"Database must have a name.", @"message of panel when no db name is given"));
} else {
[mySQLConnection queryString:[NSString stringWithFormat:@"CREATE DATABASE `%@`", [databaseNameField stringValue]]];
if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
//db created with success
if ( ![mySQLConnection selectDB:[databaseNameField stringValue]] ) {
//error while selecting new db (is this possible?!)
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"),
[databaseNameField stringValue]]);
[self setDatabases:self];
} else {
//select new db
[selectedDatabase release];
selectedDatabase = nil;
selectedDatabase = [[databaseNameField stringValue] retain];
[self setDatabases:self];
[tablesListInstance setConnection:mySQLConnection];
[tableDumpInstance setConnection:mySQLConnection];
[tableWindow setTitle:[NSString stringWithFormat:@"(MySQL %@) %@@%@/%@",
mySQLVersion, [userField stringValue], [hostField stringValue],
selectedDatabase]];
}
} else {
//error while creating db
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection getLastErrorMessage]]);
}
}
}
}
- (IBAction)closeDatabaseSheet:(id)sender
/*
closes the add-db sheet and stops modal session
*/
{
[NSApp stopModalWithCode:[sender tag]];
}
- (IBAction)removeDatabase:(id)sender
/*
opens sheet to ask user if he really wants to delete the db
*/
{
if ( [chooseDatabaseButton indexOfSelectedItem] == 0 )
return;
if ( ![tablesListInstance selectionShouldChangeInTableView:nil] )
return;
NSBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"Delete", @"delete button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, tableWindow, self, nil,
@selector(sheetDidEnd:returnCode:contextInfo:), @"removedatabase",
[NSString stringWithFormat:NSLocalizedString(@"Do you really want to delete the database %@?", @"message of panel asking for confirmation for deleting db"), [self database]] );
}
//console methods
- (void)toggleConsole
/*
shows or hides the console
*/
{
NSDrawerState state = [consoleDrawer state];
if (NSDrawerOpeningState == state || NSDrawerOpenState == state) {
[consoleDrawer close];
} else {
[consoleTextView scrollRangeToVisible:[consoleTextView selectedRange]];
[consoleDrawer openOnEdge:NSMinYEdge];
}
}
- (void)clearConsole
/*
clears the console
*/
{
[consoleTextView setString:@""];
}
- (BOOL)consoleIsOpened
/*
returns YES if the console is visible
*/
{
if ( [consoleDrawer state] == NSDrawerOpeningState || [consoleDrawer state] == NSDrawerOpenState )
{
return YES;
} else {
return NO;
}
}
- (void)showMessageInConsole:(NSString *)message
/*
shows a message in the console
*/
{
int begin, end;
[consoleTextView setSelectedRange:NSMakeRange([[consoleTextView string] length],0)];
begin = [[consoleTextView string] length];
[consoleTextView replaceCharactersInRange:NSMakeRange(begin,0)
withString:message];
end = [[consoleTextView string] length];
[consoleTextView setTextColor:[NSColor blackColor] range:NSMakeRange(begin,end-begin)];
if ( [self consoleIsOpened] ) {
/*
NSClipView *clipView = [consoleTextView superview];
if (![clipView isKindOfClass:[NSClipView class]]) return;
[clipView scrollToPoint:[clipView constrainScrollPoint:NSMakePoint(0,[consoleTextView frame].size.height)]];
[[clipView superview] reflectScrolledClipView:clipView];
*/
[consoleTextView displayIfNeeded];
[consoleTextView scrollRangeToVisible:[consoleTextView selectedRange]];
}
}
- (void)showErrorInConsole:(NSString *)error
/*
shows an error in the console (red)
*/
{
int begin, end;
[consoleTextView setSelectedRange:NSMakeRange([[consoleTextView string] length],0)];
begin = [[consoleTextView string] length];
[consoleTextView replaceCharactersInRange:NSMakeRange(begin,0)
withString:error];
end = [[consoleTextView string] length];
[consoleTextView setTextColor:[NSColor redColor] range:NSMakeRange(begin,end-begin)];
if ( [self consoleIsOpened] ) {
/*
NSClipView *clipView = [consoleTextView superview];
if (![clipView isKindOfClass:[NSClipView class]]) return;
[clipView scrollToPoint:[clipView constrainScrollPoint:NSMakePoint(0,[consoleTextView frame].size.height)]];
[[clipView superview] reflectScrolledClipView:clipView];
*/
[consoleTextView displayIfNeeded];
[consoleTextView scrollRangeToVisible:[consoleTextView selectedRange]];
}
}
//encoding methods
- (void)setEncoding:(NSString *)encoding
/*
set the encoding for the database
*/
{
// set encoding of connection and client
[mySQLConnection queryString:[NSString stringWithFormat:@"SET NAMES '%@'", encoding]];
if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
[mySQLConnection setEncoding:[CMMCPConnection encodingForMySQLEncoding:[encoding cString]]];
} else {
[self detectEncoding];
}
//NSLog(@"set encoding to %@", encoding);
[tableSourceInstance reloadTable:self];
[tableContentInstance reloadTable:self];
[tableStatusInstance reloadTable:self];
// int encodingCode;
/* if( [encoding isEqualToString:@"ISO Latin 1"] ) {
encodingCode = NSISOLatin1StringEncoding;
} else if( [encoding isEqualToString:@"ISO Latin 2"] ) {
encodingCode = NSISOLatin2StringEncoding;
} else if( [encoding isEqualToString:@"Win Latin 1"] ) {
encodingCode = NSWindowsCP1252StringEncoding;
} else if( [encoding isEqualToString:@"Win Latin 2"] ) {
encodingCode = NSWindowsCP1250StringEncoding;
} else if( [encoding isEqualToString:@"Cyrillic"] ) {
encodingCode = NSWindowsCP1251StringEncoding;
} else if( [encoding isEqualToString:@"Greek"] ) {
encodingCode = NSWindowsCP1253StringEncoding;
} else if( [encoding isEqualToString:@"Turkish"] ) {
encodingCode = NSWindowsCP1254StringEncoding;
} else if ( [encoding isEqualToString:@"Shift-JIS"] ) {
encodingCode = NSShiftJISStringEncoding;
} else if ( [encoding isEqualToString:@"EUC-JP"] ) {
encodingCode = NSJapaneseEUCStringEncoding;
} else if ( [encoding isEqualToString:@"ISO 2022-JP"] ) {
encodingCode = NSISO2022JPStringEncoding;
} else if ( [encoding isEqualToString:@"UTF-8"] ) {
encodingCode = NSUTF8StringEncoding;
*/
/*
if( [encoding isEqualToString:@"ISO Latin 1"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatin1);
} else if( [encoding isEqualToString:@"ISO Latin 2"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatin2);
} else if ( [encoding isEqualToString:@"ISO Cyrillic"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinCyrillic);
} else if ( [encoding isEqualToString:@"ISO Greek"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinGreek);
} else if ( [encoding isEqualToString:@"ISO Turkish"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatin5);
} else if ( [encoding isEqualToString:@"ISO Arabic"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinArabic);
} else if ( [encoding isEqualToString:@"ISO Hebrew"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinHebrew);
} else if ( [encoding isEqualToString:@"ISO Thai"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISOLatinThai);
} else if( [encoding isEqualToString:@"Win Latin 1"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsLatin1);
} else if( [encoding isEqualToString:@"Win Latin 2"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsLatin2);
} else if( [encoding isEqualToString:@"Win Cyrillic"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsCyrillic);
} else if( [encoding isEqualToString:@"Win Greek"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsGreek);
} else if( [encoding isEqualToString:@"Win Turkish"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsLatin5);
} else if( [encoding isEqualToString:@"Win Arabic"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic);
} else if( [encoding isEqualToString:@"Win Baltic Rim"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsBalticRim);
} else if( [encoding isEqualToString:@"Win Korean"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsKoreanJohab);
} else if( [encoding isEqualToString:@"Win Vietnamese"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsVietnamese);
} else if ( [encoding isEqualToString:@"Shift-JIS"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingShiftJIS);
} else if ( [encoding isEqualToString:@"EUC-JP"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_JP);
} else if ( [encoding isEqualToString:@"ISO 2022-JP"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISO_2022_JP);
} else if ( [encoding isEqualToString:@"EUC-CN"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_CN);
} else if ( [encoding isEqualToString:@"EUC-TW"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_TW);
} else if ( [encoding isEqualToString:@"EUC-KR"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingEUC_KR);
} else if ( [encoding isEqualToString:@"ISO 2022-KR"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISO_2022_KR);
} else if ( [encoding isEqualToString:@"ISO 2022-CN"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISO_2022_CN);
} else if ( [encoding isEqualToString:@"KOI8-R"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingKOI8_R);
} else if ( [encoding isEqualToString:@"HZ"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingHZ_GB_2312);
} else if ( [encoding isEqualToString:@"UTF-8"] ) {
encodingCode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF8);
} else {
encodingCode = NSISOLatin1StringEncoding; // default is ISO Latin 1
}
if(encodingCode == kCFStringEncodingInvalidId)
encodingCode = NSISOLatin1StringEncoding;
*/
}
- (void)detectEncoding
/*
autodetects the connection encoding and sets the encoding dropdown
*/
{
id mysqlEncoding;
// mysql > 4.0
mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set_connection'"] fetchRowAsDictionary] objectForKey:@"Value"];
if ( [mysqlEncoding isKindOfClass:[NSData class]] ) {
// MySQL 4.1.14 returns the mysql variables as nsdata
mysqlEncoding = [mySQLConnection stringWithText:mysqlEncoding];
}
if ( !mysqlEncoding ) {
// mysql 4.0 or older -> only default character set possible, cannot choose others using "set names xy"
mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] fetchRowAsDictionary] objectForKey:@"Value"];
[chooseEncodingButton setEnabled:NO];
}
if ( !mysqlEncoding ) {
// older version? -> set encoding to mysql default encoding latin1, chooseEncodingButton is already disabled
NSLog(@"error: no character encoding found, mysql version is %@", [self mySQLVersion]);
mysqlEncoding = @"latin1";
}
[mySQLConnection setEncoding:[CMMCPConnection encodingForMySQLEncoding:[mysqlEncoding cString]]];
//NSLog(@"autodetected %@", mysqlEncoding);
if ( [mysqlEncoding isEqualToString:@"ucs2"] ) {
[chooseEncodingButton selectItemWithTitle:@"UCS-2 Unicode (ucs2)"];
} else if ( [mysqlEncoding isEqualToString:@"utf8"] ) {
[chooseEncodingButton selectItemWithTitle:@"UTF-8 Unicode (utf8)"];
} else if ( [mysqlEncoding isEqualToString:@"ascii"] ) {
[chooseEncodingButton selectItemWithTitle:@"US ASCII (ascii)"];
} else if ( [mysqlEncoding isEqualToString:@"latin1"] ) {
[chooseEncodingButton selectItemWithTitle:@"ISO Latin 1 (latin1)"];
} else if ( [mysqlEncoding isEqualToString:@"macroman"] ) {
[chooseEncodingButton selectItemWithTitle:@"Mac Roman (macroman)"];
} else if ( [mysqlEncoding isEqualToString:@"cp1250"] ) {
[chooseEncodingButton selectItemWithTitle:@"Windows Latin 2 (cp1250)"];
} else if ( [mysqlEncoding isEqualToString:@"latin2"] ) {
[chooseEncodingButton selectItemWithTitle:@"ISO Latin 2 (latin2)"];
} else if ( [mysqlEncoding isEqualToString:@"cp1256"] ) {
[chooseEncodingButton selectItemWithTitle:@"Windows Arabic (cp1256)"];
} else if ( [mysqlEncoding isEqualToString:@"greek"] ) {
[chooseEncodingButton selectItemWithTitle:@"ISO Greek (greek)"];
} else if ( [mysqlEncoding isEqualToString:@"hebrew"] ) {
[chooseEncodingButton selectItemWithTitle:@"ISO Hebrew (hebrew)"];
} else if ( [mysqlEncoding isEqualToString:@"latin5"] ) {
[chooseEncodingButton selectItemWithTitle:@"ISO Turkish (latin5)"];
} else if ( [mysqlEncoding isEqualToString:@"cp1257"] ) {
[chooseEncodingButton selectItemWithTitle:@"Windows Baltic (cp1257)"];
} else if ( [mysqlEncoding isEqualToString:@"cp1251"] ) {
[chooseEncodingButton selectItemWithTitle:@"Windows Cyrillic (cp1251)"];
} else if ( [mysqlEncoding isEqualToString:@"big5"] ) {
[chooseEncodingButton selectItemWithTitle:@"Big5 Traditional Chinese (big5)"];
} else if ( [mysqlEncoding isEqualToString:@"sjis"] ) {
[chooseEncodingButton selectItemWithTitle:@"Shift-JIS Japanese (sjis)"];
} else if ( [mysqlEncoding isEqualToString:@"ujis"] ) {
[chooseEncodingButton selectItemWithTitle:@"EUC-JP Japanese (ujis)"];
} else {
NSLog(@"unsupported encoding %@! falling back to utf8.", mysqlEncoding);
[chooseEncodingButton selectItemWithTitle:@"UTF-8 Unicode (utf8)"];
[self setEncoding:[self getSelectedEncoding]];
}
}
- (NSString *)getSelectedEncoding
/*
gets the selected mysql encoding
*/
{
NSString *mysqlEncoding;
NSString *encoding = [chooseEncodingButton titleOfSelectedItem];
// unicode
if ( [encoding isEqualToString:@"UCS-2 Unicode (ucs2)"] ) {
mysqlEncoding = @"ucs2";
} else if ( [encoding isEqualToString:@"UTF-8 Unicode (utf8)"] ) {
mysqlEncoding = @"utf8";
// west european
} else if( [encoding isEqualToString:@"US ASCII (ascii)"] ) {
mysqlEncoding = @"ascii";
} else if ( [encoding isEqualToString:@"ISO Latin 1 (latin1)"] ) {
mysqlEncoding = @"latin1";
} else if ( [encoding isEqualToString:@"Mac Roman (macroman)"] ) {
mysqlEncoding = @"macroman";
// central european
} else if ( [encoding isEqualToString:@"Windows Latin 2 (cp1250)"] ) {
mysqlEncoding = @"cp1250";
} else if ( [encoding isEqualToString:@"ISO Latin 2 (latin2)"] ) {
mysqlEncoding = @"latin2";
// south european and middle east
} else if ( [encoding isEqualToString:@"Windows Arabic (cp1256)"] ) {
mysqlEncoding = @"cp1256";
} else if ( [encoding isEqualToString:@"ISO Greek (greek)"] ) {
mysqlEncoding = @"greek";
} else if ( [encoding isEqualToString:@"ISO Hebrew (hebrew)"] ) {
mysqlEncoding = @"hebrew";
} else if ( [encoding isEqualToString:@"ISO Turkish (latin5)"] ) {
mysqlEncoding = @"latin5";
// baltic
} else if ( [encoding isEqualToString:@"Windows Baltic (cp1257)"] ) {
mysqlEncoding = @"cp1257";
// cyrillic
} else if ( [encoding isEqualToString:@"Windows Cyrillic (cp1251)"] ) {
mysqlEncoding = @"cp1251";
// asian
} else if ( [encoding isEqualToString:@"Big5 Traditional Chinese (big5)"] ) {
mysqlEncoding = @"big5";
} else if ( [encoding isEqualToString:@"Shift-JIS Japanese (sjis)"] ) {
mysqlEncoding = @"sjis";
} else if ( [encoding isEqualToString:@"EUC-JP Japanese (ujis)"] ) {
mysqlEncoding = @"ujis";
} else {
// unknown encoding
NSLog(@"error: unknown encoding %@", encoding);
mysqlEncoding = @"utf8";
}
return [mysqlEncoding autorelease];
}
- (IBAction)chooseEncoding:(id)sender
/*
choose encoding
*/
{
// Set encoding
[self setEncoding:[self getSelectedEncoding]];
}
- (BOOL)supportsEncoding
/*
returny YES if MySQL server supports choosing connection and table encodings (MySQL 4.1 and newer)
*/
{
return [chooseEncodingButton isEnabled];
}
//other methods
- (NSString *)host
/*
returns the host
*/
{
return [hostField stringValue];
}
- (void)doPerformQueryService:(NSString *)query
/*
passes query to tablesListInstance
*/
{
[tableWindow makeKeyAndOrderFront:self];
[tablesListInstance doPerformQueryService:query];
}
- (void)flushPrivileges
/*
flushes the mysql privileges
*/
{
[mySQLConnection queryString:@"FLUSH PRIVILEGES"];
if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
//flushed privileges without errors
NSBeginAlertSheet(NSLocalizedString(@"Flushed Privileges", @"title of panel when successfully flushed privs"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
NSLocalizedString(@"Succesfully flushed privileges.", @"message of panel when successfully flushed privs"));
} else {
//error while flushing privileges
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"),
[mySQLConnection getLastErrorMessage]]);
}
}
- (void)openTableOperationsSheet
/*
opens the sheet for table operations (check/analyze/optimize/repair/flush) and performs desired operation
*/
{
int code, operation;
CMMCPResult *theResult;
NSDictionary *theRow;
NSString *query;
NSString *operationText;
NSString *messageType;
NSString *messageText;
[NSApp beginSheet:tableOperationsSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
code = [NSApp runModalForWindow:tableOperationsSheet];
[NSApp endSheet:tableOperationsSheet];
[tableOperationsSheet orderOut:nil];
NSLog(@"%d",code);
if ( !code )
return;
// get operation
operation = [[chooseTableOperationButton selectedItem] tag];
switch ( operation ) {
case 0:
// check table
query = [NSString stringWithFormat:@"CHECK TABLE `%@`", [self table]];
break;
case 1:
// analyze table
query = [NSString stringWithFormat:@"ANALYZE TABLE `%@`", [self table]];
break;
case 2:
// optimize table
query = [NSString stringWithFormat:@"OPTIMIZE TABLE `%@`", [self table]];
break;
case 3:
// repair table
query = [NSString stringWithFormat:@"REPAIR TABLE `%@`", [self table]];
break;
case 4:
// flush table
query = [NSString stringWithFormat:@"FLUSH TABLE `%@`", [self table]];
break;
}
// perform operation
theResult = [mySQLConnection queryString:query];
if ( [[mySQLConnection getLastErrorMessage] isEqualToString:@""] ) {
// no errors
if ( operation == 4 ) {
// flushed -> no return values
operationText = [NSString stringWithString:@"flush"];
messageType = [NSString stringWithString:@"-"];
messageText = [NSString stringWithString:@"-"];
} else {
// other operations -> get return values
theRow = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
operationText = [NSString stringWithString:[theRow objectForKey:@"Op"]];
messageType = [NSString stringWithString:[theRow objectForKey:@"Msg_type"]];
messageText = [NSString stringWithString:[theRow objectForKey:@"Msg_text"]];
}
NSBeginAlertSheet(NSLocalizedString(@"Successfully performed table operation", @"title of panel when successfully performed table operation"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Operation: %@\nMsg_type: %@\nMsg_text: %@", @"message of panel when successfully performed table operation"),
operationText, messageType, messageText]);
} else {
// error
NSBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Couldn't perform table operation.\nMySQL said: %@", @"message of panel when table operation failed"),
[mySQLConnection getLastErrorMessage]]);
}
}
- (IBAction)doTableOperation:(id)sender
/*
closes the sheet and ends modal with 0 if cancel and 1 if ok
*/
{
[NSApp stopModalWithCode:[sender tag]];
}
- (void)showVariables
/*
shows the mysql variables
*/
{
CMMCPResult *theResult;
NSMutableArray *tempResult = [NSMutableArray array];
int i;
if ( variables ) {
[variables release];
variables = nil;
}
//get variables
theResult = [mySQLConnection queryString:@"SHOW VARIABLES"];
for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
[theResult dataSeek:i];
[tempResult addObject:[theResult fetchRowAsDictionary]];
}
variables = [[NSArray arrayWithArray:tempResult] retain];
[variablesTableView reloadData];
//show variables sheet
[NSApp beginSheet:variablesSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
[NSApp runModalForWindow:variablesSheet];
[NSApp endSheet:variablesSheet];
[variablesSheet orderOut:nil];
}
- (void)showCreateTable
/*
shows the mysql command used to create the selected table
*/
{
id createTableSyntax;
CMMCPResult *result = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE `%@`",
[self table]]];
createTableSyntax = [[result fetchRowAsArray] objectAtIndex:1];
if ( [createTableSyntax isKindOfClass:[NSData class]] ) {
createTableSyntax = [[NSString alloc] initWithData:createTableSyntax encoding:[mySQLConnection encoding]];
}
[createTableSyntaxView setString:createTableSyntax];
[createTableSyntaxView selectAll:self];
//show createTableSyntaxSheet
[NSApp beginSheet:createTableSyntaxSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
[NSApp runModalForWindow:createTableSyntaxSheet];
[NSApp endSheet:createTableSyntaxSheet];
[createTableSyntaxSheet orderOut:nil];
}
- (void)closeConnection
{
[mySQLConnection disconnect];
}
//getter methods
- (NSString *)database
/*
returns the currently selected database
*/
{
return selectedDatabase;
}
- (NSString *)table
/*
returns the currently selected table (passing the request to TablesList)
*/
{
return [tablesListInstance table];
}
- (NSString *)mySQLVersion
/*
returns the mysql version
*/
{
return mySQLVersion;
}
- (NSString *)user
/*
returns the mysql version
*/
{
return [userField stringValue];
}
//notification center methods
- (void)willPerformQuery:(NSNotification *)notification
/*
invoked before a query is performed
*/
{
[queryProgressBar startAnimation:self];
}
- (void)hasPerformedQuery:(NSNotification *)notification
/*
invoked after a query has been performed
*/
{
[queryProgressBar stopAnimation:self];
}
- (void)applicationWillTerminate:(NSNotification *)notification
/*
invoked when the application will terminate
*/
{
[tablesListInstance selectionShouldChangeInTableView:nil];
}
- (void)tunnelStatusChanged:(NSNotification *)notification
/*
the status of the tunnel has changed
*/
{
NSLog([tunnel status]);
}
//menu methods
- (IBAction)import:(id)sender
/*
passes the request to the tableDump object
*/
{
[tableDumpInstance importFile:[sender tag]];
}
- (IBAction)export:(id)sender
/*
passes the request to the tableDump object
*/
{
[tableDumpInstance exportFile:[sender tag]];
}
- (BOOL)validateMenuItem:(NSMenuItem *)anItem
/*
do menu validation
*/
{
switch ( [anItem tag] ) {
case 1:
//import dump
if ( ![self database] ) {
return NO;
}
break;
case 2:
//import CSV
if ( ![self database] || ![self table] ) {
return NO;
}
break;
case 5:
//export dump
if ( ![self database] ) {
return NO;
}
break;
case 6:
//export table content as CSV
if ( ![self database] || ![self table] ) {
return NO;
}
break;
case 7:
//export table content as XML
if ( ![self database] || ![self table] ) {
return NO;
}
break;
case 8:
//export custom result as CSV
return YES;
break;
case 9:
//export custom result as XML
return YES;
break;
case 10:
//export multiple tables as CSV
if ( ![self database] ) {
return NO;
}
break;
case 11:
//export multiple tables as XML
if ( ![self database] ) {
return NO;
}
break;
}
return YES;
}
- (IBAction)viewStructure:(id)sender
{
[tableTabView selectTabViewItemAtIndex:0];
}
- (IBAction)viewContent:(id)sender
{
[tableTabView selectTabViewItemAtIndex:1];
}
- (IBAction)viewQuery:(id)sender
{
[tableTabView selectTabViewItemAtIndex:2];
}
- (IBAction)viewStatus:(id)sender
{
[tableTabView selectTabViewItemAtIndex:3];
}
//toolbar methods
- (void)setupToolbar
/*
set up the standard toolbar
*/
{
//create a new toolbar instance, and attach it to our document window
NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:@"TableWindowToolbar"] autorelease];
//set up toolbar properties
[toolbar setAllowsUserCustomization: YES];
[toolbar setAutosavesConfiguration: YES];
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
//set ourself as the delegate
[toolbar setDelegate:self];
//attach the toolbar to the document window
[tableWindow setToolbar:toolbar];
}
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
/*
toolbar delegate method
*/
{
NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
if ([itemIdentifier isEqualToString:@"ToggleConsoleIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setPaletteLabel:NSLocalizedString(@"Show/Hide Console", @"toolbar item for show/hide console")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Show or hide the console which shows all MySQL commands performed by Sequel Pro", @"tooltip for toolbar item for show/hide console")];
if ( [self consoleIsOpened] ) {
[toolbarItem setLabel:NSLocalizedString(@"Hide Console", @"toolbar item for hide console")];
[toolbarItem setImage:[NSImage imageNamed:@"hideconsole"]];
} else {
[toolbarItem setLabel:NSLocalizedString(@"Show Console", @"toolbar item for showconsole")];
[toolbarItem setImage:[NSImage imageNamed:@"showconsole"]];
}
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(toggleConsole)];
} else if ([itemIdentifier isEqualToString:@"ClearConsoleIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setLabel:NSLocalizedString(@"Clear Console", @"toolbar item for clear console")];
[toolbarItem setPaletteLabel:NSLocalizedString(@"Clear Console", @"toolbar item for clear console")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Clear the console which shows all MySQL commands performed by Sequel Pro", @"tooltip for toolbar item for clear console")];
[toolbarItem setImage:[NSImage imageNamed:@"clearconsole"]];
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(clearConsole)];
} else if ([itemIdentifier isEqualToString:@"FlushPrivilegesIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setLabel:NSLocalizedString(@"Flush Privileges", @"toolbar item for flush privileges")];
[toolbarItem setPaletteLabel:NSLocalizedString(@"Flush Privileges", @"toolbar item for flush privileges")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Reload the MySQL privileges saved in the mysql database", @"tooltip for toolbar item for flush privileges")];
[toolbarItem setImage:[NSImage imageNamed:@"flushprivileges"]];
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(flushPrivileges)];
} else if ([itemIdentifier isEqualToString:@"OptimizeTableIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setLabel:NSLocalizedString(@"Table Operations", @"toolbar item for perform table operations")];
[toolbarItem setPaletteLabel:NSLocalizedString(@"Table Operations", @"toolbar item for perform table operations")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Perform table operations for the selected table", @"tooltip for toolbar item for perform table operations")];
[toolbarItem setImage:[NSImage imageNamed:@"optimizetable"]];
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(openTableOperationsSheet)];
} else if ([itemIdentifier isEqualToString:@"ShowVariablesIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setLabel:NSLocalizedString(@"Show Variables", @"toolbar item for show variables")];
[toolbarItem setPaletteLabel:NSLocalizedString(@"Show Variables", @"toolbar item for show variables")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Show the MySQL Variables", @"tooltip for toolbar item for show variables")];
[toolbarItem setImage:[NSImage imageNamed:@"showvariables"]];
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(showVariables)];
} else if ([itemIdentifier isEqualToString:@"ShowCreateTableIdentifier"]) {
//set the text label to be displayed in the toolbar and customization palette
[toolbarItem setLabel:NSLocalizedString(@"Create Table Syntax", @"toolbar item for create table syntax")];
[toolbarItem setPaletteLabel:NSLocalizedString(@"Create Table Syntax", @"toolbar item for create table syntax")];
//set up tooltip and image
[toolbarItem setToolTip:NSLocalizedString(@"Show the MySQL command used to create the selected table", @"tooltip for toolbar item for create table syntax")];
[toolbarItem setImage:[NSImage imageNamed:@"createtablesyntax"]];
//set up the target action
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(showCreateTable)];
} else {
//itemIdentifier refered to a toolbar item that is not provided or supported by us or cocoa
toolbarItem = nil;
}
return toolbarItem;
}
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
/*
toolbar delegate method
*/
{
return [NSArray arrayWithObjects:@"ToggleConsoleIdentifier", @"ClearConsoleIdentifier", @"ShowVariablesIdentifier", @"FlushPrivilegesIdentifier", @"OptimizeTableIdentifier", @"ShowCreateTableIdentifier", NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
}
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
/*
toolbar delegate method
*/
{
return [NSArray arrayWithObjects:@"ToggleConsoleIdentifier", @"ClearConsoleIdentifier", NSToolbarSeparatorItemIdentifier, @"ShowVariablesIdentifier", @"FlushPrivilegesIdentifier", NSToolbarSeparatorItemIdentifier, @"OptimizeTableIdentifier", @"ShowCreateTableIdentifier", nil];
}
- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem;
/*
validates the toolbar items
*/
{
if ( [[toolbarItem itemIdentifier] isEqualToString:@"OptimizeTableIdentifier"] ) {
if ( ![self table] )
return NO;
} else if ( [[toolbarItem itemIdentifier] isEqualToString:@"ShowCreateTableIdentifier"] ) {
if ( ![self table] )
return NO;
} else if ( [[toolbarItem itemIdentifier] isEqualToString:@"ToggleConsoleIdentifier"] ) {
if ( [self consoleIsOpened] ) {
[toolbarItem setLabel:@"Hide Console"];
[toolbarItem setImage:[NSImage imageNamed:@"hideconsole"]];
} else {
[toolbarItem setLabel:@"Show Console"];
[toolbarItem setImage:[NSImage imageNamed:@"showconsole"]];
}
}
return YES;
}
//NSDocument methods
- (NSString *)windowNibName
/*
returns the name of the nib file
*/
{
return @"DBView";
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
/*
code that need to be executed once the windowController has loaded the document's window
sets upt the interface (small fonts)
*/
{
[aController setShouldCascadeWindows:NO];
[super windowControllerDidLoadNib:aController];
NSEnumerator *theCols = [[variablesTableView tableColumns] objectEnumerator];
NSTableColumn *theCol;
// [tableWindow makeKeyAndOrderFront:self];
prefs = [[NSUserDefaults standardUserDefaults] retain];
if ( [prefs objectForKey:@"favorites"] != nil ) {
favorites = [[NSArray alloc] initWithArray:[prefs objectForKey:@"favorites"]];
} else {
favorites = [[NSArray array] retain];
}
selectedFavorite = [[NSString alloc] initWithString:NSLocalizedString(@"Custom", @"menu item for custom connection")];
//register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willPerformQuery:)
name:@"SMySQLQueryWillBePerformed" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hasPerformedQuery:)
name:@"SMySQLQueryHasBeenPerformed" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:)
name:@"NSApplicationWillTerminateNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tunnelStatusChanged:)
name: @"STMStatusChanged" object: nil];
//set up interface
if ( [prefs boolForKey:@"useMonospacedFonts"] ) {
[consoleTextView setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]];
[createTableSyntaxView setFont:[NSFont fontWithName:@"Monaco" size:[NSFont smallSystemFontSize]]];
while ( (theCol = [theCols nextObject]) ) {
[[theCol dataCell] setFont:[NSFont fontWithName:@"Monaco" size:10]];
}
} else {
[consoleTextView setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[createTableSyntaxView setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
while ( (theCol = [theCols nextObject]) ) {
[[theCol dataCell] setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
}
}
[consoleDrawer setContentSize:NSMakeSize(110,110)];
//set up toolbar
[self setupToolbar];
//tunnel test
/*
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:@"Sequel Pro Tunnel",@"connName",
@"xy",@"connUser",
@"textor.ch",@"connHost",
[NSNumber numberWithBool:YES],@"connAuth",
[NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:@"8888",@"port",
@"textor.ch",@"host",
@"3306",@"hostport",
nil]],@"tunnelsLocal",
nil];
tunnel = [[SSHTunnel alloc] initWithDictionary:args];
[tunnel startTunnel];
*/
//sleep(3);
//[tunnel startTunnelWithArguments:args];
//end tunnel test
[self connectToDB:nil];
}
- (void)windowWillClose:(NSNotification *)aNotification
{
[self closeConnection];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//NSWindow delegate methods
- (BOOL)windowShouldClose:(id)sender
/*
invoked when the document window should close
*/
{
if ( ![tablesListInstance selectionShouldChangeInTableView:nil] ) {
return NO;
} else {
return YES;
}
}
//SMySQL delegate methods
- (void)willQueryString:(NSString *)query
/*
invoked when framework will perform a query
*/
{
NSString *currentTime = [[NSDate date] descriptionWithCalendarFormat:@"%H:%M:%S" timeZone:nil locale:nil];
[self showMessageInConsole:[NSString stringWithFormat:@"/* MySQL %@ */ %@;\n", currentTime, query]];
}
- (void)queryGaveError:(NSString *)error
/*
invoked when query gave an error
*/
{
NSString *currentTime = [[NSDate date] descriptionWithCalendarFormat:@"%H:%M:%S" timeZone:nil locale:nil];
[self showErrorInConsole:[NSString stringWithFormat:@"/* ERROR %@ */ %@;\n", currentTime, error]];
}
//splitView delegate methods
- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview
/*
tells the splitView that it can collapse views
*/
{
return YES;
}
- (float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset
/*
defines max position of splitView
*/
{
return proposedMax - 600;
}
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset
/*
defines min position of splitView
*/
{
return proposedMin + 160;
}
//tableView datasource methods
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [variables count];
}
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(int)rowIndex
{
id theValue;
theValue = [[variables objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];
if ( [theValue isKindOfClass:[NSData class]] ) {
theValue = [[NSString alloc] initWithData:theValue encoding:[mySQLConnection encoding]];
}
return theValue;
}
//for freeing up memory
- (void)dealloc
{
// NSLog(@"TableDocument dealloc");
[mySQLConnection release];
[favorites release];
if (nil != variables )
{
[variables release];
}
[selectedDatabase release];
[selectedFavorite release];
[mySQLVersion release];
[prefs release];
[super dealloc];
}
@end