File Coverage

blib/lib/DBIx/Class/Relationship/Accessor.pm
Criterion Covered Total %
statement 37 38 97.3
branch 12 16 75.0
condition 3 3 100.0
subroutine 9 9 100.0
pod 0 2 0.0
total 61 68 89.7


line stmt bran cond sub pod time code
1             package # hide from PAUSE
2             DBIx::Class::Relationship::Accessor;
3              
4 379     379   186591 use strict;
  379         12855  
  379         11894  
5 379     379   2484 use warnings;
  379         13452  
  379         12796  
6 379     379   2484 use DBIx::Class::Carp;
  379         1031  
  379         2403  
7 379     379   2671 use DBIx::Class::_Util qw(quote_sub perlstring);
  379         1193  
  379         23199  
8 379     379   2642 use namespace::clean;
  379         1198  
  379         2590  
9              
10             our %_pod_inherit_config =
11             (
12             class_map => { 'DBIx::Class::Relationship::Accessor' => 'DBIx::Class::Relationship' }
13             );
14              
15             sub register_relationship {
16 29086     29086 0 65637 my ($class, $rel, $info) = @_;
17 29086 100       80306 if (my $acc_type = $info->{attrs}{accessor}) {
18 29083         117246 $class->add_relationship_accessor($rel => $acc_type);
19             }
20 29086         3049120 $class->next::method($rel => $info);
21             }
22              
23             sub add_relationship_accessor {
24 29083     29083 0 59862 my ($class, $rel, $acc_type) = @_;
25              
26 29083 100       86733 if ($acc_type eq 'single') {
    100          
    50          
27 11196         48236 quote_sub "${class}::${rel}" => sprintf(<<'EOC', perlstring $rel);
28             my $self = shift;
29              
30             if (@_) {
31             $self->set_from_related( %1$s => @_ );
32             return $self->{_relationship_data}{%1$s} = $_[0];
33             }
34             elsif (exists $self->{_relationship_data}{%1$s}) {
35             return $self->{_relationship_data}{%1$s};
36             }
37             else {
38             my $relcond = $self->result_source->_resolve_relationship_condition(
39             rel_name => %1$s,
40             foreign_alias => %1$s,
41             self_alias => 'me',
42             self_result_object => $self,
43             );
44              
45             return undef if (
46             $relcond->{join_free_condition}
47             and
48             $relcond->{join_free_condition} ne DBIx::Class::_Util::UNRESOLVABLE_CONDITION
49             and
50             scalar grep { not defined $_ } values %%{ $relcond->{join_free_condition} || {} }
51             and
52             $self->result_source->relationship_info(%1$s)->{attrs}{undef_on_null_fk}
53             );
54              
55             my $val = $self->search_related( %1$s )->single;
56             return $val unless $val; # $val instead of undef so that null-objects can go through
57              
58             return $self->{_relationship_data}{%1$s} = $val;
59             }
60             EOC
61             }
62             elsif ($acc_type eq 'filter') {
63 5559 50       112742 $class->throw_exception("No such column '$rel' to filter")
64             unless $class->has_column($rel);
65              
66 5559         135526 my $f_class = $class->relationship_info($rel)->{class};
67              
68             $class->inflate_column($rel, {
69             inflate => sub {
70 310     310   672 my ($val, $self) = @_;
71 310         1494 return $self->find_or_new_related($rel, {}, {});
72             },
73             deflate => sub {
74 125     125   360 my ($val, $self) = @_;
75 125 50       1085 $self->throw_exception("'$val' isn't a $f_class") unless $val->isa($f_class);
76              
77             # MASSIVE FIXME - this code assumes we pointed at the PK, but the belongs_to
78             # helper does not check any of this
79             # fixup the code a bit to make things saner, but ideally 'filter' needs to
80             # be deprecated ASAP and removed shortly after
81             # Not doing so before 0.08250 however, too many things in motion already
82 125         551 my ($pk_col, @rest) = $val->result_source->_pri_cols_or_die;
83 125 50       456 $self->throw_exception(
84             "Relationship '$rel' of type 'filter' can not work with a multicolumn primary key on source '$f_class'"
85             ) if @rest;
86              
87 125         941 my $pk_val = $val->get_column($pk_col);
88 125 100 100     678 carp_unique (
89             "Unable to deflate 'filter'-type relationship '$rel' (related object "
90             . "primary key not retrieved), assuming undef instead"
91             ) if ( ! defined $pk_val and $val->in_storage );
92              
93 125         826 return $pk_val;
94             },
95 5559         91301 });
96             }
97             elsif ($acc_type eq 'multi') {
98              
99 12328         72599 quote_sub "${class}::${rel}_rs", "shift->search_related_rs( $rel => \@_ )";
100 12328         1688634 quote_sub "${class}::add_to_${rel}", "shift->create_related( $rel => \@_ )";
101 12328         1496380 quote_sub "${class}::${rel}", sprintf( <<'EOC', perlstring $rel );
102             DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = DBIx::Class::_Util::fail_on_internal_wantarray;
103             shift->search_related( %s => @_ )
104             EOC
105             }
106             else {
107 0           $class->throw_exception("No such relationship accessor type '$acc_type'");
108             }
109              
110             }
111              
112             1;