Reputation: 287
I get acquainted with Room and try to assemble a small project by reading the database from the ASSETS folder. Faced such a question: When one version of the database is thrown, it throws an exception and asks to add MIGRATION. It’s enough for me to simply rewrite the database from assets when raising the version. There is a fallbackToDestructiveMigration ()
method in the docks for this purpose. But when I specify it in the builder, in fact my database is overwritten every time the application starts. What I need is for the database to be rewritten from assets only when the application version is raised. and I don’t understand how to achieve this behavior. I would be grateful for your help.
This is how I do everything:
This is the simplest example.
DAO:
@Dao
NameDao
@Insert(entity = Name.class, onConflict = OnConflictStrategy.REPLACE)
void insertMe(Name name);
Database
@Database(version = 2, entities = [Name::class])
abstract class AppDatabase : RoomDatabase() {
abstract fun nameDao(): NameDao
}
POJO Entity
@Entity(tableName = "tips_of_the_day")
data class Name(
@ColumnInfo(name = "name")
var name: String?
) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
var id: Int = 0
}
Application class
class App : Application() {
private lateinit var appDatabase: AppDatabase
override fun onCreate() {
super.onCreate()
appDatabase = getAppDatabase()
}
fun getAppDatabase(): AppDatabase {
return Room.databaseBuilder(
this,
AppDatabase::class.java, DATABASE_NAME
)
.createFromAsset("database/tips_of_the_day.db")
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build().also { appDatabase = it }
}
companion object {
private const val DATABASE_NAME = "tips_of_the_day.db"
}
}
AND MY ACTIVITY
val db: AppDatabase = (application as App).getAppDatabase()
val dataBase = db.nameDao()
textView.setOnClickListener(){
val name: Name = Name( "Anton")
dataBase.insertMe(name)
val tableSize: Int = dataBase.all.size
toast("db size : $tableSize")
Log.d("TAG" , "db size : $tableSize")
}
It turns out that the code works until the application is restarted and then the database is overwritten by default and becomes new (
I did not want this behavior. I need to save the database until the version is up. How to achieve this?
Upvotes: 0
Views: 2950
Reputation: 5103
I know it may seemed like a dirty way to solve your problem, but you can manage migrate-or-not issue manually:
fun getAppDatabase(context: Context): AppDatabase {
// is migration really needed?
val db = SQLiteDatabase.openDatabase(context.getDatabasePath(DATABASE_NAME).path, null, SQLiteDatabase.OPEN_READONLY)
val needToMigrate = db.version < dbVersion // your actual version, could be constant
db.close()
return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
.allowMainThreadQueries().apply {
if (needToMigrate) this.createFromAsset(DATABASE_DIR)
.fallbackToDestructiveMigration()
}.build()
}
Upvotes: 1