Meadows of wild horses

Blog...

Catalyst

| Comments

DBIx::Class로 스키마 관리하기

jeen님이 발표한 스키마 관리 하기 입니다.

jeen님의 글을 보게 되면 기존의 스키마를 관리하는 방법은 sql의 잦은 교체시 많은 문제점이 발생하고 있다고 서술 합니다.

스키마 관리를 좀더 편하게 하기 위하여 마지막에 서술 하는 dbicdump를 사용하여 간편하게 스키마 관리를 해보도록 합니다.

dbicdump를 사용하기 위해 필요한 ResultBase.pm과 schema.pl파일을 만들어 보도록 하겠습니다.

schema/schema.pl

schema.pl 설명

schema.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
my $DB_NAME     = $ENV{DB}           || 'DB_NAME';
my $DB_USER     = $ENV{DB_USER}     || 'DB_USER';
my $DB_PASSWORD = $ENV{DB_PASSWORD} || 'DB_PASSWORD';

{
schema_class => "Silex::Schema",
connect_info => {
  dsn               => "dbi:mysql:$DB_NAME:127.0.0.1",
  user              => $DB_USER,
  pass              => $DB_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 'password') {
      return { %{ $col_info },
          encode_column => 1,
          encode_class  => 'Digest',
          encode_args   => { algorithm => 'SHA-1', format => 'hex' },
          encode_check_method => 'check_password' };
  } # DB password 설정
  if ($col_name eq 'created_on') {
      return { %{ $col_info }, set_on_create => 1, inflate_datetime => 1 };
  } # DB created_on 설정

  if ($col_name eq 'updated_on') {
      return { %{ $col_info }, set_on_create => 1, set_on_update => 1, inflate_datetime => 1 };
  } # DB updated_on 설정
  },
  },
}

lib/MyApp/Schema/ResultBase.pm

ResultBase 클래스의 제약 문제 때문에 result_base_class 값을 지정해 줌으로써 모든 결과 클래스들은 DBIx::Class::Core가 아닌 MyApp::Schema::ResultBase를 상속받게 합니다. MyApp::Schema::ResultBase는 개인이 정의 해주는것 이므로 아래를 참조 합니다.

MD5 체크섬 값 아래에 중복되는 코드를 매번 적어주어야 했습니다. 이렇게 사용할 컴포넌트들을 결과클래스 별로 지정하는 대신 ResultBase 클래스를 읽어들입니다. 사실 이처럼 ResultBase를 놓고 여기에 컴포넌트를 일괄해서 읽어들이는 방식은 Cookbook 문서에서도 스타트업 속도 향상을 위해 권장하고 있습니다. - by Jeen -

그리고 컴포넌트의 사용을 위한 컬럼의 속성은 custom_column_info 속성에 코드를 등록해 지정할 수 있습니다.(schema.pl 하단 참조) 위의 코드처럼 등록하면 created_on 속성에 TimeStamp 컴포넌트를 사용하기 위한 속성 값인 set_on_create 옵션이 모든 결과클래스에 추가됩니다. (이거 멋지다..)

ResultBase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;

위의 두가지 코드를 작성 하였다면 준비는 끝났습니다. (dbicdump는 db 정보를 덤프해서 스키마를 작성하는 것으로 코드 작성및 작성 후에라도 db가 정의 되어 있어야 합니다.)

dbicdump 사용하기

아래를 실행한후 lib/MyApp/Schema/Result에 .pm 파일들이 새로 생성되거나 수정 되었다면 확인을 해보라

$ dbicdump -Ilib schema/schema.pl

MakeFile.pl 모듈 추가

다른 모듈이 더 추가 될수 있습니다 에러 메세지를 확인 하고 필요한 모듈을 더 설치 하세요.

requires "DBIx::Class::TimeStamp";

Comments