Quarto se não tiver um bom sistema de migração, pelo menos não até 2.1.0-alpha03.
Portanto, até que tenhamos um sistema de migração melhor, existem algumas soluções alternativas para facilitar as migrações na sala.
Como não existe um método como @Database(createNewTables = true) ou MigrationSystem.createTable(User::class), que deveria haver um ou outro, a única maneira possível é executando
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
dentro do seu migratemétodo.
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
}
}
Para obter o script SQL acima , você tem 4 maneiras
1. Escreva sozinho
Basicamente, você deve escrever o script acima que irá corresponder ao script gerado pela Room. Esse caminho é possível, não viável. (Considere que você tem 50 campos)
2. Esquema de exportação
Se você incluir exportSchema = trueem sua @Databaseanotação, a Room irá gerar o esquema do banco de dados dentro de / schemas da pasta do seu projeto. O uso é
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
Certifique-se de incluir as linhas abaixo no build.grademódulo do seu aplicativo
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Ao executar ou construir o projeto, você obterá um arquivo JSON 2.json, que contém todas as consultas no banco de dados do Room.
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "325bd539353db508c5248423a1c88c03",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
Portanto, você pode incluir o acima createSqldentro de seu migratemétodo.
3. Obtenha a consulta de AppDatabase_Impl
Se você não quiser exportar o esquema, você ainda pode obter a consulta executando ou construindo o projeto que irá gerar o AppDatabase_Impl.javaarquivo. e dentro do arquivo especificado você pode ter.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
Dentro do createAllTablesmétodo, haverá os scripts de criação de todas as entidades. Você pode obtê-lo e incluí-lo em seu migratemétodo.
4. Processamento de anotações.
Como você pode imaginar, o Room gera todos os itens mencionados acima schema, e AppDatabase_Implarquivos dentro do tempo de compilação e com processamento de anotação que você adiciona com
kapt "androidx.room:room-compiler:$room_version"
Isso significa que você também pode fazer o mesmo e criar sua própria biblioteca de processamento de anotações que gera todas as consultas de criação necessárias para você.
A ideia é fazer uma biblioteca de processamento de anotações para anotações de Room @Entitye @Database. Pegue uma classe com anotações, @Entitypor exemplo. Estas são as etapas que você terá que seguir
- Faça um novo
StringBuildere anexe "CRIAR TABELA SE NÃO EXISTIR"
- Obtenha o nome da tabela de
class.simplenameou por tableNamecampo de @Entity. Adicione ao seuStringBuilder
- Então, para cada campo de sua classe, crie colunas de SQL. Pegue o nome, tipo e nulidade do campo pelo próprio campo ou por
@ColumnInfoanotação. Para cada campo, você deve adicionar o id INTEGER NOT NULLestilo de uma coluna ao seu StringBuilder.
- Adicionar chaves primárias por
@PrimaryKey
- Adicione
ForeignKeye Indicesse existir.
- Após terminar, converta-o em string e salve-o em alguma nova classe que deseja usar. Por exemplo, salve como abaixo
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Então, você pode usá-lo como
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
Eu fiz uma biblioteca para mim que você pode conferir e até mesmo usar em seu projeto. Observe que a biblioteca que fiz não está cheia e apenas atende aos meus requisitos para a criação de tabelas.
RoomExtension para uma melhor migração
Aplicativo que usa RoomExtension
Espero que tenha sido útil.
ATUALIZAR
No momento em que escrevi esta resposta, a versão da sala era 2.1.0-alpha03e quando enviei um e-mail aos desenvolvedores, recebi uma resposta de
Espera-se que haja um melhor sistema de migração em 2.2.0
Infelizmente, ainda não temos um sistema de migração melhor.