Browse Source

Changed up how the binding count is calculated when passing a dictionary for named parameter support. Thanks to Samuel Chen for pointing out the problem

ccgus 13 years ago
parent
commit
ca40737958
4 changed files with 75 additions and 7 deletions
  1. 3 0
      CHANGES_AND_TODO_LIST.txt
  2. 1 0
      CONTRIBUTORS.txt
  3. 6 7
      src/FMDatabase.m
  4. 65 0
      src/fmdb.m

+ 3 - 0
CHANGES_AND_TODO_LIST.txt

@@ -3,6 +3,9 @@ Zip, nada, zilch.  Got any ideas?
 
 If you would like to contribute some code- awesome!  I just ask that you make it conform to the coding conventions already set in here, and to add a couple of tests for your new code to fmdb.m.  And of course, the code should be of general use to more than just a couple of folks.  Send your patches to gus@flyingmeat.com.
 
+2012.12.13
+    Changed up how the binding count is calculated when passing a dictionary for named parameter support.  Thanks to Samuel Chen for pointing out the problem.
+
 2012.11.23
     Added keyed and indexed subscript support to FMResultSet- so you can do use the fancy boxed syntax against it (rs[@"foo"] & rs[0]).  Thanks to Robert Ryan for the patches!
 

+ 1 - 0
CONTRIBUTORS.txt

@@ -33,5 +33,6 @@ Chris Dolan
 Sriram Patil
 Geoffrey Foster
 Robert Ryan
+Samuel Chen
 
 Aaaaannnd, Gus Mueller (that's me!)

+ 6 - 7
src/FMDatabase.m

@@ -591,14 +591,13 @@ - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arr
             if (namedIdx > 0) {
                 // Standard binding from here.
                 [self bindObject:[dictionaryArgs objectForKey:dictionaryKey] toColumn:namedIdx inStatement:pStmt];
+                // increment the binding count, so our check below works out
+                idx++;
             }
             else {
                 NSLog(@"Could not find index for %@", dictionaryKey);
             }
         }
-        
-        // we need the count of params to avoid an error below.
-        idx = (int) [[dictionaryArgs allKeys] count];
     }
     else {
             
@@ -775,14 +774,14 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
             if (namedIdx > 0) {
                 // Standard binding from here.
                 [self bindObject:[dictionaryArgs objectForKey:dictionaryKey] toColumn:namedIdx inStatement:pStmt];
+                
+                // increment the binding count, so our check below works out
+                idx++;
             }
             else {
                 NSLog(@"Could not find index for %@", dictionaryKey);
             }
         }
-        
-        // we need the count of params to avoid an error below.
-        idx = (int) [[dictionaryArgs allKeys] count];
     }
     else {
         
@@ -807,7 +806,7 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
     
     
     if (idx != queryCount) {
-        NSLog(@"Error: the bind count is not correct for the # of variables (%@) (executeUpdate)", sql);
+        NSLog(@"Error: the bind count (%d) is not correct for the # of variables in the query (%d) (%@) (executeUpdate)", idx, queryCount, sql);
         sqlite3_finalize(pStmt);
         _isExecutingStatement = NO;
         return NO;

+ 65 - 0
src/fmdb.m

@@ -205,6 +205,71 @@ int main (int argc, const char * argv[]) {
     
     
     
+    
+    
+    
+    {
+        // -------------------------------------------------------------------------------
+        // Named parameters count test.
+        FMDBQuickCheck([db executeUpdate:@"create table namedparamcounttest (a text, b text, c integer, d double)"]);
+        NSMutableDictionary *dictionaryArgs = [NSMutableDictionary dictionary];
+        [dictionaryArgs setObject:@"Text1" forKey:@"a"];
+        [dictionaryArgs setObject:@"Text2" forKey:@"b"];
+        [dictionaryArgs setObject:[NSNumber numberWithInt:1] forKey:@"c"];
+        [dictionaryArgs setObject:[NSNumber numberWithDouble:2.0] forKey:@"d"];
+        FMDBQuickCheck([db executeUpdate:@"insert into namedparamcounttest values (:a, :b, :c, :d)" withParameterDictionary:dictionaryArgs]);
+        
+        rs = [db executeQuery:@"select * from namedparamcounttest"];
+        
+        FMDBQuickCheck((rs != nil));
+        
+        [rs next];
+        
+        FMDBQuickCheck([[rs stringForColumn:@"a"] isEqualToString:@"Text1"]);
+        FMDBQuickCheck([[rs stringForColumn:@"b"] isEqualToString:@"Text2"]);
+        FMDBQuickCheck([rs intForColumn:@"c"] == 1);
+        FMDBQuickCheck([rs doubleForColumn:@"d"] == 2.0);
+        
+        [rs close];
+        
+        // note that at this point, dictionaryArgs has way more values than we need, but the query should still work since
+        // a is in there, and that's all we need.
+        rs = [db executeQuery:@"select * from namedparamcounttest where a = :a" withParameterDictionary:dictionaryArgs];
+        
+        FMDBQuickCheck((rs != nil));
+        FMDBQuickCheck([rs next]);
+        [rs close];
+        
+        
+        
+        // ***** Please note the following codes *****
+        
+        dictionaryArgs = [NSMutableDictionary dictionary];
+        
+        [dictionaryArgs setObject:@"NewText1" forKey:@"a"];
+        [dictionaryArgs setObject:@"NewText2" forKey:@"b"];
+        [dictionaryArgs setObject:@"OneMoreText" forKey:@"OneMore"];
+        
+        BOOL rc = [db executeUpdate:@"update namedparamcounttest set a = :a, b = :b where b = 'Text2'" withParameterDictionary:dictionaryArgs];
+        
+        FMDBQuickCheck(rc);
+        
+        if (!rc) {
+            NSLog(@"ERROR: %d - %@", db.lastErrorCode, db.lastErrorMessage);
+        }
+    
+        
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
     // ----------------------------------------------------------------------------------------
     // blob support.
     [db executeUpdate:@"create table blobTable (a text, b blob)"];