Appcelerator Titanium Desktop でSQLiteを扱う場合の注意

Appcelerator Titanium DesktopでSQLiteを扱う場合、Titanium.Database.openでは既に存在しているDBファイルを読み込む事はできません。また、ファイル作成の場所も選べません。しかし、Titanium.Database.openFileを使うと、customのdbファイルを使えます。


APIによれば、Appcelerator Titanium DesktopでSQLiteを扱う場合、まず Titanium.Database.open("database-name")でオープン、dbファイルを作成します。
このopenメソッドは、APIを見てもらうとわかりますが、引数はファイル名しか指定出来ず、パスは指定できません。

ではどこにDBファイルが作成されるのかというと、ApplicationDataDirectoryになります。
例えばチュートリアルのTestAppの場合、OS Xなら~/Library/Application Support/Titanium/appdata/jp.katahirado.testapp/下に作成されます。
このディレクトリをのぞいてみますとDatabases.dbというdbファイルがありますが、twitter.dbはここにはありません。

 % ls
total 56
drwxr-xr-x   8 user  group    272  3  1 00:49 .
drwxr-xr-x  16 user  group    544  2 23 01:26 ..
-rw-r--r--   1 user  group   5120  3  1 00:49 Databases.db
drwxr-xr-x   6 user  group    204  3  2 01:18 app_jp.katahirado.testapp_0
-rw-r--r--   1 user  group   3072  2 23 07:10 app_jp.katahirado.testapp_0.localstorage
-rw-------   1 user  group      0  2 23 01:26 application.properties
-rw-r--r--   1 user  group    255  3  2 01:19 network_httpclient_cookies.dat
-rw-r--r--   1 user  group  10601  3  2 01:19 tiapp.log

コマンド等で中に入っているレコードをのぞいてみると、下記のようなレコードが記録されています。

% sqlite3 Databases.db 
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
Databases  Origins  
sqlite> select * from Databases;
1|app_jp.katahirado.testapp_0|app_updates|||0000000000000001.db
2|app_jp.katahirado.testapp_0|twitter|||0000000000000002.db
3|app_jp.katahirado.testapp_0|twitter.db|||0000000000000003.db
4|app_jp.katahirado.testapp_0|mydb|||0000000000000004.db

2や4は色々テストした時に出来たdbファイルです。3番目のレコードがtwitter.dbです。
このDatabases.dbはデータベース名と実際のdbファイルをひも付けしています。
よって、チュートリアルで作ってきたtwitter.dbの実体は~/Library/Application Support/Titanium/appdata/jp.katahirado.testapp/app_jp.katahirado.testapp_0/0000000000000003.dbとなります。
実際に中身を確認するとtwitter_idとpasswordが入っているのが確認出来るかと思います。
チュートリアルのアプリで間違えてid&passを入れてしまった場合は、ここにあるdbファイルを直接弄ってください。

しかしAppcelerator Titanium Desktop経由で作成したDBファイルしか使えないと、配布アプリに初期値入りのDBを用意しておいたりといった事を実現するのに面倒です。

さすがにこれは面倒だろうと要望などがあがっていないかフォーラムを調べたところ、Titanium.Database.openFileというメソッドが使えることが分かりました。
ちなみに、Web上のAPIにはのっていません。
使い方はというとこんな感じになります。

var datadir = Titanium.Filesystem.getApplicationDataDirectory();
var testFile = Titanium.Filesystem.getFile(datadir, "test_database.db");
var fileDB = Titanium.Database.openFile(testFile);
fileDB.execute("CREATE TABLE TEST (name TEXT, size INT)");
fileDB.execute("insert into TEST values (?,?)", "foofoo", 555);
fileDB.close();

sdk 0.8から使えるようになっているようです。
なお、上記コードはdrillbitというunit test のフレームワークで書かれたAppcelerator Titanium Desktopのテストコードから持ってきました。
http://github.com/appcelerator/titanium_desktop/blob/2913ff2535c5045d58994533375f8c9f19cdf8c0/apps/drillbit/Resources/tests/Database/Database.js
このようにWeb上のAPIには反映してないものがあったりしますので、サンプルアプリやソースコード、テストコードに当たった方が確実かもしれません。
また、実際の使い方の参考としてもテストを見てみるというのは、良いアプローチだと思います*1

*1:そもそもドキュメントが整ってるのが一番なんですけどね