ログ日記

作業ログと日記とメモ

PHP5用のORM作った その2

昨日 *1 の続き。
https://github.com/nishimura/Tsukiyo


Joinの条件指定が欲しい、or検索が欲しい、テーブル名指定のjoinが欲しい、ということで機能追加。ほぼS2JDBC
段々コードが見づらくなってきたかも。

OR検索

orやandが予約後なので、苦肉の策で変数代入。

<?php
$or = Tsukiyo_Helper::$or;
// または extract(Tsukiyo_Helper::$all);

$iterator = $db->from('Item')
            ->sub($or()->eq(array('name' => 'a',
                                  'opt'  => 'option1'))
                       ->like(array('name' => 'b'))
            )->isNotNull('opt')
            ->iterator();
// where ((name = 'a' and opt => 'option1') or (name like '%b%')) and opt is not null

$orはただのショートカットで、 new Tsukiyo_WhereTree('or') を返している。

条件指定join

join時に、プライマリキー以外の条件を付け加えたい場合は

<?php
        $iterator = $db->from('Item')
            ->outerJoin('SubItem',
                        $or()->eq(array('subname' => 'foo'))
                             ->isNull('subname'))
            ->iterator();
// item join sub_item on item.item_id = sub_item.item_id and 
//   (subname = 'foo' or subname is null)

のようにする。

テーブル名指定join

これは、テーブルのリレーションが複数のパスを持つ場合に必要。関連の自動設定が出来ないので。

item <-- sub_item --> tag
 ↑         |
 |_________|

こういうテーブル構成のとき、

<?php
$db->from('Item')
  ->outerJoin('SubItem')
  ->outerJoin('Tag')

とすると、Tagがどちらに結合されるか分からない。
どちらからもたどれるようにするのが理想なのかもしれないが、そういう特殊な構造は別途プログラムを書くということで。

<?php
$db->from('Item')
  ->outerJoin('SubItem')
  ->outerJoin('SubItem.Tag')

TagはSubItemの方に結合しますよーという指定をする。


関連が一意に特定できるなら(上の図でいうと item <-- tag がないなら)outerJoin('Tag') でいい。