▼ 2008/02/15(金) CakePHPでSQLite3を使う(覚書編)
CakePHP1.2で、SQLite3を動かすには、CakePHP1.2をSQLite3で動かしてみた。&ダウンロードをご覧下さい。
これは自分のための覚書。
array( 'テーブル名.フィールド名' => value )
という形を期待して、結果をfetchしている。
しかし、PHP5のPDOのSQLite3用のデバイスは、テーブル名を省略して、結果を返してくる。テーブル名が上記の形になるのは、複数のテーブルを連結した場合&取得するフィールド名が、重なった場合だけである。
(テーブル名を常につけるオプションは、現段階ではサポートされていない)
CakePHPは、この結果から、 $find で返す配列に
array ( 'テーブル名(正しくはモデル名)' => value )
とセットしている。
これをPDO,SQLite3でも実現するため、SELECT文を発行する時に、テーブル名とカラム名の組み合わせを覚えておき、結果セット取得時に、それと照合する、というやり方にする。
幸い、CakePHPは、ユーザーがテーブル名を省略して、取得フィールドを設定しても、必ず、
という形にするので、それを横取りして、この組み合わせをメンバ変数に覚えておかせることにした。
$spok_map_table,$spok_map_col
そして、フィールド名は次のようにしておく。
ただし、問題となるのは、ユーザーが as によって別名をつけた場合や、max( field ) などとした場合である。
この点は、 as があったら、as 以降を カラム名として扱うこととした。
関数を使った場合は、テーブル名を ゼロ とした。
(たぶん、他のDBOも、この仕様になっているはず)
事前に横取りして、テーブル名とカラム名の組み合わせを覚えておくのは
dbo_source.php の function renderStatement の select文発行のところ。
そこに、 $this->spok_sqlite3_maps($data['fields']) と、return直前に、横取りした。
function spok_sqlite3_maps($fields) は、同じファイルの最後に追加した。
sqlite固有の関数は、すべてPDO用に置き換えた。(たぶん問題ないと思う)
function resultSet は、そもそもその結果を使っていなかったので、すぐにreturnするようにしておいた。
function fetchResult() において、事前マッピングしたものを、ここで利用した。
ダブルクオーテーションを抜くことを忘れずに。
実現するには
これは自分のための覚書。
背景
CakePHPでは、データベースからのfetchでarray( 'テーブル名.フィールド名' => value )
という形を期待して、結果をfetchしている。
しかし、PHP5のPDOのSQLite3用のデバイスは、テーブル名を省略して、結果を返してくる。テーブル名が上記の形になるのは、複数のテーブルを連結した場合&取得するフィールド名が、重なった場合だけである。
(テーブル名を常につけるオプションは、現段階ではサポートされていない)
CakePHPは、この結果から、 $find で返す配列に
array ( 'テーブル名(正しくはモデル名)' => value )
とセットしている。
実現方法
これをPDO,SQLite3でも実現するため、SELECT文を発行する時に、テーブル名とカラム名の組み合わせを覚えておき、結果セット取得時に、それと照合する、というやり方にする。
幸い、CakePHPは、ユーザーがテーブル名を省略して、取得フィールドを設定しても、必ず、
”テーブル名(モデル名)”.”フィールド名”
という形にするので、それを横取りして、この組み合わせをメンバ変数に覚えておかせることにした。
$spok_map_table,$spok_map_col
そして、フィールド名は次のようにしておく。
”テーブル名(モデル名)”.”フィールド名” as ”テーブル名(モデル名).フィールド名”(微妙な違いがわかりますでしょうか)
ただし、問題となるのは、ユーザーが as によって別名をつけた場合や、max( field ) などとした場合である。
この点は、 as があったら、as 以降を カラム名として扱うこととした。
関数を使った場合は、テーブル名を ゼロ とした。
(たぶん、他のDBOも、この仕様になっているはず)
事前の横取りマッピング
事前に横取りして、テーブル名とカラム名の組み合わせを覚えておくのは
dbo_source.php の function renderStatement の select文発行のところ。
そこに、 $this->spok_sqlite3_maps($data['fields']) と、return直前に、横取りした。
function spok_sqlite3_maps($fields) は、同じファイルの最後に追加した。
事後のマッピング利用
dbo_sqliteをベースに改造した。sqlite固有の関数は、すべてPDO用に置き換えた。(たぶん問題ないと思う)
function resultSet は、そもそもその結果を使っていなかったので、すぐにreturnするようにしておいた。
function fetchResult() において、事前マッピングしたものを、ここで利用した。
ダブルクオーテーションを抜くことを忘れずに。
データベースconfig
login,paswordは設定しても無駄である。var $default = array( 'driver' => 'sqlite3_spok', 'connect' => 'PDO', 'host' => '', 'port' => '', 'login' => '', 'password' => '', 'database' => 'sqlite:c:\hogehoge\hogehoge\hoge.sqlite3', 'schema' => '', 'prefix' => '', 'encoding' => '' );
「*」 の問題
SELECT * FROM.....となった場合、事前マッピングが不可能になる。実現するには
- *をすべて個別のフィールドに展開してしまう
- フィールドの個数とテーブル名(モデル名)を対応させておく
▼ コメント(0件)
- TB-URL http://www.cpa-lab.com/tech/083/tb/