Indexed Database APIを使いやすくするためのライブラリ KageDB

Indexed Database APIを使いやすくするためのライブラリを開発してます。現在のバージョンは0.0.1。GW中に0.0.0を作ったのですが、ほとんど全部捨ててこの土日で作り直して0.0.1としました。

ほんとはドキュメントをもっと充実させないといけないんですけど、疲れてきたので気分転換に簡単な紹介をブログに何回かに分けて書いてみます。


もともとはWin 8のメトロアプリで使おうかなーと思ってIndexedDBを触り始めたんですが、APIがちょっと使いづらい。じゃ、何とかしようということで作り始めました。最初はIE10だけを考えていたんですが、IndexedDBはChromeでもFireFoxでも動くということなので、それら全部に対応することにしました。ちなみに、作り始めてから気づきましたが、そういう目的のライブラリは自分が作らなくてもすでに存在していたりします。


自分は、もうちょっとオリジナルのAPIに近いものがほしかったというのと、試してみたいアイデアがあったので、気にせず作ることにしました。


さて、KageDBですが、ざっくり2つの部分から成ります。スキーマの定義とデータの処理です。

スキーマの定義
var myDB = new KageDB({
    name: "myDB",
    upgrade: function (db, complete) {
        var store = db.createObjectStore("person", { keyPath: "id", autoIncrement: true });
        store.createIndex("name", "name", { unique: true });
        complete();
    }
});


nameがデータベースの名前。upgradeがスキーマの更新時に実行される関数です。
upgradeに渡ってくるdbはオリジナルIndexedDBのIDBDatabaseのラッパーで大体同じAPIです。このオブジェクトを基点にObjectStoreやIndexを作れます。作成するAPIはオリジナルのAPIそのままです。completeは、upgradeの処理が終わったら呼び出すコールバック。completeは古いIndexedDBのAPIを使っているChromeと他のブラウザ(IEFireFox)の挙動をあわせるために導入せざるを得なかった。

ここではやっていないですが、初期データの投入とかもupgrade関数のなかでできます。

データの処理
myDB.tx(["person"], function (tx, person) {
    person.add({ name: "SMITH", age: 31 }, function (key) {
        console.log("done: key=" + key); // done: key=1
    }
});


スキーマの定義のところで定義したmyDBという変数を基点に処理します。
IndexedDBの処理はトランザクション内で実行されることになっているので、txという関数でトランザクションを始めてデータ処理します(ちなみにデフォルトではREAD WRITEなトランザクションにしています)。
txの第1引数は、トランザクション内で利用するObjectStoreの名前の配列です。これは、まったく同じではないですがオリジナルのAPIに似せています。
txの第2引数は、コールバック関数ですが、コールバック関数の第2引数以降で先ほど名前指定したObjectStoreのインスタンスを受け取れます。
したがって、personはオリジナルIndexedDBのIDBObjectStoreのラッパーになります。
上の例では、データを1件追加するaddという関数を呼び出しています。


ポイントは、データの処理は常に次のような形式になるということです。

myDB.tx(["objectStore1", "objectStore2"...], function (tx, objectStore1, objectStore2...) {
    ...
});


まぁ、説明してもわかりにくいですよね。
とても単純なサンプルアプリケーションがあるのでぜひお試してください。

Internet Explorer 10 Platform Preview 5、Google Chrome 18、FireFox 12 などで動作します。
ちなみに、このサンプルは http://www.html5rocks.com/en/tutorials/indexeddb/todo/ をベースにしています。オリジナルのコードと見比べてみるとKageDBを使うとどれだけ楽になるかわかりやすいと思います。


それから、テストもQUnitを使って書いています。こっちのコードをみても使い方のイメージが湧くと思います。