Question

I'm having trouble opening a sqlite3 file by passing the directory of it to sqlite3_open().

By logging the result, and the value of dbPath, it can be seen that sqlite does attempt to, and the file has been found. What I'm unsure about is if the format of dbPath is correct.

The following code returns false, as result != SQLITE_OK, it equals SQLITE_CANTOPEN instead.

//load from the Data/ directory (or assets/ if android)
std::string dbPath = CCFileUtils::getInstance()->fullPathForFilename("molemioDB.sql");

result = sqlite3_open(dbPath.c_str(),&pDB);

//failed to open database?
if (result != SQLITE_OK){
    CCLOG("ERROR: Failed to open database: %i", result);

    return false;
}

Result has a value of 14, and from sqlite3.h:

#define SQLITE_CANTOPEN    14   /* Unable to open the database file */

And dbPath's value is shown after using a MessageBox to display it. It equals:

"assets/molemioDB.sql"

Why does this happen? The database file is inside the assets file in proj.android. And, also in the Data/ folder in the highest directory on my computer - although this is for the iOS version, which loads the database perfectly fine.

A few things to note is that the database is obviously precreated, using a python script I had written. The permissions for the molemioDB.sql file is 644, although the database is only read.

Thanks in advance.

Was it helpful?

Solution

Android assets cannot be accessed directly, neither in Java nor in native code. They are not files on the filesystem but are compressed data inside of your APK.

Here's what you should do:

  1. Android has built-in support for SQLite. Rather than including a database file in your app, let your app create the database in Java, using what's provided in the android.database package. This will create a regular SQLite database file (usually found in data/data/your.app.package/databases/) accessible in native code.

  2. If that's not feasible and you really want to go with the asset approach, use AssetManager in Java to extract the asset and create a regular file accessible in native code, i.e. effectively creating a copy of what's contained in the asset.

Perhaps the best thing in the long run would be to restructure your app such that you do not need to handle a database in native code at all. Instead, open and query the database in Java (using one of the two solutions above) and pass only the necessary data to native code. Typically, the more application logic you can shift to Java, the better.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top