2015年4月30日木曜日

CouchDB データを表示/更新するサンプル

ずいぶん前回から時間が空いてしまいました。余裕がなかったのもありますが、一番大きいのがこのBloggerでHTMLのソースを表示する方法が中々わからなかったのが一番大きい理由です。prettyprint使っても、どうしても内部のhtmlを本物のタグと解釈してしまうんです。結局そのままブログにペーストするのは諦めて、「偽の」HTMLに変換してからprettyprintすることにしました。(一手間増えるのと、ブログ編集中に確認がしづらいのでこの方法はどうしても嫌だったんですが、どうもこれしかなさそうです。あと変換ツールの問題なのか、シングルクオート、ダブルクオートの前にバックスラッシュが入ってしまいます。手作業で少しは削除しましたが、途中でめげました。) さて以下がサンプルで作成したHTMLの表示例です。
地球半径をCouchDBに登録したものです。「読み込み」ボタンでCouchDBからデータを読み込み表示し、「変更」でvalueに入力されている値をCouchDBに書き込みます。デバッグ用に、一番下に読み込んだり、書き込んだりするjson形式のデータを表示しています。
以下がそのサンプルです。(注:クオートの前にバックスラッシュが入ってしまっているのは無視してください。)

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="UTF-8">
  <title>HTML5</title>
  <script src="jquery-1.11.2.min.js"></script>
  <script src="stringify.js"></script>
 </head>
 <body>
  <p>Hello Ajax, couchdb データ更新をします</p>
  <input type="button" value="読み込み" onclick="readCouch('msg');">
  <input type="button" value="変更" onclick="change()">
  <!-- <TEXTAREA cols="40" rows="6" id="texts" wrap="on"></TEXTAREA> -->
  <script>
   var url;
   url = 'http://localhost:5984/environment/Radius';
   var json;

   function readCouch(id) {
    var target = document.getElementById(id);

    $('#texts').text("これから読みます:");
    $('#msg').append("これから読みます:</br>");

    $.ajax({
     type: "GET",
     url: url,
     dataType:'json',
    }).done(function(data) {
     // alert('読み込み');
     json = data;
     $(\'#id_text\').val(data._id);
     $(\'#name_text\').val(data.name);
     $(\'#value_text\').val(data.value.toString());
     $(\'#unit_text\').val(data.unit);

     var str = $.stringify(data);
     $(\'#msg\').append(str);
    }).fail(function(xhr, textStatus, errorThrown){
     alert(\'error!!\');
     console.log(\"NG:\" + xhr.status);
     console.log(\"NG:\" + textStatus.status);
     $(\'#msg\').append(\"失敗しました</br>\");
    });

    $(\'#msg\').empty();
    $(\'#msg\').append(\"うまくいった?</br>\");

   }

   function change() {
    json.value = parseFloat($(\'#value_text\').val());
    var jsonStr = JSON.stringify(json);

    $.ajax({
     type: \"PUT\",
     url: url,
     data: jsonStr,
     dataType:\'json\',
    }).done(function(data) {

     var str = $.stringify(data);
     $(\'#msg\').append(str);
    }).fail(function(xhr, textStatus, errorThrown){
     alert(\'error!!\');
     console.log(\"NG:\" + xhr.status);
     console.log(\"NG:\" + textStatus.status);
     $(\'#msg\').append(\"失敗しました</br>\");
    });
   }
  </script>
  <br>
  <table border=\"0\">
   <tr>
    <td align=\"right\"><label>id : </label></td>
    <td><input type=\"text\" id=\"id_text\"></td>
   </tr>
   <tr>
    <td align=\"right\"><label>name : </label></td>
    <td><input type=\"text\" id=\"name_text\"></td>
   </tr>
   <tr>
    <td align=\"right\"><label>value : </label></td>
    <td><input type=\"text\" id=\"value_text\"></td>
   </tr>
   <tr>
    <td align=\"right\"><label>unit : </label></td>
    <td><input type=\"text\" id=\"unit_text\"></td>
   </tr>
  </table>
  <br>
  <p id=\"msg\"></p>
 </body>
</html>

これまでGUIでのデータ入出力画面をMotifやらViduslaStuioで組んできましたが、こっちの方がOSを選ばないので汎用性が高いです。(ただ2次元のグラフも表示したい、3次元のグラフィックが欲しい、とか言われるとHTML5のCanvsタグが必要になってくるので、現時点ではブラウザを選んでしまうのが悩ましいところです。)

追記:
ところで上記サンプルでは更新したいのは"value"だけなのに、ドキュメント全体のjsonデータをCouchDBに送信しています。これって無駄が多くない?と思い調べてみると、jsonStrを作るstringify( )で第2引数に特定のjsonデータだけを指定してやればjsonStrもそれだけが作れることがわかりました。
これはいい!と思って早速試してみたんですが、CouchDBのデータを管理するのがドキュメント単位で、さらにそれにrev番号まで付いています。つまり変更したい部分だけのjsonStrを送信してしまうと、残りの部分がなくなったドキュメントになってしまいます。ちょっとこれではうまくありません。あきらめるしかないようです。(あまりでかいドキュメントが必要になるようなデータベース構成にすると処理時間が問題になってきます)