Indexed Database APIを使いやすくするためのライブラリ KageDB その6 - マイグレーション

KageDB の紹介です。


今回は、マイグレーションについて書きます。

Indexed DBのデータベースはスキーマのバージョンを持っていて、バージョンが上がったタイミングをフックできるようになっています。標準のAPIでやってくれるのはここまでなのですが、KageDBでは、バージョンごとに関数を登録できるようにしていて、そこで任意のマイグレーションを実行できるようにしています。たとえば、バージョンに応じて、ObjectStoreを追加したり、Indexを追加したり、データをメンテナンスしたりできます。
こんな感じで書きます。

var todos = new KageDB({
    name: "todos",
    version: 2,
    migration: {
        1: function (ctx, next) {
            var db = ctx.db;
            db.createObjectStore("todo", { keyPath: "timeStamp" });
            next();
        },
        2: function (ctx, next) {
            var tx = ctx.tx;
            var todo = tx.objectStore("todo");
            todo.createIndex("text", "text", { unique: false });
            next();
        }
    }
});


migrationプロパティに設定している1番目と2番目の関数がマイグレーション用のコードです。まだDBが存在していない場合は両方が順に実行されます。すでにバージョン1のDBが存在している場合は2番目の関数だけが実行され、また、すでにバージョンが2のDBがあればどちらの関数も実行されないというわけです。

引数で渡ってくる1番目のctxオブジェクトですが、WebIDLっぽい記法で書くと次のような構造になっています。

interface IDBKeyRange {
    attribute IDBDatabase db; // データベースの接続
    attribute IDBTransaction tx; // VERSION_CHANGEモードのトランザクション
    attribute unsigned long long oldVersion; // マイグレーション前のバージョン
    attribute unsigned long long newVersion; // マイグレーション後のバージョン
}

引数の2番目のnextは、callback関数で、バージョンに対応するマイグレーション処理が終わったら呼び出す必要があります。この例だとcallbackの必要性がわかりにくいですが、callbackを使うことでデータ更新の非同期実行が完了してから次のマイグレーション処理を実行できます(非同期実行が終わったらcallbackを呼ぶように記述するということです)。