[s2container-php5:86] Re: 【質問】s2dao.php5に関して2点(PRADO連携・update)
Yusuke Hata
[E-MAIL ADDRESS DELETED]
2007年 3月 14日 (水) 01:40:24 JST
ハタです。
すいません、ウソっぱち書いてました。
S2Dao_DBMetaDataFactoryがロードできないクラスのロードを行う件についてですが
class_exists('class', false)だと__autoloadの読み込みは行われないんですね。。。
事前にrequireするのは変なので(?)、当面の対応として
if(strcasecmp($dbmd, 'S2Dao_MySQLDBMetaData') === 0){
return new S2Dao_StandardDBMetaData($db, $dbms);
} else if(class_exists($dbmd)){
return new $dbmd($db, $dbms);
}
return new S2Dao_StandardDBMetaData($db, $dbms);
として修正しました。
本来ならどこかにマッピングをする必要があると思いますので
S2Daoとしてロードできる部分はどこかでマッピングしようと思います。
また、autoloadでrequireする場合もクラスの存在チェックを行ってもらうように
ドキュメントの一部に記述しておきます。
ex)
function __autoload($className){
// exists for...
if(class_exists($className, false) || interface_exists($className, false)){
// S2ContainerClassLoader::load($className);
// XXX
require $className . '.class.php';
}
}
以上です。
On Tue, 13 Mar 2007 00:29:14 +0900
Yusuke Hata <[E-MAIL ADDRESS DELETED]> wrote:
> ハタです。こんばんわ
>
> まず、S2Dao_DBMetaDataFactoryのclass_exists($dbmd)は
> class_exists($dbmd, false)が正解でした。
> こちらは私の修正ミスで、本来ならば存在しないクラスのロードは行わないよ
> うに実装すべき点でした。(修正しておきます)
>
> また、本来PDOはMySQLドライバ実装の動きをしますが(getColumnMetaなどにつ
> いて)、それの実装がされていないPDOドライバOracleやSybaseなどと互換を持
> つために用意しているのが DBMetaDataインタフェースになっています。
>
> なので、MySQLについてはS2Dao_StandardDbMetaDataクラスで実装していると
> おりで問題がないハズです。この件についてはclass_exists($dbmd, false)と
> して、 MySQLではS2Dao_StandardDbMetaDataを使うようにしてください。
> # 私の怠慢でドキュメントに残していない部分が多いですねorz
>
> そして
> > S2Dao_NotSingleRowUpdatedRuntimeException
> > Description
> > Target for update must be single row(actual:0).(ProductEntity)
>
> これはMySQL以外でもおこりゆる更新が行われなかった場合の例外なのですが
> この件については、どう対応するかは "実装次第" となると思います。
>
> 更新が行われなかった際にfalseを返すとか、更新されなかったので0
> (integer)を返すというのは更新されている状態(値)が判別しにくいため、
> DAOの例外として上記どおりの実装になっています。 (本家Javaも同じ実装)
>
> で、この例外をどのように扱うかの一実装として
> S2DaoAssertAtLeastOneRowInterceptorがあげられます。
> org.seasar.dao.interceptorsのパッケージにあるのですが上記のinterceptor
> は更新結果が1件未満の場合に例外を発生させるもの(今回の例外実装と同じ)
> です。
>
> もし、更新がなくとも処理は継続したい && try/catchを含めないとするなら
> ば、上記のようにinterceptor内で綴じ込めてしまうのも1つの実装パターンと
> 思います。
>
> また、上記のようなinterceptorを含むdiconの記述例は以下になります。
> <components>
> <component class="EmployeeDao">
> <aspect>
> <component class="S2DaoInterceptor">
> <aspect>
> <component
> class="S2DaoAssertAtLeastOneRowInterceptor" /> </aspect>
> </component>
> </aspect>
> </component>
> </components>
>
> ということで、投げやりですがDAOの実装として更新がなかった場合の実装は
> アプリ任せてしまう他、ないものと考えています。
>
> 以上です。よろしくお願いします。
>
> On Mon, 12 Mar 2007 23:08:08 +0900
> "Yoshinari Ueyama" <[E-MAIL ADDRESS DELETED]> wrote:
>
> > 植山です。
> > 週末にPHPでのプログラミングを楽しんだのですが、その際に発生したこと
> > に関して2点ほど質問があります。いろいろとご意見をお聞かせください。
> >
> > 1.Mysqlでのupdate処理
> >
> > 今までSQLITEのみで作業をしていたのは片手落ち、MysqlでのDB操作も試さ
> > ねば・・・と思い、 MYSQLを用いたS2Daoプログラミングを行っていくと、
> > 下記のようなエラーが発生しました。
> >
> > S2Dao_NotSingleRowUpdatedRuntimeException
> > Description
> > Target for update must be single row(actual:0).(ProductEntity)
> >
> > データの編集画面において、データを変更せずにdaoのupdate($entity)メ
> > ソッドを実行した際に発生することがわかり、 おそらく下記の挙動が原因
> > だと推測しています。
> >
> > -------------------------------------------------------------------------------------------------------------------------------
> > http://dev.mysql.com/doc/refman/4.1/ja/update.html
> > カラムの値がそのカラムの現在の値に設定される場合、MySQL はそれが現在
> > の値であることを認識し、更新処理を行いません。
> > -------------------------------------------------------------------------------------------------------------------------------
> >
> > これは、本来どのように対処すべきなのでしょうか?
> > 1)画面入力値チェックの一環としてデータが変更されていないことを確認
> > し、変更されていなければupdate処理を実行しない。
> > 2)エラーが発生しないようにS2Daoの修正を行う。
> >
> > 2)S2Dao_MySQLDBMetaDataクラスについて
> >
> > S2Base.PHP5のPRADO pluginとS2Dao.PHP5を用いたプログラムを実行したと
> > ころ、下記のようなエラーが発生しました。
> >
> > S2Dao_SQLRuntimeException
> >
> > Description
> > SQLException occured, because [Warning]
> > PradoBase::include_once(S2Dao_MySQLDBMetaData.php)
> > [<a
> > href='function.PradoBase-include-once'>function.PradoBase-include-once
> > </a>]: failed to open stream: No such file or directory
> > (@line 98 in file
> > /private/var/www/public_html/prado/framework/PradoBase.php).
> >
> > これは、S2Dao_DBMetaDataFactoryの下記の処理実行時に
> > class S2Dao_DBMetaDataFactory {
> >
> > const DBMetaData_Suffix = 'DBMetaData';
> >
> > public static function create(PDO $db, S2Dao_Dbms $dbms){
> > $dbmd = get_class($dbms) . self::DBMetaData_Suffix;
> > if(class_exists($dbmd)){
> > return new $dbmd($db, $dbms);
> > }
> > return new S2Dao_StandardDBMetaData($db, $dbms);
> > }
> > }
> >
> > S2Dao_MySQLDBMetaDataクラスをロードする必要が出てきて、
> >
> > PradoBaseクラスの下記メソッドが実行された際に
> > public static function autoload($className)
> > {
> > include_once($className.self::CLASS_FILE_EXT);
> > if(!class_exists($className,false) &&
> > !interface_exists($className,false))
> > self::fatalError("Class file for '$className' cannot be
> > found.");
> > }
> >
> > S2Dao_MySQLDBMetaData.phpが存在していないために発生したと推測してい
> > ます。(あまり深くソースを追ってませんが・・)
> >
> > 今は、S2Dao_MySQLDBMetaDataを継承しただけのS2Dao_MySQLDBMetaDataクラ
> > スが定義された S2Dao_MySQLDBMetaData.class.phpを作成し、エラーが発生
> > しないようにしましたが、本来はどのように対処すべきでしょうか?
> >
> > 以上です。
> >
>
>
> --
> Yusuke Hata <[E-MAIL ADDRESS DELETED]>
> blog: http://blog.xole.net/
> _______________________________________________
> S2Container-PHP5 mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/s2container-php5
--
Yusuke Hata <[E-MAIL ADDRESS DELETED]>
blog: http://blog.xole.net/
S2Container-PHP5 メーリングリストの案内