TitaniumMobile勉強記

Web系エンジニア向けのキャリアアドバイザーやってましたが現在はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連(Node.js、Titanium)あたり

046-SQLite活用したJSON形式のファイルの保存・読込処理

SQLiteを活用してJSON形式のデータを保存できるようになったので、今度は読込について考えました。

実装方法に最初はまる

SQLiteに保存する時に

    //省略
     var res = this.db.execute(
        'INSERT INTO entries (blogger,permalink,title,html_body,post_date) VALUES(?,?,?,?,?)',
        entry.blogger,
        entry.permalink,
        entry.title,
        entry.html_body,
        entry.post_date
      );

としているためentriesテーブルの各カラムの情報をループで取得するのは簡単だけど、下記のようなJSON形式に戻さないと結局使いものにならないということに気づきました。

[
  {
    "permalink":"http://blog.pasonatech.co.jp/hibi/299/1814.html",
    "title":"IT\u7cfb\u30d9\u30f3\u30c1\u30e3\u30fc\uff0b\u30de\u30de\uff0bSOHO\uff1a\u521d\u30a8\u30f3\u30c8\u30ea\u30fc",
    "html_body":"<p>省略</p>",
    "_id":"4d99001ce93ac16b6c000001",
    "post_date":"2006-08-10T14:09:00Z",
    "blogger":"hibi"
  },
  {
    // 以下続く
  }
]

以前見つけたjoli.jsのソース参考にならないか後で調べようと思っていたのですが、こんな感じの神の声が届きました。

@h5y1m141 JSON文字列をSQLiteに保存しておいてはどうですか?

「そっか。元々JSON形式の情報を取得済だし、文字列のまま保存するカラム用意してそこに突っ込んでおけばいいのか」
といことに気づきました。

キャッシュ処理の実装

色々悩んだ挙句、現時点でこういう形にしました。何も考えずにeval()するのって、なんとなく気持ち悪いがするので、入力値チェックしたほうが良さそう

var Cache = function(){
  this.dbName = "entry";
  this.db = null;
};
Cache.prototype = {
  open:function(){
    this.db = Titanium.Database.open(this.dbName);
    return true;
  },
  close :function () {
    this.db.close();
    this.db = null;
  },
  save:function(entries) {
    this.open();
    this.db.execute('CREATE TABLE IF NOT EXISTS entries(blogger TEXT, permalink TEXT, title TEXT, html_body TEXT, post_date DATE, json TEXT)');
    for (var i=0;i<entries.length;i++) {
      var entry = entries[i];
      var json = JSON.stringify(entry);
      var rows = this.db.execute(
        'SELECT post_date FROM entries WHERE post_date = ?',
        entry.post_date
      );
      Titanium.API.info('Found: ' + rows.getRowCount() );
      if ( rows.getRowCount() > 0 ) continue;

      var res = this.db.execute(
        'INSERT INTO entries (blogger,permalink,title,html_body,post_date,json) VALUES(?,?,?,?,?,?)',
        entry.blogger,
        entry.permalink,
        entry.title,
        entry.html_body,
        entry.post_date,
	json // 今回追加した箇所
      );
    }
    this.close();
    return true;
  },

  load:function(post_date){
    this.open();
    var rows = this.db.execute(
      "SELECT * FROM entries WHERE post_date >= '"
       + post_date
       + "' order by post_date desc"
    );
    var arr = [];
    while (rows.isValidRow()){
      arr.push(rows.fieldByName("json"));
      rows.next();
    }
    var result = "[" +arr.join(",") + "]";
    this.close();
    return eval(result);
  }
};

今後の実装に向けて

なんとなく完成の目処が見えてきた..と思ったのですが今朝コード書いてて今後の課題になりそうなことに気づいたので自分用にメモ

サーバ側から情報取得するときのURL

これまでは /ブロガー名/ページ/1件あたりの件数/としていたのでこんな感じのURLになっていました
localhost:4567/api/hibi/1/5

今後の処理を考えると「ページ数」ではなく、「最終投稿日」をパラメータにしたほうが良さそうなので
localhost:4567/api/hibi/lastupdate/2006-08-10T14:09:00Z
という形のほうが扱いやすいので、サーバ側変更の必要ある。

twitter APIとか、Google Readerの非公式APIなどを参考にして、日付をパラメータで扱うのに良い形式についてもうすこし調査の必要ありそう

WebViewのswipeイベント活用して各エントリの画面遷移

GoogleReader用のiPhoneアプリでよくあるように、スワイプによる各エントリの移動を出来れば実装したい。