Affamative Way

前向きにグダグダいいながらコード書く

S2Ethnaを使って見る 〜その2〜

example | S2Ethna v0.2

S2Container.PHP5のサンプルはMaple使ってたこともあり
ソース読んで理解した。

解らん人は CodeZine:S2Container.PHP5を用いたDIベースの開発を見ると解るかも


その後のサンプルを実行する為に
以下のようなDBを用意した。

HOST  :localhost
DB    :s2ethna
USER  :hoge
PASS  :hoge

DB設定の定義行っている場所が2箇所あった

  • s2ethna-ini.php
<?php
$config = array(
	/* 中略 */

    // デモンストレーション
    'demonstration' => false,
    'demonstration_dsn' => 'mysql://hoge:hoge@localhost/s2ethna',
    'demonstration_page' => '1',

これ替えなくても動くみたい。。。どんな時に使ってるんだろうか。。。*1

  • pdo.dicon
    <component name="dataSource" class="S2Ethna_PDODataSource">
        <property name="dsn">"mysql:host=localhost; dbname=s2ethna"</property>
        <property name="user">"hoge"</property>
        <property name="password">"hoge"</property>
        <property name="option">
            array(PDO::ATTR_ORACLE_NULLS => PDO::NULL_EMPTY_STRING,
                  PDO::ATTR_AUTOCOMMIT => false);
        </property>
    </component>

ひとまず、上記のようにを変更した。

AppManagerでDAOを利用する

S2Dao.PHP5サンプル|AppManagerでDAOを利用する|解説


項番1.の通りに以下のSQLを実行するとエラーとなる。。。

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 (`CD_ID`, `ID`)
     , INDEX (`CD_ID`)
     , CONSTRAINT `FK_shelf_1` FOREIGN KEY (`CD_ID`)
                  REFERENCES `cd` (`ID`)
)TYPE=InnoDB;

BEGIN;
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' ) ;
COMMIT;
1075 Incorrect table definition; there can be only one auto column and it must be defined as a key

あれこれいじってみると、原因はPK定義の順序が悪かったらしい

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`)

CD_IDとIDの順序を入れ替えてあげればOK
早速、ブラウザで動作確認するとちゃんと動きましたー


BeanとDaoの定義さえ完了してaspectすれば、↓だけで動くとのはすばらしいっ!

<?php
     function getCdList()  
     {  
         return $this->dao->readCdList();  
     }  


以下の2ファイル内容が一緒だが、AppManagerにDIしていて
dao.diconは使われていない。

  • app/S2ethna_ExampleDaoManager.dicon
  • app/action/Example/Di/dao.dicon


試しにActionClassにDIしてみた。

<?php
    /**
     *  example_daoアクションの実装
     *
     *  @access public
     *  @return string  遷移名
     */
    function perform()
    {
        //$list = $this->backend->getManager('ExampleDao')->getCdList();
        // 【追記】直接daoのメソッドを利用するように変更した。
        $list = $this->dao->readCdList();
        $this->af->setApp('cdlist',$list);

        return 'example_dao';
    }
    
    // 【追記】DIを受け取る
    private $dao;
    function setCdDao(CdDao $dao) {
        $this->dao = $dao;
    }

おぉ動いた。EthnaAppManagerを使う意味を考えるとこんな絶対使い方しませんが・・・

電子掲示板

S2Dao.PHP5サンプル|電子掲示板|解説|S2Ethna v0.2

項番1のSQLを実行して早速、ローカルの掲示版アプリを早速見る。

トランザクションを行うため、interfaceを用意し、AppManagerに実装させます。

ん〜、若干めんどくさいような。あとから見たときの解り安さとトレードというところでしょうか?


しかし、ページャー便利ねーDBレイヤーと連動してて無駄がない。。。


今後、調査する項目

複数テーブルに対してのトランザクションの実行処理を作って見る。

S2Container.PHP5の仕様により、$this->createArticleと呼ぶとトランザクションがかかりません。外部から呼んでください。

複数のAppManagerを跨いでトランザクションをかけたい場合は、S2Ethna_PDODataSourceの解説をご覧ください。

色々と制約もあるようですし、何より。。想像が付かないのでseasarの慣れがてらやってみることにします。

複数DBの定義を試す

DB周りはレプリケーションして実装したいので、以下のリンクの方法を試してみる。
S2で複数DBとのコネクションを取得する方法は?|FAQ/S2DAO - SeasarWiki

負荷分散の為にテーブルをインクリメンタルに数字を増やしていった場合の対処

負荷が予想されるので以下のようなことを行おうと検討中*2

親ID が 1 〜 10000 の時は 子table_00に
親ID が10001 〜 20001 の時は 子table_01に

参照はviewで何とかなるとして、更新系はどうしたもんか・・・
都度、beanとDaoを作るのも無駄な気がするのでどうしたものか考える


実際ここまでくるとS2だとどうなるんだろうなぁ・・・
TechTargetジャパン:mixiの生みの親“バタラ氏”が語るMySQLの意外な利用法

想像がつかない。。。

今日気になった物

[rakuten:foronefirst:10002062:detail]
これがあったら仕事の効率上がるだろうなぁ・・・1時間毎に期限を設けて目標を立てて自らを追い込めるし

*1:TO DO:要調査

*2:有効なのだろうか・・・