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

Reply via email to