From: Matt S Trout Date: Sat, 14 Jan 2006 06:47:58 +0000 (+0000) Subject: Improved join condition possiblities - arrayrefs of hashrefs now work for OR X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5efe4c7916e1fb2132c1b73ab4ddddbced317adb;p=dbsrgits%2FDBIx-Class-Historic.git Improved join condition possiblities - arrayrefs of hashrefs now work for OR --- diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 384e269..285d10f 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -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 :("); } diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 5c858ec..d54b1c1 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -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 { diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm index 092c317..6f37ba9 100644 --- a/t/lib/DBICTest/Schema.pm +++ b/t/lib/DBICTest/Schema.pm @@ -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 index 0000000..3c0a379 --- /dev/null +++ b/t/lib/DBICTest/Schema/ArtistUndirectedMap.pm @@ -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; diff --git a/t/lib/DBICTest/Schema/BasicRels.pm b/t/lib/DBICTest/Schema/BasicRels.pm index 0d01ff9..a3e7279 100644 --- a/t/lib/DBICTest/Schema/BasicRels.pm +++ b/t/lib/DBICTest/Schema/BasicRels.pm @@ -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' }, diff --git a/t/lib/DBICTest/Schema/HelperRels.pm b/t/lib/DBICTest/Schema/HelperRels.pm index bfd331d..4c7ea1d 100644 --- a/t/lib/DBICTest/Schema/HelperRels.pm +++ b/t/lib/DBICTest/Schema/HelperRels.pm @@ -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'); diff --git a/t/lib/DBICTest/Setup.pm b/t/lib/DBICTest/Setup.pm index bcca718..94de234 100755 --- a/t/lib/DBICTest/Setup.pm +++ b/t/lib/DBICTest/Setup.pm @@ -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); diff --git a/t/run/06relationship.tl b/t/run/06relationship.tl index 2ea31e4..57ff1f6 100644 --- a/t/run/06relationship.tl +++ b/t/run/06relationship.tl @@ -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;