''withBlock" not fired.
The db is opened successfully, but the performQuery's withBlock is not executed for some reason.
It seems the issue happens when a query related error occurs.
[[AFSQLManager sharedManager]openLocalDatabaseWithName:@"testdb.sqlite" andStatusBlock:^(BOOL success, NSError *error) {
[[AFSQLManager sharedManager]performQuery:
@"SELECT 1 FROM user LIMIT 1;" withBlock:^(NSArray *row, NSError *error, BOOL finished) {
NSLog(@"TABLE CHECK");
}];
}];
I tried the example and I see the same problem aswell. It seems to call the completion block when everything is ok and doesnt call it when theres an error for example selecting a database that doesnt exist etc doesnt fire the completion block with an error.
Here is how I fixed it while just playing around with it hope it helps. I went in the AFSQLManager.m file and thats in the AFSQLManager folder in the demo project.
find the
-(void)performQuery:(NSString *)query withBlock:(completionBlock)completion
function and basically look what Iv done below iv commented everything:
NSString *fixedQuery = [query stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [fixedQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSMutableArray *row = [NSMutableArray array];
for (int i = 0; i < sqlite3_column_count(statement); i++) {
[row addObject:((char *)sqlite3_column_text(statement, i)) ? [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, i)] : [NSNull null]];
}
if (completion) {
completion(row, nil, NO);
}
}
sqlite3_finalize(statement);
completion(nil, nil, YES);
//iv added this else on the end and added the completion to return errors from a custom function that basically just formats an sqlite error to NsError because thats what the completion block needs // we need the else because at top the if statement is basically checking if the query went ok and simply wasnt doing anything if things were not ok and we basically need the error if things fail. }else{ NSLog(@"caught error"); completion(nil,[self handleSqlError:_database],NO); }
}
Here is the function I added to AFSQLManager.m and .h to format the NsError basically just pass in your database and it returns an nserror for the error codes returned from the sqlite database. Obviously you could do it other ways or even directly in the else {} above but hope that gives you some ideas. I decided that way as a helper function incase its needed multiple places then I can just pass in the database and let it catch the errors.
-(NSError *)handleSqlError:(sqlite3 *)db
{
NSLog(@"Error while executing sql statement. '%s'", sqlite3_errmsg(db));
NSError *underlyingError = [[NSError alloc] initWithDomain:@"db" code:sqlite3_errcode(db) userInfo:nil];
return underlyingError;
}