Your SlideShare is downloading. ×
  • Like
Customization of DBIC::Schema::Loader
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Customization of DBIC::Schema::Loader

  • 2,137 views
Published

 

Published in Technology , Sports
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
2,137
On SlideShare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
11
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Customization DBIC::Schema::Loader d:id:ZIGOROu Toru Yamaguchi <zigorou@cpan.org>
  • 2. Agenda
    • DBIC::Schema::Loader のおさらい
      • make_schema_at()
        • 生成されたファイル自体に拡張
        • inc パスの追加による拡張
        • really_erase_files の値
        • Schema クラスも拡張対象にする
      • DBIC::Schema::Loader を改造
        • DBIC::Schema::Loader の概要
        • 名前に制約をつけてリレーション設定
      • まとめ
  • 3. make_schema_at()
    • DBIC::Schema::Loader のメソッド
      • 引数
        • 1. schema クラス名
        • 2. 生成オプション (HASHREF)
        • 3. connect_info (ARRAYREF)
      • 基本系
        • #!/usr/bin/perl
        • use FindBin;
        • use File::Spec;
        • use DBIx::Class::Schema::Loader qw(make_schema_at) ;
        • make_schema_at( 'MyApp::DBIC::Schema' , {
        • dump_directory => File::Spec->catfile( $FindBin::Bin , '..' , 'lib' ),
        • relly_erase_files => 1 , },
        • [ 'dbi:mysql:database=dbictest' , 'root' ],
        • );
  • 4. 拡張 (1) ファイル直書き方式 - 1
    • 生成されたファイルに拡張
      • 生成された Schema, Table クラスそれぞれの下の方に “ DO NOT MODIFY THIS ” と書かれたコメントがある
        • そこから “ You can replace this text ” の領域は拡張領域で自動生成の対象ではない
        • 生成されたファイルに直接書いて良い
          • 追加で load_components() したりとか
          • あるいは他のプラグインのメソッド叩いたり
          • テーブル定義をゴニョゴニョしたりとか
  • 5. 拡張 (1) ファイル直書き方式 - 2
    • # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:WFbbTfTFDFr/kewSj3QwAw
    • package MyApp::DBIC::Schema;
    • __PACKAGE__->load_components(
    • qw/+MyApp::DBIC::MyComp/
    • );
    • __PACKAGE__->init_mycomp;
    • # You can replace this text with custom content, and it will be preserved on regeneration 1 ;
  • 6. 拡張 (2) incにあるテンプレ読み込み方式 - 1
    • incパスに通したテンプレからinclude
      • use libで適当なディレクトリにパスを通すと、そこにあるファイルを対応するモジュールの拡張領域に差し込んでくれる機能
        • ここで注意しないとダメなのはSchemaクラスは対象外
        • Tableクラスのみ拡張可能
        • ちなみに拡張領域の箇所はファイル直書き方式と同じ
  • 7. 拡張 (2) incにあるテンプレ読み込み方式 - 2
    • ディレクトリ構成
    lib MyApp DBIC Schema User.pm schema MyApp DBIC Schema User.pm 自動生成される領域 Include ( ファイルの下部にくっつく )
  • 8. make_schema_at() [2]
    • really_erase_files ( 生成オプション )
      • true の時
        • 毎回ファイルを消して生成する
        • Schema, Table クラス両方消しちゃうので、 ファイル直書き方式は使えない ><
          • 必然的に include になるが、 Schema に対しては適用出来ない
      • false の時
        • 毎回ファイルを消さない
        • 直書き方式が使える
          • 但し消さないと include で挿入されたブロックが次回の直書きと見なされ、再び include されるので重複コードになるwww
  • 9. ここまでのまとめ
    • 現在の問題点
      • Schema, Table 共に後付的に拡張したい
        • Schema も対象にするなら really_erase_files を false にする
        • そうすると直書き領域に make_schema_at する度に重複するコードが出来てしまう
      • どうすれば良いか
        • really_erase_files => 0
        • でも自分で Table クラスを消せば同じ事になる
        • 拡張は Schema は直書き、 Table は include でやる。
  • 10. 改良版Schema生成
    • 改良版
      • #!/usr/bin/perl
      • use strict ;
      • use warnings ;
      • use FindBin;
      • use File::Spec;
      • use lib (
      • File::Spec->catfile( $FindBin::Bin , qw/.. lib/ ),
      • File::Spec->catfile( $FindBin::Bin , qw/.. schema/ )
      • );
      • use DBIx::Class::Schema::Loader qw(make_schema_at) ;
      • die unless @ARGV ;
      • my $schema_class = 'MyClass::DBIC::Schema' ;
      • # こんな感じで自分で消す
      • unlink ( glob ( File::Spec->catdir( $FindBin::Bin , '..' , 'lib' , split ( / :: / , $schema_class ) ) . '/*.pm' ) );
      • make_schema_at(
      • $schema_class ,
      • {
      • components => [ qw/ResultSetManager UTF8Columns InflateColumn::DateTime TimeStamp/ ],
      • dump_directory => File::Spec->catfile( $FindBin::Bin , qw/.. lib/ ),
      • debug => 0 ,
      • really_erase_my_files => 0 ,
      • },
      • @ARGV
      • );
  • 11. さらなる改良
    • Schema::Loader について
      • 中で何やってるか理解すればもっとカスタマイズ出来そう
        • 特にリレーションとか通常の使い方では手出しできない部分を何とかしたい
        • まずはクラス図から
  • 12. Class::Diagram of DBIC::Schema::Loader
    • Class Diagram
    DBIC::Schema::Loader DBIC::Schema ::Loader::Base DBIC::Schema ::Loader::Base::DBI::mysql DBIC::Schema ::Loader::RelBuilder 各ドライバごとにクラスがある リレーションの構築 Dump 時のオプションの詳細
  • 13. RelationShip [1]
    • belongs_to とか has_many とか
      • belongs_to(“user_id”, ...)
        • $rs-> user_id -> user_id
        • ダサすぎ
        • 残念ながら現在はこうなる
      • belongs_to(“user”, ...)
        • $rs-> user -> user_id
        • $rs-> user_id も OK
        • 自然になる
        • こうしたい
  • 14. RelationShip [2]
    • 問題の箇所
      • DBIC::Schema::Loader::Base の _load_relationship()
        • foreach my $src_class ( sort keys %$rel_stmts ) {
        • my $src_stmts = $rel_stmts ->{ $src_class };
        • foreach my $stmt ( @$src_stmts ) {
        • ### ここら辺を書き換えちゃえば良い
        • $self ->_dbic_stmt(
        • $src_class , $stmt ->{method}, ## belongs_to とか
        • @{ $stmt ->{args}} ## belongs_to の引数リスト
        • );
        • }
        • }
  • 15. RelationShip [4]
    • 改良版
    • foreach my $src_class ( sort keys %$rel_stmts ) {
    • my $src_stmts = $rel_stmts ->{ $src_class };
    • foreach my $stmt ( @$src_stmts ) {
    • ### belongs_to の時だけ無茶する
    • if ( $stmt ->{method} eq 'belongs_to' ) {
    • my $table_class_suffix = [
    • split / :: / => $stmt ->{args}->[ 1 ]
    • ]->[ -1 ];
    • $stmt ->{args}->[ 0 ] =
    • String::CamelCase::decamelize( $table_class_suffix );
    • }
    • $self ->_dbic_stmt( $src_class , $stmt ->{method}, @{ $stmt ->{args} } );
    • }
    • }
  • 16. まとめ
    • Schema::Loader との付き合いかた
      • really_erase_files を false
        • でも自分で Table 消す
        • Schema は直書き、 Table は include で辻褄合わせる
        • belongs_to は問題箇所を redifine する
          • 名前でコード生成時の制約をつけるのは良さそう。 on_created, on_updated(DATETIME) で NOW() 相当とか
        • 時間の都合上割愛したけど、それ以上は自分で DBIC 流儀のプラグイン書く ( 割と便利 )
      • そこまでするなら自分で Loader 書くべき?(ぇ
      • あるいは DBIC を使わない
  • 17. おしまい
    • ご清聴ありがとうございました