aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/SPDatabaseDocument.h24
-rw-r--r--Source/SPDatabaseDocument.m16
-rw-r--r--Source/SPExtendedTableInfo.m1
-rw-r--r--Source/SPTableRelations.h7
-rw-r--r--Source/SPTableRelations.m199
5 files changed, 160 insertions, 87 deletions
diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h
index a0d02bb6..d79610e9 100644
--- a/Source/SPDatabaseDocument.h
+++ b/Source/SPDatabaseDocument.h
@@ -240,6 +240,19 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
}
#ifdef SP_REFACTOR /* ivars */
+@property (assign) SPDatabaseData* databaseDataInstance;
+@property (assign) SPTableData* tableDataInstance;
+@property (assign) SPCustomQuery* customQueryInstance;
+@property (assign) id databaseNameField;
+@property (assign) id databaseEncodingButton;
+@property (assign) id addDatabaseButton;
+
+@property (assign) id databaseRenameNameField;
+@property (assign) id renameDatabaseButton;
+@property (assign) id databaseRenameSheet;
+#endif
+
+#ifdef SP_REFACTOR /* ivars */
@property (assign) id delegate;
@property (readonly) NSMutableArray* allDatabases;
@property (assign) NSProgressIndicator* queryProgressBar;
@@ -449,17 +462,6 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
- (void)setTableSourceInstance:(SPTableStructure*)source;
- (void)setTableContentInstance:(SPTableContent*)content;
-@property (assign) SPDatabaseData* databaseDataInstance;
-@property (assign) SPTableData* tableDataInstance;
-@property (assign) SPCustomQuery* customQueryInstance;
-@property (assign) id databaseNameField;
-@property (assign) id databaseEncodingButton;
-@property (assign) id addDatabaseButton;
-
-@property (assign) id databaseRenameNameField;
-@property (assign) id renameDatabaseButton;
-@property (assign) id databaseRenameSheet;
-
#endif
@end
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index 52858787..a6b905b2 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -73,6 +73,7 @@ enum {
#import "SPDatabaseCopy.h"
#import "SPTableCopy.h"
#import "SPDatabaseRename.h"
+#import "SPTableRelations.h"
#endif
#import "SPServerSupport.h"
#ifndef SP_REFACTOR /* headers */
@@ -227,6 +228,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// Set the connection controller's delegate
[connectionController setDelegate:self];
+
return connectionController;
}
@@ -5890,7 +5892,6 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
#endif
}
-
/**
* Select the specified database and, optionally, table.
*/
@@ -5923,7 +5924,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// End the task first to ensure the database dropdown can be reselected
[self endTask];
- if ( [mySQLConnection isConnected] ) {
+ if ([mySQLConnection isConnected]) {
// Update the database list
[[self onMainThread] setDatabases:self];
@@ -5970,10 +5971,14 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// Set focus to table list filter field if visible
// otherwise set focus to Table List view
- if ( [[tablesListInstance tables] count] > 20 )
+ if ([[tablesListInstance tables] count] > 20) {
[[parentWindow onMainThread] makeFirstResponder:listFilterField];
- else
+ }
+ else {
[[parentWindow onMainThread] makeFirstResponder:[tablesListInstance valueForKeyPath:@"tablesListView"]];
+ }
+
+ [tableRelationsInstance loadUsedRelationNames];
#endif
}
@@ -6031,8 +6036,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
#endif
#ifdef SP_REFACTOR /* glue */
- if ( delegate && [delegate respondsToSelector:@selector(databaseDidChange:)] )
+ if (delegate && [delegate respondsToSelector:@selector(databaseDidChange:)]) {
[delegate performSelectorOnMainThread:@selector(databaseDidChange:) withObject:self waitUntilDone:NO];
+ }
#endif
[taskPool drain];
diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m
index 13e60f92..a1e59110 100644
--- a/Source/SPExtendedTableInfo.m
+++ b/Source/SPExtendedTableInfo.m
@@ -383,7 +383,6 @@
*/
- (NSDictionary *)tableInformationForPrinting
{
-
// Update possible pending comment changes by set the focus to create table syntax view
[[NSApp keyWindow] makeFirstResponder:tableCreateSyntaxTextView];
diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h
index 74dd0a17..a600ebf0 100644
--- a/Source/SPTableRelations.h
+++ b/Source/SPTableRelations.h
@@ -50,12 +50,16 @@
IBOutlet NSPopUpButton *onUpdatePopUpButton;
IBOutlet NSPopUpButton *onDeletePopUpButton;
IBOutlet NSButton *confirmAddRelationButton;
+ IBOutlet NSProgressIndicator *dataProgressIndicator;
+ IBOutlet NSTextField *progressStatusTextField;
MCPConnection *connection;
- NSMutableArray *relationData;
NSUserDefaults *prefs;
+ NSMutableArray *relationData;
NSMutableArray *takenConstraintNames;
+
+ BOOL isRetrievingRelationNames;
}
@property (readonly) NSMutableArray *relationData;
@@ -77,6 +81,7 @@
- (void)endDocumentTaskForTab:(NSNotification *)aNotification;
// Other
+- (void)loadUsedRelationNames;
- (NSArray *)relationDataForPrinting;
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo;
diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m
index 01fc4a6e..a26e9039 100644
--- a/Source/SPTableRelations.m
+++ b/Source/SPTableRelations.m
@@ -30,10 +30,14 @@
#import "SPTableView.h"
#import "SPAlertSheets.h"
+static NSString *SPRemoveRelation = @"SPRemoveRelation";
+
@interface SPTableRelations ()
- (void)_refreshRelationDataForcingCacheRefresh:(BOOL)clearAllCaches;
- (void)_updateAvailableTableColumns;
+- (void)_loadUsedRelationNamesInBackground;
+- (void)_relationNamesLoaded;
@end
@@ -51,6 +55,8 @@
relationData = [[NSMutableArray alloc] init];
prefs = [NSUserDefaults standardUserDefaults];
takenConstraintNames = [[NSMutableArray alloc] init];
+
+ isRetrievingRelationNames = NO;
}
return self;
@@ -176,7 +182,6 @@
*/
- (IBAction)addRelation:(id)sender
{
-
// Check whether table editing is permitted (necessary as some actions - eg table double-click - bypass validation)
if ([tableDocumentInstance isWorking] || [tablesListInstance tableType] != SPTableTypeTable) return;
@@ -208,17 +213,6 @@
[refTablePopUpButton addItemWithTitle:[[result fetchRowAsArray] objectAtIndex:0]];
}
- // Get a list of used constraint names for this db
- [takenConstraintNames removeAllObjects];
- result = [connection queryString:[NSString stringWithFormat:@"SELECT DISTINCT constraint_name FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY' AND constraint_schema = %@", [[tableDocumentInstance database] tickQuotedString]]];
-
- [result dataSeek:0];
-
- for (NSUInteger i = 0; i < [result numOfRows]; i++)
- {
- [takenConstraintNames addObject:[[[result fetchRowAsArray] objectAtIndex:0] lowercaseString]];
- }
-
// Reset other fields
[constraintName setStringValue:@""];
[onDeletePopUpButton selectItemAtIndex:0];
@@ -258,7 +252,7 @@
[[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask];
[[buttons objectAtIndex:1] setKeyEquivalent:@"\r"];
- [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:@"removeRelation"];
+ [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:SPRemoveRelation];
}
}
@@ -293,7 +287,8 @@
[addRelationButton setEnabled:enableInteraction];
[refreshRelationsButton setEnabled:enableInteraction];
[relationsTableView setEnabled:YES];
- } else {
+ }
+ else {
[addRelationButton setEnabled:NO];
[refreshRelationsButton setEnabled:NO];
[relationsTableView setEnabled:NO];
@@ -307,34 +302,31 @@
#pragma mark -
#pragma mark TextField delegate methods
-- (void)controlTextDidChange:(NSNotification *)aNotification
-{
- id field = [aNotification object];
-
+- (void)controlTextDidChange:(NSNotification *)notification
+{
// Make sure the user does not enter a taken name
- if (field == constraintName) {
+ if ([notification object] == constraintName) {
- NSString *userValue = [[constraintName stringValue] lowercaseString];
BOOL taken = NO;
- for(NSString *takenName in takenConstraintNames) {
- if([takenName isEqualToString:userValue]) {
+ NSString *userValue = [[constraintName stringValue] lowercaseString];
+
+ for (NSString *takenName in takenConstraintNames)
+ {
+ if ([takenName isEqualToString:userValue]) {
taken = YES;
break;
}
}
- //make field red and disable add button
- if(taken) {
+ // Make field red and disable add button
+ if (taken) {
[constraintName setTextColor:[NSColor redColor]];
[confirmAddRelationButton setEnabled:NO];
}
- //reset
else {
[constraintName setTextColor:[NSColor controlTextColor]];
[confirmAddRelationButton setEnabled:YES];
}
-
- return;
}
}
@@ -366,7 +358,7 @@
* Double-click action on table cells - for the time being, return
* NO to disable editing.
*/
-- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
+- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
if ([tableDocumentInstance isWorking]) return NO;
@@ -376,7 +368,7 @@
/**
* Disable row selection while the document is working.
*/
-- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex
+- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex
{
return ![tableDocumentInstance isWorking];
}
@@ -419,6 +411,26 @@
#pragma mark Other
/**
+ * Loads the currently used relation names from information_schema.table_constraints.
+ */
+- (void)loadUsedRelationNames
+{
+ if (isRetrievingRelationNames) return;
+
+ [dataProgressIndicator setHidden:NO];
+ [dataProgressIndicator startAnimation:self];
+
+ [progressStatusTextField setHidden:NO];
+
+ [constraintName setEnabled:NO];
+ [confirmAddRelationButton setEnabled:NO];
+
+ isRetrievingRelationNames = YES;
+
+ [NSThread detachNewThreadSelector:@selector(_loadUsedRelationNamesInBackground) toTarget:self withObject:nil];
+}
+
+/**
* Returns an array of relation data to be used for printing purposes. The first element in the array is always
* an array of the columns and each subsequent element is an array of relation data.
*/
@@ -462,7 +474,7 @@
*/
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo
{
- if ([contextInfo isEqualToString:@"removeRelation"]) {
+ if ([contextInfo isEqualToString:SPRemoveRelation]) {
if (returnCode == NSAlertDefaultReturn) {
@@ -536,22 +548,7 @@
}
#pragma mark -
-
-/*
- * Dealloc.
- */
-- (void)dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:SPUseMonospacedFonts];
-
- [relationData release], relationData = nil;
-
- [takenConstraintNames release];
- takenConstraintNames = nil;
-
- [super dealloc];
-}
+#pragma mark Private API
/**
* Refresh the displayed relations, optionally forcing a refresh of the underlying cache.
@@ -561,22 +558,22 @@
[relationData removeAllObjects];
if ([tablesListInstance tableType] == SPTableTypeTable) {
-
+
if (clearAllCaches) [tableDataInstance updateInformationForCurrentTable];
-
+
NSArray *constraints = [tableDataInstance getConstraints];
-
+
for (NSDictionary *constraint in constraints)
{
[relationData addObject:[NSDictionary dictionaryWithObjectsAndKeys:
- [constraint objectForKey:@"name"], @"name",
- [[constraint objectForKey:@"columns"] objectAtIndex:0], @"columns",
- [constraint objectForKey:@"ref_table"], @"fk_table",
- [constraint objectForKey:@"ref_columns"], @"fk_columns",
- ([constraint objectForKey:@"update"] ? [constraint objectForKey:@"update"] : @""), @"on_update",
- ([constraint objectForKey:@"delete"] ? [constraint objectForKey:@"delete"] : @""), @"on_delete",
- nil]];
-
+ [constraint objectForKey:@"name"], @"name",
+ [[constraint objectForKey:@"columns"] objectAtIndex:0], @"columns",
+ [constraint objectForKey:@"ref_table"], @"fk_table",
+ [constraint objectForKey:@"ref_columns"], @"fk_columns",
+ ([constraint objectForKey:@"update"] ? [constraint objectForKey:@"update"] : @""), @"on_update",
+ ([constraint objectForKey:@"delete"] ? [constraint objectForKey:@"delete"] : @""), @"on_delete",
+ nil]];
+
}
}
@@ -591,24 +588,24 @@
{
NSString *column = [columnPopUpButton titleOfSelectedItem];
NSString *table = [refTablePopUpButton titleOfSelectedItem];
-
+
[tableDataInstance resetAllData];
[tableDataInstance updateInformationForCurrentTable];
-
+
NSDictionary *columnInfo = [[tableDataInstance columnWithName:column] copy];
-
+
[refColumnPopUpButton setEnabled:NO];
[confirmAddRelationButton setEnabled:NO];
-
+
[refColumnPopUpButton removeAllItems];
-
+
[tableDataInstance resetAllData];
NSDictionary *tableInfo = [tableDataInstance informationForTable:table];
-
+
NSArray *columns = [tableInfo objectForKey:@"columns"];
-
+
NSMutableArray *validColumns = [NSMutableArray array];
-
+
// Only add columns of the same data type
for (NSDictionary *aColumn in columns)
{
@@ -616,17 +613,81 @@
[validColumns addObject:[aColumn objectForKey:@"name"]];
}
}
-
+
// Add the valid columns
if ([validColumns count] > 0) {
NSArray *columnTitles = ([prefs boolForKey:SPAlphabeticalTableSorting])? [validColumns sortedArrayUsingSelector:@selector(compare:)] : validColumns;
+
[refColumnPopUpButton addItemsWithTitles:columnTitles];
-
+
[refColumnPopUpButton setEnabled:YES];
- [confirmAddRelationButton setEnabled:YES];
+
+ if (!isRetrievingRelationNames) {
+ [confirmAddRelationButton setEnabled:YES];
+ }
}
-
+
[columnInfo release];
}
+/**
+ * Loads all of the current foreign key relationship names for the current database. This method should be
+ * spawned on a separate thread.
+ */
+- (void)_loadUsedRelationNamesInBackground
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ [takenConstraintNames removeAllObjects];
+
+ MCPResult *result = [connection queryString:[NSString stringWithFormat:@"SELECT DISTINCT constraint_name FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY' AND constraint_schema = %@", [[tableDocumentInstance database] tickQuotedString]]];
+
+ [result dataSeek:0];
+
+ for (NSUInteger i = 0; i < [result numOfRows]; i++)
+ {
+ [takenConstraintNames addObject:[[[result fetchRowAsArray] objectAtIndex:0] lowercaseString]];
+ }
+
+ // Update the UI on the main thread
+ [self performSelectorOnMainThread:@selector(_relationNamesLoaded) withObject:nil waitUntilDone:NO];
+
+ [pool release];
+}
+
+/**
+ * Called on the main thread, once all the current table relation names have been loaded and re-enables all
+ * the relevant UI controls.
+ */
+- (void)_relationNamesLoaded
+{
+ [dataProgressIndicator setHidden:YES];
+ [dataProgressIndicator stopAnimation:self];
+
+ [progressStatusTextField setHidden:YES];
+
+ [constraintName setEnabled:YES];
+ [confirmAddRelationButton setEnabled:YES];
+
+ [addRelationPanel makeFirstResponder:constraintName];
+
+ isRetrievingRelationNames = NO;
+}
+
+#pragma mark -
+
+/*
+ * Dealloc.
+ */
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:SPUseMonospacedFonts];
+
+ [relationData release], relationData = nil;
+ [takenConstraintNames release], takenConstraintNames = nil;
+
+ [super dealloc];
+}
+
@end