[Kotlin]Roomのデータ構造を更新する手順(autoMigration)

# 概要
Roomデータベースのデータ構造を更新する時に大切なポイントをまとめてみました。autoMigrationを使えばアプリ内のデータベース情報も正常に引き継ぐことができます。

:::note info
ここで紹介するのはautoMigration機能を使った更新の仕方です。使用するためにはRoomのバージョンが2.4.0-alpha01以降である必要があります。
:::

# 列を追加したい時の手順
例として「member」という列を追加してみます。

## ＠Databaseの修正
Entityを更新した時はversionの数字を増やす必要があります。一緒にautoMigrationsを追加して、元バージョンと新しいバージョンを記述します。

更新前

```kotlin
@Database(entities = [ToDoTask::class], version = 1, exportSchema = true)
abstract class ToDoDatabase: RoomDatabase() {
   abstract fun toDoDao(): ToDoDao
}
```

更新後

```kotlin
@Database(entities = [ToDoTask::class], version = 2, exportSchema = true,
   autoMigrations = [
       AutoMigration (from = 1, to = 2)
   ]
)
abstract class ToDoDatabase: RoomDatabase() {
   abstract fun toDoDao(): ToDoDao
}
```

ちなみに、更に更新したくなった時はこんな感じで積み重ねていきます

```kotlin
@Database(entities = [ToDoTask::class], version = 3, exportSchema = true,
   autoMigrations = [
       AutoMigration (from = 1, to = 2),
       AutoMigration (from = 2, to = 3)
   ]
)
abstract class ToDoDatabase: RoomDatabase() {
   abstract fun toDoDao(): ToDoDao
}
```
:::note warn
exportSchema = falseだとautoMigrationを使うことができません。
exportSchema = trueにしてバージョンを上げる前とあげた後のスキーマが必要になります。
(exportSchemaを省略した時はデフォルトのtrueになります)
:::
## スキーマの書き出しフォルダの指定
＠Databaseに「exportSchema = true」を指定するとRoomがバージョン管理をするために必要なjsonファイルを出力してくれます。
出力先フォルダを「build.gradle(:app)」に記述しておく必要があります。


```kotlin
defaultConfig {
   kapt {
       arguments {
           arg("room.schemaLocation", "$projectDir/schemas")
       }
   }
}
```

## ＠Entityの修正
項目を追加するためにはデフォルト値を指定しないとエラーが出るので、以下のように指定します。

更新前

```kotlin
@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
)

```

更新後

```kotlin
@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val description: String,
   @ColumnInfo(defaultValue="0") val member: String,
)
```
# 列の名前を変更したい時の手順
例として「description」を「memo」に変更します。
## ＠Databaseの修正
@RenameColumnアノテーションを追加したり、記述が多くなります。

```kotlin
@Database(entities = [ToDoTask::class], version = 2, exportSchema = true,
   autoMigrations = [
       AutoMigration (from = 1, to = 2, spec = ToDoDatabase.MyAutoMigration::class)
   ]
)
abstract class ToDoDatabase: RoomDatabase() {
    @RenameColumn(
        tableName = "todo_table",
        fromColumnName = "description",
        toColumnName = "memo"
    )
    class MyAutoMigration : AutoMigrationSpec
   abstract fun toDoDao(): ToDoDao
}
```
## ＠Entityの修正
列の名前を新しい名前に変更しておきます。
(AndroidStudioのRenameを使えば、対象箇所も一緒に変更できて楽です！)

```kotlin
@Entity(tableName = "todo_table")
data class ToDoTask (
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,
   val title: String,
   val memo: String,
)
```


# 補足1
プロジェクトのフォルダをapp > schemas > [プロジェクト名]と辿ると、バージョンアップに使われたjsonファイルを確認する事も出来ます。
![スクリーンショット 2022-03-25 14.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a94b6270-02fb-a643-1d97-d71c88ae3439.png)

![スクリーンショット 2022-03-26 10.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/60fa491c-6341-d185-4bef-d18f2844e381.png)

# 補足2
Androidエミュレータ内のデータベースを確認したい時はDatabase Inspectorが便利です。
AndroidStudioの標準機能です。
https://developer.android.com/studio/inspect/database?hl=ja

こちらは公式の動画で、Migration / autoMigrationの説明が出てきます
https://www.youtube.com/watch?v=i5coKoVy1g4

# 参考にしたstackoverflow
https://stackoverflow.com/questions/44322178/room-schema-export-directory-is-not-provided-to-the-annotation-processor-so-we