From f36685ae1bee7b9274de27414ab8b64dbc57770f Mon Sep 17 00:00:00 2001 From: drx777 Date: Wed, 28 Apr 2010 17:11:41 +0000 Subject: This changeset implements renaming and duplicating databases on a server. Details as follows: * altered MCPConnection listTablesFromDB:like: to return NSArray * altered MCPConnection listFieldsFromTable:like: to use backtick quoted strings for table and fieldnames * added MCPConnection listTablesFromDB for a complete table list * added SPStringAdditions.h to various files to prevent warnings * added sheets for duplicate/rename DB in DBView.xib * added duplicate/rename menu items to MainMenu.xib * added outlets in TableDocument: databaseNewSheet databaseRenameSheet databaseCopyNameField databaseRenameNameField copyOnlyStructureButton copyDatabaseButton renameDatabaseButton * added methods in TableDocument: getConnection, copyDatabase, renameDatabase, _copyDatabase, _renameDatabase * added OCMock Framework for object mocking in tests * added group Others/DatabaseActions --- Source/SPDatabaseCopy.h | 80 ++++++++++++++++++++++++ Source/SPDatabaseCopy.m | 113 ++++++++++++++++++++++++++++++++++ Source/SPDatabaseInfo.h | 54 +++++++++++++++++ Source/SPDatabaseInfo.m | 66 ++++++++++++++++++++ Source/SPDatabaseRename.h | 89 +++++++++++++++++++++++++++ Source/SPDatabaseRename.m | 135 +++++++++++++++++++++++++++++++++++++++++ Source/SPTableCopy.h | 74 +++++++++++++++++++++++ Source/SPTableCopy.m | 151 ++++++++++++++++++++++++++++++++++++++++++++++ Source/TableDocument.h | 10 +++ Source/TableDocument.m | 90 ++++++++++++++++++++++++++- 10 files changed, 860 insertions(+), 2 deletions(-) create mode 100644 Source/SPDatabaseCopy.h create mode 100644 Source/SPDatabaseCopy.m create mode 100644 Source/SPDatabaseInfo.h create mode 100644 Source/SPDatabaseInfo.m create mode 100644 Source/SPDatabaseRename.h create mode 100644 Source/SPDatabaseRename.m create mode 100644 Source/SPTableCopy.h create mode 100644 Source/SPTableCopy.m (limited to 'Source') diff --git a/Source/SPDatabaseCopy.h b/Source/SPDatabaseCopy.h new file mode 100644 index 00000000..f0e2e03a --- /dev/null +++ b/Source/SPDatabaseCopy.h @@ -0,0 +1,80 @@ +// +// $Id: $ +// +// SPDatabaseCopy.h +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + + +#import +#import +#import "SPDatabaseInfo.h" + +/** + * The SPDatabaseCopy class povides functionality to create a copy of a database. + */ +@interface SPDatabaseCopy : NSObject { + MCPConnection *connection; + SPDatabaseInfo *dbInfo; + NSObject *parent; +} + +/** + * @property MCPConnection references the MCPKit connection to MySQL; it has to be set. + */ +@property (retain) MCPConnection *connection; + +/** + * @property SPDatabaseInfo an instance of the database info class + */ +@property (retain) SPDatabaseInfo *dbInfo; + +/** + * @property the parent object that issues the action, needs to provide stuff like tableWindow for messages + */ +@property (retain) NSObject *parent; + + +/** + * This method retrieves the dbInfo object if it exists; otherwise it is generated and the + * connection is passed to it. + * + * @result SPDatabaseInfo dbInfo object + */ +- (SPDatabaseInfo *)getDBInfoObject; + +/** + * This method clones an existing database. + * + * @param NSString sourceDatabaseName the name of the source database + * @param NSString targetDatabaseName the name of the target database + * @result BOOL success + */ +- (BOOL)copyDatabaseFrom: (NSString *)sourceDatabaseName to: (NSString *)targetDatabaseName withContent: (BOOL)copyWithContent; + +/** + * This method creates a new database. + * + * @param NSString newDatabaseName name of the new database to be created + * @return BOOL YES on success, otherwise NO + */ +- (BOOL) createDatabase: (NSString *)newDatabaseName; + +@end diff --git a/Source/SPDatabaseCopy.m b/Source/SPDatabaseCopy.m new file mode 100644 index 00000000..98c97587 --- /dev/null +++ b/Source/SPDatabaseCopy.m @@ -0,0 +1,113 @@ +// +// $Id: $ +// +// SPDatabaseCopy.m +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import +#import +#import "SPAlertSheets.h" +#import "SPStringAdditions.h" +#import "SPDatabaseCopy.h" +#import "SPTableCopy.h" +#import "SPDatabaseInfo.h" +#import "Sequel-Pro.pch" + +@implementation SPDatabaseCopy + +@synthesize connection; +@synthesize dbInfo; +@synthesize parent; + +- (SPDatabaseInfo *)getDBInfoObject { + if (dbInfo != nil) { + return dbInfo; + } else { + dbInfo = [[SPDatabaseInfo alloc] init]; + [dbInfo setConnection:[self connection]]; + [dbInfo setParent:[self parent]]; + } + return dbInfo; +} + +- (NSObject *)getTableWindow { + return [NSApp mainWindow]; +} + +- (BOOL)copyDatabaseFrom: (NSString *)sourceDatabaseName to: (NSString *)targetDatabaseName withContent:(BOOL)copyWithContent { + + SPDatabaseInfo *databaseInfo = [self getDBInfoObject]; + // check, whether the source database exists and the target database doesn't. + NSArray *tables = [NSArray array]; + BOOL sourceExists = [databaseInfo databaseExists:sourceDatabaseName]; + BOOL targetExists = [databaseInfo databaseExists:targetDatabaseName]; + if (sourceExists && !targetExists) { + // retrieve the list of tables/views/funcs/triggers from the source database + + tables = [connection listTablesFromDB:sourceDatabaseName]; + } else { + SPBeginAlertSheet(NSLocalizedString(@"Cannot create existing database", @"create database exists error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to create the target database.\n\nDatabase %@ already exists.", + @"create database error informative message"), + targetDatabaseName]); + + return NO; + } + DLog(@"list of found tables of source db: %@", tables); + + [self createDatabase:targetDatabaseName]; + SPTableCopy *dbActionTableCopy = [[SPTableCopy alloc] init]; + [dbActionTableCopy setConnection:connection]; + + for (NSString *currentTable in tables) { + if ([dbActionTableCopy copyTable:currentTable + from:sourceDatabaseName + to:targetDatabaseName + withContent:copyWithContent]) { + } + } +} + +- (BOOL) createDatabase: (NSString *)newDatabaseName { + NSString *createStatement = [NSString stringWithFormat:@"CREATE DATABASE %@", + [newDatabaseName backtickQuotedString]]; + [connection queryString:createStatement]; + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to create database", @"create database error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to create the target database.\n\nMySQL said: %@", + @"create database error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; + + +} + +- (void)dealloc { + [dbInfo dealloc]; +} + + +@end \ No newline at end of file diff --git a/Source/SPDatabaseInfo.h b/Source/SPDatabaseInfo.h new file mode 100644 index 00000000..e71863eb --- /dev/null +++ b/Source/SPDatabaseInfo.h @@ -0,0 +1,54 @@ +// +// SPDatabaseInfo.h +// sequel-pro +// +// Created by David Rekowski on 19.04.10. +// Copyright 2010 Papaya Software GmbH. All rights reserved. +// + +#import +#import "MCPConnection.h" +#import "MCPResult.h" + +/* + * The SPDatabaseInfo class provides means of retrieving a list of database names + */ +@interface SPDatabaseInfo : NSObject { + MCPConnection *connection; + NSObject *parent; +} + +/** + * @property MCPConnection references the MCPKit connection to MySQL; it has to be set. + */ +@property (retain) MCPConnection *connection; + +/** + * @property the parent object that issues the action, needs to provide stuff like tableWindow for messages + */ +@property (retain) NSObject *parent; + +/** + * This method checks, whether a database exists. + * + * @param databaseName the name of the database to check + * @result TRUE if it exists, otherwise FALSE + */ +-(BOOL)databaseExists:(NSString *)databaseName; + +/** + * This method retrieves a list of all databases. + * + * @result NSArray databaseNames + */ +- (NSArray *)listDBs; + +/** + * This method retrieves a list of databases like the given string + * + * @param NSString dbsName name of the database substring to match + * @result NSArray databaseNames + */ +- (NSArray *)listDBsLike:(NSString *)dbsName; + +@end diff --git a/Source/SPDatabaseInfo.m b/Source/SPDatabaseInfo.m new file mode 100644 index 00000000..b2c2469d --- /dev/null +++ b/Source/SPDatabaseInfo.m @@ -0,0 +1,66 @@ +// +// SPDatabaseInfo.m +// sequel-pro +// +// Created by David Rekowski on 19.04.10. +// Copyright 2010 Papaya Software GmbH. All rights reserved. +// + +#import "SPAlertSheets.h" +#import "SPDatabaseInfo.h" +#import "SPStringAdditions.h" +#import "Sequel-Pro.pch" + +@implementation SPDatabaseInfo + +@synthesize connection; +@synthesize parent; + +- (NSObject *)getTableWindow { + return [NSApp mainWindow]; +} + +-(BOOL)databaseExists:(NSString *)databaseName { + NSArray *names = [self listDBs]; + return [names containsObject:databaseName]; +} + +- (NSArray *)listDBs { + return [self listDBsLike:nil]; +} + +- (NSArray *)listDBsLike:(NSString *)dbsName +{ + NSString *listDBStatement = nil; + if ((dbsName == nil) || ([dbsName isEqualToString:@""])) { + listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES"]; + } + else { + listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES LIKE %@", [dbsName backtickQuotedString]]; + } + DLog(@"running query : %@", listDBStatement); + MCPResult *theResult = [connection queryString:listDBStatement]; + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to retrieve databases list", @"database list error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to retrieve a list of databases.\n\nMySQL said: %@", + @"database list error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + + NSMutableArray *names = [NSMutableArray array]; + NSMutableString *name; + if ([theResult numOfRows] > 1) { + int i; + for ( i = 0 ; i < [theResult numOfRows] ; i++ ) { + name = [[theResult fetchRowAsArray] objectAtIndex:0]; + [names addObject:name]; + } + } + + return names; +} + +@end diff --git a/Source/SPDatabaseRename.h b/Source/SPDatabaseRename.h new file mode 100644 index 00000000..66ed2d7b --- /dev/null +++ b/Source/SPDatabaseRename.h @@ -0,0 +1,89 @@ +// +// $Id: $ +// +// SPDatabaseRename.h +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + + +#import +#import +#import "SPDatabaseInfo.h" +#import "SPStringAdditions.h" + +/** + * The SPDatabaseRename class povides functionality to rename a database. + */ +@interface SPDatabaseRename : NSObject { + MCPConnection *connection; + SPDatabaseInfo *dbInfo; + NSObject *parent; +} + +/** + * @property MCPConnection references the MCPKit connection to MySQL; it has to be set. + */ +@property (retain) MCPConnection *connection; + +/** + * @property SPDatabaseInfo an instance of the database info class + */ +@property (retain) SPDatabaseInfo *dbInfo; + +/** + * @property the parent object that issues the action, needs to provide stuff like tableWindow for messages + */ +@property (retain) NSObject *parent; + + +/** + * This method retrieves the dbInfo object if it exists; otherwise it is generated and the + * connection is passed to it. + * + * @result SPDatabaseInfo dbInfo object + */ +- (SPDatabaseInfo *)getDBInfoObject; + +/** + * This method renames an existing database. + * + * @param NSString sourceDatabaseName the name of the source database + * @param NSString targetDatabaseName the name of the target database + * @result BOOL success + */ +- (BOOL)renameDatabaseFrom: (NSString *)sourceDatabaseName to: (NSString *)targetDatabaseName; + +/** + * This method creates a new database. + * + * @param NSString newDatabaseName name of the new database to be created + * @return BOOL YES on success, otherwise NO + */ +- (BOOL) createDatabase: (NSString *)newDatabaseName; + +/** + * This method drops a database. + * + * @param NSString databaseName name of the database to drop + * @return BOOL YES on success, otherwise NO + */ +- (BOOL) dropDatabase: (NSString *)databaseName; + +@end diff --git a/Source/SPDatabaseRename.m b/Source/SPDatabaseRename.m new file mode 100644 index 00000000..c4b2e52c --- /dev/null +++ b/Source/SPDatabaseRename.m @@ -0,0 +1,135 @@ +// +// $Id: $ +// +// SPDatabaseRename.m +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + + +#import +#import +#import "SPAlertSheets.h" +#import "SPStringAdditions.h" +#import "SPDatabaseRename.h" +#import "SPDatabaseInfo.h" +#import "SPTableCopy.h" +#import "Sequel-Pro.pch" + +@implementation SPDatabaseRename + +@synthesize connection; +@synthesize dbInfo; +@synthesize parent; + +- (SPDatabaseInfo *)getDBInfoObject { + if (dbInfo != nil) { + return dbInfo; + } else { + dbInfo = [[SPDatabaseInfo alloc] init]; + [dbInfo setConnection:[self connection]]; + [dbInfo setParent:[self parent]]; + } + return dbInfo; +} + +- (NSObject *)getTableWindow { + return [NSApp mainWindow]; +} + +- (BOOL)renameDatabaseFrom: (NSString *)sourceDatabaseName to: (NSString *)targetDatabaseName { + SPDatabaseInfo *databaseInfo = [self getDBInfoObject]; + + // check, whether the source database exists and the target database doesn't. + NSArray *tables = [NSArray array]; + BOOL sourceExists = [databaseInfo databaseExists:sourceDatabaseName]; + BOOL targetExists = [databaseInfo databaseExists:targetDatabaseName]; + if (sourceExists && !targetExists) { + // retrieve the list of tables/views/funcs/triggers from the source database + + tables = [connection listTablesFromDB:sourceDatabaseName]; + } else { + SPBeginAlertSheet(NSLocalizedString(@"Cannot create existing database", @"create database exists error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to create the target database.\n\nDatabase %@ already exists.", + @"create database error informative message"), + targetDatabaseName]); + return NO; + } + DLog(@"list of found tables of source db: %@", tables); + + [self createDatabase:targetDatabaseName]; + SPTableCopy *dbActionTableCopy = [[SPTableCopy alloc] init]; + [dbActionTableCopy setConnection:connection]; + + for (NSString *currentTable in tables) { + if ([dbActionTableCopy moveTable:currentTable + from:sourceDatabaseName + to:targetDatabaseName]) { + } + } + tables = [connection listTablesFromDB:sourceDatabaseName]; + if ([tables count] == 0) { + [self dropDatabase:sourceDatabaseName]; + } else { + SPBeginAlertSheet(NSLocalizedString(@"Failed to delete database", @"delete database error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"Database %@ not empty, skipping drop database.", + @"delete database not empty error informative message"), + sourceDatabaseName]); + } +} + +- (BOOL) createDatabase: (NSString *)newDatabaseName { + NSString *createStatement = [NSString stringWithFormat:@"CREATE DATABASE %@", + [newDatabaseName backtickQuotedString]]; + [connection queryString:createStatement]; + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to create database", @"create database error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to create a database.\n\nMySQL said: %@", + @"create database error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; + +} + +- (BOOL) dropDatabase: (NSString *)databaseName { + NSString *dropStatement = [NSString stringWithFormat:@"DROP DATABASE %@", + [databaseName backtickQuotedString]]; + [connection queryString:dropStatement]; + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to drop database", @"drop database error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to drop a database.\n\nMySQL said: %@", + @"drop database error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; + +} + +- (void)dealloc { + [dbInfo dealloc]; +} + +@end \ No newline at end of file diff --git a/Source/SPTableCopy.h b/Source/SPTableCopy.h new file mode 100644 index 00000000..23cf9dc1 --- /dev/null +++ b/Source/SPTableCopy.h @@ -0,0 +1,74 @@ +// +// $Id: $ +// +// SPTableCopy.h +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import +#import + +/** + * The SPTableCopy class povides functionality to copy tables between databases. + */ +@interface SPTableCopy : NSObject { + MCPConnection *connection; + NSObject *parent; +} + +/** + * @property MCPConnection references the MCPKit connection to MySQL; it has to be set. + */ +@property (retain) MCPConnection *connection; + +/** + * @property the parent object that issues the action, needs to provide stuff like tableWindow for messages + */ +@property (retain) NSObject *parent; + +/** + * This method copies a table structure from one db to another. + * + * @param name name of the table in the source database + * @param sourceDB name of the source database + * @param targetDB name of the target database + */ +- (BOOL)copyTable:(NSString *)name from: (NSString *)sourceDB to: (NSString *)targetDB; + +/** + * This method moves a table from one db to another. + * + * @param name name of the table in the source database + * @param sourceDB name of the source database + * @param targetDB name of the target database + */ +- (BOOL)moveTable:(NSString *)name from: (NSString *)sourceDB to: (NSString *)targetDB; + +/** + * This method copies a table including its data from one db to another. + * + * @param name name of the table in the source database + * @param sourceDB name of the source database + * @param targetDB name of the target database + * @param copyWithContent whether to copy the content too, otherwise only structure + */ +- (BOOL)copyTable:(NSString *)tableName from: (NSString *)sourceDB to: (NSString *)targetDB withContent:(BOOL)copyWithContent; + +@end diff --git a/Source/SPTableCopy.m b/Source/SPTableCopy.m new file mode 100644 index 00000000..2e8c2461 --- /dev/null +++ b/Source/SPTableCopy.m @@ -0,0 +1,151 @@ +// +// $Id: $ +// +// SPTableCopy.m +// sequel-pro +// +// Created by David Rekowski on Apr 13, 2010 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import +#import "SPAlertSheets.h" +#import "SPStringAdditions.h" +#import "SPTableCopy.h" +#import "Sequel-Pro.pch" + +@implementation SPTableCopy + +@synthesize connection; +@synthesize parent; + +- (NSObject *)getTableWindow { + return [NSApp mainWindow]; +} + +- (NSString *)getCreateTableStatementFor: (NSString *)tableName inDB: (NSString *)sourceDB { + NSString *showCreateTableStatment = [NSString stringWithFormat:@"SHOW CREATE TABLE %@.%@", + [sourceDB backtickQuotedString], + [tableName backtickQuotedString] + ]; + NSLog(showCreateTableStatment); + MCPResult *theResult = [connection queryString:showCreateTableStatment]; + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to show create table statement", @"show create table error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to retrieve the create table statement for a table.\n\nMySQL said: %@", + @"show create table error informative message"), + [connection getLastErrorMessage]]); + } + NSLog(@"%i", [theResult numOfRows]); + if ([theResult numOfRows] != 0) { + NSString *createTableStatment = [[theResult fetchRowAsArray] objectAtIndex:1]; + return createTableStatment; + } +} + +- (BOOL)copyTable:(NSString *)tableName from: (NSString *)sourceDB to: (NSString *)targetDB { + + NSMutableString *createTableStatement = [[NSMutableString alloc] initWithString:[self getCreateTableStatementFor:tableName inDB:sourceDB]]; + + // adding the target DB name and the separator dot after "CREATE TABLE ". + [createTableStatement insertString:@"." atIndex:13]; + [createTableStatement insertString:[targetDB backtickQuotedString] atIndex:13]; + /* + // this only works with MySQL >= 4.1 + NSString *copyStatement = [NSString stringWithFormat:@"CREATE TABLE %@.%@ LIKE %@.%@", + [targetDB backtickQuotedString], + [tableName backtickQuotedString], + [sourceDB backtickQuotedString], + [tableName backtickQuotedString] + ]; + DLog(@"Copying table %@ from %@ to %@", tableName, sourceDB, targetDB); + DLog(@"Copying table: %@", copyStatement); + [connection queryString:copyStatement]; + */ + + [connection queryString:createTableStatement]; + [createTableStatement release]; + + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to copy table", @"copy table error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to copy a table.\n\nMySQL said: %@", + @"copy table error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; +} + +- (BOOL)copyTable:(NSString *)tableName from: (NSString *)sourceDB to: (NSString *)targetDB withContent:(BOOL)copyWithContent{ + // copy the table structure + BOOL structureCopyResult = [self copyTable:tableName from:sourceDB to:targetDB]; + + // optionally copy the table data using an insert select + if (copyWithContent == YES) { + NSString *copyDataStatement = [NSString stringWithFormat:@"INSERT INTO %@.%@ SELECT * FROM %@.%@", + [targetDB backtickQuotedString], + [tableName backtickQuotedString], + [sourceDB backtickQuotedString], + [tableName backtickQuotedString] + ]; + DLog(@"Copying table data: %@", copyDataStatement); + [connection queryString:copyDataStatement]; + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to copy table data", @"copy table data error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to copy a table's data.\n\nMySQL said: %@", + @"copy table data error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; + + } + return structureCopyResult; +} + +- (BOOL)moveTable:(NSString *)tableName from: (NSString *)sourceDB to: (NSString *)targetDB { + + NSString *moveStatement = [NSString stringWithFormat:@"RENAME TABLE %@.%@ TO %@.%@", + [sourceDB backtickQuotedString], + [tableName backtickQuotedString], + [targetDB backtickQuotedString], + [tableName backtickQuotedString] + ]; + // moving the table + DLog(@"Moving table %@ from %@ to %@", tableName, sourceDB, targetDB); + DLog(@"Moving table: %@", moveStatement); + [connection queryString:moveStatement]; + + if ([connection queryErrored]) { + SPBeginAlertSheet(NSLocalizedString(@"Failed to move table", @"move table error message"), + NSLocalizedString(@"OK", @"OK button"), nil, nil, [self getTableWindow], self, nil, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to move a table.\n\nMySQL said: %@", + @"move table error informative message"), + [connection getLastErrorMessage]]); + return NO; + } + return YES; +} + + +@end diff --git a/Source/TableDocument.h b/Source/TableDocument.h index 530fa1b4..8eb6cb4b 100644 --- a/Source/TableDocument.h +++ b/Source/TableDocument.h @@ -65,6 +65,8 @@ IBOutlet id titleStringView; IBOutlet id databaseSheet; + IBOutlet id databaseNewSheet; + IBOutlet id databaseRenameSheet; IBOutlet id queryProgressBar; IBOutlet NSBox *taskProgressLayer; @@ -75,8 +77,13 @@ IBOutlet id favoritesButton; IBOutlet id databaseNameField; + IBOutlet id databaseCopyNameField; + IBOutlet id databaseRenameNameField; IBOutlet id databaseEncodingButton; + IBOutlet id copyOnlyStructureButton; IBOutlet id addDatabaseButton; + IBOutlet id copyDatabaseButton; + IBOutlet id renameDatabaseButton; IBOutlet id chooseDatabaseButton; IBOutlet id historyControl; IBOutlet NSTabView *tableTabView; @@ -174,6 +181,7 @@ - (void)initWithConnectionFile:(NSString *)path; // Connection callback and methods - (void)setConnection:(MCPConnection *)theConnection; +- (MCPConnection *) getConnection; - (void)setShouldAutomaticallyConnect:(BOOL)shouldAutomaticallyConnect; - (BOOL)shouldAutomaticallyConnect; - (void)setKeychainID:(NSString *)theID; @@ -184,6 +192,8 @@ - (void)selectDatabase:(NSString *)aDatabase item:(NSString *)anItem; - (IBAction)addDatabase:(id)sender; - (IBAction)removeDatabase:(id)sender; +- (IBAction)copyDatabase:(id)sender; +- (IBAction)renameDatabase:(id)sender; - (IBAction)showMySQLHelp:(id)sender; - (IBAction)showServerVariables:(id)sender; - (IBAction)showServerProcesses:(id)sender; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index 3cda7ad1..6e0cac4c 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -57,10 +57,15 @@ #import "SPConstants.h" #import "SPMainThreadTrampoline.h" #import "SPLogger.h" +#import "SPDatabaseCopy.h" +#import "SPTableCopy.h" +#import "SPDatabaseRename.h" @interface TableDocument (PrivateAPI) - (void)_addDatabase; +- (void)_copyDatabase; +- (void)_renameDatabase; - (void)_removeDatabase; - (void)_selectDatabaseAndItem:(NSDictionary *)selectionDetails; @@ -755,6 +760,11 @@ } } +- (MCPConnection *) getConnection { + return mySQLConnection; +} + + /** * Set whether the connection controller should automatically start * connecting; called by maincontroller, but only for first window. @@ -911,9 +921,9 @@ - (IBAction)addDatabase:(id)sender { if (![tablesListInstance selectionShouldChangeInTableView:nil]) return; - + [databaseNameField setStringValue:@""]; - + [NSApp beginSheet:databaseSheet modalForWindow:tableWindow modalDelegate:self @@ -921,6 +931,39 @@ contextInfo:@"addDatabase"]; } + +/** + * opens the copy database sheet and copies the databsae + */ +- (IBAction)copyDatabase:(id)sender +{ + if (![tablesListInstance selectionShouldChangeInTableView:nil]) return; + + [databaseCopyNameField setStringValue:@""]; + + [NSApp beginSheet:databaseNewSheet + modalForWindow:tableWindow + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:@"copyDatabase"]; +} + +/** + * opens the rename database sheet and renames the databsae + */ +- (IBAction)renameDatabase:(id)sender +{ + if (![tablesListInstance selectionShouldChangeInTableView:nil]) return; + + [databaseRenameNameField setStringValue:@""]; + + [NSApp beginSheet:databaseRenameSheet + modalForWindow:tableWindow + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:@"renameDatabase"]; +} + /** * opens sheet to ask user if he really wants to delete the db */ @@ -1035,6 +1078,12 @@ else [chooseDatabaseButton selectItemAtIndex:0]; } + } + else if ([contextInfo isEqualToString:@"copyDatabase"]) { + [self _copyDatabase]; + } + else if ([contextInfo isEqualToString:@"renameDatabase"]) { + [self _renameDatabase]; } // Close error status sheet for OPTIMIZE, CHECK, REPAIR etc. else if ([contextInfo isEqualToString:@"statusError"]) { @@ -4086,6 +4135,43 @@ @implementation TableDocument (PrivateAPI) +- (void)_copyDatabase { + if ([[databaseCopyNameField stringValue] isEqualToString:@""]) { + SPBeginAlertSheet(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")); + return; + } + SPDatabaseCopy *dbActionCopy = [[SPDatabaseCopy alloc] init]; + [dbActionCopy setConnection: [self getConnection]]; + [dbActionCopy setParent: self]; + + BOOL copyWithContent = [copyOnlyStructureButton state] == NSOffState; + + [dbActionCopy copyDatabaseFrom: [self database] + to: [databaseCopyNameField stringValue] + withContent: copyWithContent]; + [dbActionCopy release]; + [selectedDatabase release]; + selectedDatabase = [[NSString alloc] initWithString:[databaseCopyNameField stringValue]]; + [self setDatabases: self]; +} + +- (void)_renameDatabase { + if ([[databaseRenameNameField stringValue] isEqualToString:@""]) { + SPBeginAlertSheet(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")); + return; + } + SPDatabaseRename *dbActionRename = [[SPDatabaseRename alloc] init]; + [dbActionRename setConnection: [self getConnection]]; + [dbActionRename setParent: self]; + + [dbActionRename renameDatabaseFrom: [self database] + to: [databaseRenameNameField stringValue]]; + [dbActionRename release]; + [selectedDatabase release]; + selectedDatabase = [[NSString alloc] initWithString:[databaseRenameNameField stringValue]]; + [self setDatabases: self]; +} + /** * Adds a new database. */ -- cgit v1.2.3