IndexedDB アプリケーションをデバッグする
IndexedDB (英語) は、インターネットに接続されていない場合でもユーザーのローカル クライアント上でデータを保存、検索、取得できる JavaScript の開発を可能にする W3C 草案 (英語) です。今回のブログ記事では、私たちが IndexedDB アプリケーションをデバッグするために内部的に使用している IDBExplorer というツールについてお話ししたいと思います。IDBExplorer を使って、データベース スキーマ、オブジェクト ストアのコンテンツ、インデックスの詳細を確認することができます。
IndexedDB のサンプル アプリを使用してツールを検証する
このツールをご紹介するにあたって、新年の抱負をトラッキングする New Year's Resolution (英語) というアプリケーションを IndexedDB を使用して作成してみました。このアプリケーションでは、抱負をデータとして (Web ページを閲覧しているシステム上で) ローカルに保存してアクセスします。ユーザーは自由に抱負を追加、編集でき、[Done That!] ボタンをクリックすると、選択した抱負がリストから削除され、その抱負の内部表現もデータベースから削除されます。
IndexedDB では、データベースを情報のコンテナーとして定義します。各データベースには JavaScript オブジェクトのリポジトリであるオブジェクト ストアが格納されます。各オブジェクトには API を使って照会できる属性が格納されます。リレーショナル データベースになじみのある方は、オブジェクト ストアはテーブルと同じものと考えてください。オブジェクト ストア内の各 JavaScript オブジェクトはレコードに当たります。ただし、IndexedDB のオブジェクト ストアに格納されているオブジェクトは、不透明 (opaque) エンティティとして扱われます。また、これらのオブジェクトには同じプロパティを含める必要はありません。
JavaScript オブジェクトをリレーショナル データベースのレコードと同様のものと考えると、オブジェクトのプロパティはテーブルの列 (またはフィールド) と考えることができます。したがって、オブジェクト ストア内のレコードは、オブジェクトのプロパティを使って検索できます。IndexedDB では、このプロパティを特定するインデックスを定義することができます。このインデックスにより、JavaScript オブジェクトの属性値で IndexedDB のデータをスキャンして検索することが可能になります。
IndexedDB ではそれぞれのドメインで複数のデータベースを保持できます。New Year's Resolution アプリ (英語) では、"NewYear" という 1 つのデータベースを使用しています。抱負のデータは "NewYear" データベース内の "Resolutions" という名前のオブジェクト ストアに保存されます。それぞれの抱負データは、次の属性を持つ JavaScript オブジェクトです。
priorityId
:抱負に優先度を割り当てますname
:抱負の名前occurrenceId
:抱負として掲げた行動を行う頻度をトラッキングしますdueDate
:抱負の完了日createdDate
:抱負がオブジェクト ストアに追加された日 (内部的な日付)categoryId
:抱負のアクティビティの種類を定義します
すべての属性がアプリケーションの UI に表示されるわけではありません。属性は内部でのみ使用される場合もあります (このサンプルでは createdDate
)。
それでは、IDBExplorer ツールで "Resolutions" オブジェクト ストアのコンテンツがどのように表示されるか見てみましょう。
"Resolutions" オブジェクト ストアには、"priorityId" という名前の priorityId
属性のインデックスも格納されています。このインデックスを使用すると、アプリケーションで priorityId
プロパティを使ってオブジェクトを照会することができます。priorityId
のそれぞれの値の詳細は、"Priorities" オブジェクト ストアに格納されています。同様に、occurrenceId
の値の詳細は "Occurrences" オブジェクト ストアに、categoryId
の値の詳細は "Categories" オブジェクト ストアに、それぞれ格納されています。
IDBExplorer ツールでは、ツリー階層を使用してこれらの関係を示しています。
IDBExplorer ツールを見ると、データベースには抱負が 5 つ (優先度が "高" のタスクが 2 つ、"中" のタスクが 2 つ、"低" のタスクが 1 つ) 格納されていることがわかります。
このアプリケーションでは、新しい抱負を追加することができます。
[Occurrence
]、[Priority
]、[Category
] の各フィールドの値は、それぞれ対応するオブジェクト ストアからカーソルを使って取得され、ユーザーに表示されます。IDBExplorer ツールを使用すると、これらの値がオブジェクト ストアでどのように格納されているかを確認することができます。たとえば、Categories
オブジェクト ストアをクリックすると、選択できるカテゴリとその詳細が表示されます。
抱負データを更新する場合は、[WorkOn] 画面でその抱負を選択して、[Edit] をクリックします。変更を加えた後で [Update] ボタンをクリックすると、変更が確定され、"Resolutions" オブジェクト ストアの値が更新されます。
アプリケーションで IDBExplorer を使用する
IDBExplorer ツールは、Metro スタイル アプリや Web サイトに追加することができます。ただし、アプリでツールを展開することはお勧めしません。
サイトにツールを追加するには、IDBExplorer パッケージのコンテンツをサイトにコピーして解凍します。アプリケーションは IDBExplorer フォルダー内に格納されている IDBExplorer.html ファイルにリンクさせる必要があります。これには、iframe 要素か新しいウィンドウを使用します。
ご紹介したサンプルでは iframe 要素内で IDBExplorer をホストする方法を採用していますが、通常の開発では、新しいウィンドウでこの URI をホストすることをお勧めします。この方法なら、データベースやアプリケーションをデバッグする際に、サイトのユーザー インターフェイスに影響を与えずに画面を左右に並べてデバッグを行うことができます。
IDBExplorer をホストする場合は、クエリ文字列を使ってデータベースの名前を指定する必要があります。このサンプルでは、iframe 要素の src 属性を使ってデータベース名を指定しています。
<iframe id="debuggerId" class="debuggerContainer" src="IDBExplorer/IDBExplorer.html?name=NewYear"></iframe>
Metro スタイル アプリでこの機能をホストすることをお考えの場合は、Metro スタイル アプリは全画面表示で実行されるということを念頭に置いて、新しいウィンドウを開かずにこの URL に移動するようにしてください (その場合、アプリケーションに戻れるようにするために、IDBExplorer.html に [Back] (戻る) ボタンを追加する必要があります)。あるいは、代わりに iframe 要素を追加して、要素内にツールを表示することもできます。
ぜひツールをご活用いただき、ご意見をお寄せください!
—Internet Explorer 担当グループ主任プログラム マネージャー (博士) Israel Hilerio