1 package #hide from PAUSE
2 DBIx::Class::ResultSource::FromSpec::Util;
10 find_join_path_to_alias
13 use Scalar::Util 'blessed';
15 # Takes $fromspec, \@column_names
17 # returns { $column_name => \%column_info, ... } for fully qualified and
18 # where possible also unqualified variants
19 # also note: this adds -result_source => $rsrc to the column info
21 # If no columns_names are supplied returns info about *all* columns
23 sub fromspec_columns_info {
24 my ($fromspec, $colnames) = @_;
26 return {} if $colnames and ! @$colnames;
29 # this is compat mode for insert/update/delete which do not deal with aliases
33 $fromspec->isa('DBIx::Class::ResultSource')
34 ) ? +{ me => $fromspec }
36 # not a known fromspec - no columns to resolve: return directly
37 : ref($fromspec) ne 'ARRAY' ? return +{}
40 # otherwise decompose into alias/rsrc pairs
43 ( $_->{-rsrc} and $_->{-alias} )
44 ? ( @{$_}{qw( -alias -rsrc )} )
49 ( ref $_ eq 'ARRAY' and ref $_->[0] eq 'HASH' ) ? $_->[0]
50 : ( ref $_ eq 'HASH' ) ? $_
57 $_ = { rsrc => $_, colinfos => $_->columns_info }
60 my (%seen_cols, @auto_colnames);
62 # compile a global list of column names, to be able to properly
63 # disambiguate unqualified column names (if at all possible)
64 for my $alias (keys %$sources) {
66 ++$seen_cols{$_}{$alias}
70 push @auto_colnames, "$alias.$_"
71 ) for keys %{ $sources->{$alias}{colinfos} };
76 ( grep { keys %{$seen_cols{$_}} == 1 } keys %seen_cols ),
81 my ($colname, $source_alias) = reverse split /\./, $_;
86 # if the column was seen exactly once - we know which rsrc it came from
90 keys %{$seen_cols{$colname}} == 1
92 ( %{$seen_cols{$colname}} )[0]
98 DBIx::Class::Exception->throw(
99 "No such column '$colname' on source " . $sources->{$assumed_alias}{rsrc}->source_name
100 ) unless $seen_cols{$colname}{$assumed_alias};
103 %{ $sources->{$assumed_alias}{colinfos}{$colname} },
104 -result_source => $sources->{$assumed_alias}{rsrc},
105 -source_alias => $assumed_alias,
106 -fq_colname => "$assumed_alias.$colname",
107 -colname => $colname,
110 $return{"$assumed_alias.$colname"} = $return{$_}
111 unless $source_alias;
117 sub find_join_path_to_alias {
118 my ($fromspec, $target_alias) = @_;
120 # subqueries and other oddness are naturally not supported
122 ref $fromspec ne 'ARRAY'
124 ref $fromspec->[0] ne 'HASH'
126 ! defined $fromspec->[0]{-alias}
129 # no path - the head *is* the alias
130 return [] if $fromspec->[0]{-alias} eq $target_alias;
132 for my $i (1 .. $#$fromspec) {
133 return $fromspec->[$i][0]{-join_path} if ( ($fromspec->[$i][0]{-alias}||'') eq $target_alias );
136 # something else went quite wrong