aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-03-30 13:29:49 +0000
committerBibiko <bibiko@eva.mpg.de>2010-03-30 13:29:49 +0000
commit052959a5d7f92a629445deffd990da315da5c856 (patch)
treec1080bad74547cd2445eb62a2cb3860473fe33e0
parentd6403ef10ff74af3d9ce05ce089055ff102a06eb (diff)
downloadsequelpro-052959a5d7f92a629445deffd990da315da5c856.tar.gz
sequelpro-052959a5d7f92a629445deffd990da315da5c856.tar.bz2
sequelpro-052959a5d7f92a629445deffd990da315da5c856.zip
• next trial to make getAllKeysOfDbStructure thread safe
• some speed improvements for navigator - pre-calculate display string for type info to avoid doing it all the time while refreshing the outline view • suppress double-clicking at a not yet queried db structure if the same connection is querying another structure to avoid accessing the same storage objects from different threads (test) • reload outline view after filtering in navigator runs in its own thread to avoid blocking SP • fixed memory leaks while returning [obj copy]
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m34
-rw-r--r--Source/SPNavigatorController.h2
-rw-r--r--Source/SPNavigatorController.m164
3 files changed, 135 insertions, 65 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
index 35d07a39..fd9842aa 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
@@ -33,6 +33,7 @@
#import "MCPStreamingResult.h"
#import "MCPConnectionProxy.h"
#import "MCPStringAdditions.h"
+#import "RegexKitLite.h"
#include <unistd.h>
#include <mach/mach_time.h>
@@ -1897,11 +1898,14 @@ void performThreadedKeepAlive(void *ptr)
SPUniqueSchemaDelimiter,
[[[self delegate] allDatabaseNames] componentsJoinedByString:SPUniqueSchemaDelimiter]]
componentsSeparatedByString:SPUniqueSchemaDelimiter];
+
for(id db in dbs) {
- if(![[structure valueForKey:connectionID] objectForKey:[NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, db]]) {
+ NSString *dbid = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, db];
+ if(![[structure valueForKey:connectionID] objectForKey:dbid]) {
// NSLog(@"added db %@", db);
removeAddFlag = YES;
- [[structure valueForKey:connectionID] setObject:db forKey:[NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, db]];
+ [[structure valueForKey:connectionID] setObject:db forKey:dbid];
+ [allKeysofDbStructure addObject:dbid];
}
}
@@ -2078,6 +2082,7 @@ void performThreadedKeepAlive(void *ptr)
while(row = mysql_fetch_row(theResult)) {
NSString *field = [self stringWithUTF8CString:row[0]];
NSString *type = [self stringWithUTF8CString:row[1]];
+ NSString *type_display = [type stringByReplacingOccurrencesOfRegex:@"\\(.*?,.*?\\)" withString:@"(…)"];
NSString *coll = [self stringWithUTF8CString:row[2]];
NSString *isnull = [self stringWithUTF8CString:row[3]];
NSString *key = [self stringWithUTF8CString:row[4]];
@@ -2097,7 +2102,7 @@ void performThreadedKeepAlive(void *ptr)
if(![[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id])
[[[structure valueForKey:connectionID] valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
- [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:[NSArray arrayWithObjects:type, def, isnull, charset, coll, key, extra, priv, comment, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:[NSArray arrayWithObjects:type, def, isnull, charset, coll, key, extra, priv, comment, type_display, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
[[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:@"0" forKey:@" struct_type "];
uniqueCounter++;
}
@@ -2126,6 +2131,7 @@ void performThreadedKeepAlive(void *ptr)
while(row = mysql_fetch_row(theResult)) {
NSString *field = [self stringWithUTF8CString:row[0]];
NSString *type = [self stringWithUTF8CString:row[1]];
+ NSString *type_display = [type stringByReplacingOccurrencesOfRegex:@"\\(.*?,.*?\\)" withString:@"(…)"];
NSString *coll = [self stringWithUTF8CString:row[2]];
NSString *isnull = [self stringWithUTF8CString:row[3]];
NSString *key = [self stringWithUTF8CString:row[4]];
@@ -2145,7 +2151,7 @@ void performThreadedKeepAlive(void *ptr)
if(![[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id])
[[[structure valueForKey:connectionID] valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
- [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:[NSArray arrayWithObjects:type, def, isnull, charset, coll, key, extra, priv, comment, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:[NSArray arrayWithObjects:type, def, isnull, charset, coll, key, extra, priv, comment, type_display, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
[[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:@"1" forKey:@" struct_type "];
uniqueCounter++;
}
@@ -2213,7 +2219,7 @@ void performThreadedKeepAlive(void *ptr)
*/
- (NSDictionary *)getDbStructure
{
- return [structure copy];
+ return [[structure copy] autorelease];
}
/**
@@ -2221,7 +2227,23 @@ void performThreadedKeepAlive(void *ptr)
*/
- (NSArray *)getAllKeysOfDbStructure
{
- return [allKeysofDbStructure copy];
+ NSArray *r = nil;
+ @try
+ {
+ r = [NSArray arrayWithArray:allKeysofDbStructure];
+ }
+ @catch(id ae)
+ {
+ @try
+ {
+ r = [NSArray arrayWithArray:allKeysofDbStructure];
+ }
+ @catch(id ae)
+ {
+ return nil;
+ }
+ }
+ return r;
}
#pragma mark -
diff --git a/Source/SPNavigatorController.h b/Source/SPNavigatorController.h
index 061ebd86..6c31b013 100644
--- a/Source/SPNavigatorController.h
+++ b/Source/SPNavigatorController.h
@@ -56,6 +56,8 @@
BOOL ignoreUpdate;
BOOL isFiltered;
+ BOOL isFiltering;
+
NSImage *connectionIcon;
NSImage *databaseIcon;
NSImage *tableIcon;
diff --git a/Source/SPNavigatorController.m b/Source/SPNavigatorController.m
index 40a7ef7c..439b4d5c 100644
--- a/Source/SPNavigatorController.m
+++ b/Source/SPNavigatorController.m
@@ -75,6 +75,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
selectedKey2 = @"";
ignoreUpdate = NO;
isFiltered = NO;
+ isFiltering = NO;
[syncButton setState:NSOffState];
NSDictionaryClass = [NSDictionary class];
@@ -222,6 +223,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)selectPath:(NSString*)schemaPath
{
+
if(schemaPath && [schemaPath length]) {
// Do not change the selection if a field of schemaPath's table is already selected
@@ -358,16 +360,28 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)selectInActiveDocumentItem:(id)item fromView:(id)outlineView
{
+ // Do nothing for connection root item yet
if([outlineView levelForItem:item] == 0) return;
+
+ NSPoint pos = [NSEvent mouseLocation];
+ pos.y -= 20;
+
+ // Suppress selecting for not queried database if connection is just querying an other database
+ if([outlineView levelForItem:item] == 1
+ && ![outlineView isExpandable:item] && [updatingConnections count]) {
+ [SPTooltip showWithObject:NSLocalizedString(@"The connection is busy. Please wait and try again.", @"the connection is busy. please wait and try again tooltip")
+ atLocation:pos
+ ofType:@"text"];
+
+ return;
+ }
+
id parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
if(!parentObject) return;
id parentKeys = [parentObject allKeysForObject:item];
if(parentKeys && [parentKeys count] == 1) {
- NSPoint pos = [NSEvent mouseLocation];
- pos.y -= 20;
-
NSArray *pathArray = [[[parentKeys objectAtIndex:0] description] componentsSeparatedByString:SPUniqueSchemaDelimiter];
if([pathArray count] > 1) {
@@ -406,10 +420,10 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)isUpdatingNavigator:(NSNotification *)aNotification
{
- id object = [aNotification object];
-
- if([object isKindOfClass:[TableDocument class]])
- [updatingConnections addObject:[object connectionID]];
+ // id object = [aNotification object];
+ //
+ // if([object isKindOfClass:[TableDocument class]])
+ // [updatingConnections addObject:[object connectionID]];
}
@@ -439,6 +453,9 @@ static SPNavigatorController *sharedNavigatorController = nil;
return;
}
+ [updatingConnections addObject:connectionName];
+
+
if(![schemaData objectForKey:connectionName]) {
[schemaData setObject:[NSMutableDictionary dictionary] forKey:connectionName];
}
@@ -463,13 +480,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
[schemaData setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"%@&DEL&no data loaded yet", connectionName]];
[allSchemaKeys setObject:[NSArray array] forKey:connectionName];
}
- [updatingConnections removeObject:connectionName];
[outlineSchema1 reloadData];
[outlineSchema2 reloadData];
[self restoreExpandStatus];
[self restoreSelectedItems];
+
+ [updatingConnections removeObject:connectionName];
+
}
[self syncButtonAction:self];
@@ -574,6 +593,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
[schemaDataFiltered removeAllObjects];
[schemaData removeObjectForKey:connectionID];
[allSchemaKeys removeObjectForKey:connectionID];
+ [updatingConnections removeAllObjects];
[infoArray removeAllObjects];
[expandStatus1 removeAllObjects];
[expandStatus2 removeAllObjects];
@@ -598,8 +618,12 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (IBAction)filterTree:(id)sender
{
+
NSString *pattern = [[[searchField stringValue] stringByReplacingOccurrencesOfString:@"." withString:SPUniqueSchemaDelimiter] lowercaseString];
+ // Suppress search for '.' since this matches everything
+ if([pattern isEqualToString:SPUniqueSchemaDelimiter]) return;
+
[self saveSelectedItems];
id currentItem = [outlineSchema2 selectedItem];
@@ -609,67 +633,88 @@ static SPNavigatorController *sharedNavigatorController = nil;
else
parentObject = [outlineSchema2 parentForItem:currentItem] ? [outlineSchema2 parentForItem:currentItem] : schemaData;
- NSString *connectionID = nil;
- if(parentObject && [[parentObject allKeys] count])
- connectionID = [[[[parentObject allKeys] objectAtIndex:0] componentsSeparatedByString:SPUniqueSchemaDelimiter] objectAtIndex:0];
+ @try{
+
+
+ NSString *connectionID = nil;
+ if(parentObject && [[parentObject allKeys] count])
+ connectionID = [[[[parentObject allKeys] objectAtIndex:0] componentsSeparatedByString:SPUniqueSchemaDelimiter] objectAtIndex:0];
- if((pattern && ![pattern length]) || !parentObject || ![[parentObject allKeys] count] || !connectionID || [connectionID length] < 2 || ![allSchemaKeys objectForKey:connectionID]) {
- isFiltered = NO;
- [searchField setStringValue:@""];
- [schemaDataFiltered removeAllObjects];
- [outlineSchema2 reloadData];
- [self restoreExpandStatus];
- [self restoreSelectedItems];
- return;
- }
+ if((pattern && ![pattern length]) || !parentObject || ![[parentObject allKeys] count] || !connectionID || [connectionID length] < 2 || ![allSchemaKeys objectForKey:connectionID]) {
+ isFiltered = NO;
+ [searchField setStringValue:@""];
+ [schemaDataFiltered removeAllObjects];
+ [outlineSchema2 reloadData];
+ [self restoreExpandStatus];
+ [self restoreSelectedItems];
+ isFiltering = NO;
+ return;
+ }
- isFiltered = YES;
+ if(isFiltering) return;
- [syncButton setState:NSOffState];
+ isFiltered = YES;
- NSMutableDictionary *structure = [NSMutableDictionary dictionary];
- [structure setObject:[NSMutableDictionary dictionary] forKey:connectionID];
+ [syncButton setState:NSOffState];
+ NSMutableDictionary *structure = [NSMutableDictionary dictionary];
+ [structure setObject:[NSMutableDictionary dictionary] forKey:connectionID];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", pattern];
- NSArray *filteredItems = [[allSchemaKeys objectForKey:connectionID] filteredArrayUsingPredicate:predicate];
- for(NSString* item in filteredItems) {
- NSArray *a = [item componentsSeparatedByString:SPUniqueSchemaDelimiter];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", pattern];
+ NSArray *filteredItems = [[allSchemaKeys objectForKey:connectionID] filteredArrayUsingPredicate:predicate];
- NSString *db_id = [NSString stringWithFormat:@"%@%@%@", connectionID,SPUniqueSchemaDelimiter,NSArrayObjectAtIndex(a, 1)];
+ BOOL searchFailed = NO;
- if(!a || [a count] < 2) continue;
+ for(NSString* item in filteredItems) {
+ NSArray *a = [item componentsSeparatedByString:SPUniqueSchemaDelimiter];
- if(![[structure valueForKey:connectionID] valueForKey:db_id]) {
- [[structure valueForKey:connectionID] setObject:[NSMutableDictionary dictionary] forKey:db_id];
- }
- if([a count] > 2) {
+ NSString *db_id = [NSString stringWithFormat:@"%@%@%@", connectionID,SPUniqueSchemaDelimiter,NSArrayObjectAtIndex(a, 1)];
- NSString *table_id = [NSString stringWithFormat:@"%@%@%@", db_id,SPUniqueSchemaDelimiter,[a objectAtIndex:2]];
+ if(!a || [a count] < 2) continue;
- if(![[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id]) {
- [[[structure valueForKey:connectionID] valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
+ if(![[structure valueForKey:connectionID] valueForKey:db_id]) {
+ [[structure valueForKey:connectionID] setObject:[NSMutableDictionary dictionary] forKey:db_id];
}
+ if([a count] > 2) {
+
+ NSString *table_id = [NSString stringWithFormat:@"%@%@%@", db_id,SPUniqueSchemaDelimiter,[a objectAtIndex:2]];
- if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "])
- [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
- [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "] forKey:@" struct_type "];
- else
- [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
- [NSNumber numberWithInt:0] forKey:@" struct_type "];
+ if(![[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id]) {
+ [[[structure valueForKey:connectionID] valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
+ }
- if([a count] > 3) {
- NSString *field_id = [NSString stringWithFormat:@"%@%@%@", table_id,SPUniqueSchemaDelimiter,[a objectAtIndex:3]];
- if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id])
+ if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "])
[[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
- [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id] forKey:field_id];
+ [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "] forKey:@" struct_type "];
+ else
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
+ [NSNumber numberWithInt:0] forKey:@" struct_type "];
+
+ if([a count] > 3) {
+ NSString *field_id = [NSString stringWithFormat:@"%@%@%@", table_id,SPUniqueSchemaDelimiter,[a objectAtIndex:3]];
+ if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id])
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
+ [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id] forKey:field_id];
+ }
}
}
+ [schemaDataFiltered setDictionary:[structure retain]];
+ [NSThread detachNewThreadSelector:@selector(reloadAfterFiltering) toTarget:self withObject:nil];
+
+ }
+ @catch(id ae)
+ {
+ NSPoint pos = [NSEvent mouseLocation];
+ pos.y -= 20;
+
+ [SPTooltip showWithObject:NSLocalizedString(@"Filtering failed. Please try again.", @"filtering failed. please try again. tooltip")
+ atLocation:pos
+ ofType:@"text"];
+
+ isFiltering = NO;
}
- [schemaDataFiltered setDictionary:[structure retain]];
- [NSThread detachNewThreadSelector:@selector(reloadAfterFiltering) toTarget:self withObject:nil];
}
@@ -678,6 +723,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[outlineSchema2 reloadData];
[outlineSchema2 expandItem:[outlineSchema2 itemAtRow:0] expandChildren:YES];
+ isFiltering = NO;
[pool release];
}
@@ -905,8 +951,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
if([outlineView levelForItem:item] == 3 && [item isKindOfClass:[NSArray class]])
{
- NSString *typ = [NSString stringWithFormat:@"%@,%@,%@", [NSArrayObjectAtIndex(item, 0) stringByReplacingOccurrencesOfRegex:@"\\(.*?,.*?\\)" withString:@"(…)"], NSArrayObjectAtIndex(item, 3), NSArrayObjectAtIndex(item, 5)];
- NSTokenFieldCell *b = [[[NSTokenFieldCell alloc] initTextCell:typ] autorelease];
+ NSTokenFieldCell *b = [[[NSTokenFieldCell alloc] initTextCell:NSArrayObjectAtIndex(item, 9)] autorelease];
[b setEditable:NO];
[b setAlignment:NSRightTextAlignment];
[b setFont:[NSFont systemFontOfSize:11]];
@@ -986,11 +1031,12 @@ static SPNavigatorController *sharedNavigatorController = nil;
// selected item is a field
if([selectedItem isKindOfClass:[NSArray class]]) {
NSInteger i = 0;
- for(id item in selectedItem) {
- if([item isKindOfClass:[NSString class]] && [(NSString*)item length]) {
- [infoArray addObject:[NSString stringWithFormat:@"%@: %@", [self tableInfoLabelForIndex:i ofType:0], [item stringByReplacingOccurrencesOfString:@"," withString:@", "]]];
- }
- i++;
+ for(i=0; i<[selectedItem count]-2; i++) {
+ NSString *item = NSArrayObjectAtIndex(selectedItem, i);
+ if(![item length]) continue;
+ [infoArray addObject:[NSString stringWithFormat:@"%@: %@",
+ [self tableInfoLabelForIndex:i ofType:0],
+ [item stringByReplacingOccurrencesOfString:@"," withString:@", "]]];
}
}
@@ -1002,9 +1048,9 @@ static SPNavigatorController *sharedNavigatorController = nil;
NSInteger keyIndex = 0;
if(keys && [keys count] == 2) {
// there only are two keys, get that key which doesn't begin with " " due to it's the struct_type key
- if([[keys objectAtIndex:keyIndex] hasPrefix:@" "]) keyIndex++;
- if([keys objectAtIndex:keyIndex] && [[selectedItem objectForKey:[keys objectAtIndex:keyIndex]] isKindOfClass:[NSArray class]]) {
- for(id item in [selectedItem objectForKey:[keys objectAtIndex:keyIndex]]) {
+ if([NSArrayObjectAtIndex(keys, keyIndex) hasPrefix:@" "]) keyIndex++;
+ if(NSArrayObjectAtIndex(keys, keyIndex) && [[selectedItem objectForKey:NSArrayObjectAtIndex(keys, keyIndex)] isKindOfClass:[NSArray class]]) {
+ for(id item in [selectedItem objectForKey:NSArrayObjectAtIndex(keys, keyIndex)]) {
if([item isKindOfClass:[NSString class]] && [(NSString*)item length]) {
[infoArray addObject:[NSString stringWithFormat:@"%@: %@", [self tableInfoLabelForIndex:i ofType:type], item]];
}