Author: rfm
Date: Thu Dec 11 18:26:32 2014
New Revision: 38249
URL: http://svn.gna.org/viewcvs/gnustep?rev=38249&view=rev
Log:
convenience methods
Modified:
libs/sqlclient/trunk/ChangeLog
libs/sqlclient/trunk/Postgres.m
libs/sqlclient/trunk/SQLClient.h
libs/sqlclient/trunk/SQLClient.m
libs/sqlclient/trunk/SQLClientPool.m
libs/sqlclient/trunk/testPostgres.m
Modified: libs/sqlclient/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/ChangeLog?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/ChangeLog (original)
+++ libs/sqlclient/trunk/ChangeLog Thu Dec 11 18:26:32 2014
@@ -1,3 +1,11 @@
+2014-12-11 Richard Frith-Macdonald <[email protected]>
+
+ * Postgres.m: Fix minor thread safety issue.
+ * SQLClient.h:
+ * SQLClient.m:
+ * SQLClientPool.m:
+ Convenience methods to let a pool act as a client for any one-off op.
+
2014-11-19 Richard Frith-Macdonald <[email protected]>
* GNUmakefile: bump version to 1.8.2 for bugfix release.
Modified: libs/sqlclient/trunk/Postgres.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/Postgres.m?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/Postgres.m (original)
+++ libs/sqlclient/trunk/Postgres.m Thu Dec 11 18:26:32 2014
@@ -1032,8 +1032,20 @@
#ifdef HAVE_PQESCAPESTRINGCONN
int err;
- [self connect];
- l = PQescapeStringConn(connection, (char*)(to + 1), [d bytes], l, &err);
+ [lock lock];
+ NS_DURING
+ {
+ [self connect];
+ l = PQescapeStringConn(connection, (char*)(to + 1), [d bytes], l, &err);
+ }
+ NS_HANDLER
+ {
+ [lock unlock];
+ NSZoneFree(NSDefaultMallocZone(), to);
+ [localException raise];
+ }
+ NS_ENDHANDLER
+ [lock unlock];
#else
l = PQescapeString(to + 1, [d bytes], l);
#endif
Modified: libs/sqlclient/trunk/SQLClient.h
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.h?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.h (original)
+++ libs/sqlclient/trunk/SQLClient.h Thu Dec 11 18:26:32 2014
@@ -1187,36 +1187,11 @@
@interface SQLClient (Convenience)
/**
- * Returns a transaction object configured to handle batching and
- * execute part of a batch of statements if execution of the whole
- * using the [SQLTransaction-executeBatch] method fails.<br />
- * If stopOnFailure is YES than execution of the transaction will
- * stop with the first statement to fail, otherwise it will execute
- * all the statements it can, skipping any failed statements.
- */
-- (SQLTransaction*) batch: (BOOL)stopOnFailure;
-
-/**
* Convenience method to deal with the results of a query converting the
* normal array of records into an array of record columns. Each column
* in the array is an array containing all the values from that column.
*/
-- (NSMutableArray*) columns: (NSMutableArray*)records;
-
-/**
- * Executes a query (like the -query:,... method) and checks the result
- * (raising an exception if the query did not contain a single record)
- * and returns the resulting record.
- */
-- (SQLRecord*) queryRecord: (NSString*)stmt,...;
-
-/**
- * Executes a query (like the -query:,... method) and checks the result.<br />
- * Raises an exception if the query did not contain a single record, or
- * if the record did not contain a single field.<br />
- * Returns the resulting field as a <em>string</em>.
- */
-- (NSString*) queryString: (NSString*)stmt,...;
++ (NSMutableArray*) columns: (NSMutableArray*)records;
/**
* Convenience method to deal with the results of a query where each
@@ -1226,6 +1201,39 @@
* actually instances of [SQLRecord], so you must ensure you don't
* call it more than once on the same array (something that may happen
* if you retrieve the array using a cache based query).
+ */
++ (void) singletons: (NSMutableArray*)records;
+
+/**
+ * Returns a transaction object configured to handle batching and
+ * execute part of a batch of statements if execution of the whole
+ * using the [SQLTransaction-executeBatch] method fails.<br />
+ * If stopOnFailure is YES than execution of the transaction will
+ * stop with the first statement to fail, otherwise it will execute
+ * all the statements it can, skipping any failed statements.
+ */
+- (SQLTransaction*) batch: (BOOL)stopOnFailure;
+
+/** The same as the [SQLClient+columns:] method.
+ */
+- (NSMutableArray*) columns: (NSMutableArray*)records;
+
+/**
+ * Executes a query (like the -query:,... method) and checks the result
+ * (raising an exception if the query did not contain a single record)
+ * and returns the resulting record.
+ */
+- (SQLRecord*) queryRecord: (NSString*)stmt,...;
+
+/**
+ * Executes a query (like the -query:,... method) and checks the result.<br />
+ * Raises an exception if the query did not contain a single record, or
+ * if the record did not contain a single field.<br />
+ * Returns the resulting field as a <em>string</em>.
+ */
+- (NSString*) queryString: (NSString*)stmt,...;
+
+/** The same as the [SQLClient+singletons:] method.
*/
- (void) singletons: (NSMutableArray*)records;
@@ -1531,6 +1539,47 @@
@end
+/** This category lists the convenience methods provided by a pool instance
+ * for proxying messages to a one-off client instance in the pool.<br />
+ * The behavior of each method is, of course, as documentf for instances
+ * of the [SQLClient] class.
+ */
+@interface SQLClientPool (Convenience)
+- (NSString*) buildQuery: (NSString*)stmt,...;
+- (NSString*) buildQuery: (NSString*)stmt with: (NSDictionary*)values;
+- (NSMutableArray*) cache: (int)seconds
+ query: (NSString*)stmt,...;
+- (NSMutableArray*) cache: (int)seconds
+ query: (NSString*)stmt
+ with: (NSDictionary*)values;
+- (NSMutableArray*) cache: (int)seconds simpleQuery: (NSString*)stmt;
+- (NSMutableArray*) cache: (int)seconds
+ simpleQuery: (NSString*)stmt
+ recordType: (id)rtype
+ listType: (id)ltype;
+- (NSMutableArray*) columns: (NSMutableArray*)records;
+- (NSInteger) execute: (NSString*)stmt,...;
+- (NSInteger) execute: (NSString*)stmt with: (NSDictionary*)values;
+- (NSMutableArray*) query: (NSString*)stmt,...;
+- (NSMutableArray*) query: (NSString*)stmt with: (NSDictionary*)values;
+- (SQLRecord*) queryRecord: (NSString*)stmt,...;
+- (NSString*) queryString: (NSString*)stmt,...;
+- (NSString*) quote: (id)obj;
+- (NSString*) quotef: (NSString*)fmt, ...;
+- (NSString*) quoteBigInteger: (int64_t)i;
+- (NSString*) quoteCString: (const char *)s;
+- (NSString*) quoteChar: (char)c;
+- (NSString*) quoteFloat: (float)f;
+- (NSString*) quoteInteger: (int)i;
+- (NSString*) quoteString: (NSString *)s;
+- (NSInteger) simpleExecute: (NSArray*)info;
+- (void) singletons: (NSMutableArray*)records;
+- (NSMutableArray*) simpleQuery: (NSString*)stmt;
+- (NSMutableArray*) simpleQuery: (NSString*)stmt
+ recordType: (id)rtype
+ listType: (id)ltype;
+@end
+
/**
* The SQLTransaction transaction class provides a convenient mechanism
* for grouping together a series of SQL statements to be executed as a
Modified: libs/sqlclient/trunk/SQLClient.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m (original)
+++ libs/sqlclient/trunk/SQLClient.m Thu Dec 11 18:26:32 2014
@@ -2539,6 +2539,54 @@
@implementation SQLClient(Convenience)
++ (NSMutableArray*) columns: (NSMutableArray*)records
+{
+ SQLRecord *r = [records lastObject];
+ unsigned rowCount = [records count];
+ unsigned colCount = [r count];
+ NSMutableArray *m;
+
+ if (rowCount == 0 || colCount == 0)
+ {
+ m = [NSMutableArray array];
+ }
+ else
+ {
+ NSMutableArray *cols[colCount];
+ unsigned i;
+
+ m = [NSMutableArray arrayWithCapacity: colCount];
+ for (i = 0; i < colCount; i++)
+ {
+ cols[i] = [[NSMutableArray alloc] initWithCapacity: rowCount];
+ [m addObject: cols[i]];
+ [cols[i] release];
+ }
+ for (i = 0; i < rowCount; i++)
+ {
+ unsigned j;
+
+ r = [records objectAtIndex: i];
+ for (j = 0; j < colCount; j++)
+ {
+ [cols[j] addObject: [r objectAtIndex: j]];
+ }
+ }
+ }
+ return m;
+}
+
++ (void) singletons: (NSMutableArray*)records
+{
+ unsigned c = [records count];
+
+ while (c-- > 0)
+ {
+ [records replaceObjectAtIndex: c
+ withObject: [[records objectAtIndex: c] lastObject]];
+ }
+}
+
- (SQLTransaction*) batch: (BOOL)stopOnFailure
{
SQLTransaction *transaction;
@@ -2555,39 +2603,7 @@
- (NSMutableArray*) columns: (NSMutableArray*)records
{
- SQLRecord *r = [records lastObject];
- unsigned rowCount = [records count];
- unsigned colCount = [r count];
- NSMutableArray *m;
-
- if (rowCount == 0 || colCount == 0)
- {
- m = [NSMutableArray array];
- }
- else
- {
- NSMutableArray *cols[colCount];
- unsigned i;
-
- m = [NSMutableArray arrayWithCapacity: colCount];
- for (i = 0; i < colCount; i++)
- {
- cols[i] = [[NSMutableArray alloc] initWithCapacity: rowCount];
- [m addObject: cols[i]];
- [cols[i] release];
- }
- for (i = 0; i < rowCount; i++)
- {
- unsigned j;
-
- r = [records objectAtIndex: i];
- for (j = 0; j < colCount; j++)
- {
- [cols[j] addObject: [r objectAtIndex: j]];
- }
- }
- }
- return m;
+ return [SQLClient columns: records];
}
- (SQLRecord*) queryRecord: (NSString*)stmt, ...
@@ -2649,13 +2665,7 @@
- (void) singletons: (NSMutableArray*)records
{
- unsigned c = [records count];
-
- while (c-- > 0)
- {
- [records replaceObjectAtIndex: c
- withObject: [[records objectAtIndex: c] lastObject]];
- }
+ [SQLClient singletons: records];
}
- (SQLTransaction*) transaction
Modified: libs/sqlclient/trunk/SQLClientPool.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClientPool.m?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClientPool.m (original)
+++ libs/sqlclient/trunk/SQLClientPool.m Thu Dec 11 18:26:32 2014
@@ -542,60 +542,320 @@
@end
-@implementation SQLClientPool (Proxying)
-
-static BOOL
-selIsBad(SEL aSelector)
-{
- const char *n = sel_getName(aSelector);
-
- if (strncmp(n, "set", 3) == 0)
- {
- return YES;
- }
- if (strncmp(n, "backend", 7) == 0)
- {
- return YES;
- }
- if (strcmp(n, "begin") == 0)
- {
- return YES;
- }
- return NO;
-}
-
-- (void) forwardInvocation: (NSInvocation*)anInvocation
-{
- SQLClient *db;
-
- db = [self provideClient];
- [anInvocation invokeWithTarget: db];
- [self swallowClient: db];
-}
-
-- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
-{
- NSMethodSignature *methodSig;
-
- methodSig = [super methodSignatureForSelector: aSelector];
- if (nil == methodSig && 0 != c && NO == selIsBad(aSelector))
- {
- methodSig = [c[0] methodSignatureForSelector: aSelector];
- }
- return methodSig;
-}
-
-- (BOOL) respondsToSelector: (SEL)aSelector
-{
- BOOL result;
-
- result = [super respondsToSelector: aSelector];
- if (NO == result && 0 != c && NO == selIsBad(aSelector))
- {
- result = [c[0] respondsToSelector: aSelector];
- }
- return result;
-}
-
+@interface SQLClient (Private)
+- (NSMutableArray*) _prepare: (NSString*)stmt args: (va_list)args;
@end
+@implementation SQLClientPool (ConvenienceMethods)
+
+- (NSString*) buildQuery: (NSString*)stmt, ...
+{
+ SQLClient *db = [self provideClient];
+ NSString *sql = nil;
+ va_list ap;
+
+ /*
+ * First check validity and concatenate parts of the query.
+ */
+ va_start (ap, stmt);
+ sql = [[db _prepare: stmt args: ap] objectAtIndex: 0];
+ va_end (ap);
+ [self swallowClient: db];
+
+ return sql;
+}
+
+- (NSString*) buildQuery: (NSString*)stmt with: (NSDictionary*)values
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db buildQuery: stmt with: values];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) cache: (int)seconds
+ query: (NSString*)stmt,...
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result;
+ va_list ap;
+
+ va_start (ap, stmt);
+ stmt = [[db _prepare: stmt args: ap] objectAtIndex: 0];
+ va_end (ap);
+ result = [db cache: seconds simpleQuery: stmt];
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) cache: (int)seconds
+ query: (NSString*)stmt
+ with: (NSDictionary*)values
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result = [db cache: seconds query: stmt with: values];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) cache: (int)seconds simpleQuery: (NSString*)stmt;
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result = [db cache: seconds simpleQuery: stmt];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) cache: (int)seconds
+ simpleQuery: (NSString*)stmt
+ recordType: (id)rtype
+ listType: (id)ltype
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result;
+
+ result = [db cache: seconds
+ simpleQuery: stmt
+ recordType: rtype
+ listType: ltype];
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) columns: (NSMutableArray*)records
+{
+ return [SQLClient columns: records];
+}
+
+- (NSInteger) execute: (NSString*)stmt, ...
+{
+ SQLClient *db = [self provideClient];
+ NSInteger result;
+ NSArray *info;
+ va_list ap;
+
+ va_start (ap, stmt);
+ info = [db _prepare: stmt args: ap];
+ va_end (ap);
+ result = [db simpleExecute: info];
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSInteger) execute: (NSString*)stmt with: (NSDictionary*)values
+{
+ SQLClient *db = [self provideClient];
+ NSInteger result = [db execute: stmt with: values];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) query: (NSString*)stmt, ...
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result = nil;
+ va_list ap;
+
+ /*
+ * First check validity and concatenate parts of the query.
+ */
+ va_start (ap, stmt);
+ stmt = [[db _prepare: stmt args: ap] objectAtIndex: 0];
+ va_end (ap);
+ result = [db simpleQuery: stmt];
+ [self swallowClient: db];
+
+ return result;
+}
+
+- (NSMutableArray*) query: (NSString*)stmt with: (NSDictionary*)values
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result = [db query: stmt with: values];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (SQLRecord*) queryRecord: (NSString*)stmt, ...
+{
+ SQLClient *db = [self provideClient];
+ NSArray *result = nil;
+ SQLRecord *record;
+ va_list ap;
+
+ va_start (ap, stmt);
+ stmt = [[db _prepare: stmt args: ap] objectAtIndex: 0];
+ va_end (ap);
+ result = [db simpleQuery: stmt];
+ [self swallowClient: db];
+
+ if ([result count] > 1)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"Query returns more than one record -\n%@\n", stmt];
+ }
+ record = [result lastObject];
+ if (record == nil)
+ {
+ [NSException raise: SQLEmptyException
+ format: @"Query returns no data -\n%@\n", stmt];
+ }
+ return record;
+}
+
+- (NSString*) queryString: (NSString*)stmt, ...
+{
+ SQLClient *db = [self provideClient];
+ NSArray *result = nil;
+ SQLRecord *record;
+ va_list ap;
+
+ va_start (ap, stmt);
+ stmt = [[db _prepare: stmt args: ap] objectAtIndex: 0];
+ va_end (ap);
+ result = [db simpleQuery: stmt];
+ [self swallowClient: db];
+
+ if ([result count] > 1)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"Query returns more than one record -\n%@\n", stmt];
+ }
+ record = [result lastObject];
+ if (record == nil)
+ {
+ [NSException raise: SQLEmptyException
+ format: @"Query returns no data -\n%@\n", stmt];
+ }
+ if ([record count] > 1)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"Query returns multiple fields -\n%@\n", stmt];
+ }
+ return [[record lastObject] description];
+}
+
+- (NSString*) quote: (id)obj
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quote: obj];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quotef: (NSString*)fmt, ...
+{
+ SQLClient *db = [self provideClient];
+ va_list ap;
+ NSString *str;
+ NSString *quoted;
+
+ va_start(ap, fmt);
+ str = [[NSString allocWithZone: NSDefaultMallocZone()]
+ initWithFormat: fmt arguments: ap];
+ va_end(ap);
+ quoted = [self quoteString: str];
+ [self swallowClient: db];
+ [str release];
+ return quoted;
+}
+
+- (NSString*) quoteBigInteger: (int64_t)i
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteBigInteger: i];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quoteCString: (const char *)s
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteCString: s];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quoteChar: (char)chr
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteChar: chr];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quoteFloat: (float)f
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteFloat: f];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quoteInteger: (int)i
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteInteger: i];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSString*) quoteString: (NSString *)s
+{
+ SQLClient *db = [self provideClient];
+ NSString *result = [db quoteString: s];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSInteger) simpleExecute: (NSArray*)info
+{
+ SQLClient *db = [self provideClient];
+ NSInteger result = [db simpleExecute: info];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) simpleQuery: (NSString*)stmt
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result = [db simpleQuery: stmt];
+
+ [self swallowClient: db];
+ return result;
+}
+
+- (NSMutableArray*) simpleQuery: (NSString*)stmt
+ recordType: (id)rtype
+ listType: (id)ltype
+{
+ SQLClient *db = [self provideClient];
+ NSMutableArray *result;
+
+ result = [db simpleQuery: stmt
+ recordType: rtype
+ listType: ltype];
+ [self swallowClient: db];
+ return result;
+}
+
+- (void) singletons: (NSMutableArray*)records
+{
+ [SQLClient singletons: records];
+}
+
+@end
+
Modified: libs/sqlclient/trunk/testPostgres.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/testPostgres.m?rev=38249&r1=38248&r2=38249&view=diff
==============================================================================
--- libs/sqlclient/trunk/testPostgres.m (original)
+++ libs/sqlclient/trunk/testPostgres.m Thu Dec 11 18:26:32 2014
@@ -95,6 +95,7 @@
#endif
db = [sp provideClient];
[sp swallowClient: db];
+ [sp queryString: @"SELECT CURRENT_TIMESTAMP", nil];
db = [sp provideClient];
l = [Logger new];
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs