PhoneGap でも使えるという HTML5 の Web SQL Database を試してみた

PhoneGap で何かスマートフォンアプリでも作ろうかなと思ってネットで調べてたけど、PhoneGap ってデータベースに HTML5 の Web SQL Database を使うのか。Titanium Mobile みたいに独自の API とかじゃないんだね。

Web SQL Database なら、Web サービスのキャッシュとしても使えるし、使い方を覚えて損はないよね。ってことで、練習として基本の CRUD 処理を書いてみた。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Web Database Test</title>
    </head>
    <body>
        <script type="text/javascript">
            // データベースに接続
            var db = openDatabase("test", "0.1", "Test", 1024 * 1024);

            // トランザクション開始
            // SQLトランザクション内で発行する
            // SQL を発行するための executeSql メソッドはトランザクションオブジェクトにしかない
            db.transaction(function(tx) {
                // テーブルを作成
                tx.executeSql("CREATE TABLE IF NOT EXISTS books (id INTEGER, title TEXT)");

                // 行を挿入
                // SQLプレースホルダが使える
                tx.executeSql("INSERT INTO books (id, title) VALUES (?, ?)", [1, "foo"]);
                tx.executeSql("INSERT INTO books (id, title) VALUES (?, ?)", [2, "bar"]);
                tx.executeSql("INSERT INTO books (id, title) VALUES (?, ?)", [3, "hoge"]);
                tx.executeSql("INSERT INTO books (id, title) VALUES (?, ?)", [4, "fuga"]);

                // 行を更新
                tx.executeSql("UPDATE books SET title = 'foobar' WHERE title IN ('foo', 'bar')");

                // 行を削除
                tx.executeSql("DELETE FROM books WHERE title = 'hoge'");

                // 行を選択
                // 第3引数には SQL 成功時に呼び出されるコールバックを指定
                tx.executeSql("SELECT * FROM books", [], function(tran, resp) {
                    // 配列に詰め直してコンソールに出力
                    var result = [];
                    for (var i = 0, len = resp.rows.length; i < len; i++) {
                        var row = resp.rows.item(i);
                        result.push(row.title);
                    }
                    console.log(result); //=> ["foobar", "foobar", "fuga"]
                });

                // テーブルを削除
                tx.executeSql("DROP TABLE IF EXISTS books");
            },
            // 第2引数はエラー時のコールバック
            function(err) {
                console.log("失敗");
            },
            // 第3引数は成功時のコールバック
            function(resp) {
                console.log("成功");
            });
        </script>
    </body>
</html>

transaction や executeSql は非同期で実行されるから、複雑なことをやろうとしたら、コールバック地獄に陥ってしまいそうだ。あと、SQL 文を直接書いたのも随分と久しぶり。アプリを開発するときは AlexRecord や jsdeferred-webdatabase といった ORM を使うのがよさそうだな。