Improved join condition possiblities - arrayrefs of hashrefs now work for OR
Matt S Trout [Sat, 14 Jan 2006 06:47:58 +0000 (06:47 +0000)]
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Storage/DBI.pm
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/ArtistUndirectedMap.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/BasicRels.pm
t/lib/DBICTest/Schema/HelperRels.pm
t/lib/DBICTest/Setup.pm
t/run/06relationship.tl

index 384e269..285d10f 100644 (file)
@@ -352,6 +352,8 @@ sub resolve_condition {
       }
     }
     return \%ret;
+  } elsif (ref $cond eq 'ARRAY') {
+    return [ map { $self->resolve_condition($_, $rel, $for) } @$cond ];
   } else {
    die("Can't handle this yet :(");
   }
index 5c858ec..d54b1c1 100644 (file)
@@ -114,10 +114,15 @@ sub _skip_options {
 
 sub _join_condition {
   my ($self, $cond) = @_;
-  die "no chance" unless ref $cond eq 'HASH';
-  my %j;
-  for (keys %$cond) { my $x = '= '.$self->_quote($cond->{$_}); $j{$_} = \$x; };
-  return $self->_recurse_where(\%j);
+  if (ref $cond eq 'HASH') {
+    my %j;
+    for (keys %$cond) { my $x = '= '.$self->_quote($cond->{$_}); $j{$_} = \$x; };
+    return $self->_recurse_where(\%j);
+  } elsif (ref $cond eq 'ARRAY') {
+    return join(' OR ', map { $self->_join_condition($_) } @$cond);
+  } else {
+    die "Can't handle this yet!";
+  }
 }
 
 sub _quote {
index 092c317..6f37ba9 100644 (file)
@@ -21,6 +21,7 @@ __PACKAGE__->load_classes(qw/
     'FourKeys',
     '#dummy',
     'SelfRef',
+    'ArtistUndirectedMap',
     'Producer',
     'CD_to_Producer',
   ),
diff --git a/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm b/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm
new file mode 100644 (file)
index 0000000..3c0a379
--- /dev/null
@@ -0,0 +1,9 @@
+package DBICTest::Schema::ArtistUndirectedMap;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('artist_undirected_map');
+__PACKAGE__->add_columns(qw/id1 id2/);
+__PACKAGE__->set_primary_key(qw/id1 id2/);
+
+1;
index 0d01ff9..a3e7279 100644 (file)
@@ -15,7 +15,15 @@ DBICTest::Schema::Artist->add_relationship(
     onekeys => 'DBICTest::Schema::OneKey',
     { 'foreign.artist' => 'self.artistid' }
 );
-
+DBICTest::Schema::Artist->add_relationship(
+    artist_undirected_maps => 'DBICTest::Schema::ArtistUndirectedMap',
+    [{'foreign.id1' => 'self.artistid'}, {'foreign.id2' => 'self.artistid'}],
+    { accessor => 'multi' }
+);
+DBICTest::Schema::ArtistUndirectedMap->add_relationship(
+    'mapped_artists', 'DBICTest::Schema::Artist',
+    [{'foreign.artistid' => 'self.id1'}, {'foreign.artistid' => 'self.id2'}]
+);
 DBICTest::Schema::CD->add_relationship(
     artist => 'DBICTest::Schema::Artist',
     { 'foreign.artistid' => 'self.artist' },
index bfd331d..4c7ea1d 100644 (file)
@@ -32,8 +32,25 @@ DBICTest::Schema::Track->belongs_to('disc', 'DBICTest::Schema::CD', 'cd');
 DBICTest::Schema::TwoKeys->belongs_to('artist', 'DBICTest::Schema::Artist');
 DBICTest::Schema::TwoKeys->belongs_to('cd', 'DBICTest::Schema::CD');
 
-DBICTest::Schema::CD_to_Producer->belongs_to('cd', 'DBICTest::Schema::CD', { 'foreign.cdid' => 'self.cd' });
-DBICTest::Schema::CD_to_Producer->belongs_to('producer', 'DBICTest::Schema::Producer', { 'foreign.producerid' => 'self.producer' });
+DBICTest::Schema::CD_to_Producer->belongs_to(
+  'cd', 'DBICTest::Schema::CD',
+  { 'foreign.cdid' => 'self.cd' }
+);
+DBICTest::Schema::CD_to_Producer->belongs_to(
+  'producer', 'DBICTest::Schema::Producer',
+  { 'foreign.producerid' => 'self.producer' }
+);
+DBICTest::Schema::Artist->has_many(
+  'artist_undirected_maps', 'DBICTest::Schema::ArtistUndirectedMap',
+  [{'foreign.id1' => 'self.artistid'}, {'foreign.id2' => 'self.artistid'}]
+);
+DBICTest::Schema::ArtistUndirectedMap->belongs_to(
+  'artist1', 'DBICTest::Schema::Artist', 'id1');
+DBICTest::Schema::ArtistUndirectedMap->belongs_to(
+  'artist2', 'DBICTest::Schema::Artist', 'id2');
+DBICTest::Schema::ArtistUndirectedMap->has_many(
+  'mapped_artists', 'DBICTest::Schema::Artist',
+  [{'foreign.artistid' => 'self.id1'}, {'foreign.artistid' => 'self.id2'}]);
 
 # now the Helpers
 DBICTest::Schema::CD->many_to_many( 'producers', 'cd_to_producer', 'producer');
index bcca718..94de234 100755 (executable)
@@ -44,6 +44,8 @@ CREATE TABLE self_ref (id INTEGER NOT NULL PRIMARY KEY,
 CREATE TABLE self_ref_alias (self_ref INTEGER NOT NULL, alias INTEGER NOT NULL,
                       PRIMARY KEY( self_ref, alias ) );
 
+CREATE TABLE artist_undirected_map (id1 INTEGER NOT NULL, id2 INTEGER NOT NULL, PRIMARY KEY(id1, id2));
+
 CREATE TABLE producer (producerid INTEGER NOT NULL PRIMARY KEY, name VARCHAR);
 
 CREATE TABLE cd_to_producer (cd INTEGER NOT NULL, producer INTEGER NOT NULL);
@@ -118,6 +120,8 @@ INSERT INTO self_ref (id, name) VALUES (2, 'Second');
 
 INSERT INTO self_ref_alias (self_ref, alias) VALUES (1, 2);
 
+INSERT INTO artist_undirected_map (id1, id2) VALUES (1, 2);
+
 INSERT INTO producer (producerid, name) VALUES (1, 'Matt S Trout');
 
 INSERT INTO cd_to_producer (cd, producer) VALUES (1, 1);
index 2ea31e4..57ff1f6 100644 (file)
@@ -1,6 +1,8 @@
 sub run_tests {
-  
-plan tests => 14;
+
+use strict;
+use warnings;  
+plan tests => 17;
 
 # has_a test
 my $cd = DBICTest->class("CD")->find(4);
@@ -109,6 +111,17 @@ $cd = DBICTest->class("CD")->find(1);
 my @producers = $cd->producers();
 is( $producers[0]->name, 'Matt S Trout', 'many_to_many ok' );
 
+# test undirected many-to-many relationship (e.g. "related artists")
+my $undir_maps = DBICTest->class("Artist")->find(1)->artist_undirected_maps;
+is($undir_maps->count, 1, 'found 1 undirected map for artist 1');
+
+$undir_maps = DBICTest->class("Artist")->find(2)->artist_undirected_maps;
+is($undir_maps->count, 1, 'found 1 undirected map for artist 2');
+
+my @art = $undir_maps->search_related('mapped_artists')->all;
+
+cmp_ok(@art, '==', 2, "Both artist returned from map");
+
 }
 
 1;