ようこそゲストさん

CPA-LABテクニカル

2008/02/02(土) CakePHPがSQLite3に対応しにくい理由

はてブ情報 はてブに登録 はてブ数 cakephpspok
(追記があります。)CakePHP1.2をSQLite3で動かしてみた。&ダウンロード
PHP5のPDOは、すごく便利。
プリペアードステートメントで、インジェクションから守ってくれるわ、バインドでコードが楽ちんだわ、様々な利点がある。
しかし、PDO & SQLite で唯一の弱点がある。
それは、

SELECT文において、フィールド名につけられたテーブル名は、重複しない限り、結果セットに返さない

というものである。
(SQLiteの場合であり、他のデータベースは知らない)
つまり
SELECT "tableA"."fieldA" FROM "TableA"
としても、結果セットには、fieldAの記述しかなく、tableAを返さないのだ。
cakephpのデータ管理方法は
[データ順][テーブル名(モデルのクラス名)][フィールド名]
となっているため、結果セットからテーブル名を取り出している。

別に、tableAから結果を引っ張ってきているのだから、必要ないのでは?
この場合はそうなのだが、複雑なjoinをしていると、その管理は面倒である。

だから、、、cakephpでは、結果セットから、テーブル名を取得しているのであろう。

これが、SQLite2のsqlite_・・・関数ではできるんだ。テーブル名とフィールド名をドットで連結して返してくれる。


実はPDOには、オプションで、テーブル名を返す、というものも用意されている。




PHP5のPDOドライバは、SQLiteに関して、そのオプションを設定する、コマンド setAttribute をサポートしていないのだ!(セットしようとすると怒られる)。

本当は
PDO::ATTR_FETCH_TABLE_NAMES (integer) 
結果セット中の各カラム名にテーブル名を追加します。 テーブル名とカラム名は、小数点 (.) で区切られます。 
さえ使えれば移植は楽なのに、これを設定できないのがつらい。


PDO::FETCH_NAMED、PDO::FETCH_ASSOCは、fetchの方で設定できるが、これだとテーブル名は返さない。。。。


漸進的な改善策としては、ASを使うことだろう。
SELECT "tableA"."fieldA" AS "tableA.fieldA" FROM・・・・
こうすれば、結果セットにテーブル名も返すことになる(”の位置に注意)


しかしそれは、cakephpの中枢部にメスを入れないといけない話なので、私は断念した。
特に複数のテーブルと連結したときや、関数を使った場合分けが面倒のよう。


でも、これもその場しのぎにすぎない。
本当は、cakephpがきちんとPDOに対応して欲しい。そうすれば、今みたいにデータベースごとに巨大なファイルを書かなくても、ほんのちょっとの修正で、様々なデータベースに対応できる。


何より、変数バインドやプリペアなどをPDOで面倒みてくれるのだから、断然早いはず。


PDOへの対応そのものは、dboの全面書き直しになるので、大変なのはよくわかるけど、早くPDO対応になって欲しいなあ。別にPDOとcakephpの相性が悪いのでなくて、cakephpがPHP4にも対応しているからこそ、問題がややこしくなっているような気がする。


(覚書の追記)下も試したけどダメだった。おそらくSQLiteがきちんとテーブル名を返しても、PDOドライバが無視するのだろう。

PRAGMA full_column_names = ON; (1)
PRAGMA full_column_names = OFF; (0)

SQLite のコールバック関数で報告されるカラム名は、"テーブル名.カラム名" の形式が使われない限り、単にカラムの名前そのものです。しかし full_column_names が ON にされると、単純なクエリーにおいてもカラム名は 常に "テーブル名.カラム名" 形式で報告されます。
SQLite が認識できる SQL

名前:  非公開コメント   

  • TB-URL  http://www.cpa-lab.com/tech/049/tb/
  • CakePHP1.2をSQLite3で動かしてみた。&ダウンロード CPA-LABテクニカル spok
    私はSQLite2でなく、SQLite3が好きだ。だから、以前はSQLite2で動いていたサイトをCakePHPでSQLite3を対応させてみた。本を買う前にこの書評を読め!PaginatorでPaginateしてみた。は、CakePHP version ...