ついにDoctrine 1.2がリリース!

Today I am very happy to announce that Doctrine 1.2.0 stable has been released.

http://www.doctrine-project.org/blog/doctrine-1-2-0-stable-released

Doctrine 1系の最終形といってもいいでしょう、Doctrine 1.2が本日正式リリースされました。

Doctrine 1.2で新しく追加された機能や変更された機能には以下のようなものがあります。

Doctrine_Core

今までのDoctrineクラスはDoctrine_Coreに置き換えられています。DoctrineクラスはDoctrine_Coreを継承していますが、定数などはDoctrine_Core::ATTR_XXXXのように指定する必要があります。

また、パフォーマンスを考慮して、文字列でのAttributeの指定がおこなえなくなりました。

<?php
$manager = Doctrine_Manager::getInstance();
// $manager->setAttribute('use_dql_callbacks', true);  // => 現在は利用不可能
$manager->setAttribute(Doctrine_Core::ATTR_USE_DQL_CALLBACKS, true);

カスタムクラスの利用

Doctrine 1.2になるまで、Hydrator、Connectionなどの内部で使われるクラスはハードコーディングされており、カスタムクラスを利用することができませんでした。また、Query、Collection、Tableといったユーザが利用するクラスもハードコーディングされていたため、カスタムクラスを使うには色々と面倒だったり、内部で使われているものには手を加えることができませんでした。

Doctrine 1.2ではこれらが改良され、カスタムクラスの指定が可能になりました。

<?php
$manager = Doctrine_Manager::getInstance();
// Hydrator
$manager->registerHydrator('my_hydrator', 'MyHydrator');
$query->execute(array(), 'my_hydrator');

// Connection
$manager->registerConnectionDriver('mysql', 'MyMysqlConnection');

// Query
$manager->setAttribute(Doctrine_Core::ATTR_QUERY_CLASS, 'MyQuery');
echo get_class(Doctrine_Query::create());  // => MyQuery

// Collection
$manager->setAttribute(Doctrine_Core::ATTR_COLLECTION_CLASS, 'MyCollection');
echo get_class(Doctrine_Collection::create($table));  // => MyCollection

// Table
$manager->setAttribute(Doctrine_Core::ATTR_TABLE_CLASS, 'MyTable');
# これを設定したあとにタスクでモデルを自動生成すると、Tableクラスの親クラスがMyTableになる

マジックファインダメソッドの改良

DoctrineではfindOneById()やfindByUsername()といったメソッドが自動的に使えるようになります。これは__cal()マジックメソッドを経由して、Byに続く値をカラム名として検索し、findByならCollection(レコードの配列)、findOneByならRecord(単一のレコード)を取得するという仕組みです。

Doctrine 1.2からはこの仕組みに、findOneByUsernameAndPassword('fivestar', 'mypass') や findByIsAdminOrIsModerator(true, true) のようにANDやORでカラムを複数指定できるようになりました。
これはいくつでも組み合わせることができ、ANDとORの組み合わせも可能です。

リレーションにORDER BY句の自動付与

各リレーションを取得する際に、自動的にORDER BYを付与することができるようになりました。

User:
  columns:
    username: string(255)
    password: string(255)
  relations:
    Articles:
      class: Article
      local: id
      foreign: user_id
      type: many
      foreignType: one
      orderBy: published_at DESC

この機能、実際に使ってみてはいないのですが、どうやらYAMLでは一方方向でしか指定できないみたいです。YAMLのリレーション定義は基本的にone-to-manyのmany側として使うような設定にデフォルトでなっているのですが、これを使うときにはoneからmanyを取得した際の指定をおこないたいと思いますので、そうするとone側にリレーションの定義をする必要があり、若干面倒だなあと思いました。

このあたりの処理はRelation::getOrderByStatement()からTable::processOrderBy()が呼び出されるという仕組みでおこなわれています。詳しくは追っていませんが、この機能を詳しく追う場合はこのあたりを見ればよいかと思います。


その他の機能についてはUpgrade from 1.1 to 1.2を見ていただければと思います。

Doctrine 1.2はカスタムクラスが使えるようになったりしたので、かなり使いやすくなったと思います。

あとはsymfony 1.3/1.4ですね!