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));
}
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 {
--- /dev/null
+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');