From: Daniel Westermann-Clark Date: Sat, 8 Apr 2006 19:06:30 +0000 (-0400) Subject: First pass at reimplementation X-Git-Tag: v0.07002~75^2~237^2~23 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8dc40f3efa5b88acd00c49165521aa620282a282;p=dbsrgits%2FDBIx-Class.git First pass at reimplementation --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 3541516..323abf4 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -295,40 +295,57 @@ sub find { my ($self, @vals) = @_; my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {}); - my @cols = $self->result_source->primary_columns; + my %unique_constraints = $self->result_source->unique_constraints; + $self->throw_exception( + "Can't find unless a primary key or unique constraint is defined" + ) unless %unique_constraints; + + my @constraint_names = keys %unique_constraints; if (exists $attrs->{key}) { - my %uniq = $self->result_source->unique_constraints; $self->throw_exception( "Unknown key $attrs->{key} on '" . $self->result_source->name . "'" - ) unless exists $uniq{$attrs->{key}}; - @cols = @{ $uniq{$attrs->{key}} }; - } - #use Data::Dumper; warn Dumper($attrs, @vals, @cols); - $self->throw_exception( - "Can't find unless a primary key or unique constraint is defined" - ) unless @cols; - - my $query; - if (ref $vals[0] eq 'HASH') { - $query = { %{$vals[0]} }; - } elsif (@cols == @vals) { - $query = {}; - @{$query}{@cols} = @vals; - } else { - $query = {@vals}; + ) unless exists $unique_constraints{$attrs->{key}}; + + @constraint_names = ($attrs->{key}); } - foreach my $key (grep { ! m/\./ } keys %$query) { - $query->{"$self->{attrs}{alias}.$key"} = delete $query->{$key}; + + my @unique_hashes; + foreach my $name (@constraint_names) { + my @unique_cols = @{ $unique_constraints{$name} }; + my %unique_hash; + if (ref $vals[0] eq 'HASH') { + %unique_hash = + map { $_ => $vals[0]->{$_} } + grep { exists $vals[0]->{$_} } + @unique_cols; + } + elsif (scalar @unique_cols == scalar @vals) { + # Assume the argument order corresponds to the constraint definition + @unique_hash{@unique_cols} = @vals; + } + elsif (scalar @vals % 2 == 0) { + # Fix for CDBI calling with a hash + %unique_hash = @vals; + } + + foreach my $key (grep { ! m/\./ } keys %unique_hash) { + $unique_hash{"$self->{attrs}{alias}.$key"} = delete $unique_hash{$key}; + } + + #use Data::Dumper; warn Dumper \@vals, \@unique_cols, \%unique_hash; + push @unique_hashes, \%unique_hash if %unique_hash; } - #warn Dumper($query); - + + # Handle cases where the ResultSet already defines the query + my $query = @unique_hashes ? \@unique_hashes : undef; + if (keys %$attrs) { - my $rs = $self->search($query,$attrs); - return keys %{$rs->{collapse}} ? $rs->next : $rs->single; + my $rs = $self->search($query,$attrs); + return keys %{$rs->{collapse}} ? $rs->next : $rs->single; } else { - return keys %{$self->{collapse}} ? - $self->search($query)->next : - $self->single($query); + return keys %{$self->{collapse}} + ? $self->search($query)->next + : $self->single($query); } } diff --git a/t/run/20unique.tl b/t/run/20unique.tl index eb747eb..024f09f 100644 --- a/t/run/20unique.tl +++ b/t/run/20unique.tl @@ -1,7 +1,7 @@ sub run_tests { my $schema = shift; -plan tests => 18; +plan tests => 26; my $artistid = 1; my $title = 'UNIQUE Constraint'; @@ -69,6 +69,35 @@ is($cd5->get_column('artist'), $cd2->get_column('artist'), 'artist is correct'); is($cd5->title, $cd2->title, 'title is correct'); is($cd5->year, 2005, 'updated year is correct'); +my $cd6 = $schema->resultset('CD')->find_or_create( + { + artist => $artistid, + title => $title, + year => 2010, + }, + { key => 'artist_title' } +); + +is($cd6->cdid, $cd1->cdid, 'find or create by specific key: cdid is correct'); +is($cd6->get_column('artist'), $cd1->get_column('artist'), 'artist is correct'); +is($cd6->title, $cd1->title, 'title is correct'); +is($cd6->year, $cd1->year, 'year is correct'); + +my $artist = $schema->resultset('Artist')->find($artistid); +my $cd7 = $artist->find_or_create_related('cds', + { + artist => $artistid, + title => $title, + year => 2020, + }, + { key => 'artist_title' } +); + +is($cd7->cdid, $cd1->cdid, 'find or create related by specific key: cdid is correct'); +is($cd7->get_column('artist'), $cd1->get_column('artist'), 'artist is correct'); +is($cd7->title, $cd1->title, 'title is correct'); +is($cd7->year, $cd1->year, 'year is correct'); + } 1;