IndexedDBの(少し詳しい)サンプルコード

More than 1 year has passed since last update.

IndexedDBは検索すればすぐにサンプルコードが出てきますが、一部不明瞭な点があるのでそれを補完したサンプルコードです。


IndexedDBとは

(大量の)オブジェクトを格納するためのHTML5アプリで使えるデータベースです。


サンプルコード

//1.indexedDBを開く

var idbReq = indexedDB.open("archives", 1);

//2.DBの新規作成時、またはバージョン変更時に実行するコード
idbReq.onupgradeneeded = function (event) {
var db = event.target.result;
var twitterStore = db.createObjectStore("twitter", { keyPath: "id_str" });
var pocketStore = db.createObjectStore("pocket", { keyPath: "item_id" });

//データの追加
twitterStore.add({ id_str: "1", text: "test" })
pocketStore.add({ item_id: "1", url:"http://test.com"})
}

indexedDB.open("<DBの名前>", <バージョン>)で"archives"という名前のDBを開いています(存在しない場合は新規作成が行われます)。2番目の引数はバージョンで、DBの構造を変える場合などは変更し、次のidbReq.onupgradeneededが実行されるようにします。

idbReq.onupgradeneededはDBの新規作成時またはバージョン変更時に1回だけ実行される関数で、DBの構造自体の変更が行えます。たとえばオブジェクトストア(RDBで言えばテーブルに当たる)の作成などです。

ここではtwitterとpocketのデータを保存するためdb.createObjectStoreで"twitter","pocket"の二つのオブジェクトストアを作成しています。2番目の引数{ keyPath: "id_str" }は格納するjsonオブジェクトのどの項目を「キー」(RDBで言えばプライマリーキーに当たる)と見なすかを表しています。

//3-1.DBオープン失敗時の処理

idbReq.onerror = function (event) {
console.log("error");
};

//3-2.DBオープン成功時の処理
var db;
idbReq.onsuccess = function (event) {
db = idbReq.result;

//"twitter", "pocket"2つのオブジェクトストアを読み書き権限付きで使用することを宣言
var transaction = db.transaction(["twitter", "pocket"], "readwrite");

//各オブジェクトストアの取り出し
var twitterStore = transaction.objectStore("twitter");
var pocketStore = transaction.objectStore("pocket");

//twitterオブジェクトストアから全データの取り出し
twitterStore.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log("id_str:" + cursor.key + " Text: " + cursor.value.text);
cursor.continue();
}
};
//pocketオブジェクトストアからの全データの取り出し
pocketStore.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log("item_id:" + cursor.key + " url: " + cursor.value.url);
cursor.continue();
}
};
}

よくあるサンプルコードではdb.transaction()transaction.objectStore()の引数が同じでこの二つの関数の違いが良くわからないんですが、db.transaction()ではどのオブジェクトストアを使うのかを(配列で)示し、transaction.objectStore()で指定したオブジェクトストアを取り出すという形になっています。

上の例では二つのオブジェクトストアから全てのデータを取り出しコンソールに出力しています。


トランザクションの連続性について

Indexeddbのトランザクションは関数の連続した流れが途切れたところで自動的に終了します。たとえば次のように非同期のコールバックがある場合トランザクションは連続しません。

var transaction = db.transaction(["twitter", "pocket"], "readwrite");

var twitterStore = transaction.objectStore("twitter");
/* twitterデータ取得関数 */.callback(function(data){
twitterStore.add(data);//error
});

この場合以下のようにコールバック内部で再度トランザクションを取得する必要があります。

/* twitterデータ取得関数 */.callback(function(data){

//これなら大丈夫
var transaction = db.transaction(["twitter", "pocket"], "readwrite");
var twitterStore = transaction.objectStore("twitter");
twitterStore.add(data);
});

参考リンク: How do you keep an indexeddb transaction alive? - Stack Overflow


その他

さらに詳しい内容は検索するか以下のページなどを参考にしてください