2008/04/15

[google gears]SQLは、openしてexecuteで実行

前々回、google gearsで、SQL文を実行する前に、Objectの設定をする必要性を書きました。
そこで、今回は、SQL文の実行をしてみたいと思います。

Database Module APIを参考にすると、google.gears.factory.create('beta.database')を作成後、database名でopenします。

流れとしては、こんな感じ。

var db = google.gears.factory.create('beta.database');
db.open('database-test');

via:Database Module API

database名は、書かずに、

db.open();

と書いても、エラーは発生しません。

話は飛んでしまいますが、2行目のdb.open('database-test');は、「database-testというdatabase命をオープンしてください。」という意味ですが、オープンする前に、該当する名前のdatabaseを作成する必要があるのでしょうか?

答えは、Noで、open文を書いた瞬間に、自動的にdatabase名でdbを作ってくれるんですね。
しかも、一回作った後、再度、openメソッドを使うと、すでに作成されているdatabase名をopenしてくれます。

database fileは各OSによって、作成される場所が違ってくるようです。

Windows Vista - Internet Explorer
Location: {FOLDERID_LocalAppDataLow}\Google\Google Gears for Internet Explorer
Example: C:\Users\Bob\AppData\LocalLow\Google\Google Gears for Internet Explorer

Windows XP - Internet Explorer
Location: C:\Documents and Settings\\Local Settings\Application Data\Google\Google Gears for Internet Explorer
Example: C:\Documents and Settings\Bob\Local Settings\Application Data\Google\Google Gears for Internet Explorer

Windows XP - Firefox
Location: C:\Documents and Settings\\Local Settings\Application Data\Mozilla\Firefox\Profiles\{profile}\Google Gears for Firefox
Example: C:\Documents and Settings\Bob\Local Settings\Application Data\Mozilla\Firefox\Profiles\uelib44s.default\Google Gears for Firefox

via:Location of Database File(一部抜粋)

ここでミソなのは、firefox、IEとブラウザによって変わってしまうこと。
同じにすればいいのにーと思ってしまうのですが。。。

後、open時に引数を入力せずに、実行した場合も、上のディレクトリにdatabaseが作成されます。

作成されるファイル名ですが、「入力したdatabase名#database」で作成されるようです。
なので、引数がない場合は、「#database」で作成されます。

で、話が横にそれましたが、dbをopenした後、いよいよsqlの実行です。

SQL文は、executeメソッドを実行することで、発行することができます。

var db = google.gears.factory.create('beta.database');
db.open('database-test');
/* テーブルを作成する */
db.execute('create table if not exists Test' + ' (Phrase text, Timestamp int)');
/* insertでデータを登録 */
db.execute('insert into Test values (?, ?)', ['Monkey!', new Date().getTime()]);
/* selectでデータを取得 */
var rs = db.execute('select * from Test order by Timestamp desc');

via:Database Module API

rsには、実行結果であるResultSetがセットされます。

ここで、上の文の一番最後に、drop tableを実行したとしてもdatabaseが削除されるわけではなく、テーブルが削除されるだけです。

databaseまるごと削除は、ディレクトリからたどって直接削除する方法があります。

また、上のinsert文で、valueの後が?になって、その後ろに配列が書かれていますが、?をエスケープして、?と同じ順番に配列の値を対応させているようです。

これは、Securityで書かれていましたが、SQLインジェクションを避けるためにとった方法らしいです。

でも、どうして、

db.execute('insert into Test values (' + '"Monkey!"' + ',' + new Date().getTime() +')');

とは、書かずに、

db.execute('insert into Test values (?, ?)', ['Monkey!', new Date().getTime()]);

と書くのでしょうか??

こう書くことによって、SQLインジェクションの直接の原因となる要素を取り除くことができるんだと思うんですけど、それが何かはわからないっす。

というわけで、パラメータがn個の場合、

db.execute('insert into Tablename values (?1, ?2,・・・,?n)', [p1, p2,・・・,pn]);

と書くようです。

select文の結果は、fetchすれば値が取れるのですが、それについては次回書きたいと思います。

1 件のコメント:

  1. >ここでミソなのは、firefox、IEとブラウザによって変わってしまうこと。
    >同じにすればいいのにーと思ってしまうのですが。。。
    これはGoogle側の仕様じゃなくて、多分
    ブラウザとOS依存だからじゃないのかな??

    >SQL文における'?'を使う事
    これバインド変数って言うんだよね。
    もちろんSQLインジェクション対策っていうのもあるし
    バインド変数を使うといちいちコード内でクエリを組み立てるより
    早く処理が出来るはずだよ。

    返信削除