HTML5 WebDatabases を使用したシンプルな TODO リスト

はじめに

ウェブ データベースは HTML5 の新機能です。ウェブ データベースは、ユーザーのブラウザ内でホストされ、維持されます。デベロッパーが豊富なクエリ機能を備えたアプリケーションを作成できるようにすることで、オンラインでもオフラインでも動作する新しいタイプのウェブ アプリケーションが登場することが期待されます。

この記事の例のコードは、非常にシンプルな ToDo リスト マネージャーを作成する方法を示しています。ここでは、HTML5 で使用できる機能のいくつかを紹介します。

前提条件

このサンプルでは、名前空間を使用してデータベース ロジックをカプセル化します。

var html5rocks = {};
html5rocks.webdb = {};

非同期とトランザクション

ウェブ データベースのサポートを使用するほとんどのケースでは、非同期 API を使用します。非同期 API は非ブロック システムであるため、戻り値を通じてデータを取得するのではなく、定義済みのコールバック関数に配信されたデータを取得します。

HTML によるウェブ データベースのサポートはトランザクション型です。トランザクションの外部で SQL ステートメントを実行することはできません。トランザクションには、読み取り/書き込みトランザクション(transaction())と読み取り専用トランザクション(readTransaction())の 2 種類があります。読み取り/書き込みはデータベース全体をロックします。

ステップ 1: データベースを開く

データベースにアクセスするには、まずそのデータベースを開く必要があります。
データベースの名前、バージョン、説明、サイズを定義する必要があります。

html5rocks.webdb.db = null;

html5rocks.webdb.open = function() {
var dbSize = 5 * 1024 * 1024; // 5MB
html5rocks.webdb.db = openDatabase("Todo", "1", "Todo manager", dbSize);
}

html5rocks.webdb.onError = function(tx, e) {
alert("There has been an error: " + e.message);
}

html5rocks.webdb.onSuccess = function(tx, r) {
// re-render the data.
// loadTodoItems is defined in Step 4a
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}

手順 2. テーブルの作成

テーブルを作成するには、トランザクション内で CREATE TABLE SQL ステートメントを実行する必要があります。

body の onload イベントでテーブルを作成する関数を定義しました。テーブルが存在しない場合は作成されます。

このテーブルは todo という名前で、3 つの列があります。

  • ID - 増分する連続 ID 列
  • todo - アイテムの本文であるテキスト列
  • added_on - ToDo アイテムが作成された時刻
html5rocks.webdb.createTable = function() {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS " +
                "todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", []);
});
}

ステップ 3: テーブルへのデータの追加

ToDo リスト マネージャーを構築するため、データベースに ToDo アイテムを追加できることが非常に重要です。

トランザクションが作成され、そのトランザクション内で ToDo テーブルへの INSERT が実行されます。

RunSql は、複数のパラメータ、実行する SQL、クエリをバインドするためのパラメータ値を受け取ります。

html5rocks.webdb.addTodo = function(todoText) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
var addedOn = new Date();
tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)",
    [todoText, addedOn],
    html5rocks.webdb.onSuccess,
    html5rocks.webdb.onError);
});
}

ステップ 4: テーブルからのデータの選択

データがデータベースに格納されたら、そのデータを取り出す関数が必要になります。Chrome では、ウェブ データベースは標準の SQLite SELECT クエリを使用します。

html5rocks.webdb.getAllTodoItems = function(renderFunc) {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM todo", [], renderFunc,
    html5rocks.webdb.onError);
});
}

このサンプルで使用されているこれらのコマンドはすべて非同期であるため、データはトランザクションまたは executeSql 呼び出しから返されません。結果は成功コールバックに渡されます。

ステップ 4a. テーブルからのデータのレンダリング

テーブルからデータを取得すると、loadTodoItems メソッドが呼び出されます。

onSuccess コールバックは 2 つのパラメータを受け取ります。1 つ目はクエリのトランザクションで、2 つ目は結果セットです。データ全体での反復処理は非常に簡単です。

function loadTodoItems(tx, rs) {
var rowOutput = "";
var todoItems = document.getElementById("todoItems");
for (var i=0; i < rs.rows.length; i++) {
rowOutput += renderTodo(rs.rows.item(i));
}

todoItems.innerHTML = rowOutput;
}
function renderTodo(row) {
return "<li>" + row.todo + 
        " [<a href='javascript:void(0);' onclick=\'html5rocks.webdb.deleteTodo(" + 
        row.ID +");\'>Delete</a>]</li>";
}

このメソッド呼び出しの結果、ToDo リストは「todoItems」という DOM 要素にレンダリングされます。

ステップ 5. テーブルからのデータの削除

html5rocks.webdb.deleteTodo = function(id) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
tx.executeSql("DELETE FROM todo WHERE ID=?", [id],
    html5rocks.webdb.onSuccess,
    html5rocks.webdb.onError);
});
}

ステップ 6. すべてを網羅する

ページが読み込まれたら、データベースを開いてテーブルを作成し(必要な場合)、すでにデータベース内にある ToDo アイテムをレンダリングします。

....
function init() {
html5rocks.webdb.open();
html5rocks.webdb.createTable();
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}
</script>

<body onload="init();">

DOM からデータを取り出す関数が必要なため、 html5rocks.webdb.addTodo メソッドを呼び出します。

function addTodo() {
var todo = document.getElementById("todo");
html5rocks.webdb.addTodo(todo.value);
todo.value = "";
}