0

I have a function in an iOS app which reads in some data from a database. The function is extremely simple:

-(void) readCategories {
    sqlite3 *database;

    if([[NSFileManager defaultManager] fileExistsAtPath:databasePath]){
        if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
            const char *sqlStatement = "SELECT * FROM Categories ORDER BY name COLLATE NOCASE ASC";
            sqlite3_stmt *compiledStatement;
            int errorCode = sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL);

            if(errorCode == SQLITE_OK) {
                while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                    [categories addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]];
                }
            } else {
                 NSLog(@"Error reading categories. Code: %d, message: '%s'", errorCode,sqlite3_errmsg(database));
            }
            sqlite3_finalize(compiledStatement);
            sqlite3_close(database);
        } else {
            NSLog(@"Error opening DB");
        }
    } else {
        NSLog(@"DB does not exist.");
    }
}

The problem is that the errorCode is always SQLITE_ERROR which according to the documentation is: "SQL error or missing database". The message given is: 'no such table: Categories'

Now, if I look at the database file on my computer, the table is clearly there. I can also run exactly the same query on it and it works correctly.

Does anyone have any ideas on what is going wrong?

Thanks.

13
  • are you sure that the file at databasePath is a correct database file? Commented Jul 3, 2012 at 12:30
  • 1
    you should use sqlite3_errmsg (sqlite.org/c3ref/errcode.html) to see what's wrong. SQLITE_ERROR can also mean, that your SQL is wrong. Commented Jul 3, 2012 at 12:33
  • I have edited my post with more info. Commented Jul 3, 2012 at 13:07
  • plese print error code NSLog(@"error = %d",sqlite3_errcode(database)); before sqlite3_finalize(compiledStatement); Commented Jul 3, 2012 at 13:09
  • 1
    use this line (sqlite3_prepare_v2(database, [sqlStatement cStringUsingEncoding:NSUTF8StringEncoding], -1, &compiledStatement, NULL) Commented Jul 3, 2012 at 13:22

2 Answers 2

3

If you ever ran this code prior to adding the [[NSFileManager defaultManager] fileExistsAtPath:databasePath] check, the standard sqlite3_open will have created a blank database for you if it didn't find one. So,

  1. Reset your Simulator via "Reset Content and Settings..." on the Simulator's menu. This will clear out any extraneous database files that may have been created in the past. (If you're doing this on a device, remove the app and then reinstall it.)

  2. The sqlite3_open command will create blank database if it's not found. To be safe, in the future, use sqlite3_open_v2 instead, which will never create a blank database:

    if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
        // handle opening error here
    }
    

    By using sqlite3_open_v2, it will ensure that a database will never be created during the open process.

  3. If you're still having problems, navigate to your simulator's directory on your machine, namely "~/Library/Application Support/iPhone Simulator". (You might have to unhide your Library folder by typing the following command in the terminal window:

    chflags nohidden ~/Library
    

    Try examining the database there (rather than the version in your Xcode project) and see if the database has all of the tables you expected it to.

  4. If after doing all of this, you're not seeing your database being copied to your simulator/device, make sure you've set your target's Build Phases settings so that the database is include via "Copy Bundle Resources".

  5. As others have suggested, whenever you get SQLITE_ERROR, always check out the error details via something like NSLog(@"%s SQLITE_ERROR '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));.

Sign up to request clarification or add additional context in comments.

2 Comments

1) I am using a device and can only use a device due to hardware constraints. However, I have removed everything as this was indeed happening. 2) Done. 3) As I said, using hardware, so this won't work unfortunately. 4) Yeah this is all correct on my project. 5) Yup, using that now.
@Velox if the database wasn't being copied over, it's undoubtedly point #4, which will make sure it's part of the bundle. You may also, then, want to have the app copy this file to the Documents folder so that any user updates won't get blown away by future app upgrades.
0

So the bug was that it wasn't copying over the database file. I still have no idea why it wasn't. I fortunately have the luxury of being able to create the database file programatically. Doing that solved the problem. Not sure why the file wouldn't copy however.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.