Home > 技術 > Safari3.1に搭載されたClient-side Database storageを試してみた

Safari3.1に搭載されたClient-side Database storageを試してみた

ご存知のとおりHTML5の仕様でSelectors APIというものがありまして、これはクライアント側での永続化としてリレーショナルDBを使えるようにするものです。
これを初めて知ったときは「ええっ!」となりましたが、CookieではなくDBに値を入れておくということがじょじょに可能になりつつあるようです。
本当にオフラインでも動くサイトが出てきそうですね。

具体的な話はamachangの記事で話されているのですが、基本的にはJDBC使ってDBにアクセスする雰囲気でいけます。
(JavaScriptでトランザクションなんてことは想像もしてなかったですが・・・w)


Database storage簡単な使い方

openDatabase
データベース開く
transaction
トランザクション張る
executeSql
SQLを実行する

の3つの関数を使って、SQL実行しその結果を取得する!なんてことが出来るみたいです。
では簡単ですが使い方をコードと一緒に見ていってみましょう!

openDatabase関数の使い方

windowオブジェクトにopenDatabaseプロパティがあるかを確認しています。
あったらそれを使うし、なかったらSafariじゃないね~といった感じです。

// DB初期設定
try {
    if (window.openDatabase) {
        db = openDatabase("Test", "1.0");
        if (!db)alert("DB使えないよ!");
    }
    else
        alert("DBないね!");
}
catch (err) {
}

簡単ですね。


transaction関数の使い方

引数のtxはSQLTransactionオブジェクト。
このオブジェクトがトランザクションを持っているので、そこからSQLを実行したりします。

db.transaction(function (tx) {
    // ここでSQL実行したりします
}
);


executeSql関数の使い方

SQLを実行してくれる関数です。

第一引数にクエリー文字列。
第二引数にバインド変数の配列。
第三引数に結果を取得した際に実行するfunction。

db.transaction(function (tx) {
    tx.executeSql(query, [], function (result) {
        // 取得できた
    }
    , function (tx, error) {
        // こっちはエラー
    }
    );
});

おそらくこの関数をもっとも使うことになりそうです。

ちょっとしたクエリーアナライザ

ここは個人的なメモです。

var db;
// document.getElementByIdのエイリアス
function $(x) {
    return document.getElementById(x);
}
// onloadで呼ばれる
function loaded() {
    // DB初期設定
    try {
        if (window.openDatabase) {
            db = openDatabase("Test", "1.0");
            if (!db)alert("DB使えないよ!");
        }
        elsealert("DBないね!");
    }
    catch (err) {
    }
}
// クエリー発行!!
function execute() {
    var query = $("query").value;
    console.log("Query:" + query);
    db.transaction(function (tx) {
        tx.executeSql(query, [], function (result) {
            // あるならロード
            resultLoad();
            $("result").style.display = "block";
            $("errors").innerHTML = "";
        }
        , function (tx, error) {
            // エラーは表示
            $("result").style.display = "none";
            $("errors").innerHTML = error.message;
        }
        );
    }
    );
}
// result
function resultLoad() {
    db.transaction(function (tx) {
        tx.executeSql("SELECT id, name, timestamp FROM test", [], function (tx, result) {
            var models = [];
            for (var i = 0; i < result.rows.length; ++i) {
                var row = result.rows.item(i);
                var model =  new TestModel();
                model.id = row['id'];
                model.name = row['name'];
                model.timestamp = row['timestamp'];
                models.push(model);
            }
            $("result").innerHTML = table(models);
        }
        , function (tx, error) {
            alert(error.message);
            return;
        }
        );
    }
    );
}
function table(models) {
    var html = [];
    var tas = "<table>", tae = "</table>";
    var trs = "<tr>", tre = "</tr>";
    var tds = "<td>", tde = "</td>";
    // header
    html.push(tas);
    html.push(trs);
    html.push(tds + "id:" + tde);
    html.push(tds + "name:" + tde);
    html.push(tds + "timestamp:" + tde);
    html.push(tre);
    // data
    for (var i = 0; i < models.length; ++i) {
        var model = models[i];
        html.push(trs);
        html.push(tds + model.id + tde);
        html.push(tds + model.name + tde);
        html.push(tds + model.getModifiedDateTime() + tde);
        html.push(tre);
    }
    html.push(tae);
    return html.join("");
}
var TestModel = function () {
}
TestModel.prototype = {
    // id
    getid() {
        if (!("_id" in this))this._id = 0;
        return this._id;
    }
    , setid(x) {
        this._id = x;
    }
    , // name
    getname() {
        if (!("_name" in this))this._name = 0;
        return this._name;
    }
    , setname(x) {
        this._name = x;
    }
    , // timestamp
    gettimestamp() {
        if (!("_timestamp" in this))this._timestamp = 0;
        return this._timestamp;
    }
    , settimestamp(x) {
        this._timestamp = x;
    }
    , // function
    getModifiedDateTime : function () {
        var date =  new Date();
        date.setTime(parseFloat(this._timestamp));
        return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
    }
}
addEventListener('load', loaded, false);

このコードはカラムを3つもつテーブルを対象に作成しています。
汎用性を持たせたい場合は、もうちょっと工夫が必要ですね。

ちょっぴりハマったのが、SafariのWeb Inspectorを開いても以下の画面になってしまいテーブルの中身が見れない現象がありました。

どうやらデータにnullがあると表示されないみたい。(本当か?)

■関連リンク
Safari 3.1 に実装された「Client-side database storage (SQL API)」とは何か? - IT戦記
Macはじめました。: Safari 3.1の「Client-side Database Storage」を試してみた。
HTML 5 Database storage(英文)
WebKit HTML 5 SQL Storage Notes Demo

Trackback:0

TrackBack URL for this entry
http://hisasann.com/cgi-bin/mt/mt-tb.cgi/1057
Listed below are links to weblogs that reference
Safari3.1に搭載されたClient-side Database storageを試してみた from HouseTect, JavaScriptな情報をあなたに

Home > 技術 > Safari3.1に搭載されたClient-side Database storageを試してみた

Tag cloud
月別アーカイブ
Powered by
Powered by
Movable Type Commercial 4.261

Page Top