From be9d9def4513394bf0ee987bb6b52f284ae3a5a6 Mon Sep 17 00:00:00 2001 From: rfm Date: Fri, 26 Jun 2015 12:06:13 +0000 Subject: [PATCH] client name settings git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@38694 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 12 +++++- SQLClient.h | 37 +++++++++++++--- SQLClient.m | 110 ++++++++++++++++++++++++++++++++++++++---------- SQLClientPool.m | 34 +++++++++++++++ 4 files changed, 163 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 574192f..ee4491c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,17 @@ +2015-06-26 Richard Frith-Macdonald + + * SQLClient.h: + * SQLClient.m: + * SQLClientPool.m: + Implement -transaction method for client pools so that we can build + a transaction which, when executed, will use any available client + from the pool. + Support setting of the client name for clients in a pool. + 2015-06-25 Niels Grewe * SQLClient.[hm]: Add an accessor method to obtain the SQLClientPool - object owning a specific SQLClient. + object owning a specific SQLClient. 2015-06-25 Richard Frith-Macdonald diff --git a/SQLClient.h b/SQLClient.h index 5c3a13e..f54eb75 100644 --- a/SQLClient.h +++ b/SQLClient.h @@ -924,6 +924,14 @@ SQLCLIENT_PRIVATE */ - (void) rollback; +/** + * Set the client name for this client.
+ * If this is not set (or is set to nul) a globally unique string is used.
+ * NB. Setting the name may not be reflected in the database server until + * the client disconnects and reconnects. + */ +- (void) setClientName: (NSString*)s; + /** * Set the database host/name for this object.
* This is called automatically to configure the connection ... @@ -1343,8 +1351,7 @@ SQLCLIENT_PRIVATE */ - (void) singletons: (NSMutableArray*)records; -/** - * Creates and returns an autoreleased SQLTransaction instance which will +/** Creates and returns an autoreleased SQLTransaction instance which will * use the receiver as the database connection to perform transactions. */ - (SQLTransaction*) transaction; @@ -1637,11 +1644,20 @@ SQLCLIENT_PRIVATE */ - (void) setCache: (GSCache*)aCache; -/** - * Sets the cache thread for all the clients in the pool. +/** Sets the cache thread for all the clients in the pool. */ - (void) setCacheThread: (NSThread*)aThread; +/** Set the client name for all the client connections in the pool.
+ * If the argument is not nil, the name of each client in the pool + * is set to the argument with a suffix of '(x)' where x is the number + * of the client within the pool, otherwise (nil argument) each client + * is allocated a globally unique string as its name.
+ * NB. This setting does not apply to new connections added when the pool + * maximum size is increased. + */ +- (void) setClientName: (NSString*)s; + /** Set the debugging level for all clients in the pool. */ - (void) setDebugging: (unsigned int)level; @@ -1686,6 +1702,11 @@ SQLCLIENT_PRIVATE */ - (BOOL) swallowClient: (SQLClient*)client; +/** Creates and returns an autoreleased SQLTransaction instance which will + * use the receiver as the database connection to perform transactions. + */ +- (SQLTransaction*) transaction; + @end /** This category lists the convenience methods provided by a pool instance @@ -1750,7 +1771,7 @@ SQLCLIENT_PRIVATE @interface SQLTransaction : NSObject { SQLCLIENT_PRIVATE - SQLClient *_db; + id _db; NSMutableArray *_info; unsigned _count; BOOL _batch; @@ -1803,9 +1824,11 @@ SQLCLIENT_PRIVATE /** * Returns the database client with which this instance operates.
- * This client is retained by the transaction. + * This client is retained by the transaction.
+ * If the transaction was created by/for an SQLClientPool, this method + * returns that pool rather than an individual client. */ -- (SQLClient*) db; +- (id) db; /** *

Performs any statements added to the transaction as a single operation. diff --git a/SQLClient.m b/SQLClient.m index 6914ef3..5275a0c 100644 --- a/SQLClient.m +++ b/SQLClient.m @@ -88,6 +88,9 @@ static Class SQLClientClass = Nil; @interface SQLClientPool (Swallow) - (BOOL) _swallowClient: (SQLClient*)client withRetain: (BOOL)shouldRetain; @end +@interface SQLTransaction (Creation) ++ (SQLTransaction*) _transactionUsing: (id)clientOrPool; +@end @implementation SQLRecordKeys @@ -1088,7 +1091,16 @@ static int poolConnections = 0; - (NSString*) clientName { - return _client; + NSString *s; + + [lock lock]; + if (nil == _client) + { + _client = [[[NSProcessInfo processInfo] globallyUniqueString] retain]; + } + s = [_client retain]; + [lock unlock]; + return [s autorelease]; } - (void) commit @@ -1890,6 +1902,13 @@ static int poolConnections = 0; NS_ENDHANDLER } +- (void) setClientName: (NSString*)s +{ + [lock lock]; + ASSIGNCOPY(_client, s); + [lock unlock]; +} + - (void) setDatabase: (NSString*)s { [lock lock]; @@ -1949,8 +1968,11 @@ static int poolConnections = 0; s = [s copy]; [_name release]; _name = s; - [_client release]; - _client = [[[NSProcessInfo processInfo] globallyUniqueString] retain]; + if (nil == _client) + { + _client + = [[[NSProcessInfo processInfo] globallyUniqueString] retain]; + } if (nil == _pool && _name != nil) { NSMapInsert(clientsMap, (void*)_name, (void*)self); @@ -2842,15 +2864,9 @@ static int poolConnections = 0; - (SQLTransaction*) transaction { - SQLTransaction *transaction; - - transaction = (SQLTransaction*)NSAllocateObject([SQLTransaction class], 0, - NSDefaultMallocZone()); - - transaction->_db = [self retain]; - transaction->_info = [NSMutableArray new]; - return [(SQLTransaction*)transaction autorelease]; + return [SQLTransaction _transactionUsing: self]; } + @end @@ -3108,6 +3124,18 @@ static int poolConnections = 0; @implementation SQLTransaction ++ (SQLTransaction*) _transactionUsing: (id)clientOrPool +{ + SQLTransaction *transaction; + + transaction = (SQLTransaction*)NSAllocateObject(self, 0, + NSDefaultMallocZone()); + + transaction->_db = [clientOrPool retain]; + transaction->_info = [NSMutableArray new]; + return [transaction autorelease]; +} + - (void) _addSQL: (NSMutableString*)sql andArgs: (NSMutableArray*)args { unsigned count = [_info count]; @@ -3399,7 +3427,7 @@ static int poolConnections = 0; return [_info count]; } -- (SQLClient*) db +- (id) db { return _db; } @@ -3423,11 +3451,24 @@ static int poolConnections = 0; if (_count > 0) { NSMutableArray *info = nil; - NSRecursiveLock *dbLock = [_db _lock]; + SQLClientPool *pool = nil; + SQLClient *db; + NSRecursiveLock *dbLock; BOOL wrap; + if ([_db isKindOfClass: [SQLClientPool class]]) + { + pool = (SQLClientPool*)_db; + db = [pool provideClient]; + } + else + { + db = _db; + } + + dbLock = [db _lock]; [dbLock lock]; - wrap = [_db isInTransaction] ? NO : YES; + wrap = [db isInTransaction] ? NO : YES; NS_DURING { NSMutableString *sql; @@ -3454,9 +3495,13 @@ static int poolConnections = 0; [sql appendString: @"commit;"]; } - [_db simpleExecute: info]; + [db simpleExecute: info]; [info release]; info = nil; [dbLock unlock]; + if (nil != pool) + { + [pool swallowClient: db]; + } } NS_HANDLER { @@ -3467,16 +3512,20 @@ static int poolConnections = 0; { NS_DURING { - [_db simpleExecute: rollbackStatement]; + [db simpleExecute: rollbackStatement]; } NS_HANDLER { - [_db disconnect]; + [db disconnect]; NSLog(@"Disconnected due to failed rollback after %@", e); } NS_ENDHANDLER } [dbLock unlock]; + if (nil != pool) + { + [pool swallowClient: db]; + } [e raise]; } NS_ENDHANDLER @@ -3496,7 +3545,20 @@ static int poolConnections = 0; if (_count > 0) { NSRecursiveLock *dbLock = [_db _lock]; + SQLClientPool *pool = nil; + SQLClient *db; + if ([_db isKindOfClass: [SQLClientPool class]]) + { + pool = (SQLClientPool*)_db; + db = [pool provideClient]; + } + else + { + db = _db; + } + + dbLock = [db _lock]; [dbLock lock]; NS_DURING { @@ -3505,9 +3567,9 @@ static int poolConnections = 0; } NS_HANDLER { - if (log == YES || [_db debugging] > 0) + if (log == YES || [db debugging] > 0) { - [_db debug: @"Initial failure executing batch %@: %@", + [db debug: @"Initial failure executing batch %@: %@", self, localException]; } if (_batch == YES) @@ -3536,7 +3598,7 @@ static int poolConnections = 0; */ if (wrapper == nil) { - wrapper = [_db transaction]; + wrapper = [db transaction]; } [wrapper reset]; [wrapper addPrepared: o]; @@ -3550,9 +3612,9 @@ static int poolConnections = 0; { [failures addPrepared: o]; } - if (log == YES || [_db debugging] > 0) + if (log == YES || [db debugging] > 0) { - [_db debug: + [db debug: @"Failure of %d executing batch %@: %@", i, self, localException]; } @@ -3601,6 +3663,10 @@ static int poolConnections = 0; } NS_ENDHANDLER [dbLock unlock]; + if (nil != pool) + { + [pool swallowClient: db]; + } } return executed; } diff --git a/SQLClientPool.m b/SQLClientPool.m index aa1e1b1..5f6b779 100644 --- a/SQLClientPool.m +++ b/SQLClientPool.m @@ -61,6 +61,10 @@ - (void) _unlock; @end +@interface SQLTransaction (Creation) ++ (SQLTransaction*) _transactionUsing: (id)clientOrPool; +@end + @implementation SQLClientPool - (int) availableConnections @@ -724,6 +728,36 @@ { return [self _swallowClient: client withRetain: YES]; } + +- (void) setClientName: (NSString*)s +{ + unsigned int index; + + [lock lock]; + for (index = 0; index < max; index++) + { + SQLClient *client = c[index]; + + if (nil == s) + { + [client setClientName: s]; + } + else + { + NSString *n; + + n = [s stringByAppendingFormat: @" (%u)", index]; + [client setClientName: n]; + } + } + [lock unlock]; +} + +- (SQLTransaction*) transaction +{ + return [SQLTransaction _transactionUsing: self]; +} + @end @implementation SQLClientPool (Private)