Merged andyg's fixes to joins and joins tests. Added -sql_type => 'xxx' option, added...
Andres Kievsky [Sun, 4 Sep 2005 20:21:22 +0000 (20:21 +0000)]
lib/DBIx/Class/Storage/DBI.pm
t/16joins.t [new file with mode: 0644]

index a873d2b..8b35adb 100644 (file)
@@ -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 (file)
index 0000000..7360213
--- /dev/null
@@ -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');