IndexedDBの（少し詳しい）サンプルコード

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

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

# サンプルコード

```js
//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で言えばプライマリーキーに当たる)と見なすかを表しています。

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

```js
var transaction = db.transaction(["twitter", "pocket"], "readwrite");
var twitterStore = transaction.objectStore("twitter");
/* twitterデータ取得関数 */.callback(function(data){
  twitterStore.add(data);//error
});
```
この場合以下のようにコールバック内部で再度トランザクションを取得する必要があります。

```js
/* 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](http://stackoverflow.com/questions/10385364/how-do-you-keep-an-indexeddb-transaction-alive "How do you keep an indexeddb transaction alive? - Stack Overflow")

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

* [連載：人気順に説明する初めてのHTML5開発：Webアプリもオフライン実行？ Indexed Databaseを使いこなそう (1/2) - ＠IT](http://www.atmarkit.co.jp/ait/articles/1202/14/news138.html "連載：人気順に説明する初めてのHTML5開発：Webアプリもオフライン実行？ Indexed Databaseを使いこなそう (1/2) - ＠IT")
* [[HTML5][JavaScript] Indexed Database を使ってみた | unlinked log](http://log.noiretaya.com/231 "[HTML5][JavaScript] Indexed Database を使ってみた | unlinked log")