Cocos2d-x using populated database

I found myself questioning whether it would actually be a good idea to make a copy on iOS anyway and keep the original of the database in case something gets corrupted. Have the game check the integrity of the writeable/copied database on launch and if something’s not right, copy the original database file again. I’m not doing any writes to the database so I should be alright in this case, but something to think about for the future.

Hey clearmend,

Can you share your code for copying prepopulated database?

I did it the same way as you.

Hi, I used the code as suggested by your but I am getting the following error when I try to access the copied code:
[logging] database corruption at line 68621 of [2b0954060f]

At the line where the code tries to run an SQL command, I get the following error.
“Error executing SQL statement: database disk image is malformed”

Any idea what could be causing this. I am executing the initDB from AppDelegate so that I am certain that the database is ready by the time I need to access it. I also have put a check point before the line where I call the database, at the break point I browsed to the simulator’s writeable directory and verified that the database had been copied. However, the size of the file differs from the original file in the bundled resources.

Filesize in bundled resources - 4777984
Filesize in the writeable directory of simulator - 4775936

Lastly, below is the initDB code that I have copied. It is a static function, in case that makes any difference. Would really appreciate it if someone can help me figure out the issue and help me correct it.

void Database::initDB(){
std::string wpath = FileUtils::getInstance()->getWritablePath();
wpath.append("wordbounce.sqlite");

FILE* f = fopen(wpath.c_str(), "r");
if (f == nullptr) {
    //this is the first run, lets copy the DB
    CCLOG("this is the first run, lets copy the DB");
    ssize_t size = 0;
    const char* data = (char*)FileUtils::getInstance()->getFileData("wordbounce.sqlite", "rb", &size);
    //open for write the file this time !
    f = fopen(wpath.c_str(), "wb");
    //write data read from file f
    fwrite(data, size, 1, f);
    
    CC_SAFE_DELETE_ARRAY(data);
}

}

Many thanks!

Try replacing with:

 if (f == nullptr) {

     auto data = FileUtils::getInstance()->getDataFromFile("wordbounce.sqlite");
     FileUtils::getInstance()->writeDataToFile(data, wpath);

Works!!! Awesome… Thanks a ton Darvydas. Superb. :ok_hand::+1: