0

I'm targeting iOS 5.1 and trying to copy a database from my application files to my Documents folder. I've done this with this same code on apps in the past so I'm a little confuse as to why it isn't working this time.

This is the method I'm using to check if it exists and copy it over if it doesn't. It's from here.

-(void) checkAndCreateDatabase{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];

// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:self.databasePath];

// If the database already exists then return without doing anything
if(success) return;

NSLog(@"Installing db: %@", self.databasePath);
// If not then proceed to copy the database from the application to the users filesystem

// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];

//[databasePathFromApp release];
//[fileManager release];

}

When I try to query the db I do so like this:

sqlite3 *database1; 

// Open the database from the users filessytem
if(sqlite3_open([self.databasePath UTF8String], &database1) == SQLITE_OK) {
    // Setup the SQL Statement and compile it for faster access

    NSString *sqlStatement = [NSString stringWithFormat: @"update login set is_logged=0"];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database1, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {

        if(SQLITE_DONE != sqlite3_step(compiledStatement)){
            NSAssert1(0, @"Error while updating logged. '%s'", sqlite3_errmsg(database1));
            NSLog(@"Error setting logged_in to 0: %s", sqlite3_errmsg(database1));
        }
        else{
            NSLog(@"Made Logged_in=0");
        }
    }
    else{
        NSLog(@"Prop problem1: %s", sqlite3_errmsg(database1));
        NSLog(@"Couldn't prep 1");
    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);
}
else{

    NSLog(@"Couldn't even open db1");
}
sqlite3_close(database1);

The sqlite3_open() function returns false in this case with an sqlite3_errmsg of no such table: login.

I have a function that is called every second that creates an object that uses this database object. Could it be that the database hasn't been copied in that second and the next call is interrupting the previous copy? That doesn't sound likely.

Any ideas what might be the issue?

Solution I consulted this question:here and as per point number 2 it seems that my database was not in the "Copy Bundle Resources" list. I added it and everything seems fine now.

Thanks for getting me thinking in the right direction guys.

Community
  • 1
  • 1
emachine
  • 1,135
  • 4
  • 17
  • 25
  • 1
    Use Organizer to download the files from the phone and see what got copied. (Also, be aware that you will likely need to mark the DB file "do not backup" to get past Apple's new 5.1 standards.) – Hot Licks Mar 14 '12 at 15:28
  • It's showing up in the Documents folder but the contents are blank. I would assume this is related to an encoding issue with the sql file then? – emachine Mar 14 '12 at 15:33
  • Scratch that, I just deleted the app and re-installed and the database is not in the Documents folder. It seems that the [empty] database file appears only after I try to query it. – emachine Mar 14 '12 at 15:38
  • 1
    Yep, Sqlite will create a file if there is none. Double check that you're copying FROM the right place, etc. – Hot Licks Mar 14 '12 at 16:37

1 Answers1

1

Try verifying that each stage of your copy procedure returns a valid object. It could be that (for example) you are not including the extension when searching for the resource path. I tend to favor the NSBundle pathForResource:ofType function to get stuff from the bundle. Also, with regards to the empty DB, sqlite's open function creates a database if it doesn't exist, and opens that. Try getting the error from copyItemAtPath

borrrden
  • 33,256
  • 8
  • 74
  • 109
  • The error is: Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn‚Äôt be completed. (Cocoa error 260.)" UserInfo=0x271dd0 {NSFilePath=/var/mobile/Applications/F39FFDFB-32FB-4533-8EE2-5ECA8A7FBF60/MyApp.app/myappdb.sql, NSUnderlyingError=0x271d30 "The operation couldn‚Äôt be completed. No such file or directory"} – emachine Mar 14 '12 at 16:08
  • When I use [[NSBundle mainBundle] pathForResource:@"myappdb" ofType:@"sql"] I get this error - Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSFileManager copyItemAtPath:toPath:error:]: source path is nil' – emachine Mar 14 '12 at 16:19
  • So it seems to me that my issue is the path I'm using to go get the original database in my resources folder... – emachine Mar 14 '12 at 16:27
  • Ah, it seems that the database wasn't in the "Copy bundel Resources" list. I added it and all seems fine now. Odd that it wasn't automatically added. – emachine Mar 14 '12 at 17:00
  • @emachine :- Add your comment as an Answer to the question – Jamal Zafar Jul 10 '13 at 08:43