From: Andres Kievsky Date: Sun, 4 Sep 2005 20:21:22 +0000 (+0000) Subject: Merged andyg's fixes to joins and joins tests. Added -sql_type => 'xxx' option, added... X-Git-Tag: v0.03001~18^2~8 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=73856587c4eb3b77e0906414a1a8a67f27186e24;p=dbsrgits%2FDBIx-Class.git Merged andyg's fixes to joins and joins tests. Added -sql_type => 'xxx' option, added test. --- diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index a873d2b..8b35adb 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -34,11 +34,20 @@ sub _recurse_from { push(@sqlf, $self->_make_as($from)); foreach my $j (@join) { my ($to, $on) = @$j; - push(@sqlf, ' JOIN '); + + # check whether a join type exists + my $join_clause = ''; + if (ref($to) eq 'HASH' and exists($to->{-join_type})) { + $join_clause = ' '.uc($to->{-join_type}).' JOIN '; + } else { + $join_clause = ' JOIN '; + } + push(@sqlf, $join_clause); + if (ref $to eq 'ARRAY') { push(@sqlf, '(', $self->_recurse_from(@$to), ')'); } else { - push(@sqlf, $self->_make_as($to)); + push(@sqlf, '(', $self->_make_as($to), ')'); } push(@sqlf, ' ON ', $self->_join_condition($on)); } @@ -47,7 +56,15 @@ sub _recurse_from { sub _make_as { my ($self, $from) = @_; - return join(' ', reverse each %$from); + return join(' AS ', reverse each %{$self->_skip_options($from)}); +} + +sub _skip_options { + my ($self, $hash) = @_; + my $clean_hash = {}; + $clean_hash->{$_} = $hash->{$_} + for grep {!/^-/} keys %$hash; + return $clean_hash; } sub _join_condition { diff --git a/t/16joins.t b/t/16joins.t new file mode 100644 index 0000000..7360213 --- /dev/null +++ b/t/16joins.t @@ -0,0 +1,55 @@ +use strict; +use Test::More; + +BEGIN { + eval "use DBD::SQLite"; + plan $@ + ? ( skip_all => 'needs DBD::SQLite for testing' ) + : ( tests => 4 ); +} + +use lib qw(t/lib); + +use_ok('DBICTest'); + +# test the abstract join => SQL generator +my $sa = new DBIC::SQL::Abstract; + +my @j = ( + { child => 'person' }, + [ { father => 'person' }, { 'father.person_id' => 'child.father_id' }, ], + [ { mother => 'person' }, { 'mother.person_id' => 'child.mother_id' } ], +); +my $match = 'person AS child JOIN (person AS father) ON ( father.person_id = ' + . 'child.father_id ) JOIN (person AS mother) ON ( mother.person_id ' + . '= child.mother_id )' + ; +is( $sa->_recurse_from(@j), $match, 'join 1 ok' ); + +my @j2 = ( + { mother => 'person' }, + [ [ { child => 'person' }, + [ { father => 'person' }, + { 'father.person_id' => 'child.father_id' } + ] + ], + { 'mother.person_id' => 'child.mother_id' } + ], +); +$match = 'person AS mother JOIN (person AS child JOIN (person AS father) ON (' + . ' father.person_id = child.father_id )) ON ( mother.person_id = ' + . 'child.mother_id )' + ; +is( $sa->_recurse_from(@j2), $match, 'join 2 ok' ); + +my @j3 = ( + { child => 'person' }, + [ { father => 'person', -join_type => 'inner' }, { 'father.person_id' => 'child.father_id' }, ], + [ { mother => 'person', -join_type => 'inner' }, { 'mother.person_id' => 'child.mother_id' } ], +); +my $match = 'person AS child INNER JOIN (person AS father) ON ( father.person_id = ' + . 'child.father_id ) INNER JOIN (person AS mother) ON ( mother.person_id ' + . '= child.mother_id )' + ; + +is( $sa->_recurse_from(@j3), $match, 'join 3 (inner join) ok');