Author: rfm
Date: Sat Aug 9 16:02:11 2014
New Revision: 38043
URL: http://svn.gna.org/viewcvs/gnustep?rev=38043&view=rev
Log:
lter merging mechanism for flexibility and ease of use
Modified:
libs/sqlclient/trunk/ChangeLog
libs/sqlclient/trunk/SQLClient.h
libs/sqlclient/trunk/SQLClient.m
Modified: libs/sqlclient/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/ChangeLog?rev=38043&r1=38042&r2=38043&view=diff
==============================================================================
--- libs/sqlclient/trunk/ChangeLog (original)
+++ libs/sqlclient/trunk/ChangeLog Sat Aug 9 16:02:11 2014
@@ -1,3 +1,11 @@
+2014-08-09 Richard Frith-Macdonald <[email protected]>
+
+ * SQLClient.h:
+ * SQLClient.m:
+ Redesign merging to give control over the number of statements
+ merged and to make merging an attribute of the transaction
+ rather than something done by a specific method.
+
2014-08-08 Richard Frith-Macdonald <[email protected]>
* SQLClient.h:
Modified: libs/sqlclient/trunk/SQLClient.h
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.h?rev=38043&r1=38042&r2=38043&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.h (original)
+++ libs/sqlclient/trunk/SQLClient.h Sat Aug 9 16:02:11 2014
@@ -1537,6 +1537,7 @@
unsigned _count;
BOOL _batch;
BOOL _stop;
+ uint8_t _merge;
}
/**
@@ -1649,10 +1650,25 @@
*/
- (void) insertTransaction: (SQLTransaction*)trn atIndex: (unsigned)index;
-/**
- * Like -add:... but, if the new statement can be merged with a recently
- * added one, this does that rather than adding as a separate statement.
- * <p>You may use this with an insert statement of the form:<br />
+/** Remove the index'th transaction or statement from the receiver.
+ */
+- (void) removeTransactionAtIndex: (unsigned)index;
+
+/**
+ * Resets the transaction, removing all previously added statements.
+ * This allows the transaction object to be re-used for multiple
+ * transactions.
+ */
+- (void) reset;
+
+/** <p>Use this method to enable merging of statemements subsequently added
+ * or appended to the receiver. The history argument specifies how many
+ * of the most recent statements in the transaction should be checked for
+ * merging in a new statement, with a value of zero meaning that no
+ * merging is done.<br />
+ * Returns the previous setting for the transaction.
+ * </p>
+ * <p>You may use this feature with an insert statement of the form:<br />
* INSERT INTO table (fieldnames) VALUES (values);<br />
* For databases which support multiline inserts such that they can be
* merged into something of the form:
@@ -1667,35 +1683,15 @@
* added to the transaction.<br />
* Caveats:<br />
* 1. databases may not actually support multiline insert.<br />
- * 2. Only the most recent five statements in a transaction are checked
- * for eligibility.<br />
- * 3. Merging is done only if the statement up to the string 'VALUES'
+ * 2. Merging is done only if the statement up to the string 'VALUES'
* (for insert) or 'WHERE' (for update) matches.<br />
- * 4. Merging into any of the last 5 statements may of course change the
- * order of statements in the transaction, so care must be taken not to
- * use this feature where that migfht matter.<br />
- * 5. This is a simple text match rather than sql syntactic analysis,
+ * 3. Merging into any of the last N statements (where N is greater than 1)
+ * may of course change the order of statements in the transaction,
+ * so care must be taken not to use this feature where that might matter.<br />
+ * 4. This is a simple text match rather than sql syntactic analysis,
* so it's possible to confuse the process with complex statements.
*/
-- (void) merge: (NSString*)stmt,...;
-
-/**
- * Like -add:with: but, if the new statement can be merged with a recently
- * added one, this does that rather than adding as a separate statement.
- * See -merge:,... for meore details.
- */
-- (void) merge: (NSString*)stmt with: (NSDictionary*)values;
-
-/** Remove the index'th transaction or statement from the receiver.
- */
-- (void) removeTransactionAtIndex: (unsigned)index;
-
-/**
- * Resets the transaction, removing all previously added statements.
- * This allows the transaction object to be re-used for multiple
- * transactions.
- */
-- (void) reset;
+- (uint8_t) setMerge: (uint8_t)history;
/**
* Returns the total count of statements in this transaction including
Modified: libs/sqlclient/trunk/SQLClient.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/sqlclient/trunk/SQLClient.m?rev=38043&r1=38042&r2=38043&view=diff
==============================================================================
--- libs/sqlclient/trunk/SQLClient.m (original)
+++ libs/sqlclient/trunk/SQLClient.m Sat Aug 9 16:02:11 2014
@@ -2947,20 +2947,184 @@
}
}
+/* Try to merge the prepared statement p with an earlier statement in the
+ * transaction. We search up to 5 earlier statements and we merge if we can.
+ */
+- (void) _merge: (NSMutableArray*)p
+{
+ if (_count > 0 && _merge > 0)
+ {
+ static NSCharacterSet *w = nil;
+ NSString *s;
+ NSRange r;
+
+ s = [p objectAtIndex: 0]; // Get SQL part of array
+
+ if (nil == w)
+ {
+ w = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
+ }
+
+ r = [s rangeOfString: @"INSERT" options: NSCaseInsensitiveSearch];
+ if (r.length > 0 && 0 == r.location)
+ {
+ r = [s rangeOfString: @"VALUES" options: NSCaseInsensitiveSearch];
+ if (r.length > 0)
+ {
+ NSUInteger l = [s length];
+ NSUInteger pos = NSMaxRange(r);
+
+ while (pos < l
+ && [w characterIsMember: [s characterAtIndex: pos]])
+ {
+ pos++;
+ }
+ if (pos < l && [s characterAtIndex: pos] == '(')
+ {
+ NSString *t = [s substringToIndex: pos];
+ NSUInteger index = _count;
+ NSUInteger attempts = 0;
+
+ s = [s substringFromIndex: pos];
+ while (index-- > 0 && attempts++ < _merge)
+ {
+ NSMutableArray *o;
+ NSString *os;
+
+ o = [_info objectAtIndex: index];
+ os = [o objectAtIndex: 0];
+ if ([os hasPrefix: t])
+ {
+ NSMutableString *m;
+
+ if ([os isKindOfClass: [NSMutableString class]])
+ {
+ m = (NSMutableString*)os;
+ }
+ else
+ {
+ m = [NSMutableString
+ stringWithCapacity: [os length] * 100];
+ [m appendString: os];
+ }
+ [m appendString: @","];
+ [m appendString: s];
+ [o replaceObjectAtIndex: 0 withObject: m];
+ for (index = 1; index < [p count]; index++)
+ {
+ [o addObject: [p objectAtIndex: index]];
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ r = [s rangeOfString: @"UPDATE" options: NSCaseInsensitiveSearch];
+ if (0 == r.length)
+ {
+ r = [s rangeOfString: @"DELETE" options: NSCaseInsensitiveSearch];
+ }
+ if (r.length > 0 && 0 == r.location)
+ {
+ r = [s rangeOfString: @"WHERE" options: NSCaseInsensitiveSearch];
+ if (r.length > 0)
+ {
+ NSUInteger l = [s length];
+ NSUInteger pos = NSMaxRange(r);
+
+ while (pos < l
+ && [w characterIsMember: [s characterAtIndex: pos]])
+ {
+ pos++;
+ }
+ if (pos < l && [s characterAtIndex: pos] == '(')
+ {
+ NSString *t = [s substringToIndex: pos];
+ NSUInteger index = _count;
+ NSUInteger attempts = 0;
+
+ /* Get the condition after the WHERE and if it's not
+ * in brackets, add them so the merge can work.
+ */
+ s = [s substringFromIndex: pos];
+ if ([s characterAtIndex: 0] != '(')
+ {
+ s = [NSString stringWithFormat: @"(%@)", s];
+ }
+
+ while (index-- > 0 && attempts++ < _merge)
+ {
+ NSMutableArray *o;
+ NSString *os;
+
+ o = [_info objectAtIndex: index];
+ os = [o objectAtIndex: 0];
+ if ([os hasPrefix: t])
+ {
+ NSMutableString *m;
+
+ l = [os length];
+ if ([os characterAtIndex: l - 1] == ')')
+ {
+ if ([os isKindOfClass: [NSMutableString class]])
+ {
+ m = (NSMutableString*)os;
+ }
+ else
+ {
+ m = [NSMutableString
+ stringWithCapacity: l * 100];
+ [m appendString: os];
+ }
+ }
+ else
+ {
+ /* The condition of the WHERE clause was not
+ * bracketed, so we extract it and build a
+ * new statement in which it is bracketed.
+ */
+ os = [os substringFromIndex: pos];
+ m = [NSMutableString
+ stringWithCapacity: l * 100];
+ [m appendFormat: @"%@(%@)", t, os];
+ }
+ [m appendString: @" OR "];
+ [m appendString: s];
+ [o replaceObjectAtIndex: 0 withObject: m];
+ for (index = 1; index < [p count]; index++)
+ {
+ [o addObject: [p objectAtIndex: index]];
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ [_info addObject: p];
+ _count++;
+}
+
- (void) add: (NSString*)stmt,...
{
- va_list ap;
+ va_list ap;
+ NSMutableArray *p;
va_start (ap, stmt);
- [_info addObject: [_db _prepare: stmt args: ap]];
- _count++;
+ p = [_db _prepare: stmt args: ap];
va_end (ap);
+ [self _merge: p];
}
- (void) add: (NSString*)stmt with: (NSDictionary*)values
{
- [_info addObject: [_db _substitute: stmt with: values]];
- _count++;
+ NSMutableArray *p;
+
+ p = [_db _substitute: stmt with: values];
+ [self _merge: p];
}
- (void) append: (SQLTransaction*)other
@@ -2973,10 +3137,25 @@
format: @"[%@-%@] database client missmatch",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
- other = [other copy];
- [_info addObject: other];
- _count += other->_count;
- [other release];
+ if (_merge > 0)
+ {
+ unsigned index;
+
+ /* Merging of statements is turned on ... try to merge statements
+ * from other transaction rather than simply appending a copy of it.
+ */
+ for (index = 0; index < other->_count; index++)
+ {
+ [self _merge: [other->_info objectAtIndex: index]];
+ }
+ }
+ else
+ {
+ other = [other copy];
+ [_info addObject: other];
+ _count += other->_count;
+ [other release];
+ }
}
}
@@ -3202,186 +3381,6 @@
[trn release];
}
-/* Try to merge the prepared statement p with an earlier statement in the
- * transaction. We search up to 5 earlier statements and we merge if we can.
- */
-- (void) _merge: (NSMutableArray*)p
-{
- if (_count > 0)
- {
- static NSCharacterSet *w = nil;
- NSString *s;
- NSRange r;
-
- s = [p objectAtIndex: 0]; // Get SQL part of array
-
- if (nil == w)
- {
- w = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
- }
-
- r = [s rangeOfString: @"INSERT" options: NSCaseInsensitiveSearch];
- if (r.length > 0 && 0 == r.location)
- {
- r = [s rangeOfString: @"VALUES" options: NSCaseInsensitiveSearch];
- if (r.length > 0)
- {
- NSUInteger l = [s length];
- NSUInteger pos = NSMaxRange(r);
-
- while (pos < l
- && [w characterIsMember: [s characterAtIndex: pos]])
- {
- pos++;
- }
- if (pos < l && [s characterAtIndex: pos] == '(')
- {
- NSString *t = [s substringToIndex: pos];
- NSUInteger index = _count;
- NSUInteger attempts = 0;
-
- s = [s substringFromIndex: pos];
- while (index-- > 0 && attempts++ < 5)
- {
- NSMutableArray *o;
- NSString *os;
-
- o = [_info objectAtIndex: index];
- os = [o objectAtIndex: 0];
- if ([os hasPrefix: t])
- {
- NSMutableString *m;
-
- if ([os isKindOfClass: [NSMutableString class]])
- {
- m = (NSMutableString*)os;
- }
- else
- {
- m = [NSMutableString
- stringWithCapacity: [os length] * 100];
- [m appendString: os];
- }
- [m appendString: @","];
- [m appendString: s];
- [o replaceObjectAtIndex: 0 withObject: m];
- for (index = 1; index < [p count]; index++)
- {
- [o addObject: [p objectAtIndex: index]];
- }
- return;
- }
- }
- }
- }
- }
-
- r = [s rangeOfString: @"UPDATE" options: NSCaseInsensitiveSearch];
- if (0 == r.length)
- {
- r = [s rangeOfString: @"DELETE" options: NSCaseInsensitiveSearch];
- }
- if (r.length > 0 && 0 == r.location)
- {
- r = [s rangeOfString: @"WHERE" options: NSCaseInsensitiveSearch];
- if (r.length > 0)
- {
- NSUInteger l = [s length];
- NSUInteger pos = NSMaxRange(r);
-
- while (pos < l
- && [w characterIsMember: [s characterAtIndex: pos]])
- {
- pos++;
- }
- if (pos < l && [s characterAtIndex: pos] == '(')
- {
- NSString *t = [s substringToIndex: pos];
- NSUInteger index = _count;
- NSUInteger attempts = 0;
-
- /* Get the condition after the WHERE and if it's not
- * in brackets, add them so the merge can work.
- */
- s = [s substringFromIndex: pos];
- if ([s characterAtIndex: 0] != '(')
- {
- s = [NSString stringWithFormat: @"(%@)", s];
- }
-
- while (index-- > 0 && attempts++ < 5)
- {
- NSMutableArray *o;
- NSString *os;
-
- o = [_info objectAtIndex: index];
- os = [o objectAtIndex: 0];
- if ([os hasPrefix: t])
- {
- NSMutableString *m;
-
- l = [os length];
- if ([os characterAtIndex: l - 1] == ')')
- {
- if ([os isKindOfClass: [NSMutableString class]])
- {
- m = (NSMutableString*)os;
- }
- else
- {
- m = [NSMutableString
- stringWithCapacity: l * 100];
- [m appendString: os];
- }
- }
- else
- {
- /* The condition of the WHERE clause was not
- * bracketed, so we extract it and build a
- * new statement in which it is bracketed.
- */
- os = [os substringFromIndex: pos];
- m = [NSMutableString
- stringWithCapacity: l * 100];
- [m appendFormat: @"%@(%@)", t, os];
- }
- [m appendString: @" OR "];
- [m appendString: s];
- [o replaceObjectAtIndex: 0 withObject: m];
- for (index = 1; index < [p count]; index++)
- {
- [o addObject: [p objectAtIndex: index]];
- }
- return;
- }
- }
- }
- }
- }
- }
- [_info addObject: p];
- _count++;
-}
-
-- (void) merge: (NSString*)stmt,...
-{
- va_list ap;
- NSMutableArray *p;
-
- va_start (ap, stmt);
- p = [_db _prepare: stmt args: ap];
- va_end (ap);
- [self _merge: p];
-}
-
-- (void) merge: (NSString*)stmt with: (NSDictionary*)values
-{
- NSMutableArray *p;
-
- p = [_db _substitute: stmt with: values];
- [self _merge: p];
-}
-
- (void) removeTransactionAtIndex: (unsigned)index
{
id o;
@@ -3408,6 +3407,14 @@
{
[_info removeAllObjects];
_count = 0;
+}
+
+- (uint8_t) setMerge: (uint8_t)history
+{
+ uint8_t old = _merge;
+
+ _merge = history;
+ return old;
}
- (unsigned) totalCount
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs