99
101

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptAdvent Calendar 2022

Day 18

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

Last updated at Posted at 2015-03-06

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

その他

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

99
101
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
99
101

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?