X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=2b347ed3e473c2dc25abf51dcbf89facdbb28224;hb=c079518f7bbe43998aae31cead6127b3b85be92e;hp=5575a0a925ca16108122c18996f9af8b3940dcef;hpb=e5f4d2a612ba63dacaaf94c125840ed00f66bf03;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 5575a0a..2b347ed 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -196,44 +196,44 @@ call it as C. sub search { my $self = shift; - - my $rs; - if( @_ ) { - my $attrs = { %{$self->{attrs}} }; - my $having = delete $attrs->{having}; - $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH'; - - my $where = (@_ - ? ((@_ == 1 || ref $_[0] eq "HASH") - ? shift - : ((@_ % 2) - ? $self->throw_exception( - "Odd number of arguments to search") - : {@_})) - : undef()); - if (defined $where) { - $attrs->{where} = (defined $attrs->{where} - ? { '-and' => - [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ } - $where, $attrs->{where} ] } - : $where); - } - - if (defined $having) { - $attrs->{having} = (defined $attrs->{having} - ? { '-and' => - [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ } - $having, $attrs->{having} ] } - : $having); - } + my $attrs = { %{$self->{attrs}} }; + my $having = delete $attrs->{having}; + $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH'; + + my $where = (@_ + ? ((@_ == 1 || ref $_[0] eq "HASH") + ? shift + : ((@_ % 2) + ? $self->throw_exception( + "Odd number of arguments to search") + : {@_})) + : undef()); + if (defined $where) { + $attrs->{where} = (defined $attrs->{where} + ? { '-and' => + [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ } + $where, $attrs->{where} ] } + : $where); + } - $rs = (ref $self)->new($self->result_source, $attrs); + if (defined $having) { + $attrs->{having} = (defined $attrs->{having} + ? { '-and' => + [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ } + $having, $attrs->{having} ] } + : $having); } - else { - $rs = $self; - $rs->reset; + + my $rs = (ref $self)->new($self->result_source, $attrs); + + unless (@_) { # no search, effectively just a clone + my $rows = $self->get_cache; + if( @{$rows} ) { + $rs->set_cache($rows); + } } + return (wantarray ? $rs->all : $rs); } @@ -277,8 +277,8 @@ a row by its primary key: my $cd = $schema->resultset('CD')->find(5); -You can also find a row by a specific key or unique constraint by specifying -the C attribute. For example: +You can also find a row by a specific unique constraint using the C +attribute. For example: my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', { key => 'artist_title' }); @@ -304,63 +304,54 @@ L. =cut sub find { - my ($self, @vals) = @_; - my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {}); - - 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; - - $self->throw_exception( - "Unknown key $attrs->{key} on '" . $self->result_source->name . "'" - ) if (exists $attrs->{key} and not exists $unique_constraints{$attrs->{key}}); - - # Build a list of queries - my @unique_hashes; - - if (ref $vals[0] eq 'HASH') { - my @constraint_names = exists $attrs->{key} - ? ($attrs->{key}) - : keys %unique_constraints; + my $self = shift; + my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); - foreach my $name (@constraint_names) { - my @unique_cols = @{ $unique_constraints{$name} }; - my $unique_hash = $self->_unique_hash($vals[0], \@unique_cols); + # Parse out a hash from input + my @cols = exists $attrs->{key} + ? $self->result_source->unique_constraint_columns($attrs->{key}) + : $self->result_source->primary_columns; - # TODO: Check that the ResultSet defines the rest of the query - push @unique_hashes, $unique_hash - if scalar keys %$unique_hash;# == scalar @unique_cols; - } + my $hash; + if (ref $_[0] eq 'HASH') { + $hash = { %{$_[0]} }; + } + elsif (@_ == @cols) { + $hash = {}; + @{$hash}{@cols} = @_; } else { - my @unique_cols = exists $attrs->{key} - ? @{ $unique_constraints{$attrs->{key}} } - : $self->result_source->primary_columns; + $self->throw_exception( + "Arguments to find must be a hashref or match the number of columns in the " + . exists $attrs->{key} ? "$attrs->{key} unique constraint" : "primary key" + ); + } - if (@vals == @unique_cols) { - my %unique_hash; - @unique_hash{@unique_cols} = @vals; + # Check the hash we just parsed against our source's unique constraints + my @constraint_names = exists $attrs->{key} + ? ($attrs->{key}) + : $self->result_source->unique_constraint_names; + $self->throw_exception( + "Can't find unless a primary key or unique constraint is defined" + ) unless @constraint_names; - push @unique_hashes, \%unique_hash; - } - else { - # Hack for CDBI queries - my %hash = @vals; - push @unique_hashes, \%hash; - } - } + my @unique_queries; + foreach my $name (@constraint_names) { + my @unique_cols = $self->result_source->unique_constraint_columns($name); + my $unique_query = $self->_build_unique_query($hash, \@unique_cols); - # Add the ResultSet's alias - foreach my $unique_hash (@unique_hashes) { - foreach my $key (grep { ! m/\./ } keys %$unique_hash) { - $unique_hash->{"$self->{attrs}{alias}.$key"} = delete $unique_hash->{$key}; + # Add the ResultSet's alias + foreach my $key (grep { ! m/\./ } keys %$unique_query) { + $unique_query->{"$self->{attrs}{alias}.$key"} = delete $unique_query->{$key}; } + + push @unique_queries, $unique_query if %$unique_query; } # Handle cases where the ResultSet already defines the query - my $query = @unique_hashes ? \@unique_hashes : undef; + my $query = @unique_queries ? \@unique_queries : undef; + # Run the query if (keys %$attrs) { my $rs = $self->search($query, $attrs); return keys %{$rs->{collapse}} ? $rs->next : $rs->single; @@ -372,26 +363,19 @@ sub find { } } -# _unique_hash +# _build_unique_query # -# Constrain the specified hash based on the specific column names. - -sub _unique_hash { - my ($self, $hash, $unique_cols) = @_; +# Constrain the specified query hash based on the specified column names. - # Ugh, CDBI lowercases column names - if (exists $INC{'DBIx/Class/CDBICompat/ColumnCase.pm'}) { - foreach my $key (keys %$hash) { - $hash->{lc $key} = delete $hash->{$key}; - } - } +sub _build_unique_query { + my ($self, $query, $unique_cols) = @_; - my %unique_hash = - map { $_ => $hash->{$_} } - grep { exists $hash->{$_} } + my %unique_query = + map { $_ => $query->{$_} } + grep { exists $query->{$_} } @$unique_cols; - return \%unique_hash; + return \%unique_query; } =head2 search_related