普通のSQLは主キーは非nullになるが、SQLiteは歴史的な理由、初期のバグの影響で主キーにnullを設定できてしまうまま現在に至るらしい。not null制約を明示的に指定して作っていないかぎり、既存のテーブルのスキーマを読むと主キーがnullableになっているのはそんな訳があった
普通のSQLは主キーは非nullになるが、SQLiteは歴史的な理由、初期のバグの影響で主キーにnullを設定できてしまうまま現在に至るらしい。not null制約を明示的に指定して作っていないかぎり、既存のテーブルのスキーマを読むと主キーがnullableになっているのはそんな訳があった
Room で興味深かったのは現在のテーブル構成の情報の取得方法。 https://android.googlesource.com/platform/frameworks/support/+/refs/heads/oreo-m4-s8-release/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java にある、pragmaを使ったクエリでスキーマの情報が取れる。
SQLiteは型を指定せずにカラムを定義することができて、Roomではそれに該当する指定は不可能なので詰んだ。別のDBファイルに手動でコピーするしかない。
https://gist.github.com/tateisu/2c80cdbb22b34b08ee1a9a0deab77cf8 こんな感じの泥臭い作業をしている
エラーメッセージも非常にわかりにくく、テーブル定義のどこが異なるのか指摘してくれず定義全体をまとめてダンプする。仕方ないから比較スクリプトを書いたよ
SQLiteで作った既存のテーブルをRoomで使うの超めんどくさい。sqliteで"_id integer primary key autoincrement" と定義したカラムと Roomで @ColumnInfo(name = BaseColumns._ID) var id: Long?= 0, と定義したカラムはRoomのバリデータによるとnullabilityが異なったとみなされマイグレーション失敗の例外が出るのだ