简体   繁体   中英

Cannot reset the resource statement or I go in an infinite loop

I saw that I was getting code error 5 when I was trying to close the SQLite database.
So I struggled to reset all the resource used.
I believe that this is the method where I don't properly reset all the resources:

- (NSArray*) allObjects
{
    NSMutableArray* objects=[NSMutableArray new];
    // resource is an ivar of type sqlite3_stmt* , it has been initialized with   
    // sqlite3_prepare, a query where I select some rows of a table
    if(!resource)
    {
        return nil;
    }
    while(sqlite3_step(resource)== SQLITE_ROW)
    {
        NSMutableDictionary* object=[NSMutableDictionary new];
        int count= sqlite3_column_count(resource);
        for(int i=0; i<count; i++)
        {
            // I need to know the type and the name of all columns to build
            // a dictionary object.Later I'll optimize it doing this only at 
            // the first loop iteration.
            const char* key=sqlite3_column_name(resource, i);
            int type= sqlite3_column_type(resource, i);
            const unsigned char* text;
            double value;
            switch (type)
            {
                case SQLITE_TEXT:
                    text=sqlite3_column_text(resource, i);
                    [object setObject: [NSString stringWithFormat: @"%s",text] forKey: [NSString stringWithFormat: @"%s",key]];
                    break;
                case SQLITE_INTEGER:
                    value= sqlite3_column_int(resource, i);
                    [object setObject: @(value) forKey: [NSString stringWithFormat: @"%s",key]];
                    break;
                case SQLITE_FLOAT:
                    value= sqlite3_column_double(resource, i);
                    [object setObject: @(value) forKey: [NSString stringWithFormat: @"%s",key]];
                    break;
                case SQLITE_NULL:
                    [object setObject: [NSNull null] forKey: [NSString stringWithFormat: @"%s",key]];
                    break;
                default:
                    break;
            }
        }
        // sqlite3_reset(resource);  Point 1
        [objects addObject: object];
    }
    // sqlite3_reset(resource);  Point 2
    return objects;
}

So if I put sqlite3_reset(resource) at point 2 when I close the database I get error 5, if I put it at point 1 I go in an infinite loop.
I'm almost sure the problem is in this function,I am also doing other things with the database, so the error may be in other parts of the code, but that's a lot of code.So if the problem isn't here write it in the comment and I'll post other "suspicious" part of code.

You should put the "reset" at point #2. And then you should call sqlite3_finalize on the prepared statement when you don't need it anymore at all. You should also set the ivar to nil after doing this.

sqlite3_reset says you are ready to use the statement again. sqlite3_finalize says that you are completely done with the statement and its resources should be cleaned up.

An error 5 is SQLITE_BUSY . IF the "finalize" doesn't fix the problem, do some searching on causes of SQLITE_BUSY .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM