From 56fc0088ad1ae858b68ba7ebc83980007e4617b4 Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Mon, 4 Mar 2013 14:47:29 +0000 Subject: [PATCH] add helper classes git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@36261 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 8 ++++++ SQLClient.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ SQLClient.m | 59 +++++++++++++++++++++++++++++++++++++++++++ SQLite.m | 2 +- testSQLite.m | 4 +-- 5 files changed, 140 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58363f5..29d51d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-03-04 Richard Frith-Macdonald + + * SQLClient.h: Add helper classe interfaces. + * SQLClient.m: Add helper classe implementations. + Add performance helper classes for when querying a set of records + containing single values and when querying a dataset which contains + key/value pairs more naturally haqndled as a dictionary than an array. + 2013-02-11 Sebastian Reitenbach * ECPG.pgm * testECPG.m diff --git a/SQLClient.h b/SQLClient.h index 6a3bd4f..204663d 100644 --- a/SQLClient.h +++ b/SQLClient.h @@ -853,6 +853,8 @@ SQLCLIENT_PRIVATE * method to initialise itsself and the [NSMutableArray-addObject:] method * to add records to the list.
* If ltype is nil then the [NSMutableArray] class is used.
+ * This library provides a few helper classes to provide alternative + * values for rtype and ltype. */ - (NSMutableArray*) simpleQuery: (NSString*)stmt recordType: (id)rtype @@ -1509,5 +1511,73 @@ SQLCLIENT_PRIVATE - (SQLTransaction*) transactionAtIndex: (unsigned)index; @end + + +/* A helper for building a dictionary from an SQL query which returns + * key-value pairs (you can subclass it to handle other records).
+ * You create an instance of this class, and pass it as both the + * record and list class arguments of the low level SQLClient query.
+ * The query (which must return a number of records, each with two fields) + * will result in a mutable dictionary being built, with dictionary keys + * being the first field from each record and dictionary values being the + * second field of each record.
+ * If you want to handle records containing more than two values, you + * must create a subclass which overrides the -newWithValues:keys:count: + * method to create the record objects and add them to the content + * dictionary.
+ * See [SQLClient-simpleQuery:recordType:listType:] also.
+ * NB. When this class is used, the query will actually return an + * [NSMutableDictionary] instance rather than an [NSMutableArray] of + * [SQLRecord] objects. + */ +@interface SQLDictionaryBuilder : NSObject +{ + NSMutableDictionary *content; +} + +/** No need to do anything ... the object will already have been added by + * the -newWithValues:keys:count: method. + */ +- (void) addObject: (id)anObject; + +/** When a container is supposed to be allocated, we just return the + * receiver (which will then quietly ignore -addObject: messages). + */ +- (id) alloc; + +/** Returns the content dictionary for the receiver. + */ +- (NSMutableDictionary*) content; + +/** Creates a new content dictionary ... this method will be called + * automatically by the SQLClient object when it performs a query, + * so there is no need to call it at any other time. + */ +- (id) initWithCapacity: (NSUInteger)capacity; + +/** This is the main workhorse of the class ... it is called once for + * every record read from the database, and is responsible for adding + * that record to the content dictionary. The default implementation, + * instead of creating an object to hold the supplied record data, + * uses the two fields from the record as a key-value pair to add to + * the content dictionary, and returns nil as the record object. + * It's OK to return a nil object since we ignore the -addObject: + * argument. + */ +- (id) newWithValues: (id*)values keys: (id*)keys count: (unsigned int)count; +@end + +/* A helper for building a collection of singletons from an SQL query + * which returns singleton values.
+ * You create an instance of this class, and pass it as the record + * class argument of the low level SQLClient query.
+ * The query (which must return a number of records, each with one field) + * will result in the singleton values being stored in the list class.
+ * See [SQLClient-simpleQuery:recordType:listType:] also. + */ +@interface SQLSingletonBuilder : NSObject +- (id) newWithValues: (id*)values keys: (id*)keys count: (unsigned int)count; +@end + #endif diff --git a/SQLClient.m b/SQLClient.m index 08284c6..a2ee90a 100644 --- a/SQLClient.m +++ b/SQLClient.m @@ -3504,3 +3504,62 @@ validName(NSString *name) [lock unlock]; } @end + + + +@implementation SQLDictionaryBuilder +- (void) addObject: (id)anObject +{ + return; +} + +- (id) alloc +{ + return [self retain]; +} + +- (NSMutableDictionary*) content +{ + return content; +} + +- (void) dealloc +{ + [content release]; + [super dealloc]; +} + +- (id) initWithCapacity: (NSUInteger)capacity +{ + DESTROY(content); + content = [[NSMutableDictionary alloc] initWithCapacity: capacity]; + return self; +} + +- (id) newWithValues: (id*)values keys: (id*)keys count: (unsigned int)count +{ + if (count != 2) + { + [NSException raise: NSInvalidArgumentException + format: @"Query did not return key/value pairs"]; + } + [content setObject: values[1] forKey: values[0]]; + return nil; +} +@end + +@implementation SQLSingletonBuilder +- (id) newWithValues: (id*)values keys: (id*)keys count: (unsigned int)count +{ + /* Instead of creating an object to hold the supplied record, + * we use the field from the record as the value to be used. + */ + if (count != 1) + { + [NSException raise: NSInvalidArgumentException + format: @"Query did not return singleton values"]; + } + return [values[0] retain]; +} +@end + diff --git a/SQLite.m b/SQLite.m index f2c0200..bb568bf 100644 --- a/SQLite.m +++ b/SQLite.m @@ -1,6 +1,6 @@ /* -*-objc-*- */ -/** Implementation of SQLClientPostgres for GNUStep +/** Implementation of SQLClientSQLite for GNUStep Copyright (C) 2005 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald diff --git a/testSQLite.m b/testSQLite.m index b21509d..389b0cd 100644 --- a/testSQLite.m +++ b/testSQLite.m @@ -91,8 +91,8 @@ main() [db execute: @"insert into xxx " @"(k, char1, intval, realval, b) " - @"values (" - @"'hello', " + @"values (", + [db quoteString: @"hello"], @", " @"'X', " @"1, ", @"12345.6789, ",