diff options
author | August Mueller <gus@flyingmeat.com> | 2014-02-12 23:03:50 +0400 |
---|---|---|
committer | August Mueller <gus@flyingmeat.com> | 2014-02-12 23:03:50 +0400 |
commit | 995dbb5540d3431decb10de6eff51a79c86527c8 (patch) | |
tree | 9397474aefb662275a28802bfb1a35df413399a5 | |
parent | e42b50f2435c8308711f8ece6dc768f8b9620bb3 (diff) |
Adding back in a loop for catching database busy errors. It needs to be added back in other spots as well, which I'll do - but I haven't thought of the best way to break out of the loop yet, so I'm going to request some comments on that.
-rw-r--r-- | src/FMDatabase.m | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/src/FMDatabase.m b/src/FMDatabase.m index 445ecb0..d3736a2 100644 --- a/src/FMDatabase.m +++ b/src/FMDatabase.m @@ -660,26 +660,37 @@ [statement reset]; } - if (!pStmt) { - rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0); + + if (!pStmt) { - if (SQLITE_OK != rc) { - if (_logsErrors) { - NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); - NSLog(@"DB Query: %@", sql); - NSLog(@"DB Path: %@", _databasePath); - } + BOOL retry; + + do { + retry = NO; + rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0); - if (_crashOnErrors) { - NSAssert(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); - abort(); + /*if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { + retry = YES; + } + else */if (SQLITE_OK != rc) { + if (_logsErrors) { + NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); + NSLog(@"DB Query: %@", sql); + NSLog(@"DB Path: %@", _databasePath); + } + + if (_crashOnErrors) { + NSAssert(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); + abort(); + } + + sqlite3_finalize(pStmt); + _isExecutingStatement = NO; + return nil; } - sqlite3_finalize(pStmt); - _isExecutingStatement = NO; - return nil; - } + } while (retry); } id obj; @@ -835,6 +846,8 @@ if (!pStmt) { rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0); + #pragma message "FIXME: need the busy loop here." + if (SQLITE_OK != rc) { if (_logsErrors) { NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); @@ -929,31 +942,55 @@ ** executed is not a SELECT statement, we assume no data will be returned. */ - rc = sqlite3_step(pStmt); + BOOL retry; + NSInteger numberOfRetries = 0; - if (SQLITE_DONE == rc) { - // all is well, let's return. - } - else if (SQLITE_ERROR == rc) { - if (_logsErrors) { - NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_ERROR", rc, sqlite3_errmsg(_db)); - NSLog(@"DB Query: %@", sql); + do { + retry = NO; + rc = sqlite3_step(pStmt); + + if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { + retry = YES; + + if (SQLITE_LOCKED == rc) { + rc = sqlite3_reset(pStmt); + if (rc != SQLITE_LOCKED) { + NSLog(@"Unexpected result from sqlite3_reset (%d) eu", rc); + } + } + +#pragma message "FIXME: HOW DO WE KNOW HOW TO BREAK OUT OF THIS? 10 is kind of a magic number?" + + if ((numberOfRetries++ > 10)) { + NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [self databasePath]); + NSLog(@"Database busy"); + retry = NO; + } } - } - 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 if (SQLITE_DONE == rc) { + // all is well, let's return. } - } - else { - // wtf? - if (_logsErrors) { - NSLog(@"Unknown error calling sqlite3_step (%d: %s) eu", rc, sqlite3_errmsg(_db)); - NSLog(@"DB Query: %@", sql); + else 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); + } + } + } while (retry); if (rc == SQLITE_ROW) { NSAssert(NO, @"A executeUpdate is being called with a query string '%@'", sql); |