localStorageをWeb SQL Databaseで代用してみる。(2)

前回(localStorageをWeb SQL Databaseで代用してみる。(1))の続きです。

特に何も考えず、localStorageをWeb SQL Databaseに置き換えようと考えていた私は、 コーディングを初めて間もなくあることに気づきました。

Web SQL Databaseが非同期だということに。

setItemを実装する段階で気がつきました。 setItemするんだけども存在したらupdateだよね。あ、selectというかWeb SQL Databaseってコールバックで色々制御するんだ。 なるほど〜c言語で初めてデータベース触る感覚に似ているね・・・ と考えつつ、若干嫌な予感しながら、setItemを実装。

(function(w){
  var ls = {};

  var db = openDatabase("localStorage", "", "localStorage", 1024*1024);
  db.transaction(
    function(tr){
      tr.executeSql("CREATE TABLE IF NOT EXISTS LOCALSTRAGE(key TEXT, value TEXT) ", []);
    }
  );
  ls.setItem = function(key, value){
    db.transaction(function(tr){
      tr.executeSql("SELECT * FROM LOCALSTRAGE WHERE key = ?", [ key ],
        function(rt, rs) {
          if(rs.rows.length > 0){
            tr.executeSql("UPDATE LOCALSTRAGE SET value = ? WHERE key = ?", [ value, key ]);
          }else{
            tr.executeSql("INSERT INTO LOCALSTRAGE (key, value) VALUES (?, ?)", [ key, value ]);
          }
        }
      )
    });
    return undefined;
    //return localStorage.setItem(key, value);
  }
  ls.getItem = function(key){
    return localStorage.getItem(key);
  }  
  ls.removeItem = function(key){
    return localStorage.removeItem(key);
  }
  ls.clear = function(){
    return localStorage.clear();
  }

  if(!w.localStorageDB){
    w.localStorageDB = ls;
  }
}(window));

さあgetItemを・・・

そうそう、getItemは戻り値が重要・・・・ あ、実装できない。

Web SQL Databaseってselectの受け取りがcallbackだから、localStorageみたいなことできない。。

ということで、無理矢理ですが、getItemのメソッドの役割を若干変えてしまいます。

メソッド 意味
setItem keyとvalueを指定してlocalStorageに保存する
getItem keyを指定してlocalStorageからvalueを取り出す
getItem※ keyを指定してcallback関数で、localStorageから取り出したvalueを渡す
getItem(key, callback)
removeItem keyを指定してlocalStorageからkey valueのペアを取り除く
clear localStorageの中身を全て取り除く

仕様が変わったので、テストも書き換える。テストは前回と同じくqunitで。

asyncTest( "asyncTest getItem", function() {
  expect(1);
  localStorageDB.clear();
  localStorageDB.setItem("key", "value");
  localStorageDB.getItem("key", function(value){
    ok( value === "value" , "Passed!" );
    start();
  });
});

Web SQL Databaseは非同期ということで、asyncTestに置き換えます。 これで、setItemとgetItemの実装が終了。

次回で完結としましょう。