aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2013-03-09 23:22:03 +0000
committerrowanbeentje <rowan@beent.je>2013-03-09 23:22:03 +0000
commit5f3881c0f03e6d103bb09a4fb8da525b761b40dc (patch)
tree73e424b2607d01025ed7673f12f6ee794f6ffe92 /Source
parentc51d93d760b6ad47ac4256bdf564688cb9a5d2f8 (diff)
downloadsequelpro-5f3881c0f03e6d103bb09a4fb8da525b761b40dc.tar.gz
sequelpro-5f3881c0f03e6d103bb09a4fb8da525b761b40dc.tar.bz2
sequelpro-5f3881c0f03e6d103bb09a4fb8da525b761b40dc.zip
Tweak and improve the User Manager:
- Rework how data to populate the user manager is retrieved from the server, speeding up display of lots of users by a large factor - Fix support for schema permissions for the Anonymous user, and add support for '%' and '' hostnames (only showing if already set once), fixing Issue #1620 - Highlight databases in the user manager that have permissions set for the selected user - Switch to using the centrally provided database list to reduce queries and remove the information_schema and performance_schema "databases" - Speed up a number of operations by tweaking the logic and queries used
Diffstat (limited to 'Source')
-rw-r--r--Source/SPDatabaseDocument.m17
-rw-r--r--Source/SPUserMO.m8
-rw-r--r--Source/SPUserManager.h3
-rw-r--r--Source/SPUserManager.m137
-rw-r--r--Source/SPUserManagerDataSource.h37
-rw-r--r--Source/SPUserManagerDataSource.m53
-rw-r--r--Source/SPUserManagerDelegate.m54
7 files changed, 236 insertions, 73 deletions
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index f8b673ff..8286167a 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -2382,16 +2382,17 @@ static NSString *SPRenameDatabaseAction = @"SPRenameDatabase";
*/
- (IBAction)showUserManager:(id)sender
{
- if (!userManagerInstance)
- {
- userManagerInstance = [[SPUserManager alloc] init];
+ if (!userManagerInstance)
+ {
+ userManagerInstance = [[SPUserManager alloc] init];
- [userManagerInstance setConnection:mySQLConnection];
+ [userManagerInstance setDatabaseDocument:self];
+ [userManagerInstance setConnection:mySQLConnection];
[userManagerInstance setServerSupport:serverSupport];
- }
-
+ }
+
// Before displaying the user manager make sure the current user has access to the mysql.user table.
- SPMySQLResult *result = [mySQLConnection queryString:@"SELECT * FROM `mysql`.`user` ORDER BY `user`"];
+ SPMySQLResult *result = [mySQLConnection queryString:@"SELECT user FROM mysql.user LIMIT 1"];
if ([mySQLConnection queryErrored] && ([result numberOfRows] == 0)) {
@@ -2417,7 +2418,7 @@ static NSString *SPRenameDatabaseAction = @"SPRenameDatabase";
- (void)userManagerSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context
{
- [userManagerInstance release], userManagerInstance = nil;
+ [userManagerInstance release], userManagerInstance = nil;
}
/**
diff --git a/Source/SPUserMO.m b/Source/SPUserMO.m
index e02bb009..6e166700 100644
--- a/Source/SPUserMO.m
+++ b/Source/SPUserMO.m
@@ -46,7 +46,13 @@ static NSString *SPUserMOChildrenKey = @"children";
- (NSString *)displayName
{
- return ([self valueForKey:SPUserMOParentKey] == nil) ? self.user : self.host;
+ if ([self valueForKey:SPUserMOParentKey] == nil) {
+ return self.user;
+ }
+ if ([self.host length]) {
+ return self.host;
+ }
+ return @"%";
}
- (void)setDisplayName:(NSString *)value
diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h
index b156cd4c..caa12776 100644
--- a/Source/SPUserManager.h
+++ b/Source/SPUserManager.h
@@ -33,6 +33,7 @@
@class SPServerSupport;
@class SPMySQLConnection;
@class SPSplitView;
+@class SPDatabaseDocument;
@interface SPUserManager : NSWindowController
{
@@ -50,7 +51,6 @@
IBOutlet NSTreeController *treeController;
IBOutlet NSMutableDictionary *privsSupportedByServer;
- IBOutlet NSArrayController *schemaController;
IBOutlet NSArrayController *grantedController;
IBOutlet NSArrayController *availableController;
@@ -82,6 +82,7 @@
}
@property (nonatomic, retain) SPMySQLConnection *connection;
+@property (nonatomic, assign) SPDatabaseDocument *databaseDocument;
@property (nonatomic, retain) SPServerSupport *serverSupport;
@property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m
index eb69203a..388da2b1 100644
--- a/Source/SPUserManager.m
+++ b/Source/SPUserManager.m
@@ -38,6 +38,7 @@
#import "SPServerSupport.h"
#import "SPAlertSheets.h"
#import "SPSplitView.h"
+#import "SPDatabaseDocument.h"
#import <SPMySQL/SPMySQL.h>
#import <QueryKit/QueryKit.h>
@@ -56,7 +57,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
- (BOOL)_checkAndDisplayMySqlError;
- (void)_clearData;
- (void)_initializeChild:(NSManagedObject *)child withItem:(NSDictionary *)item;
-- (void)_initializeSchemaPrivsForChild:(NSManagedObject *)child;
+- (void)_initializeSchemaPrivsForChild:(NSManagedObject *)child fromData:(NSArray *)dataForUser;
- (void)_initializeSchemaPrivs;
- (NSArray *)_fetchPrivsWithUser:(NSString *)username schema:(NSString *)selectedSchema host:(NSString *)host;
- (void)_setSchemaPrivValues:(NSArray *)objects enabled:(BOOL)enabled;
@@ -68,6 +69,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
@implementation SPUserManager
@synthesize connection;
+@synthesize databaseDocument;
@synthesize privsSupportedByServer;
@synthesize managedObjectContext;
@synthesize managedObjectModel;
@@ -128,8 +130,9 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
[grantedTableView setDoubleAction:@selector(doubleClickSchemaPriv:)];
[availableTableView setDoubleAction:@selector(doubleClickSchemaPriv:)];
- [self _initializeUsers];
[self _initializeSchemaPrivs];
+ [self _initializeUsers];
+ [self _initializeAvailablePrivs];
treeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayName" ascending:YES];
@@ -213,6 +216,28 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
*/
- (void)_initializeTree:(NSArray *)items
{
+
+ // Retrieve all the user data in order to be able to initialise the schema privs for each child,
+ // copying into a dictionary keyed by user, each with all the host rows.
+ NSMutableDictionary *schemaPrivilegeData = [NSMutableDictionary dictionary];
+ SPMySQLResult *queryResults = [[self connection] queryString:@"SELECT * FROM mysql.db"];
+ [queryResults setReturnDataAsStrings:YES];
+ for (NSDictionary *privRow in queryResults) {
+ if (![schemaPrivilegeData objectForKey:[privRow objectForKey:@"User"]]) {
+ [schemaPrivilegeData setObject:[NSMutableArray array] forKey:[privRow objectForKey:@"User"]];
+ }
+ [[schemaPrivilegeData objectForKey:[privRow objectForKey:@"User"]] addObject:privRow];
+
+ // If "all database" values were found, add them to the schemas list if not already present
+ NSString *schemaName = [privRow objectForKey:@"Db"];
+ if ([schemaName isEqualToString:@""] || [schemaName isEqualToString:@"%"]) {
+ if (![schemas containsObject:schemaName]) {
+ [schemas addObject:schemaName];
+ [schemasTableView noteNumberOfRowsChanged];
+ }
+ }
+ }
+
// Go through each item that contains a dictionary of key-value pairs
// for each user currently in the database.
for (NSUInteger i = 0; i < [items count]; i++)
@@ -220,26 +245,20 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
NSString *username = [[items objectAtIndex:i] objectForKey:@"User"];
NSArray *parentResults = [[self _fetchUserWithUserName:username] retain];
NSDictionary *item = [items objectAtIndex:i];
+ NSManagedObject *parent;
+ NSManagedObject *child;
// Check to make sure if we already have added the parent
if (parentResults != nil && [parentResults count] > 0) {
// Add Children
- NSManagedObject *parent = [parentResults objectAtIndex:0];
- NSManagedObject *child = [self _createNewSPUser];
-
- // Setup the NSManagedObject with values from the dictionary
- [self _initializeChild:child withItem:item];
-
- NSMutableSet *children = [parent mutableSetValueForKey:@"children"];
- [children addObject:child];
-
- [self _initializeSchemaPrivsForChild:child];
+ parent = [parentResults objectAtIndex:0];
+ child = [self _createNewSPUser];
}
else {
// Add Parent
- NSManagedObject *parent = [self _createNewSPUser];
- NSManagedObject *child = [self _createNewSPUser];
+ parent = [self _createNewSPUser];
+ child = [self _createNewSPUser];
// We only care about setting the user and password keys on the parent, together with their
// original values for comparison purposes
@@ -247,14 +266,15 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
[parent setPrimitiveValue:username forKey:@"originaluser"];
[parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"password"];
[parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"originalpassword"];
-
- [self _initializeChild:child withItem:item];
-
- NSMutableSet *children = [parent mutableSetValueForKey:@"children"];
- [children addObject:child];
-
- [self _initializeSchemaPrivsForChild:child];
}
+
+ // Setup the NSManagedObject with values from the dictionary
+ [self _initializeChild:child withItem:item];
+
+ NSMutableSet *children = [parent mutableSetValueForKey:@"children"];
+ [children addObject:child];
+
+ [self _initializeSchemaPrivsForChild:child fromData:[schemaPrivilegeData objectForKey:username]];
// Save the initialized objects so that any new changes will be tracked.
NSError *error = nil;
@@ -304,11 +324,9 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
{
// Initialize Databases
[schemas removeAllObjects];
- [schemas addObjectsFromArray:[[self connection] databases]];
-
- [schemaController rearrangeObjects];
-
- [self _initializeAvailablePrivs];
+ [schemas addObjectsFromArray:[databaseDocument allDatabaseNames]];
+
+ [schemasTableView reloadData];
}
/**
@@ -352,24 +370,25 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
/**
* Initialize the schema privileges for the supplied child object.
+ *
+ * Assumes that the child has already been initialized with values from the
+ * global user table.
*/
-- (void)_initializeSchemaPrivsForChild:(NSManagedObject *)child
+- (void)_initializeSchemaPrivsForChild:(NSManagedObject *)child fromData:(NSArray *)dataForUser
{
- // Assumes that the child has already been initialized with values from the
- // global user table.
+ NSMutableSet *privs = [child mutableSetValueForKey:@"schema_privileges"];
// Set an originalhost key on the child to allow the tracking of edits
[child setPrimitiveValue:[child valueForKey:@"host"] forKey:@"originalhost"];
-
- // Select rows from the db table that contains schema privs for each user/host
- NSString *queryString = [NSString stringWithFormat:@"SELECT * FROM mysql.db WHERE user = %@ AND host = %@",
- [[[child parent] valueForKey:@"user"] tickQuotedString], [[child valueForKey:@"host"] tickQuotedString]];
-
- SPMySQLResult *queryResults = [[self connection] queryString:queryString];
- [queryResults setReturnDataAsStrings:YES];
-
- for (NSDictionary *rowDict in queryResults)
+
+ for (NSDictionary *rowDict in dataForUser)
{
+
+ // Verify that the host matches, or skip this entry
+ if (![[rowDict objectForKey:@"Host"] isEqualToString:[child valueForKey:@"host"]]) {
+ continue;
+ }
+
NSManagedObject *dbPriv = [NSEntityDescription insertNewObjectForEntityForName:@"Privileges" inManagedObjectContext:[self managedObjectContext]];
for (NSString *key in rowDict)
@@ -386,15 +405,13 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
[dbPriv setValue:[NSNumber numberWithBool:boolValue] forKey:key];
}
else if ([key isEqualToString:@"Db"]) {
- [dbPriv setValue:[[rowDict objectForKey:key] stringByReplacingOccurrencesOfString:@"\\_" withString:@"_"]
- forKey:key];
+ NSString *db = [[rowDict objectForKey:key] stringByReplacingOccurrencesOfString:@"\\_" withString:@"_"];
+ [dbPriv setValue:db forKey:key];
}
else if (![key isEqualToString:@"Host"] && ![key isEqualToString:@"User"]) {
[dbPriv setValue:[rowDict objectForKey:key] forKey:key];
}
}
-
- NSMutableSet *privs = [child mutableSetValueForKey:@"schema_privileges"];
[privs addObject:dbPriv];
}
}
@@ -668,9 +685,10 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
NSArray *selectedObjects = [availableController selectedObjects];
[grantedController addObjects:selectedObjects];
- [grantedTableView reloadData];
+ [grantedTableView noteNumberOfRowsChanged];
[availableController removeObjects:selectedObjects];
- [availableTableView reloadData];
+ [availableTableView noteNumberOfRowsChanged];
+ [schemasTableView setNeedsDisplay:YES];
[self _setSchemaPrivValues:selectedObjects enabled:YES];
}
@@ -683,9 +701,10 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
NSArray *selectedObjects = [grantedController selectedObjects];
[availableController addObjects:selectedObjects];
- [availableTableView reloadData];
+ [availableTableView noteNumberOfRowsChanged];
[grantedController removeObjects:selectedObjects];
- [grantedTableView reloadData];
+ [grantedTableView noteNumberOfRowsChanged];
+ [schemasTableView setNeedsDisplay:YES];
[self _setSchemaPrivValues:selectedObjects enabled:NO];
}
@@ -772,7 +791,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
// The passed in objects should be an array of NSDictionaries with a key
// of "name".
NSManagedObject *selectedHost = [[treeController selectedObjects] objectAtIndex:0];
- NSString *selectedDb = [[schemaController selectedObjects] objectAtIndex:0];
+ NSString *selectedDb = [schemas objectAtIndex:[schemasTableView selectedRow]];
NSArray *selectedPrivs = [self _fetchPrivsWithUser:[selectedHost valueForKeyPath:@"parent.user"]
schema:[selectedDb stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"]
@@ -791,12 +810,12 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
isNew = YES;
}
- // Now setup all the items that are selected to YES
+ // Now setup all the items that are selected to their enabled value
for (NSDictionary *obj in objects)
{
[priv setValue:[NSNumber numberWithBool:enabled] forKey:[obj valueForKey:@"name"]];
}
-
+
if (isNew) {
// Set up relationship
NSMutableSet *privs = [selectedHost mutableSetValueForKey:@"schema_privileges"];
@@ -1229,10 +1248,26 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
- (NSArray *)_fetchPrivsWithUser:(NSString *)username schema:(NSString *)selectedSchema host:(NSString *)host
{
NSManagedObjectContext *moc = [self managedObjectContext];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(user.parent.user like[cd] %@) AND (user.host like[cd] %@) AND (db like[cd] %@)", username, host, selectedSchema];
+ NSPredicate *predicate;
NSEntityDescription *privEntity = [NSEntityDescription entityForName:@"Privileges" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
-
+
+ // Construct the predicate depending on whether a user and schema were supplied;
+ // blank schemas indicate a default priv value (as per %)
+ if ([username length]) {
+ if ([selectedSchema length]) {
+ predicate = [NSPredicate predicateWithFormat:@"(user.parent.user like[cd] %@) AND (user.host like[cd] %@) AND (db like[cd] %@)", username, host, selectedSchema];
+ } else {
+ predicate = [NSPredicate predicateWithFormat:@"(user.parent.user like[cd] %@) AND (user.host like[cd] %@) AND (db == '')", username, host];
+ }
+ } else {
+ if ([selectedSchema length]) {
+ predicate = [NSPredicate predicateWithFormat:@"(user.parent.user == '') AND (user.host like[cd] %@) AND (db like[cd] %@)", host, selectedSchema];
+ } else {
+ predicate = [NSPredicate predicateWithFormat:@"(user.parent.user == '') AND (user.host like[cd] %@) AND (db == '')", host];
+ }
+ }
+
[request setEntity:privEntity];
[request setPredicate:predicate];
diff --git a/Source/SPUserManagerDataSource.h b/Source/SPUserManagerDataSource.h
new file mode 100644
index 00000000..f60b2118
--- /dev/null
+++ b/Source/SPUserManagerDataSource.h
@@ -0,0 +1,37 @@
+//
+// $Id$
+//
+// SPUserManagerDataSource.h
+// sequel-pro
+//
+// Created by Rowan Beentje on March 8, 2013.
+// Copyright (c) 2013 Rowan Beentje. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "SPUserManager.h"
+
+@interface SPUserManager (SPUserManagerDataSource)
+
+@end
diff --git a/Source/SPUserManagerDataSource.m b/Source/SPUserManagerDataSource.m
new file mode 100644
index 00000000..4e7f622c
--- /dev/null
+++ b/Source/SPUserManagerDataSource.m
@@ -0,0 +1,53 @@
+//
+// $Id$
+//
+// SPUserManagerDataSource.m
+// sequel-pro
+//
+// Created by Rowan Beentje on March 8, 2013.
+// Copyright (c) 2013 Rowan Beentje. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "SPUserManagerDataSource.h"
+
+@implementation SPUserManager (SPUserManagerDataSource)
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
+{
+ return [schemas count];
+}
+
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
+{
+ NSString *databaseName = [schemas objectAtIndex:rowIndex];
+ if ([databaseName isEqualToString:@""]) {
+ databaseName = NSLocalizedString(@"All Databases", @"All databases placeholder");
+ } else if ([databaseName isEqualToString:@"%"]) {
+ databaseName = NSLocalizedString(@"All Databases (%)", @"All databases (%) placeholder");
+ }
+ return databaseName;
+}
+
+@end
diff --git a/Source/SPUserManagerDelegate.m b/Source/SPUserManagerDelegate.m
index 8fa2b980..c00abba3 100644
--- a/Source/SPUserManagerDelegate.m
+++ b/Source/SPUserManagerDelegate.m
@@ -42,7 +42,6 @@ static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges";
@interface SPUserManager (DeclaredAPI)
-- (void)_initializeSchemaPrivs;
- (void)_initializeAvailablePrivs;
- (void)_selectParentFromSelection;
- (void)_selectFirstChildOfParentNode;
@@ -64,15 +63,15 @@ static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges";
if (object == schemasTableView) {
[grantedSchemaPrivs removeAllObjects];
[grantedTableView reloadData];
-
+
[self _initializeAvailablePrivs];
-
- if ([[treeController selectedObjects] count] > 0 && [[schemaController selectedObjects] count] > 0) {
+
+ if ([[treeController selectedObjects] count] > 0 && [[schemasTableView selectedRowIndexes] count] > 0) {
NSManagedObject *user = [[treeController selectedObjects] objectAtIndex:0];
// Check to see if the user host node was selected
if ([user valueForKey:@"host"]) {
- NSString *selectedSchema = [[schemaController selectedObjects] objectAtIndex:0];
+ NSString *selectedSchema = [schemas objectAtIndex:[schemasTableView selectedRow]];
NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"]
schema:[selectedSchema stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"]
@@ -116,6 +115,43 @@ static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges";
}
}
+- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ if (tableView == schemasTableView) {
+ NSString *schemaName = [schemas objectAtIndex:rowIndex];
+
+ // Gray out the "all database" entries
+ if ([schemaName isEqualToString:@""] || [schemaName isEqualToString:@"%"]) {
+ [cell setTextColor:[NSColor lightGrayColor]];
+ } else {
+ [cell setTextColor:[NSColor blackColor]];
+ }
+
+ // If the schema has permissions set, highlight with a yellow background
+ BOOL enabledPermissions = NO;
+ NSManagedObject *user = [[treeController selectedObjects] objectAtIndex:0];
+ NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"]
+ schema:[schemaName stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"]
+ host:[user valueForKey:@"host"]];
+ if ([results count]) {
+ NSManagedObject *schemaPrivs = [results objectAtIndex:0];
+ for (NSString *itemKey in [[[schemaPrivs entity] attributesByName] allKeys]) {
+ if ([itemKey hasSuffix:@"_priv"] && [[schemaPrivs valueForKey:itemKey] boolValue]) {
+ enabledPermissions = YES;
+ break;
+ }
+ }
+ }
+
+ if (enabledPermissions) {
+ [cell setDrawsBackground:YES];
+ [cell setBackgroundColor:[NSColor colorWithDeviceRed:1.f green:1.f blue:0.f alpha:0.2]];
+ } else {
+ [cell setDrawsBackground:NO];
+ }
+ }
+}
+
#pragma mark -
#pragma mark Tab View Delegate methods
@@ -191,13 +227,6 @@ static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges";
}
}
-- (void)tabView:(NSTabView *)usersTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem
-{
- if ([[tabViewItem identifier] isEqualToString:SPSchemaPrivilegesTabIdentifier]) {
- [self _initializeSchemaPrivs];
- }
-}
-
#pragma mark -
#pragma mark Outline view Delegate Methods
@@ -252,6 +281,7 @@ static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges";
}
[schemasTableView deselectAll:nil];
+ [schemasTableView setNeedsDisplay:YES];
[grantedTableView deselectAll:nil];
[availableTableView deselectAll:nil];
}