Android SQLite用にスキーマの差分DDLを生成するモジュールを書いた
前回のエントリの続きです。
SQL::Translator::Diffを真似て、Android用マイグレーションモジュールを書いてみました。Orma projectの一部です。
- gfx/Android-Orma · GitHub (v0.2.0 として利用可能)
実装は SchemaDiffMigration.java です。
たとえばexampleのTodoクラスはこんな感じになっていますが:
@Table public class Todo { @PrimaryKey public long id; @Column(indexed = true) public String title; @Column @Nullable public String content; @Column public long createdTimeMillis; }
これにカラムを一つ追加するとします:
+ @Column + @Nullable // nullableでないとカラムのnon-null制約に引っかかるため + public Set<String> tags;
CREATE TABLE "__temp_Todo" ("id" INTEGER PRIMARY KEY, "title" TEXT NOT NULL, "content" TEXT NULL, "createdTimeMillis" INTEGER NOT NULL, "tags" BLOB NOT NULL) INSERT INTO "__temp_Todo" ("title", "createdTimeMillis", "content", "id") SELECT "title", "createdTimeMillis", "content", "id" FROM "Todo" DROP TABLE "Todo"
カラムの追加だけなら ALTER TABLE ADD CLUMN
でもいけますが、SQLiteのALTER TABLE ADD COLUMNは制限が強く、条件の判定が難しいので今はどんなスキーマ変更もテーブルを再定義するようにしています。
スキーマのバージョンは PackageInfo#lastUpdateTime
で判断しており、実際にマイグレーションするかどうかはアプリがもっているモデルのスキーマとデータベースのスキーマを比較して判断します。つまりスキーマのバージョンを手動で設定する必要はありません。
とまあこんな感じで、だいたい動くようになりました。まだ作りこみがあまい部分はありますが、かなり便利になりそうな手応えは感じます。