Room fallbackToDestructiveMigration - PullRequest
       5

Room fallbackToDestructiveMigration

0 голосов
/ 14 апреля 2020

Я знакомлюсь с Room и пытаюсь собрать небольшой проект, прочитав базу данных из папки ASSETS . Столкнулся с таким вопросом: когда выбрасывается одна версия базы данных, она выдает исключение и просит добавить MIGRATION. Мне достаточно просто переписать базу данных из ресурсов при поднятии версии. Для этого в доках есть метод fallbackToDestructiveMigration (). Но когда я указываю это в компоновщике, фактически моя база данных перезаписывается при каждом запуске приложения. Мне нужно, чтобы база данных перезаписывалась из ресурсов только при повышении версии приложения. и я не понимаю, как добиться этого поведения. Буду признателен за вашу помощь.

Вот как я все делаю:

Это самый простой пример.

DAO:

 @Dao
NameDao
@Insert(entity = Name.class, onConflict = OnConflictStrategy.REPLACE)
void insertMe(Name name);

База данных

    @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
}

Класс приложения

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"
}
}

И МОЯ ДЕЯТЕЛЬНОСТЬ

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")
    }

Оказывается, код работает до тех пор, пока приложение не будет перезапущено, а затем база данных будет перезаписана по умолчанию и станет новой (

. Мне не нужно это поведение. Мне нужно сохранять базу данных до тех пор, пока версия не будет запущена. Как этого добиться?

1 Ответ

1 голос
/ 15 апреля 2020

Я знаю, что это может показаться грязным способом решения вашей проблемы, но вы можете управлять миграцией или нет, вручную:

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()
    }
...