Commit | Line | Data |
c0024355 |
1 | package # Hide from PAUSE |
2 | DBIx::Class::SQLAHacks::Oracle; |
3 | |
9ab1e5f0 |
4 | use warnings; |
5 | use strict; |
6 | |
c0024355 |
7 | use base qw( DBIx::Class::SQLAHacks ); |
8 | use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/; |
9 | |
43426175 |
10 | # |
11 | # TODO: |
2df1857d |
12 | # - Review by experienced DBIC/SQL:A developers :-) |
2ba03b16 |
13 | # - Problem with count and connect_by look the TODO in t/73oracle.t |
43426175 |
14 | # |
15 | |
9ab1e5f0 |
16 | sub new { |
17 | my $self = shift; |
18 | my %opts = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_; |
19 | push @{$opts{special_ops}}, { |
20 | regex => qr/^prior$/i, |
21 | handler => '_where_field_PRIOR', |
22 | }; |
23 | |
24 | $self->SUPER::new (\%opts); |
25 | } |
26 | |
c0024355 |
27 | sub select { |
2e4dd241 |
28 | my ($self, $table, $fields, $where, $rs_attrs, @rest) = @_; |
c0024355 |
29 | |
5c810af7 |
30 | my $sql = $self->SUPER::select($table, $fields, $where, $rs_attrs, @rest); |
c0024355 |
31 | |
5c810af7 |
32 | return wantarray ? ($sql, @{$self->{from_bind}}, @{$self->{where_bind}}, @{$self->{_oracle_connect_by_binds}}, @{$self->{having_bind}}, @{$self->{order_bind}} ) : $sql; |
c0024355 |
33 | } |
34 | |
35 | sub _emulate_limit { |
2e4dd241 |
36 | my ( $self, $syntax, $sql, $rs_attrs, $rows, $offset ) = @_; |
c0024355 |
37 | |
2e4dd241 |
38 | my ($cb_sql, @cb_bind) = $self->_connect_by($rs_attrs); |
c0024355 |
39 | $sql .= $cb_sql; |
40 | $self->{_oracle_connect_by_binds} = \@cb_bind; |
41 | |
2e4dd241 |
42 | return $self->SUPER::_emulate_limit($syntax, $sql, $rs_attrs, $rows, $offset); |
c0024355 |
43 | } |
44 | |
45 | sub _connect_by { |
2e4dd241 |
46 | my ($self, $attrs) = @_; |
47 | |
c0024355 |
48 | my $sql = ''; |
49 | my @bind; |
50 | |
51 | if ( ref($attrs) eq 'HASH' ) { |
52 | if ( $attrs->{'start_with'} ) { |
53 | my ($ws, @wb) = $self->_recurse_where( $attrs->{'start_with'} ); |
54 | $sql .= $self->_sqlcase(' start with ') . $ws; |
55 | push @bind, @wb; |
56 | } |
6b2fbbf0 |
57 | if ( my $connect_by = $attrs->{'connect_by'} || $attrs->{'connect_by_nocycle'} ) { |
58 | my ($connect_by_sql, @connect_by_sql_bind) = $self->_recurse_where( $connect_by ); |
43426175 |
59 | $sql .= sprintf(" %s %s", |
ef5db928 |
60 | ( $attrs->{'connect_by_nocycle'} ) ? $self->_sqlcase('connect by nocycle') |
2ba03b16 |
61 | : $self->_sqlcase('connect by'), |
43426175 |
62 | $connect_by_sql, |
63 | ); |
64 | push @bind, @connect_by_sql_bind; |
c0024355 |
65 | } |
66 | if ( $attrs->{'order_siblings_by'} ) { |
67 | $sql .= $self->_order_siblings_by( $attrs->{'order_siblings_by'} ); |
68 | } |
69 | } |
70 | |
71 | return wantarray ? ($sql, @bind) : $sql; |
72 | } |
73 | |
74 | sub _order_siblings_by { |
2a770efe |
75 | my ( $self, $arg ) = @_; |
76 | |
77 | my ( @sql, @bind ); |
78 | for my $c ( $self->_order_by_chunks($arg) ) { |
79 | $self->_SWITCH_refkind( |
80 | $c, |
81 | { |
82 | SCALAR => sub { push @sql, $c }, |
83 | ARRAYREF => sub { push @sql, shift @$c; push @bind, @$c }, |
84 | } |
85 | ); |
86 | } |
c0024355 |
87 | |
2a770efe |
88 | my $sql = |
89 | @sql |
90 | ? sprintf( '%s %s', $self->_sqlcase(' order siblings by'), join( ', ', @sql ) ) |
91 | : ''; |
c0024355 |
92 | |
2a770efe |
93 | return wantarray ? ( $sql, @bind ) : $sql; |
c0024355 |
94 | } |
95 | |
9ab1e5f0 |
96 | # we need to add a '=' only when PRIOR is used against a column diretly |
97 | # i.e. when it is invoked by a special_op callback |
98 | sub _where_field_PRIOR { |
99 | my ($self, $lhs, $op, $rhs) = @_; |
100 | my ($sql, @bind) = $self->_recurse_where ($rhs); |
101 | |
102 | $sql = sprintf ('%s = %s %s ', |
103 | $self->_convert($self->_quote($lhs)), |
104 | $self->_sqlcase ($op), |
105 | $sql |
106 | ); |
107 | |
108 | return ($sql, @bind); |
109 | } |
110 | |
c0024355 |
111 | 1; |
112 | |
113 | __END__ |
114 | |
115 | =pod |
116 | |
117 | =head1 NAME |
118 | |
119 | DBIx::Class::SQLAHacks::Oracle - adds hierarchical query support for Oracle to SQL::Abstract |
120 | |
121 | =head1 DESCRIPTION |
122 | |
123 | See L<DBIx::Class::Storage::DBI::Oracle::Generic> for more informations about |
124 | how to use hierarchical queries with DBIx::Class. |
125 | |
126 | =cut |