mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-21 19:01:03 +00:00
Threading/notification improvments
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@38447 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2250d65fc0
commit
bb8284b4fe
5 changed files with 75 additions and 18 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,11 +1,28 @@
|
||||||
|
2015-04-01 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* SQLClient.h:
|
||||||
|
* Postgres.m:
|
||||||
|
Fixup notification posting to be asynchronous using the default
|
||||||
|
notification queue for the thread so that the notifications do
|
||||||
|
not get delivered while the query/statement at which they were
|
||||||
|
detected is still in progress.
|
||||||
|
Add method to explicitly grab/release the client for the current
|
||||||
|
thread.
|
||||||
|
|
||||||
2015-03-11 Richard Frith-Macdonald <rfm@gnu.org>
|
2015-03-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
* SQLClientPool.m: Fixup for ewxposing prepare method
|
|
||||||
|
* SQLClientPool.m: Fixup for exposing prepare method
|
||||||
* SQLClient.h:
|
* SQLClient.h:
|
||||||
* SQLClient.m:
|
* SQLClient.m:
|
||||||
* Postgres.m:
|
* Postgres.m:
|
||||||
* testPostgres.m:
|
* testPostgres.m:
|
||||||
Add simple array support for char/varchar/text, integer/real,
|
Add simple array support for char/varchar/text, integer/real,
|
||||||
timestamp, bool and bytea.
|
timestamp, bool and bytea. When a query returns an array of
|
||||||
|
one of these types, the resulting object is an NSArray containing
|
||||||
|
the database array elements rather than an NSString containing the
|
||||||
|
string literal representation of the database array.
|
||||||
|
Also added a method to convert an NSArray to a string literal
|
||||||
|
representation of a database array.
|
||||||
|
|
||||||
2015-03-02 Richard Frith-Macdonald <rfm@gnu.org>
|
2015-03-02 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
|
22
Postgres.m
22
Postgres.m
|
@ -35,6 +35,7 @@
|
||||||
#import <Foundation/NSFileHandle.h>
|
#import <Foundation/NSFileHandle.h>
|
||||||
#import <Foundation/NSProcessInfo.h>
|
#import <Foundation/NSProcessInfo.h>
|
||||||
#import <Foundation/NSNotification.h>
|
#import <Foundation/NSNotification.h>
|
||||||
|
#import <Foundation/NSNotificationQueue.h>
|
||||||
#import <Foundation/NSUserDefaults.h>
|
#import <Foundation/NSUserDefaults.h>
|
||||||
#import <Foundation/NSMapTable.h>
|
#import <Foundation/NSMapTable.h>
|
||||||
#import <Foundation/NSLock.h>
|
#import <Foundation/NSLock.h>
|
||||||
|
@ -279,8 +280,8 @@ connectQuote(NSString *str)
|
||||||
|
|
||||||
- (void) _checkNotifications
|
- (void) _checkNotifications
|
||||||
{
|
{
|
||||||
static NSNotificationCenter *nc;
|
NSNotificationQueue *nq = nil;
|
||||||
PGnotify *notify;
|
PGnotify *notify;
|
||||||
|
|
||||||
while ((notify = PQnotifies(connection)) != 0)
|
while ((notify = PQnotifies(connection)) != 0)
|
||||||
{
|
{
|
||||||
|
@ -328,11 +329,14 @@ connectQuote(NSString *str)
|
||||||
userInfo: (NSDictionary*)userInfo];
|
userInfo: (NSDictionary*)userInfo];
|
||||||
[name release];
|
[name release];
|
||||||
[userInfo release];
|
[userInfo release];
|
||||||
if (nil == nc)
|
|
||||||
|
if (nil == nq)
|
||||||
{
|
{
|
||||||
nc = [[NSNotificationCenter defaultCenter] retain];
|
nq = [NSNotificationQueue defaultQueue];
|
||||||
}
|
}
|
||||||
[nc postNotification: n];
|
/* Post asynchronously
|
||||||
|
*/
|
||||||
|
[nq enqueueNotification: n postingStyle: NSPostASAP];
|
||||||
}
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
|
@ -523,9 +527,9 @@ static unsigned int trim(char *str)
|
||||||
}
|
}
|
||||||
if ('\"' == *p)
|
if ('\"' == *p)
|
||||||
{
|
{
|
||||||
*p++ = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
if (len == (p - start + 1))
|
if (len == (p - start))
|
||||||
{
|
{
|
||||||
v = [[NSString alloc] initWithUTF8String: start];
|
v = [[NSString alloc] initWithUTF8String: start];
|
||||||
}
|
}
|
||||||
|
@ -562,6 +566,7 @@ static unsigned int trim(char *str)
|
||||||
freeWhenDone: YES];
|
freeWhenDone: YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*p++ = '\"';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -677,6 +682,7 @@ static unsigned int trim(char *str)
|
||||||
case 1002: // CHAR ARRAY
|
case 1002: // CHAR ARRAY
|
||||||
case 1009: // TEXT ARRAY
|
case 1009: // TEXT ARRAY
|
||||||
case 1015: // VARCHAR ARRAY
|
case 1015: // VARCHAR ARRAY
|
||||||
|
case 1263: // CSTRING ARRAY
|
||||||
if ('{' == *p)
|
if ('{' == *p)
|
||||||
{
|
{
|
||||||
NSMutableArray *a;
|
NSMutableArray *a;
|
||||||
|
@ -1212,7 +1218,7 @@ static unsigned int trim(char *str)
|
||||||
else if ([o isKindOfClass: [NSDate class]])
|
else if ([o isKindOfClass: [NSDate class]])
|
||||||
{
|
{
|
||||||
[s appendString: [self quote: (NSString*)o]];
|
[s appendString: [self quote: (NSString*)o]];
|
||||||
[s appendString: @"::timestamp"];
|
[s appendString: @"::timestamp with time zone"];
|
||||||
}
|
}
|
||||||
else if ([o isKindOfClass: [NSData class]])
|
else if ([o isKindOfClass: [NSData class]])
|
||||||
{
|
{
|
||||||
|
|
34
SQLClient.h
34
SQLClient.h
|
@ -488,6 +488,13 @@ SQLCLIENT_PRIVATE
|
||||||
*/
|
*/
|
||||||
- (void) begin;
|
- (void) begin;
|
||||||
|
|
||||||
|
/** This grabs the receiver for use by the current thread.<br />
|
||||||
|
* If limit is nil or in the past, makes a single immediate attempt.<br />
|
||||||
|
* Returns NO if it fails to obtain a lock by the specified date.<br />
|
||||||
|
* Must be matched by an -unlock if it succeeds.
|
||||||
|
*/
|
||||||
|
- (BOOL) lockBeforeDate: (NSDate*)limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Build an sql query string using the supplied arguments.
|
* <p>Build an sql query string using the supplied arguments.
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -787,7 +794,12 @@ SQLCLIENT_PRIVATE
|
||||||
* YYYY-MM-DD hh:mm:ss.mmm ?ZZZZ<br />
|
* YYYY-MM-DD hh:mm:ss.mmm ?ZZZZ<br />
|
||||||
* NSData objects are not quoted ... they must not appear in queries, and
|
* NSData objects are not quoted ... they must not appear in queries, and
|
||||||
* where used for insert/update operations, they need to be passed to the
|
* where used for insert/update operations, they need to be passed to the
|
||||||
* -backendExecute: method unchanged.
|
* -backendExecute: method unchanged.<br />
|
||||||
|
* NSArray and NSSet objects are quoted as sets containing the quoted
|
||||||
|
* elements from the array/set. If you want to use SQL arrays (and your
|
||||||
|
* database backend supports it) you must explicitly use the
|
||||||
|
* -quoteArray:toString:quotingString: to convert an NSArray to a literal
|
||||||
|
* database array representation.
|
||||||
*/
|
*/
|
||||||
- (NSString*) quote: (id)obj;
|
- (NSString*) quote: (id)obj;
|
||||||
|
|
||||||
|
@ -928,6 +940,10 @@ SQLCLIENT_PRIVATE
|
||||||
recordType: (id)rtype
|
recordType: (id)rtype
|
||||||
listType: (id)ltype;
|
listType: (id)ltype;
|
||||||
|
|
||||||
|
/** Releases a lock previously obtained using -lockbeforeDate:
|
||||||
|
*/
|
||||||
|
- (void) unlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the database user for this instance (or nil).
|
* Return the database user for this instance (or nil).
|
||||||
*/
|
*/
|
||||||
|
@ -1088,7 +1104,8 @@ SQLCLIENT_PRIVATE
|
||||||
* which don't support asynchronous notifications.<br />
|
* which don't support asynchronous notifications.<br />
|
||||||
* If a backend <em>does</em> support asynchronous notifications,
|
* If a backend <em>does</em> support asynchronous notifications,
|
||||||
* it should do so by posting NSNotification instances to
|
* it should do so by posting NSNotification instances to
|
||||||
* [NSNotificationCenter defaultCenter] using the SQLClient instance as
|
* [NSNotificationQueue defaultQueue] with the posting style NSPostASAP
|
||||||
|
* (to post asynchronously) and using the SQLClient instance as
|
||||||
* the notification object and supplying any payload as a string using
|
* the notification object and supplying any payload as a string using
|
||||||
* the 'Payload' key in the NSNotification userInfo dictionary.
|
* the 'Payload' key in the NSNotification userInfo dictionary.
|
||||||
* The userInfo dictionary should also contain a boolean (NSNumber) value,
|
* The userInfo dictionary should also contain a boolean (NSNumber) value,
|
||||||
|
@ -1182,11 +1199,14 @@ SQLCLIENT_PRIVATE
|
||||||
* as an action by this SQLClient instance.<br />
|
* as an action by this SQLClient instance.<br />
|
||||||
* If the 'Payload' value is not nil, then it is a string providing extra
|
* If the 'Payload' value is not nil, then it is a string providing extra
|
||||||
* information about the notification.<br />
|
* information about the notification.<br />
|
||||||
* NB. At the point when the observer is notified about an event the
|
* Notifications are posted asynchronously using the default notification
|
||||||
* database client object will be locked and may not be used to query
|
* queue for the current thread, so they should be delivered to the
|
||||||
* or modify the database (typically a database query will already be
|
* observer after the database statement in which they were detected
|
||||||
* in progress). The method handling the notification must therefore
|
* has completed. However, delivery of the notification could still
|
||||||
* handle any database operations in a later timeout.
|
* occur inside a transaction is the -begin and -commit statements
|
||||||
|
* are used. For this reason, observing code may want to use the
|
||||||
|
* -lockBeforeDate: -isInTransaction and -unlock methods to ensure
|
||||||
|
* that they don't interfere with ongoing transactions.
|
||||||
*/
|
*/
|
||||||
- (void) addObserver: (id)anObserver
|
- (void) addObserver: (id)anObserver
|
||||||
selector: (SEL)aSelector
|
selector: (SEL)aSelector
|
||||||
|
|
14
SQLClient.m
14
SQLClient.m
|
@ -1341,6 +1341,15 @@ static int poolConnections = 0;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) lockBeforeDate: (NSDate*)limit
|
||||||
|
{
|
||||||
|
if (nil == limit)
|
||||||
|
{
|
||||||
|
return [lock tryLock];
|
||||||
|
}
|
||||||
|
return [lock lockBeforeDate: limit];
|
||||||
|
}
|
||||||
|
|
||||||
- (SQLClient*) longestIdle: (SQLClient*)other
|
- (SQLClient*) longestIdle: (SQLClient*)other
|
||||||
{
|
{
|
||||||
NSTimeInterval t0;
|
NSTimeInterval t0;
|
||||||
|
@ -2015,6 +2024,11 @@ static int poolConnections = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) unlock
|
||||||
|
{
|
||||||
|
[lock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString*) user
|
- (NSString*) user
|
||||||
{
|
{
|
||||||
return _user;
|
return _user;
|
||||||
|
|
|
@ -260,7 +260,7 @@ main()
|
||||||
@"extra2 varchar[],"
|
@"extra2 varchar[],"
|
||||||
@"extra3 bytea[],"
|
@"extra3 bytea[],"
|
||||||
@"extra4 boolean[],"
|
@"extra4 boolean[],"
|
||||||
@"extra5 timestamp[]"
|
@"extra5 timestamp with time zone[]"
|
||||||
@")",
|
@")",
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue