日記
join機能の独自拡張Edit

「Zend_Db_Tableにjoinがあれば、現時点でも使う気になるのになー」ということで、試しに独自にjoin機能を実装してみることにした。

Zend_Db_Table、Zend_Db_Table_Row、Zend_Db_Table_Rowsetを書き換えているけど、独自拡張した、

Zend_Db_Table::join(Zend_Db_Table $joinTable, $joinType = 'inner')

というメソッドを使わない限りは、従来の各クラスとの互換性があるはず。

上記リンク先にサンプルコードとか制限とかいろいろ載せているけど、要は、

create table product(
id integer primary key auto increment,
name varchar(100),
);
create table stock(
id integer primary key auto increment,
product_id integer unique,
amount integer,
);

みたいなテーブルがあった場合、

$productTable = new Product();
$productTable->join(new Stock());
$products = $productTable->fetchAll('stock.amount < 5'); // 在庫が5より少ない商品を取得
foreach ($products as $product) {
$stock = $product->stock;
$stock->amount += 5;
$stock->save();
echo '商品' . $product->name . 'の在庫を' . $stock->amount . 'に増やしました。';
}

みたいな書き方ができるようになる感じね。

ただ実際にjoin機能を作ってみて分かったけど、こういうものを汎用的に使えるようにする設計は難しいね。

今回は割り切って、規約通りのテーブル定義以外では動かないようにしたから実装がシンプルになったけど、どのくらいイレギュラー(規約外)な場合を許容しつつ、その場合の対応をどれだけスマートに記述できるようにするか、ってのを考えはじめると、いつまで経っても設計が終わらない。っつーか、最初ちょっとくらいイレギュラーな場合にも対応できるようにしようと思ってたんだけど、中途半端にしかならないんであきらめた。

ごついjoin定義情報を背後に持っておいて、それを使ってjoinに関するイレギュラーなパターンを解決するというのが、真っ先に思いつく方法ではあるけれども、それって結局は単なる力業だし、そういう実装方法をそのまま表にまで出しちゃうと、利用者側レベルでの使い勝手もjoin定義情報と同じだけ複雑になりうることになっちゃって、あんまりスマートじゃないよなー。かといって、ごついjoin定義情報を利用者レベルでスマートに設定できるインターフェースってのも、なかなか設計が難しい。

俺としては、利用者レベルの使い勝手は今回の俺の実装程度のシンプルさで済みつつも、これよりももっと融通を利かせられるような本家実装を望むところ。

Published At2006-03-30 00:00Updated At2006-03-30 00:00