EthnaにS2Ethna(S2Container+S2Dao)を組み込んでみた!
概要
S2ContainerとS2Daoを使うためのS2Ethnaを組み込んでみました。
どんどん環境を作っていく割りにEthnaでまったくプログラムを組んでない状況は無視することにします(笑)
S2Ethna 0.2
http://s2ethna.ameria.jp/
S2Container 1.2.0
http://s2container.php5.seasar.org/
環境構築
S2Ethnaのサイトを参照にして作っていきます。と。。。結構面倒です!
S2Ethnaの場合ControllerとActionFormにパッチを当てる必要があります。
なので。。。EthnaのコマンドでS2Ethnaを作るプログラムを組みました!
プロジェクトのスケルトンファイルをコピーして、S2とつけたファイルを作成。そのファイルにパッチを適用。
プロジェクトを作るハンドラと、フォルダやファイルを作成するジェネレーターをコピーしてS2をつけたコマンドを作成。
中身で新規作成したS2系のスケルトンを利用するように変更。daoフォルダ作成と標準diconファイルもコピー。
上記のコマンドで
ethna add-S2project neko
みたいな感じでS2Ethnaのプロジェクトが作成できます。
テストプロジェクトではコマンドじゃなくって、add-s2project.phpってそれ専用のスクリプトを作成。。。
ethnaAdmin.phpに取り込むか考え中。別に作ったほうがいいと思うんだよね。S2Ethnaの方だったらDaoとかEntityとかの作成機能が必要だし。
備考
/** DICON XML format DTD validation */ define('S2CONTAINER_PHP5_DOM_VALIDATE', false);
Controllerの設定ですが、パッチではデフォルトtrueになっています。サンプルではfalseになっています。
私の環境だとtrueだと動きませんでした(涙) なのでテストプロジェクトの中身はfalseに設定してあります。
diconのXMLをLoadした瞬間に固まってXAMPPが落ちました! 詳細は確認していませんが、標準関数で落ちているからねー、謎です。
DB作成
DBをあらかじめ作成しておきます。
CREATE TABLE `cd` ( `ID` INT NOT NULL , `TITLE` VARCHAR(100) , `CONTENT` VARCHAR(200) , PRIMARY KEY (`ID`) )TYPE=InnoDB; CREATE TABLE `shelf` ( `ID` INT NOT NULL AUTO_INCREMENT , `CD_ID` INT NOT NULL , `ADD_TIME` DATETIME DEFAULT '2005-12-25 10:12:13' , PRIMARY KEY (`ID`, `CD_ID`) , INDEX (`CD_ID`) , CONSTRAINT `FK_shelf_1` FOREIGN KEY (`CD_ID`) REFERENCES `cd` (`ID`) )TYPE=InnoDB; INSERT INTO `cd` ( ID, CONTENT, TITLE ) VALUES ( 1, 'hello!!', 'S2Dao!!!' ) ; INSERT INTO `shelf` ( CD_ID, ADD_TIME ) VALUES ( 1, '2005-12-18 10:12:34' ) ;
これがS2Ethnaのサンプルについていたテーブルです。DB名はなんでもいいのですがサンプルは「s2con」になっていました。
私は「s2ethna」で作成したので、何度も書き換えていましたが(笑)
仕組み
phpと同じ名前でdiconファイルを作成しておくと、勝手にDIしてDaoを作ってくれるようです。サンプルの場合にはS2ethna_ExampleDaoManager.phpがわかりやすいのですが、アプリケーションマネージャーに対してDaoを作成しています。
daoとentity(Bean)ファイルはあらかじめサンプルから /neko/app/dao にコピーしておきます。
(CdDao.class.php,CdBean.class.php)
private $dao;
function setCdDao(CdDao $dao) {
$this->dao = $dao;
}
こんな感じで作っています。ペアのdiconには
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="%BASE%/etc/dao.dicon"/> <component class="CdDao"> <aspect>dao.interceptor</aspect> </component> </components>
こうなっていて、CdDaoを自動生成している記述が書いてあります。
実際の利用の場合にはアクションからアプリケーションマネージャーを呼び出して利用します。
$list = $this->backend->getManager('ExampleDao')->getCdList(); $this->af->setApp('cdlist',$list);
getManagerでアプリケーションマネージャーを呼んで、その中でこまごました処理を書きます。
応用
アプリケーションマネージャーに処理を統一するのはいいのですが、簡単な処理の場合にはアクションの中でDIしたいです。
流れ的にはまったく同じで、上のdiconをコピーして、アクション名と同じ場所に設置します。
/neko/app/action/Daotest.dicon
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="%BASE%/etc/dao.dicon"/> <component class="CdDao"> <aspect>dao.interceptor</aspect> </component> </components>
/neko/app/action/Daotest.php
<?php class Neko_Form_Daotest extends Neko_ActionForm { var $form = array(); } class Neko_Action_Daotest extends Neko_ActionClass { function prepare() { return null; } function perform() { var_dump($this->cdDao->readCdList()); return 'daotest'; } private $cdDao; function setCdDao(CdDao $cdDao) { $this->cdDao = $cdDao; } }
データの出力はまあ、テストなのでvar_dumpなのですが。。。
S2Ethnaのサンプルはdaoになっていますが、複数のdaoを使う場合があるので明示的な名前をつけた方があとで便利だと思います。
最後に
前回使った時にはMDB2を利用しましたが、今回はS2Daoでやってみたいと思います。ちょっとファイルが増えるのであまり好きじゃないんですけれどね。。。
今はJavaでTeedaを触っているので、同じインターフェースでもいいかなって思っています。複数人で複雑なのを組むのであればS2Daoで、単純なのだったらMDB2かDBで直接SQL書いた方が楽そうです(笑)
DoltengとDbLauncherぐらいさくさくDaoファイルを作成できればいいんでしょうけれどね。diconもアクションとかの管理でさくっと追加できてもいい気がしますが作るとなるとちょっと手間かかりそうです。
作成物
プロジェクトファイル一式
http://akira.info/labs/ethna/ethna_test20080729.zip
S2Project作成用コマンド(差分)
http://akira.info/labs/ethna/Ethna2.5.0p1+S2.zip
コマンドはEthnaのフォルダに上書きしてください。既存のファイルには手を加えていないので環境を壊さないで利用することができます。
すべてEthna 2.5.0 preview 1用ですのでご注意ください。
中身はたいした事やっていないので2.3系でもすぐに作れると思います。