Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom File Path to store database file for Android #933

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion CHANGELOG-Unreleased.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog

## Unreleased

- [Android] Provides the user with the ability to pass in a file path instead of the database name only and creates the *.db file under a 'databases' sub-folder under the provided path. Pattern for file path is *file:///data/user/0/com.mattermost.rnbeta/files/xxx.db*
### BREAKING CHANGES

- [Query] `Q.where(xxx, undefined)` will now throw an error. This is a bug fix, since comparing to
Expand Down
24 changes: 22 additions & 2 deletions native/android/src/main/java/com/nozbe/watermelondb/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,46 @@ import android.database.sqlite.SQLiteCursor
import android.database.sqlite.SQLiteCursorDriver
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteQuery
import android.util.Log
import java.io.File

class Database(

private val name: String,
private val context: Context,
private val openFlags: Int = SQLiteDatabase.CREATE_IF_NECESSARY or SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING
) {

private val db: SQLiteDatabase by lazy {
// TODO: This SUCKS. Seems like Android doesn't like sqlite `?mode=memory&cache=shared` mode. To avoid random breakages, save the file to /tmp, but this is slow.
// NOTE: This is because Android system SQLite is not compiled with SQLITE_USE_URI=1
// issue `PRAGMA cache=shared` query after connection when needed


val path =
if (name == ":memory:" || name.contains("mode=memory")) {
context.cacheDir.delete()
File(context.cacheDir, name).path
} else {
}
else if (name.startsWith("/") || name.startsWith("file")) {
// Extracts the database name from the path
val dbName = name.substringAfterLast("/")
if(dbName.contains(".db")){
// Extracts the real path where the *.db file will be created
val directory = name.substringAfterLast("file://").substringBeforeLast("/")

// Creates the directory
val fileObj = File(directory, "databases")
fileObj.mkdir()
File("${directory}/databases", dbName).path
}else{
throw IllegalArgumentException("Database name should contain '.db' as extension")
}
}
else {
// On some systems there is some kind of lock on `/databases` folder ¯\_(ツ)_/¯
context.getDatabasePath("$name.db").path.replace("/databases", "")
}

return@lazy SQLiteDatabase.openDatabase(path, null, openFlags)
}

Expand Down