X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRelationship%2FAccessor.pm;h=9d4d378ce1d747714b7eb146593b4745e7ea578a;hb=09d2e66a5d5558ef9a19dc2ec510d5dafd2fb7d8;hp=fae251ee61c8d903c42bd68bbed64c5f24ee2d03;hpb=e50536940adf2ebaef907a0c29ae37fbd5ce95b1;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Relationship/Accessor.pm b/lib/DBIx/Class/Relationship/Accessor.pm index fae251e..9d4d378 100644 --- a/lib/DBIx/Class/Relationship/Accessor.pm +++ b/lib/DBIx/Class/Relationship/Accessor.pm @@ -24,7 +24,16 @@ sub add_relationship_accessor { my ($class, $rel, $acc_type) = @_; if ($acc_type eq 'single') { - quote_sub "${class}::${rel}" => sprintf(<<'EOC', perlstring $rel); + + my @qsub_args = ( {}, { + attributes => [qw( + DBIC_method_is_single_relationship_accessor + DBIC_method_is_generated_from_resultsource_metadata + )] + }); + + + quote_sub "${class}::${rel}" => sprintf(<<'EOC', perlstring $rel), @qsub_args; my $self = shift; if (@_) { @@ -37,21 +46,28 @@ sub add_relationship_accessor { else { my $rsrc = $self->result_source; - my $relcond = $rsrc->_resolve_relationship_condition( - rel_name => %1$s, - foreign_alias => %1$s, - self_alias => 'me', - self_result_object => $self, - ); + my $jfc; return undef if ( - $relcond->{join_free_condition} + + $rsrc->relationship_info(%1$s)->{attrs}{undef_on_null_fk} + and - $relcond->{join_free_condition} ne DBIx::Class::_Util::UNRESOLVABLE_CONDITION + + $jfc = ( $rsrc->_resolve_relationship_condition( + rel_name => %1$s, + foreign_alias => %1$s, + self_alias => 'me', + self_result_object => $self, + )->{join_free_condition} || {} ) + and - scalar grep { not defined $_ } values %%{ $relcond->{join_free_condition} || {} } + + $jfc ne DBIx::Class::_Util::UNRESOLVABLE_CONDITION + and - $rsrc->relationship_info(%1$s)->{attrs}{undef_on_null_fk} + + grep { not defined $_ } values %%$jfc ); my $val = $self->related_resultset( %1$s )->single; @@ -62,12 +78,13 @@ sub add_relationship_accessor { EOC } elsif ($acc_type eq 'filter') { - $class->throw_exception("No such column '$rel' to filter") - unless $class->result_source_instance->has_column($rel); - my $f_class = $class->result_source_instance - ->relationship_info($rel) - ->{class}; + my $rsrc = $class->result_source_instance; + + $rsrc->throw_exception("No such column '$rel' to filter") + unless $rsrc->has_column($rel); + + my $f_class = $rsrc->relationship_info($rel)->{class}; $class->inflate_column($rel, { inflate => sub { @@ -97,15 +114,77 @@ EOC return $pk_val; }, }); + + + # god this is horrible... + my $acc = + $rsrc->columns_info->{$rel}{accessor} + || + $rel + ; + + # because CDBI may elect to never make an accessor at all... + if( my $main_cref = $class->can($acc) ) { + + attributes->import( + $class, + $main_cref, + qw( + DBIC_method_is_filter_relationship_accessor + DBIC_method_is_generated_from_resultsource_metadata + ), + ); + + if( my $extra_cref = $class->can("_${acc}_accessor") ) { + attributes->import( + $class, + $extra_cref, + qw( + DBIC_method_is_filter_relationship_extra_accessor + DBIC_method_is_generated_from_resultsource_metadata + ), + ); + } + } } elsif ($acc_type eq 'multi') { - quote_sub "${class}::${rel}_rs", "shift->related_resultset('$rel')->search_rs( \@_ )"; - quote_sub "${class}::add_to_${rel}", "shift->related_resultset('$rel')->new_result( \@_ )->insert"; - quote_sub "${class}::${rel}", sprintf( <<'EOC', perlstring $rel ); + + my @qsub_args = ( + {}, + { + attributes => [qw( + DBIC_method_is_multi_relationship_accessor + DBIC_method_is_generated_from_resultsource_metadata + DBIC_method_is_indirect_sugar + )] + }, + ); + + + quote_sub "${class}::${rel}", sprintf( <<'EOC', perlstring $rel ), @qsub_args; + DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and DBIx::Class::_Util::fail_on_internal_call; DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = DBIx::Class::_Util::fail_on_internal_wantarray; shift->related_resultset(%s)->search( @_ ) EOC + + + $qsub_args[1]{attributes}[0] + =~ s/^DBIC_method_is_multi_relationship_accessor$/DBIC_method_is_multi_relationship_extra_accessor/ + or die "Unexpected attr '$qsub_args[1]{attributes}[0]' ..."; + + + quote_sub "${class}::${rel}_rs", sprintf( <<'EOC', perlstring $rel ), @qsub_args; + DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and DBIx::Class::_Util::fail_on_internal_call; + shift->related_resultset(%s)->search_rs( @_ ) +EOC + + + quote_sub "${class}::add_to_${rel}", sprintf( <<'EOC', perlstring $rel ), @qsub_args; + DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and DBIx::Class::_Util::fail_on_internal_call; + shift->create_related( %s => @_ ); +EOC + } else { $class->throw_exception("No such relationship accessor type '$acc_type'");