ページ

2014年7月2日水曜日

Titanium Sqlite対応

TitaniumでDB(sqlite)対応方法です。

Alloyを用いるとmodelと呼ばれる仕組みがあるので、楽にできます.


まずはプロジェクトから右クリックで「New」→「Alloy Model」を選択。


続いて、実際のテーブルにあたるスキーマーを定義そうすると下のような「models」ディレクトリにファイルが出来上がる


とりあえずこれでDBを利用できる状態になる。
exports.definition = {
 config: {
  columns: {
      "name": "text",
      "kana": "text"
  },
  adapter: {
   type: "sql",
   collection_name: "test",
   idAttribute: "name"
  }
 },
 extendModel: function(Model) {
  _.extend(Model.prototype, {
   // extended functions and properties go here
  });

  return Model;
 },
 extendCollection: function(Collection) {
  _.extend(Collection.prototype, {
   // extended functions and properties go here
  });

  return Collection;
 }
};
1行だけ基本のソースから追加しています「idAttribute: "name"」この部分ですが
この行を加えるとPKになるようになっています。
どうやら初期状態では、columnsで定義された項目意外に「id」と呼ばれるPKが自動付与されるみたいです。
外部連携をする場合はPKがあらかじめ決まっている可能性が高いので「idAttribute」は覚えておいた方がよいです。
また、バリデータもこちらに記載できます。 簡単なバリデータであればよいのですが
複雑なものをどのように書くかわかりきっていないのでとりあえず今は放置

とりあえず、Insert,SELECT,DELETE,UPDATEを行います。

INSERT
var testModel = Alloy.createModel("test");
testModel.set({"name" : "弦也", "kana" : "ゲンヤ"});
if (testModel.isValid()) {
   testModel.save();
} else {
   alert("登録に失敗しました.");
}
これで登録ができます。
isValidはバリデーションなので初期ではただtrueが返却されるだけです。

少し応用しJSONのデータを組み合わせます。
var xhr1 = Ti.Network.createHTTPClient({
    onload: function() {
        var json = JSON.parse(this.responseText);
 var count = 0;
 for (var i in json) {
  count++;
  var testModel = Alloy.createModel("test");
  testModel.set(json[i]);
  testModel.save();
 }
    }
});
xhr1.open("GET", "http://localhost/test.json");
xhr1.send();
こういった感じが実用例かと思います。

SELECT
var testModel = Alloy.createCollection("test");
testModel.fetch();
testModel.map(function(test){
    Ti.API.info("name:" + test.get("name") + " kana:" + test.get("kana"));
});
INSERTと異なり、「Alloy.createCollection」を利用している点が注意です。
fetchでデータを取得していますがこれはすべて取得になります。
当然条件を指定したいので次のように記述
var testModel = Alloy.createCollection("test");
testModel.fetch(query : { statement: 'SELECT * FROM test WHERE name = ?', params: ['弦也'] }});
testModel.map(function(test){
    Ti.API.info("name:" + test.get("name") + " kana:" + test.get("kana"));
});
PDOなどでよく見る形式になりました。
このfetchはいろいろな形式で記載できそうなのですがまだ模索中とりあえずこれで対応できるのでよしとしています。

DELETE
var testModel = Alloy.createCollection('test');
testModel.fetch(query : { statement: 'SELECT * FROM test WHERE name = ?', params: ['弦也'] }});
while(testModel.length > 0) testModel.at(0).destroy();
少し面倒だがこのような書き方が一般的みたいです。
while文を利用するのが一番行数が少ない書き方みたいですが
その他何種類かあるのでそちらも随時試してまとめ中。

UPDATE
var testModel = Alloy.createModel("test");
testModel.set({"name" : "弦也", "kana" : "ゲンヤ"});
if (testModel.isValid()) {
   testModel.save();
} else {
   alert("更新に失敗しました.");
}
どうやら、INSERT OR UPDATEと呼ばれることを内部処理されているらしく、PKが合えば更新する使用みたいです。
これが「idAttribute」を利用している理由です。
自動で割り当てられたIDも便利ですがこれでは都合が悪いときがあるので臨機応変に対応です。
UPDATEについては、まだ調べきれていないので自信がないですがこれで動くと思います。

以上AlloyでModelsを利用するです。
もう少し応用編も今後作ってみたいと思います。