Markdown-Pod

 view release on metacpan or  search on metacpan

t/2011-12-17.mkd.t  view on Meta::CPAN


    #!perl
    package MyApp::Schema::ResultBase;
    use Moose;
    use MooseX::NonMoose;
    use namespace::autoclean;
    extends 'DBIx::Class::Core';
    
    sub my_method {};
    
    __PACKAGE__->meta->make_immutable;
    
    1;

그리고 결과 클래스에서 이 C<ResultBase>를 상속합니다.

    #!perl
    package MyApp::Schema::Result::Access;
    ....
    - extends 'DBIx::Class::Core';
    + extends 'MyApp::Schema::ResultBase';
    ....

어, 그런데 뭔가 걸립니다.

    #!perl
    # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:8E8XDlgZJWsPmqTw/xP34A

맙소사! C<ResultBase>를 상속하는 것조차도 이 문구위에 놓이게 되니 맘편히 고칠수도 없네요!


=head2 스키마 클래스 덤프에 설정파일을 사용

위에서 스키마 클래스를 덤프할 때 기나긴 옵션이 붙은 커맨드가 있었습니다.
데이터베이스 구성이 바뀌어질 때마다 그 긴 커맨드를
일일이 붙여넣기 식으로 넣어야하니, 좋은 방법 같지는 않습니다.
우선 I<기존 명령>의 사용을 그만두도록 합니다.
컴포넌트 등록이나, C<ResultBase> 클래스 설정이나 컬럼의 속성 추가 등등
매번 스키마 클래스 덤프할 때마다 자신의 상황에 맞게
이것저것 개조(customize)할 필요가 있습니다.

아쉽게도 I<기존 명령>으로 호출되는 L<Catalyst::Model::DBIC::Schema|http://search.cpan.org/perldoc?Catalyst::Model::DBIC::Schema> 모듈에 속해있는
L<Catalyst::Helper::Model::DBIC::Schema|http://search.cpan.org/perldoc?Catalyst::Helper::Model::DBIC::Schema>로는 현재 상황을 헤쳐 나가기 힘듭니다.
그래서 위 모듈 안에서 본질적으로 스키마 클래스 덤프에 사용되는 모듈인
L<DBIx::Class::Schema::Loader|http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader>를 사용합니다.
L<DBIx::Class::Schema::Loader|http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader>가 설치되어 있으면
C<dbicdump>라는 명령이 존재할 것입니다.
이 C<dbicdump> 커맨드에 이제부터 이 상황을 타개할 설정 파일을 담겠습니다.
설정 파일은 L<Config::Any|http://search.cpan.org/perldoc?Config::Any> 모듈로 처리되므로
펄에서 쓰이는 어떤 형식이라도 다룰 수 있습니다.
심지어는 I<펄 코드> 자신도 설정으로 사용할 수 있습니다.
아래는 C<dbicdump> 설정 파일의  예제입니다.

    #!perl
    {
        schema_class => "MyApp::Schema",
        connect_info => {
            dsn  => $ENV{DB_DSN}      || "dbi:mysql:test_db:127.0.0.1",
            user => $ENV{DB_USER}     || "test_user",
            pass => $ENV{DB_PASSWORD} || "test_password",
            mysql_enable_utf8  => 1,
        },
        loader_options => {
            dump_directory     => 'lib',
            naming             => { ALL => 'v8' },
            skip_load_external => 1,
            relationships      => 1,
    
            use_moose          => 1,
            only_autoclean     => 1,
    
            col_collision_map  => 'column_%s',
            result_base_class => 'MyApp::Schema::ResultBase',
            overwrite_modifications => 1,
            datetime_undef_if_invalid => 1,
        
            custom_column_info => sub {
                my ($table, $col_name, $col_info) = @_;
    
                if ($col_name eq 'created_on') {
                    return { %{ $col_info }, set_on_create => 1 };
                }
            },
        },
    }

항목들이 많으므로 전부 설명하는 대신, 위에서 봉착했던 문제에 대해 추려볼까요?
우선 C<ResultBase> 클래스 문제입니다. C<result_base_class> 값을 지정해 줌으로써
모든 결과클래스들은 C<DBIx::Class::Core>가 아니라 C<MyApp::Schema::ResultBase>를
상속받게 됩니다. 물론 C<MyApp::Schema::ResultBase>는 스스로 정의해줘야 합니다.
다음은 컬럼의 컴포넌트를 이용한 확장 문제입니다.
MD5 체크섬 값 아래에 중복되는 코드를 매번 적어주어야 했습니다.
이렇게 사용할 컴포넌트들을 결과클래스 별로 지정하는 대신 C<ResultBase> 클래스를 읽어들입니다.
사실 이처럼 C<ResultBase>를 놓고 여기에 컴포넌트를 일괄해서 읽어들이는 방식은
Cookbook 문서에서도 L<스타트업 속도 향상을 위해 권장|http://search.cpan.org/~arodland/DBIx-Class-0.08196/lib/DBIx/Class/Manual/Cookbook.pod#STARTUP_SPEED>하고 있습니다.

    #!perl
    package MyApp::Schema::ResultBase;
    use Moose;
    use MooseX::NonMoose;
    use namespace::autoclean;
    extends 'DBIx::Class::Core';
    
    __PACKAGE__->load_components(qw/
      InflateColumn::DateTime
      TimeStamp
      ...
    /);
    
    __PACKAGE__->meta->make_immutable;
    
    1;

그리고 컴포넌트의 사용을 위한 컬럼의 속성은
C<custom_column_info> 속성에 코드를 등록해 지정할 수 있습니다.
위의 코드처럼 등록하면 C<created_on>에 C<TimeStamp> 컴포넌트를 사용하기 위한
속성 값인 C<set_on_create>이 모든 결과클래스에 추가됩니다.


=head2 설정파일을 이용한 스키마 덤프



( run in 1.903 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )