X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=089972e8cb5ef688a2bfba5bae71a2a362959868;hb=61e5345d84813dc974f6afa94c9bc864cff9fbc1;hp=1e976db7b54e73e206c5477061234f4a34d0ab62;hpb=b4e9f590228d1d73d4089c2ec88372e683e17aeb;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 1e976db..089972e 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -221,7 +221,7 @@ sub new { =item Arguments: $cond, \%attrs? -=item Return Value: $resultset (scalar context), @row_objs (list context) +=item Return Value: $resultset (scalar context) || @row_objs (list context) =back @@ -231,6 +231,9 @@ sub new { my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]); # year = 2005 OR year = 2004 +In list context, C<< ->all() >> is called implicitly on the resultset, thus +returning a list of row objects instead. To avoid that, use L. + If you need to pass in additional attributes but no additional condition, call it as C. @@ -540,7 +543,7 @@ sub _stack_cond { =item Arguments: $sql_fragment, @bind_values -=item Return Value: $resultset (scalar context), @row_objs (list context) +=item Return Value: $resultset (scalar context) || @row_objs (list context) =back @@ -837,7 +840,7 @@ sub _build_unique_cond { =item Arguments: $rel, $cond, \%attrs? -=item Return Value: $new_resultset +=item Return Value: $new_resultset (scalar context) || @row_objs (list context) =back @@ -848,6 +851,11 @@ sub _build_unique_cond { Searches the specified relationship, optionally specifying a condition and attributes for matching records. See L for more information. +In list context, C<< ->all() >> is called implicitly on the resultset, thus +returning a list of row objects instead. To avoid that, use L. + +See also L. + =cut sub search_related { @@ -1028,7 +1036,7 @@ sub get_column { =item Arguments: $cond, \%attrs? -=item Return Value: $resultset (scalar context), @row_objs (list context) +=item Return Value: $resultset (scalar context) || @row_objs (list context) =back @@ -1071,7 +1079,7 @@ sub search_like { =item Arguments: $first, $last -=item Return Value: $resultset (scalar context), @row_objs (list context) +=item Return Value: $resultset (scalar context) || @row_objs (list context) =back @@ -1551,8 +1559,7 @@ sub count_literal { shift->search_literal(@_)->count; } =back -Returns all elements in the resultset. Called implicitly if the resultset -is returned in list context. +Returns all elements in the resultset. =cut @@ -1837,7 +1844,7 @@ sub delete_all { Accepts either an arrayref of hashrefs or alternatively an arrayref of arrayrefs. For the arrayref of hashrefs style each hashref should be a structure suitable -forsubmitting to a $resultset->create(...) method. +for submitting to a $resultset->create(...) method. In void context, C in L is used to insert the data, as this is a faster method. @@ -3966,28 +3973,122 @@ case. Simple prefetches will be joined automatically, so there is no need for a C attribute in the above search. -C can be used with the following relationship types: C, -C (or if you're using C, any relationship declared -with an accessor type of 'single' or 'filter'). A more complex example that -prefetches an artists cds, the tracks on those cds, and the tags associated -with that artist is given below (assuming many-to-many from artists to tags): +L can be used with the any of the relationship types and +multiple prefetches can be specified together. Below is a more complex +example that prefetches a CD's artist, its liner notes (if present), +the cover image, the tracks on that cd, and the guests on those +tracks. + + # Assuming: + My::Schema::CD->belongs_to( artist => 'My::Schema::Artist' ); + My::Schema::CD->might_have( liner_note => 'My::Schema::LinerNotes' ); + My::Schema::CD->has_one( cover_image => 'My::Schema::Artwork' ); + My::Schema::CD->has_many( tracks => 'My::Schema::Track' ); + + My::Schema::Artist->belongs_to( record_label => 'My::Schema::RecordLabel' ); - my $rs = $schema->resultset('Artist')->search( + My::Schema::Track->has_many( guests => 'My::Schema::Guest' ); + + + my $rs = $schema->resultset('CD')->search( undef, { prefetch => [ - { cds => 'tracks' }, - { artist_tags => 'tags' } + { artist => 'record_label'}, # belongs_to => belongs_to + 'liner_note', # might_have + 'cover_image', # has_one + { tracks => 'guests' }, # has_many => has_many ] } ); +This will produce SQL like the following: + + SELECT cd.*, artist.*, record_label.*, liner_note.*, cover_image.*, + tracks.*, guests.* + FROM cd me + JOIN artist artist + ON artist.artistid = me.artistid + JOIN record_label record_label + ON record_label.labelid = artist.labelid + LEFT JOIN track tracks + ON tracks.cdid = me.cdid + LEFT JOIN guest guests + ON guests.trackid = track.trackid + LEFT JOIN liner_notes liner_note + ON liner_note.cdid = me.cdid + JOIN cd_artwork cover_image + ON cover_image.cdid = me.cdid + ORDER BY tracks.cd + +Now the C, C, C, C, +C, and C of the CD will all be available through the +relationship accessors without the need for additional queries to the +database. + +However, there is one caveat to be observed: it can be dangerous to +prefetch more than one L +relationship on a given level. e.g.: + + my $rs = $schema->resultset('CD')->search( + undef, + { + prefetch => [ + 'tracks', # has_many + { cd_to_producer => 'producer' }, # has_many => belongs_to (i.e. m2m) + ] + } + ); + +In fact, C will emit the following warning: + + Prefetching multiple has_many rels tracks and cd_to_producer at top + level will explode the number of row objects retrievable via ->next + or ->all. Use at your own risk. + +The collapser currently can't identify duplicate tuples for multiple +L relationships and as a +result the second L +relation could contain redundant objects. + +=head3 Using L with L + +L implies a L with the equivalent argument, and is +properly merged with any existing L specification. So the +following: + + my $rs = $schema->resultset('CD')->search( + {'record_label.name' => 'Music Product Ltd.'}, + { + join => {artist => 'record_label'}, + prefetch => 'artist', + } + ); + +... will work, searching on the record label's name, but only +prefetching the C. + +=head3 Using L with L / L / L / L + +L implies a L/L with the fields of the +prefetched relations. So given: + + my $rs = $schema->resultset('CD')->search( + undef, + { + select => ['cd.title'], + as => ['cd_title'], + prefetch => 'artist', + } + ); + +The L becomes: C<'cd.title', 'artist.*'> and the L +becomes: C<'cd_title', 'artist.*'>. -B If you specify a C attribute, the C and C