Browse Source

Fix step error handling

- The error handling in `executeUpdate` was not capturing the error in many scenarios;
- The error handling in `executeUpdate` was logging messages even if `_logErrors` was false;
- `executeUpdate` was calling finalize before building the error message;
- Some of the custom errors (e.g. parameters don't match up) in `executeUpdate` weren't generating any error at all;
Robert M. Ryan 10 years ago
parent
commit
0c4fecb40c
1 changed files with 62 additions and 37 deletions
  1. 62 37
      src/fmdb/FMDatabase.m

+ 62 - 37
src/fmdb/FMDatabase.m

@@ -73,7 +73,7 @@ - (NSString *)databasePath {
 }
 
 + (NSString*)FMDBUserVersion {
-    return @"2.6";
+    return @"2.6.2";
 }
 
 // returns 0x0240 for version 2.4.  This makes it super easy to do things like:
@@ -100,7 +100,6 @@ + (SInt32)FMDBVersion {
         
     });
     
-
     return FMDBVersionVal;
 }
 
@@ -163,7 +162,7 @@ - (BOOL)openWithFlags:(int)flags vfs:(NSString *)vfsName {
     if (_db) {
         return YES;
     }
-
+    
     int err = sqlite3_open_v2([self sqlitePath], (sqlite3**)&_db, flags, [vfsName UTF8String]);
     if(err != SQLITE_OK) {
         NSLog(@"error opening!: %d", err);
@@ -251,7 +250,7 @@ static int FMDBDatabaseBusyHandler(void *f, int count) {
         return 1;
     }
     
-	return 0;
+    return 0;
 }
 
 - (void)setMaxBusyRetryTimeInterval:(NSTimeInterval)timeout {
@@ -468,15 +467,15 @@ - (void)warnInUse {
 - (BOOL)databaseExists {
     
     if (!_db) {
-            
+        
         NSLog(@"The FMDatabase %@ is not open.", self);
         
-    #ifndef NS_BLOCK_ASSERTIONS
+#ifndef NS_BLOCK_ASSERTIONS
         if (_crashOnErrors) {
             NSAssert(false, @"The FMDatabase %@ is not open.", self);
             abort();
         }
-    #endif
+#endif
         
         return NO;
     }
@@ -503,11 +502,11 @@ - (int)lastErrorCode {
 - (NSError*)errorWithMessage:(NSString*)message {
     NSDictionary* errorMessage = [NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey];
     
-    return [NSError errorWithDomain:@"FMDatabase" code:sqlite3_errcode(_db) userInfo:errorMessage];    
+    return [NSError errorWithDomain:@"FMDatabase" code:sqlite3_errcode(_db) userInfo:errorMessage];
 }
 
 - (NSError*)lastError {
-   return [self errorWithMessage:[self lastErrorMessage]];
+    return [self errorWithMessage:[self lastErrorMessage]];
 }
 
 #pragma mark Update information routines
@@ -772,8 +771,8 @@ - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arr
     }
     
     if (!pStmt) {
-    
-        rc      = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
+        
+        rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
         
         if (SQLITE_OK != rc) {
             if (_logsErrors) {
@@ -804,7 +803,7 @@ - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arr
             
             // Prefix the key with a colon.
             NSString *parameterName = [[NSString alloc] initWithFormat:@":%@", dictionaryKey];
-
+            
             if (_traceExecution) {
                 NSLog(@"%@ = %@", parameterName, [dictionaryArgs objectForKey:dictionaryKey]);
             }
@@ -826,7 +825,7 @@ - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arr
         }
     }
     else {
-            
+        
         while (idx < queryCount) {
             
             if (arrayArgs && idx < (int)[arrayArgs count]) {
@@ -882,7 +881,7 @@ - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arr
     
     [statement setUseCount:[statement useCount] + 1];
     
-    FMDBRelease(statement); 
+    FMDBRelease(statement);
     
     _isExecutingStatement = NO;
     
@@ -905,7 +904,7 @@ - (FMResultSet *)executeQueryWithFormat:(NSString*)format, ... {
     
     NSMutableString *sql = [NSMutableString stringWithCapacity:[format length]];
     NSMutableArray *arguments = [NSMutableArray array];
-    [self extractSQL:format argumentsList:args intoString:sql arguments:arguments];    
+    [self extractSQL:format argumentsList:args intoString:sql arguments:arguments];
     
     va_end(args);
     
@@ -972,12 +971,12 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
                 abort();
             }
             
-            sqlite3_finalize(pStmt);
-            
             if (outErr) {
                 *outErr = [self errorWithMessage:[NSString stringWithUTF8String:sqlite3_errmsg(_db)]];
             }
             
+            sqlite3_finalize(pStmt);
+            
             _isExecutingStatement = NO;
             return NO;
         }
@@ -1011,7 +1010,14 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
                 idx++;
             }
             else {
-                NSLog(@"Could not find index for %@", dictionaryKey);
+                NSString *message = [NSString stringWithFormat:@"Could not find index for %@", dictionaryKey];
+                
+                if (_logsErrors) {
+                    NSLog(@"%@", message);
+                }
+                if (outErr) {
+                    *outErr = [self errorWithMessage:message];
+                }
             }
         }
     }
@@ -1047,7 +1053,14 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
     
     
     if (idx != queryCount) {
-        NSLog(@"Error: the bind count (%d) is not correct for the # of variables in the query (%d) (%@) (executeUpdate)", idx, queryCount, sql);
+        NSString *message = [NSString stringWithFormat:@"Error: the bind count (%d) is not correct for the # of variables in the query (%d) (%@) (executeUpdate)", idx, queryCount, sql];
+        if (_logsErrors) {
+            NSLog(@"%@", message);
+        }
+        if (outErr) {
+            *outErr = [self errorWithMessage:message];
+        }
+        
         sqlite3_finalize(pStmt);
         _isExecutingStatement = NO;
         return NO;
@@ -1062,29 +1075,41 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArra
     if (SQLITE_DONE == rc) {
         // all is well, let's return.
     }
-    else if (SQLITE_ERROR == rc) {
+    else if (rc == SQLITE_ROW) {
+        NSString *message = [NSString stringWithFormat:@"A executeUpdate is being called with a query string '%@'", sql];
         if (_logsErrors) {
-            NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_ERROR", rc, sqlite3_errmsg(_db));
+            NSLog(@"%@", message);
             NSLog(@"DB Query: %@", sql);
         }
-    }
-    else if (SQLITE_MISUSE == rc) {
-        // uh oh.
-        if (_logsErrors) {
-            NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_MISUSE", rc, sqlite3_errmsg(_db));
-            NSLog(@"DB Query: %@", sql);
+        if (outErr) {
+            *outErr = [self errorWithMessage:message];
         }
     }
     else {
-        // wtf?
-        if (_logsErrors) {
-            NSLog(@"Unknown error calling sqlite3_step (%d: %s) eu", rc, sqlite3_errmsg(_db));
-            NSLog(@"DB Query: %@", sql);
+        if (outErr) {
+            *outErr = [self errorWithMessage:[NSString stringWithUTF8String:sqlite3_errmsg(_db)]];
+        }
+        
+        if (SQLITE_ERROR == rc) {
+            if (_logsErrors) {
+                NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_ERROR", rc, sqlite3_errmsg(_db));
+                NSLog(@"DB Query: %@", sql);
+            }
+        }
+        else if (SQLITE_MISUSE == rc) {
+            // uh oh.
+            if (_logsErrors) {
+                NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_MISUSE", rc, sqlite3_errmsg(_db));
+                NSLog(@"DB Query: %@", sql);
+            }
+        }
+        else {
+            // wtf?
+            if (_logsErrors) {
+                NSLog(@"Unknown error calling sqlite3_step (%d: %s) eu", rc, sqlite3_errmsg(_db));
+                NSLog(@"DB Query: %@", sql);
+            }
         }
-    }
-    
-    if (rc == SQLITE_ROW) {
-        NSAssert(NO, @"A executeUpdate is being called with a query string '%@'", sql);
     }
     
     if (_shouldCacheStatements && !cachedStmt) {
@@ -1155,7 +1180,7 @@ - (BOOL)executeUpdateWithFormat:(NSString*)format, ... {
     NSMutableString *sql      = [NSMutableString stringWithCapacity:[format length]];
     NSMutableArray *arguments = [NSMutableArray array];
     
-    [self extractSQL:format argumentsList:args intoString:sql arguments:arguments];    
+    [self extractSQL:format argumentsList:args intoString:sql arguments:arguments];
     
     va_end(args);
     
@@ -1198,7 +1223,7 @@ - (BOOL)executeStatements:(NSString *)sql withResultBlock:(FMDBExecuteStatements
         NSLog(@"Error inserting batch: %s", errmsg);
         sqlite3_free(errmsg);
     }
-
+    
     return (rc == SQLITE_OK);
 }