tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

ORM とかテーブルデータゲートウェイとか、その周辺の話

このへんとかこのへんの続きみたいな話。。。だと思う。

ORM がほしい

  • 簡単な SQL を簡単に Perl から投げれるといいな
  • 難しい SQL(とくに JOIN いっぱいするような SELECT)は、クエリビルダーで頑張るのではなく、SQL を書いて実行したい
  • その際に名前付きプレースホルダが使いたいなー
  • INSERT とか UPDATE は hashref が渡せればいい
  • スキーマクラスが無くてもうごくのがいいな

テーブルデーゲートウェイがほしい

  • テーブルごとにある程度ロジックを置きたいな
    • 1枚のスキーマクラスを持つのではなく、(必要に応じて)テーブルごとに「テーブルクラス*1」をおくような感じ
    • 親子関係のテーブルの INSERT とか一発でできるとうれしいな*2
    • めんどくさいけど良く使う SELECT をメソッドとして置けるとうれしいな
  • 今はできない*3けど、将来は SQL もそこに置いておくと管理しやすくていいだろうな

テーブルデーゲートウェイについて

  • PoEAA みると、テーブルクラスがあって、ベースクラスを継承してるつくりになっている。テーブル単位のユーティリティーがそこに置かれるイメージ。ただ、Perl だと引数によるオーバーロードができないのであんまりメリットないかもなー、とも思う。たとえば insert をオーバーロードできない(オーバーライドするわけにいかない)ので、insert_by_obj 作るとか、そんな感じ。ちょっとダサい。
  • Row オブジェクトは本来不要だが、世の実装には大抵ついてるようだ。そのほうが便利だからであろう。
  • PHP の Zend_Db とか(DBIx::Simple もかな?)テーブルデーゲートウェイの実装と呼ばれてるものは、なんか単に機能が少ないだけのような気がする。Teng とか Rails の Active Record とかだってテーブルデーゲートウェイとしての機能を持ってる。(行データゲートウェイも結局 Row オブジェクトを生成するための入り口としてテーブルデーゲートウェイ相当の機能が必要だから)。*4
  • 僕がほしいのは、そうではなくて、テーブルごとにカスタマイズしたメソッドを持つことのできる物体。普通はそういうものはスキーマクラスで実現するけど、スキーマクラスがなくても動くようにしたい。
  • Row オブジェクトはプアでもよくて、つーか hashref とかでもぜんぜんいい。
  • inflate/deflate はできなくても良くて、どうしてもやりたかったら inflate は Row オブジェクトのメソッドとして、deflate はテーブルクラスのメソッドとして Row オブジェクトを受けるメソッドを提供すれば良いと思う。

その他雑談

  • SELECT して結果が返らなかった場合は undef を返すか、NULL オブジェクトを返すかどっちでもいい。使う側としては、NULL オブジェクトを返す方が実装が楽で、undef を返す方がエラーを意識して注意深く書けるので一長一短あり、好きな方を選べるといいけど、アプリ内では統一しといたほうがいいだろう。
  • トランザクション管理とか、コネクションの管理って、ORM でやった方が便利には違いないけど、別にやらなくてもいい気がするのだけど、大抵やってるのは何故だろう?結構不思議。
  • 僕のところでは、テーブルの新規追加も変更も結構頻繁なので、スキーマクラス管理とかだるいし、かといって実行時に生成すると遅いし。mod_perl とかにキャッシュすれば実行速度は速いけど、テストが遅くなるのが嫌。スキーマクラスを使う ORM*5使ってる人たちは困って無いのかなー?不思議だ。

結論

結論なんて多分ない。だって今考えてること、悩んでることをつらつら書いただけだから。

*1:これ正式な用語かどうか分からん

*2:これは行データゲートウェイだと多分ちょっとめんどい

*3:mod_perl なので __DATA__ が使えない...

*4:なので、テーブルデーゲートウェイの正しい姿、みたいなのをまだ明確にイメージできてない。もうちょい修行が必要

*5:大抵のORMはそうだよね?