X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema%2FLoader%2FBase.pm;h=6eaaddca4e77bf6238cb3fae4569c22e405e6d81;hb=95b0a8b9f13c30c12c23f28e0cd6ff642412d009;hp=c35226c57dcd3a8363d20779db1dd0fb60294f6c;hpb=a7116285a72cb974e5e1848b8f202981b0106d98;p=dbsrgits%2FDBIx-Class-Schema-Loader.git diff --git a/lib/DBIx/Class/Schema/Loader/Base.pm b/lib/DBIx/Class/Schema/Loader/Base.pm index c35226c..6eaaddc 100644 --- a/lib/DBIx/Class/Schema/Loader/Base.pm +++ b/lib/DBIx/Class/Schema/Loader/Base.pm @@ -25,7 +25,7 @@ use DBIx::Class (); use Class::Load 'load_class'; use namespace::clean; -our $VERSION = '0.07002'; +our $VERSION = '0.07010'; __PACKAGE__->mk_group_ro_accessors('simple', qw/ schema @@ -40,7 +40,7 @@ __PACKAGE__->mk_group_ro_accessors('simple', qw/ skip_relationships skip_load_external moniker_map - column_accessor_map + col_accessor_map custom_column_info inflect_singular inflect_plural @@ -88,7 +88,9 @@ __PACKAGE__->mk_group_accessors('simple', qw/ col_collision_map rel_collision_map real_dump_directory + result_component_map datetime_undef_if_invalid + _result_class_methods /); =head1 NAME @@ -309,7 +311,7 @@ together. Examples: stations_visited | StationVisited routeChange | RouteChange -=head2 column_accessor_map +=head2 col_accessor_map Same as moniker_map, but for column accessor names. If a coderef is passed, the code is called with arguments of @@ -365,6 +367,22 @@ List of additional components to be loaded into all of your table classes. A good example would be L +=head2 result_component_map + +A hashref of moniker keys and component values. Unlike C, which loads the +given components into every table class, this option allows you to load certain +components for specified tables. For example: + + result_component_map => { + StationVisited => '+YourApp::Schema::Component::StationVisited', + RouteChange => [ + '+YourApp::Schema::Component::RouteChange', + 'InflateColumn::DateTime', + ], + } + +You may use this in conjunction with C. + =head2 use_namespaces This is now the default, to go back to L pass @@ -563,6 +581,10 @@ by L. sub new { my ( $class, %args ) = @_; + if (exists $args{column_accessor_map}) { + $args{col_accessor_map} = delete $args{column_accessor_map}; + } + my $self = { %args }; # don't lose undef options @@ -592,6 +614,18 @@ sub new { $self->_validate_class_args; + if ($self->result_component_map) { + my %rc_map = %{ $self->result_component_map }; + foreach my $moniker (keys %rc_map) { + $rc_map{$moniker} = [ $rc_map{$moniker} ] unless ref $rc_map{$moniker}; + } + $self->result_component_map(\%rc_map); + } + else { + $self->result_component_map({}); + } + $self->_validate_result_component_map; + if ($self->use_moose) { if (not DBIx::Class::Schema::Loader::Optional::Dependencies->req_ok_for('use_moose')) { die sprintf "You must install the following CPAN modules to enable the use_moose option: %s.\n", @@ -785,32 +819,51 @@ EOF sub _validate_class_args { my $self = shift; - my $args = shift; foreach my $k (@CLASS_ARGS) { next unless $self->$k; my @classes = ref $self->$k eq 'ARRAY' ? @{ $self->$k } : $self->$k; - foreach my $c (@classes) { - # components default to being under the DBIx::Class namespace unless they - # are preceeded with a '+' - if ( $k =~ m/components$/ && $c !~ s/^\+// ) { - $c = 'DBIx::Class::' . $c; - } + $self->_validate_classes($k, \@classes); + } +} - # 1 == installed, 0 == not installed, undef == invalid classname - my $installed = Class::Inspector->installed($c); - if ( defined($installed) ) { - if ( $installed == 0 ) { - croak qq/$c, as specified in the loader option "$k", is not installed/; - } - } else { - croak qq/$c, as specified in the loader option "$k", is an invalid class name/; +sub _validate_result_component_map { + my $self = shift; + + my $map = $self->result_component_map; + return unless $map && ref $map eq 'HASH'; + + foreach my $classes (values %$map) { + $self->_validate_classes('result_component_map', [@$classes]); + } +} + +sub _validate_classes { + my $self = shift; + my $key = shift; + my $classes = shift; + + foreach my $c (@$classes) { + # components default to being under the DBIx::Class namespace unless they + # are preceeded with a '+' + if ( $key =~ m/component/ && $c !~ s/^\+// ) { + $c = 'DBIx::Class::' . $c; + } + + # 1 == installed, 0 == not installed, undef == invalid classname + my $installed = Class::Inspector->installed($c); + if ( defined($installed) ) { + if ( $installed == 0 ) { + croak qq/$c, as specified in the loader option "$key", is not installed/; } + } else { + croak qq/$c, as specified in the loader option "$key", is an invalid class name/; } } } + sub _find_file_in_inc { my ($self, $file) = @_; @@ -1569,40 +1622,52 @@ sub _make_src_class { $self->_use ($table_class, @{$self->additional_classes}); $self->_inject($table_class, @{$self->left_base_classes}); - if (my @components = @{ $self->components }) { - $self->_dbic_stmt($table_class, 'load_components', @components); - } + my @components = @{ $self->components || [] }; + + push @components, @{ $self->result_component_map->{$table_moniker} } + if exists $self->result_component_map->{$table_moniker}; + + $self->_dbic_stmt($table_class, 'load_components', @components) if @components; $self->_inject($table_class, @{$self->additional_base_classes}); } -{ - my %result_methods; +sub _is_result_class_method { + my ($self, $name, $table_name) = @_; - sub _is_result_class_method { - my ($self, $name) = @_; + my $table_moniker = $table_name ? $self->_table2moniker($table_name) : ''; - %result_methods || do { - my @methods; - my $base = $self->result_base_class || 'DBIx::Class::Core'; - my @components = map { /^\+/ ? substr($_,1) : "DBIx::Class::$_" } @{ $self->components || [] }; + if (not $self->_result_class_methods) { + my (@methods, %methods); + my $base = $self->result_base_class || 'DBIx::Class::Core'; - for my $class ($base, @components, $self->use_moose ? 'Moose::Object' : ()) { - load_class $class; + my @components = @{ $self->components || [] }; - push @methods, @{ Class::Inspector->methods($class) || [] }; - } + push @components, @{ $self->result_component_map->{$table_moniker} } + if exists $self->result_component_map->{$table_moniker}; - push @methods, @{ Class::Inspector->methods('UNIVERSAL') }; + for my $c (@components) { + $c = $c =~ /^\+/ ? substr($c,1) : "DBIx::Class::$c"; + } - @result_methods{@methods} = (); + for my $class ($base, @components, $self->use_moose ? 'Moose::Object' : ()) { + load_class $class; - # futureproof meta - $result_methods{meta} = undef; - }; + push @methods, @{ Class::Inspector->methods($class) || [] }; + } - return exists $result_methods{$name}; + push @methods, @{ Class::Inspector->methods('UNIVERSAL') }; + + @methods{@methods} = (); + + # futureproof meta + $methods{meta} = undef; + + $self->_result_class_methods(\%methods); } + my $result_methods = $self->_result_class_methods; + + return exists $result_methods->{$name}; } sub _resolve_col_accessor_collisions { @@ -1615,7 +1680,7 @@ sub _resolve_col_accessor_collisions { next if $accessor eq 'id'; # special case (very common column) - if ($self->_is_result_class_method($accessor)) { + if ($self->_is_result_class_method($accessor, $table_name)) { my $mapped = 0; if (my $map = $self->col_collision_map) { @@ -1638,7 +1703,7 @@ EOF } } -# use the same logic to run moniker_map, column_accessor_map, and +# use the same logic to run moniker_map, col_accessor_map, and # relationship_name_map sub _run_user_map { my ( $self, $map, $default_code, $ident, @extra ) = @_; @@ -1676,7 +1741,7 @@ sub _make_column_accessor_name { my ($self, $column_name, $column_context_info ) = @_; my $accessor = $self->_run_user_map( - $self->column_accessor_map, + $self->col_accessor_map, sub { $self->_default_column_accessor_name( shift ) }, $column_name, $column_context_info,