▼ 2008/02/02(土) CakePHPがSQLite3に対応しにくい理由
(追記があります。)CakePHP1.2をSQLite3で動かしてみた。&ダウンロード
PHP5のPDOは、すごく便利。
プリペアードステートメントで、インジェクションから守ってくれるわ、バインドでコードが楽ちんだわ、様々な利点がある。
しかし、PDO & SQLite で唯一の弱点がある。
それは、
(SQLiteの場合であり、他のデータベースは知らない)
つまり
cakephpのデータ管理方法は
別に、tableAから結果を引っ張ってきているのだから、必要ないのでは?
この場合はそうなのだが、複雑なjoinをしていると、その管理は面倒である。
だから、、、cakephpでは、結果セットから、テーブル名を取得しているのであろう。
これが、SQLite2のsqlite_・・・関数ではできるんだ。テーブル名とフィールド名をドットで連結して返してくれる。
実はPDOには、オプションで、テーブル名を返す、というものも用意されている。
が
PHP5のPDOドライバは、SQLiteに関して、そのオプションを設定する、コマンド setAttribute をサポートしていないのだ!(セットしようとすると怒られる)。
本当は
PDO::FETCH_NAMED、PDO::FETCH_ASSOCは、fetchの方で設定できるが、これだとテーブル名は返さない。。。。
漸進的な改善策としては、ASを使うことだろう。
しかしそれは、cakephpの中枢部にメスを入れないといけない話なので、私は断念した。
特に複数のテーブルと連結したときや、関数を使った場合分けが面倒のよう。
でも、これもその場しのぎにすぎない。
本当は、cakephpがきちんとPDOに対応して欲しい。そうすれば、今みたいにデータベースごとに巨大なファイルを書かなくても、ほんのちょっとの修正で、様々なデータベースに対応できる。
何より、変数バインドやプリペアなどをPDOで面倒みてくれるのだから、断然早いはず。
PDOへの対応そのものは、dboの全面書き直しになるので、大変なのはよくわかるけど、早くPDO対応になって欲しいなあ。別にPDOとcakephpの相性が悪いのでなくて、cakephpがPHP4にも対応しているからこそ、問題がややこしくなっているような気がする。
(覚書の追記)下も試したけどダメだった。おそらくSQLiteがきちんとテーブル名を返しても、PDOドライバが無視するのだろう。
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
▼ コメント(0件)
- TB-URL http://www.cpa-lab.com/tech/049/tb/
-
▼
CakePHP1.2をSQLite3で動かしてみた。&ダウンロード
CPA-LABテクニカル 私はSQLite2でなく、SQLite3が好きだ。だから、以前はSQLite2で動いていたサイトをCakePHPでSQLite3を対応させてみた。本を買う前にこの書評を読め!PaginatorでPaginateしてみた。は、CakePHP version ...