File Coverage

blib/lib/DBIx/Class/SQLMaker/OracleJoins.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package DBIx::Class::SQLMaker::OracleJoins;
2              
3 2     2   14 use warnings;
  2         4  
  2         65  
4 2     2   11 use strict;
  2         4  
  2         57  
5              
6 2     2   9 use base qw( DBIx::Class::SQLMaker::Oracle );
  2         5  
  2         782  
7              
8             sub select {
9             my ($self, $table, $fields, $where, $rs_attrs, @rest) = @_;
10              
11             # pull out all join conds as regular WHEREs from all extra tables
12             if (ref($table) eq 'ARRAY') {
13             $where = $self->_oracle_joins($where, @{ $table }[ 1 .. $#$table ]);
14             }
15              
16             return $self->next::method($table, $fields, $where, $rs_attrs, @rest);
17             }
18              
19             sub _recurse_from {
20             my ($self, $from, @join) = @_;
21              
22             my @sqlf = $self->_from_chunk_to_sql($from);
23              
24             for (@join) {
25             my ($to, $on) = @$_;
26              
27             if (ref $to eq 'ARRAY') {
28             push (@sqlf, $self->_recurse_from(@{ $to }));
29             }
30             else {
31             push (@sqlf, $self->_from_chunk_to_sql($to));
32             }
33             }
34              
35             return join q{, }, @sqlf;
36             }
37              
38             sub _oracle_joins {
39             my ($self, $where, @join) = @_;
40             my $join_where = $self->_recurse_oracle_joins(@join);
41              
42             if (keys %$join_where) {
43             if (!defined($where)) {
44             $where = $join_where;
45             } else {
46             if (ref($where) eq 'ARRAY') {
47             $where = { -or => $where };
48             }
49             $where = { -and => [ $join_where, $where ] };
50             }
51             }
52             return $where;
53             }
54              
55             sub _recurse_oracle_joins {
56             my $self = shift;
57              
58             my @where;
59             for my $j (@_) {
60             my ($to, $on) = @{ $j };
61              
62             push @where, $self->_recurse_oracle_joins(@{ $to })
63             if (ref $to eq 'ARRAY');
64              
65             my $join_opts = ref $to eq 'ARRAY' ? $to->[0] : $to;
66             my $left_join = q{};
67             my $right_join = q{};
68              
69             if (ref $join_opts eq 'HASH' and my $jt = $join_opts->{-join_type}) {
70             #TODO: Support full outer joins -- this would happen much earlier in
71             #the sequence since oracle 8's full outer join syntax is best
72             #described as INSANE.
73             $self->throw_exception("Can't handle full outer joins in Oracle 8 yet!\n")
74             if $jt =~ /full/i;
75              
76             $left_join = q{(+)} if $jt =~ /left/i
77             && $jt !~ /inner/i;
78              
79             $right_join = q{(+)} if $jt =~ /right/i
80             && $jt !~ /inner/i;
81             }
82              
83             # FIXME - the code below *UTTERLY* doesn't work with custom conds... sigh
84             # for the time being do not do any processing with the likes of _collapse_cond
85             # instead only unroll the -and hack if present
86             $on = $on->{-and}[0] if (
87             ref $on eq 'HASH'
88             and
89             keys %$on == 1
90             and
91             ref $on->{-and} eq 'ARRAY'
92             and
93             @{$on->{-and}} == 1
94             );
95              
96              
97             push @where, map { \do {
98             my ($sql) = $self->_recurse_where({
99             # FIXME - more borkage, more or less a copy of the kludge in ::SQLMaker::_join_condition()
100             $_ => ( length ref $on->{$_}
101             ? $on->{$_}
102             : { -ident => $on->{$_} }
103             )
104             });
105              
106             $sql =~ s/\s*\=/$left_join =/
107             if $left_join;
108              
109             "$sql$right_join";
110             }
111             } sort keys %$on;
112             }
113              
114             return { -and => \@where };
115             }
116              
117             1;
118              
119             __END__