
【DBMS】に関する知恵袋
【質問】
CakePHPのTestFixtureでdefault指定を柔軟的に行うにはCakePHP1.3.11のTest Suite 1.3を使用しています。ModelのテストをFixtureを使って行おうとしています。Cakeの規約どおりModelを作れなかったことが原因と思われますが、testsuiteにおいて、プライマリーキーをnullにして追加しようとすると、dao内でnotnull制約となり、レコードの追加が出来ません。普通は、プライマリーをnullにしてsaveすると、シーケンスから値をとって補正し、Insertしてくれるのが仕様と理解しています。DBMSの知恵袋を理解したいのであれば、(事実素の処理ではそのとおりになっています)fixtureは、bakeで作成したのですが、プライマリーキーの定義が以下のようになっていました。class HogeFixture extends CakeTestFixture { var $name = 'Hoge'; var $table = 'hoges'; var $fields = array( 'hoge_id' => array('type' => 'integer', 'null' => false),/*以下省略*/ );}hogesテーブルのhoge_idは、serialとなっており、通常ですと、DBMSの知恵袋を追求していくと、DBMSの機能で、defualtは、nextval("hoges_hoge_id_seq"::regclass)となるはずです。レンタルサーバーといえば、なので、これを'hoge_id' => array('type' => 'integer', 'null' => シーケンスを読んで次の値とする内容),とすれば解決すると思うのですが、試したところ、レンタルサーバーに関する解説をすると、DBMSでは、リテラルで囲った文字列が引き渡されており、DBMSでシンタックスエラーとなります。DBMSに、リテラルで囲まない文字列を引き渡すにはどうしたらよいでしょう?ご存知の方、お願いします。
【解答】
CakePHPのdboはDBMSごとに詳細が作られているようです。フレームワークのソースをご覧になり、対応をとられてはどうでしょうか。DBMSの知恵袋についてだが、DBMSの指定がありませんが、オーソドックスなMySQLと仮定しますと・・・CakePHP1.3.11のMySQLのDboは、cake\libs\model\datasource\dbo\dbo_mysql.phpだと思います。サーチしてみると、649行めのfunction value($data, $column = null, $safe = false)で設定しているようですね。ここで、default:return "'" . mysql_real_escape_string($data, $this->connection) . "'";となっているので、どうしてもリテラルになってしまうようです。他のDBMSのDboも同様な内容でしたので、柔軟的に指定することは不可能だと思いますが。(フレームワークcoreの部分を改変するのであれば可能かも)DBMSによっては、属性をserialに設定すると、レンタルサーバーを知りたいのであれば、自動的にシーケンスを作ってくれて、nullだとnextvalを指定してくれるものもあります。せっかくDBMSごとにDboを作っているのですから、そこらへんの処理を入れてくれるといいのですけどね。ちなみに、serialでサーチしてみましたが、発見できず。。。おそらく、'hoge_id' => array('type' => 'serial', 'null' => false),としたら、エラーになるんじゃありません?Version2が出たので、1.3系列はstableになるのかもしれませんが、内容を見るに、これは、チケットを出して改善してもらうべき問題だと思いますよ。(補足を受けて追加)補足の内容から考えるに、フレームワークのソースは見られていたのですね。失礼しました。dboは外だしで上書きできないと思いますのから、やはりcoreの書き換えしかないと思います。レンタルサーバーを説明すると、2.0はどうなのでしょうか。詳しく見ていないのですが、DBMSの知恵袋に対しては、この事象が改善されているといいですね。※高度な質問は、ここではなく、CakePHPのコミュニティでされるといいんじゃないでしょうか。http://cakephp.jp/modules/newbb/