マイグレーション
.sqファイルは、空のデータベースで最新のスキーマを作成する方法を常に記述します。データベースが現在古いバージョンである場合、マイグレーションファイルはそれらのデータベースを最新の状態に更新します。マイグレーションファイルは、.sqファイルと同じsqldelightフォルダーに保存されます。
src
└─ main
└─ sqdelight
├─ com/example/hockey
| ├─ Team.sq
| └─ Player.sq
└─ migrations
├─ 1.sqm
└─ 2.sqmドライバがサポートしている場合、マイグレーションはトランザクション内で実行されます。一部のドライバではクラッシュの原因となる可能性があるため、マイグレーションをBEGIN/END TRANSACTIONで囲むべきではありません。
バージョニング
スキーマの最初のバージョンは1です。マイグレーションファイルは<version to upgrade from>.sqmという名前で付けられます。バージョン2にマイグレーションするには、マイグレーションステートメントを1.sqmに記述します。
ALTER TABLE hockeyPlayer ADD COLUMN draft_year INTEGER;
ALTER TABLE hockeyPlayer ADD COLUMN draft_order INTEGER;これらのSQLステートメントは、Database.Schema.migrate()メソッドによって実行されます。マイグレーションファイルは、.sqファイルと同じソースセットに配置されます。
マイグレーションの検証
verifySqlDelightMigrationタスクがGradleプロジェクトに追加され、checkタスクの一部として実行されます。SqlDelightのソースセット(例: src/main/sqldelight)にある<version number>.dbという名前の.dbファイルに対して、<version number>.sqmから始まるすべてのマイグレーションが適用され、そのマイグレーションが最新のスキーマを持つデータベースを生成することを確認します。
最新のスキーマから.dbファイルを生成するには、gradle.mdで説明されているようにschemaOutputDirectoryを指定すると利用可能になるgenerate<source set name><database name>Schemaタスクを実行します。これは、最初のマイグレーションを作成する前に行うのが良いでしょう。例えば、プロジェクトがmainソースセットと"MyDatabase"というカスタム名を使用している場合、generateMainMyDatabaseSchemaタスクを実行する必要があります。
ほとんどのユースケースでは、データベースの初期バージョンのスキーマを表す1.dbファイルのみを持つことが有利です。複数の.dbファイルを持つことは可能ですが、その場合、各.dbファイルにそれぞれのマイグレーションが適用されることになり、多くの不要な作業が発生します。
コードマイグレーション
コードからマイグレーションを実行し、データマイグレーションを実行したい場合は、Database.Schema.migrate APIを使用できます。
Database.Schema.migrate(
driver = database,
oldVersion = 0,
newVersion = Database.Schema.version,
AfterVersion(3) { driver -> driver.execute(null, "INSERT INTO test (value) VALUES('hello')", 0) },
)以下の例では、1.sqm、2.sqm、3.sqm、4.sqm、5.sqmをマイグレーションとして持っている場合、上記のコールバックはデータベースがバージョン4のときに3.sqmが完了した後に発生します。コールバックの後、4.sqmから再開し、残りのマイグレーション(このケースでは4.sqmと5.sqm)を完了し、最終的なデータベースバージョンは6となります。
JdbcSqliteDriver を使用している場合、ドライバーの作成時にスキーマとコールバックを渡すことができます。 これは PRAGMA user_version を使用して、データベースにスキーマの現在のバージョンを保存します。
val driver: SqlDriver = JdbcSqliteDriver(
url = "jdbc:sqlite:test.db",
properties = Properties(),
schema = Database.Schema,
callbacks = arrayOf(
AfterVersion(3) { driver -> driver.execute(null, "INSERT INTO test (value) VALUES('hello')", 0) }
)
)