developer's diary

最近はc#のエントリが多いです

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

の続きです。

最終的にこうなりました。

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

localStorage-db.jsという名前にしております。

(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;
  }

  ls.getItem = function(key, setFunc){
    db.transaction(function(tr){
      tr.executeSql("SELECT * FROM LOCALSTRAGE WHERE key = ?", [ key ],
        function(rt, rs) {
          if(rs.rows.length > 0){
            var row = rs.rows.item(0);
            setFunc(row.value);
          }else{
            setFunc(null);
          }
        }
      )
    });

    return undefined;
  }  
  ls.removeItem = function(key){
    db.transaction(function(tr){
      tr.executeSql("DELETE FROM LOCALSTRAGE WHERE key = ?", [ key ]);
    });
    return undefined;
  }
  ls.clear = function(){
    db.transaction(function(tr){
      tr.executeSql("DELETE FROM LOCALSTRAGE", []);
    });
    return localStorage.clear();
  }

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

qunitでのテスト

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>localStorageDB test</title>
  <link rel="stylesheet" href="qunit-1.11.0.css" />  
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
  <script src="qunit-1.11.0.js"></script>
  <script src="localStorage-db.js"></script>
  <script type="text/javascript"> 

test( "setItem result", function() {
  localStorageDB.clear();
  ok(localStorageDB.setItem("key", "value") === undefined, "Passed !");
});

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

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

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


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


asyncTest( "clear test" , function(){
  expect(3);

  localStorageDB.setItem("key1", "value");
  localStorageDB.setItem("key2", "value");
  localStorageDB.setItem("key3", "value");

  localStorageDB.clear();

  localStorageDB.getItem("key1", function(value){
    ok( value === null , "Passed!" );
    localStorageDB.getItem("key2", function(value){
      ok( value === null , "Passed!" );
      localStorageDB.getItem("key3", function(value){
        ok( value === null , "Passed!" );
        start();
      });
    });
  });
  
});
  </script>
</body>
</html>

そして、結果です。

f:id:mitsugi-bb:20130129005720p:plain

この検証でわかったことは、Web SQL Databaseを利用して、localStorageっぽいインターフェースの部品を作ることは現時点では不可能ということがわかりました。残念。

※どうも、WebWorkersだとopenDatabaseSyncが利用できるみたいです。(参考:iOS 5 から WebWorker と Web SQL Database(同期) が使えます