1package DBIx::Class::ResultSet; 2 3use strict; 4use warnings; 5use base qw/DBIx::Class/; 6use DBIx::Class::Carp; 7use DBIx::Class::ResultSetColumn; 8use Scalar::Util qw/blessed weaken reftype/; 9use DBIx::Class::_Util qw( 10 fail_on_internal_wantarray fail_on_internal_call UNRESOLVABLE_CONDITION 11); 12use Try::Tiny; 13 14BEGIN { 15 # De-duplication in _merge_attr() is disabled, but left in for reference 16 # (the merger is used for other things that ought not to be de-duped) 17 *__HM_DEDUP = sub () { 0 }; 18} 19 20# FIXME - get rid of this 21use Hash::Merge (); 22 23use namespace::clean; 24 25use overload 26 '0+' => "count", 27 'bool' => "_bool", 28 fallback => 1; 29 30# this is real - CDBICompat overrides it with insanity 31# yes, prototype won't matter, but that's for now ;) 32sub _bool () { 1 } 33 34__PACKAGE__->mk_group_accessors('simple' => qw/_result_class result_source/); 35 36=head1 NAME 37 38DBIx::Class::ResultSet - Represents a query used for fetching a set of results. 39 40=head1 SYNOPSIS 41 42 my $users_rs = $schema->resultset('User'); 43 while( $user = $users_rs->next) { 44 print $user->username; 45 } 46 47 my $registered_users_rs = $schema->resultset('User')->search({ registered => 1 }); 48 my @cds_in_2005 = $schema->resultset('CD')->search({ year => 2005 })->all(); 49 50=head1 DESCRIPTION 51 52A ResultSet is an object which stores a set of conditions representing 53a query. It is the backbone of DBIx::Class (i.e. the really 54important/useful bit). 55 56No SQL is executed on the database when a ResultSet is created, it 57just stores all the conditions needed to create the query. 58 59A basic ResultSet representing the data of an entire table is returned 60by calling C<resultset> on a L<DBIx::Class::Schema> and passing in a 61L<Source|DBIx::Class::Manual::Glossary/ResultSource> name. 62 63 my $users_rs = $schema->resultset('User'); 64 65A new ResultSet is returned from calling L</search> on an existing 66ResultSet. The new one will contain all the conditions of the 67original, plus any new conditions added in the C<search> call. 68 69A ResultSet also incorporates an implicit iterator. L</next> and L</reset> 70can be used to walk through all the L<DBIx::Class::Row>s the ResultSet 71represents. 72 73The query that the ResultSet represents is B<only> executed against 74the database when these methods are called: 75L</find>, L</next>, L</all>, L</first>, L</single>, L</count>. 76 77If a resultset is used in a numeric context it returns the L</count>. 78However, if it is used in a boolean context it is B<always> true. So if 79you want to check if a resultset has any results, you must use C<if $rs 80!= 0>. 81 82=head1 EXAMPLES 83 84=head2 Chaining resultsets 85 86Let's say you've got a query that needs to be run to return some data 87to the user. But, you have an authorization system in place that 88prevents certain users from seeing certain information. So, you want 89to construct the basic query in one method, but add constraints to it in 90another. 91 92 sub get_data { 93 my $self = shift; 94 my $request = $self->get_request; # Get a request object somehow. 95 my $schema = $self->result_source->schema; 96 97 my $cd_rs = $schema->resultset('CD')->search({ 98 title => $request->param('title'), 99 year => $request->param('year'), 100 }); 101 102 $cd_rs = $self->apply_security_policy( $cd_rs ); 103 104 return $cd_rs->all(); 105 } 106 107 sub apply_security_policy { 108 my $self = shift; 109 my ($rs) = @_; 110 111 return $rs->search({ 112 subversive => 0, 113 }); 114 } 115 116=head3 Resolving conditions and attributes 117 118When a resultset is chained from another resultset (e.g.: 119C<< my $new_rs = $old_rs->search(\%extra_cond, \%attrs) >>), conditions 120and attributes with the same keys need resolving. 121 122If any of L</columns>, L</select>, L</as> are present, they reset the 123original selection, and start the selection "clean". 124 125The L</join>, L</prefetch>, L</+columns>, L</+select>, L</+as> attributes 126are merged into the existing ones from the original resultset. 127 128The L</where> and L</having> attributes, and any search conditions, are 129merged with an SQL C<AND> to the existing condition from the original 130resultset. 131 132All other attributes are overridden by any new ones supplied in the 133search attributes. 134 135=head2 Multiple queries 136 137Since a resultset just defines a query, you can do all sorts of 138things with it with the same object. 139 140 # Don't hit the DB yet. 141 my $cd_rs = $schema->resultset('CD')->search({ 142 title => 'something', 143 year => 2009, 144 }); 145 146 # Each of these hits the DB individually. 147 my $count = $cd_rs->count; 148 my $most_recent = $cd_rs->get_column('date_released')->max(); 149 my @records = $cd_rs->all; 150 151And it's not just limited to SELECT statements. 152 153 $cd_rs->delete(); 154 155This is even cooler: 156 157 $cd_rs->create({ artist => 'Fred' }); 158 159Which is the same as: 160 161 $schema->resultset('CD')->create({ 162 title => 'something', 163 year => 2009, 164 artist => 'Fred' 165 }); 166 167See: L</search>, L</count>, L</get_column>, L</all>, L</create>. 168 169=head2 Custom ResultSet classes 170 171To add methods to your resultsets, you can subclass L<DBIx::Class::ResultSet>, similar to: 172 173 package MyApp::Schema::ResultSet::User; 174 175 use strict; 176 use warnings; 177 178 use base 'DBIx::Class::ResultSet'; 179 180 sub active { 181 my $self = shift; 182 $self->search({ $self->current_source_alias . '.active' => 1 }); 183 } 184 185 sub unverified { 186 my $self = shift; 187 $self->search({ $self->current_source_alias . '.verified' => 0 }); 188 } 189 190 sub created_n_days_ago { 191 my ($self, $days_ago) = @_; 192 $self->search({ 193 $self->current_source_alias . '.create_date' => { 194 '<=', 195 $self->result_source->schema->storage->datetime_parser->format_datetime( 196 DateTime->now( time_zone => 'UTC' )->subtract( days => $days_ago ) 197 )} 198 }); 199 } 200 201 sub users_to_warn { shift->active->unverified->created_n_days_ago(7) } 202 203 1; 204 205See L<DBIx::Class::Schema/load_namespaces> on how DBIC can discover and 206automatically attach L<Result|DBIx::Class::Manual::ResultClass>-specific 207L<ResulSet|DBIx::Class::ResultSet> classes. 208 209=head3 ResultSet subclassing with Moose and similar constructor-providers 210 211Using L<Moose> or L<Moo> in your ResultSet classes is usually overkill, but 212you may find it useful if your ResultSets contain a lot of business logic 213(e.g. C<has xml_parser>, C<has json>, etc) or if you just prefer to organize 214your code via roles. 215 216In order to write custom ResultSet classes with L<Moo> you need to use the 217following template. The L<BUILDARGS|Moo/BUILDARGS> is necessary due to the 218unusual signature of the L<constructor provided by DBIC 219|DBIx::Class::ResultSet/new> C<< ->new($source, \%args) >>. 220 221 use Moo; 222 extends 'DBIx::Class::ResultSet'; 223 sub BUILDARGS { $_[2] || {} } # ::RS::new() expects my ($class, $rsrc, $args) = @_ 224 225 ...your code... 226 227 1; 228 229If you want to build your custom ResultSet classes with L<Moose>, you need 230a similar, though a little more elaborate template in order to interface the 231inlining of the L<Moose>-provided 232L<object constructor|Moose::Manual::Construction/WHERE'S THE CONSTRUCTOR?>, 233with the DBIC one. 234 235 package MyApp::Schema::ResultSet::User; 236 237 use Moose; 238 use MooseX::NonMoose; 239 extends 'DBIx::Class::ResultSet'; 240 241 sub BUILDARGS { $_[2] || {} } # ::RS::new() expects my ($class, $rsrc, $args) = @_ 242 243 ...your code... 244 245 __PACKAGE__->meta->make_immutable; 246 247 1; 248 249The L<MooseX::NonMoose> is necessary so that the L<Moose> constructor does not 250entirely overwrite the DBIC one (in contrast L<Moo> does this automatically). 251Alternatively, you can skip L<MooseX::NonMoose> and get by with just L<Moose> 252instead by doing: 253 254 __PACKAGE__->meta->make_immutable(inline_constructor => 0); 255 256=head1 METHODS 257 258=head2 new 259 260=over 4 261 262=item Arguments: L<$source|DBIx::Class::ResultSource>, L<\%attrs?|/ATTRIBUTES> 263 264=item Return Value: L<$resultset|/search> 265 266=back 267 268The resultset constructor. Takes a source object (usually a 269L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see 270L</ATTRIBUTES> below). Does not perform any queries -- these are 271executed as needed by the other methods. 272 273Generally you never construct a resultset manually. Instead you get one 274from e.g. a 275C<< $schema->L<resultset|DBIx::Class::Schema/resultset>('$source_name') >> 276or C<< $another_resultset->L<search|/search>(...) >> (the later called in 277scalar context): 278 279 my $rs = $schema->resultset('CD')->search({ title => '100th Window' }); 280 281=over 282 283=item WARNING 284 285If called on an object, proxies to L</new_result> instead, so 286 287 my $cd = $schema->resultset('CD')->new({ title => 'Spoon' }); 288 289will return a CD object, not a ResultSet, and is equivalent to: 290 291 my $cd = $schema->resultset('CD')->new_result({ title => 'Spoon' }); 292 293Please also keep in mind that many internals call L</new_result> directly, 294so overloading this method with the idea of intercepting new result object 295creation B<will not work>. See also warning pertaining to L</create>. 296 297=back 298 299=cut 300 301sub new { 302 my $class = shift; 303 304 if (ref $class) { 305 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call; 306 return $class->new_result(@_); 307 } 308 309 my ($source, $attrs) = @_; 310 $source = $source->resolve 311 if $source->isa('DBIx::Class::ResultSourceHandle'); 312 313 $attrs = { %{$attrs||{}} }; 314 delete @{$attrs}{qw(_last_sqlmaker_alias_map _simple_passthrough_construction)}; 315 316 if ($attrs->{page}) { 317 $attrs->{rows} ||= 10; 318 } 319 320 $attrs->{alias} ||= 'me'; 321 322 my $self = bless { 323 result_source => $source, 324 cond => $attrs->{where}, 325 pager => undef, 326 attrs => $attrs, 327 }, $class; 328 329 # if there is a dark selector, this means we are already in a 330 # chain and the cleanup/sanification was taken care of by 331 # _search_rs already 332 $self->_normalize_selection($attrs) 333 unless $attrs->{_dark_selector}; 334 335 $self->result_class( 336 $attrs->{result_class} || $source->result_class 337 ); 338 339 $self; 340} 341 342=head2 search 343 344=over 4 345 346=item Arguments: L<$cond|DBIx::Class::SQLMaker> | undef, L<\%attrs?|/ATTRIBUTES> 347 348=item Return Value: $resultset (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context) 349 350=back 351 352 my @cds = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001" 353 my $new_rs = $cd_rs->search({ year => 2005 }); 354 355 my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]); 356 # year = 2005 OR year = 2004 357 358In list context, C<< ->all() >> is called implicitly on the resultset, thus 359returning a list of L<result|DBIx::Class::Manual::ResultClass> objects instead. 360To avoid that, use L</search_rs>. 361 362If you need to pass in additional attributes but no additional condition, 363call it as C<search(undef, \%attrs)>. 364 365 # "SELECT name, artistid FROM $artist_table" 366 my @all_artists = $schema->resultset('Artist')->search(undef, { 367 columns => [qw/name artistid/], 368 }); 369 370For a list of attributes that can be passed to C<search>, see 371L</ATTRIBUTES>. For more examples of using this function, see 372L<Searching|DBIx::Class::Manual::Cookbook/SEARCHING>. For a complete 373documentation for the first argument, see 374L<SQL::Abstract::Classic/"WHERE CLAUSES"> and its extension 375L<DBIx::Class::SQLMaker>. 376 377For more help on using joins with search, see L<DBIx::Class::Manual::Joining>. 378 379=head3 CAVEAT 380 381Note that L</search> does not process/deflate any of the values passed in the 382L<SQL::Abstract::Classic>-compatible search condition structure. This is unlike 383other condition-bound methods L</new_result>, L</create> and L</find>. The user 384must ensure manually that any value passed to this method will stringify to 385something the RDBMS knows how to deal with. A notable example is the handling 386of L<DateTime> objects, for more info see: 387L<DBIx::Class::Manual::Cookbook/Formatting DateTime objects in queries>. 388 389=cut 390 391sub search { 392 my $self = shift; 393 my $rs = $self->search_rs( @_ ); 394 395 if (wantarray) { 396 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = fail_on_internal_wantarray; 397 return $rs->all; 398 } 399 elsif (defined wantarray) { 400 return $rs; 401 } 402 else { 403 # we can be called by a relationship helper, which in 404 # turn may be called in void context due to some braindead 405 # overload or whatever else the user decided to be clever 406 # at this particular day. Thus limit the exception to 407 # external code calls only 408 $self->throw_exception ('->search is *not* a mutator, calling it in void context makes no sense') 409 if (caller)[0] !~ /^\QDBIx::Class::/; 410 411 return (); 412 } 413} 414 415=head2 search_rs 416 417=over 4 418 419=item Arguments: L<$cond|DBIx::Class::SQLMaker>, L<\%attrs?|/ATTRIBUTES> 420 421=item Return Value: L<$resultset|/search> 422 423=back 424 425This method does the same exact thing as search() except it will 426always return a resultset, even in list context. 427 428=cut 429 430sub search_rs { 431 my $self = shift; 432 433 my $rsrc = $self->result_source; 434 my ($call_cond, $call_attrs); 435 436 # Special-case handling for (undef, undef) or (undef) 437 # Note that (foo => undef) is valid deprecated syntax 438 @_ = () if not scalar grep { defined $_ } @_; 439 440 # just a cond 441 if (@_ == 1) { 442 $call_cond = shift; 443 } 444 # fish out attrs in the ($condref, $attr) case 445 elsif (@_ == 2 and ( ! defined $_[0] or (ref $_[0]) ne '') ) { 446 ($call_cond, $call_attrs) = @_; 447 } 448 elsif (@_ % 2) { 449 $self->throw_exception('Odd number of arguments to search') 450 } 451 # legacy search 452 elsif (@_) { 453 carp_unique 'search( %condition ) is deprecated, use search( \%condition ) instead' 454 unless $rsrc->result_class->isa('DBIx::Class::CDBICompat'); 455 456 for my $i (0 .. $#_) { 457 next if $i % 2; 458 $self->throw_exception ('All keys in condition key/value pairs must be plain scalars') 459 if (! defined $_[$i] or ref $_[$i] ne ''); 460 } 461 462 $call_cond = { @_ }; 463 } 464 465 # see if we can keep the cache (no $rs changes) 466 my $cache; 467 my %safe = (alias => 1, cache => 1); 468 if ( ! grep { !$safe{$_} } keys %$call_attrs and ( 469 ! defined $call_cond 470 or 471 ref $call_cond eq 'HASH' && ! keys %$call_cond 472 or 473 ref $call_cond eq 'ARRAY' && ! @$call_cond 474 )) { 475 $cache = $self->get_cache; 476 } 477 478 my $old_attrs = { %{$self->{attrs}} }; 479 my ($old_having, $old_where) = delete @{$old_attrs}{qw(having where)}; 480 481 my $new_attrs = { %$old_attrs }; 482 483 # take care of call attrs (only if anything is changing) 484 if ($call_attrs and keys %$call_attrs) { 485 486 # copy for _normalize_selection 487 $call_attrs = { %$call_attrs }; 488 489 my @selector_attrs = qw/select as columns cols +select +as +columns include_columns/; 490 491 # reset the current selector list if new selectors are supplied 492 delete @{$old_attrs}{(@selector_attrs, '_dark_selector')} 493 if grep { exists $call_attrs->{$_} } qw(columns cols select as); 494 495 # Normalize the new selector list (operates on the passed-in attr structure) 496 # Need to do it on every chain instead of only once on _resolved_attrs, in 497 # order to allow detection of empty vs partial 'as' 498 $call_attrs->{_dark_selector} = $old_attrs->{_dark_selector} 499 if $old_attrs->{_dark_selector}; 500 $self->_normalize_selection ($call_attrs); 501 502 # start with blind overwriting merge, exclude selector attrs 503 $new_attrs = { %{$old_attrs}, %{$call_attrs} }; 504 delete @{$new_attrs}{@selector_attrs}; 505 506 for (@selector_attrs) { 507 $new_attrs->{$_} = $self->_merge_attr($old_attrs->{$_}, $call_attrs->{$_}) 508 if ( exists $old_attrs->{$_} or exists $call_attrs->{$_} ); 509 } 510 511 # older deprecated name, use only if {columns} is not there 512 if (my $c = delete $new_attrs->{cols}) { 513 carp_unique( "Resultset attribute 'cols' is deprecated, use 'columns' instead" ); 514 if ($new_attrs->{columns}) { 515 carp "Resultset specifies both the 'columns' and the legacy 'cols' attributes - ignoring 'cols'"; 516 } 517 else { 518 $new_attrs->{columns} = $c; 519 } 520 } 521 522 523 # join/prefetch use their own crazy merging heuristics 524 foreach my $key (qw/join prefetch/) { 525 $new_attrs->{$key} = $self->_merge_joinpref_attr($old_attrs->{$key}, $call_attrs->{$key}) 526 if exists $call_attrs->{$key}; 527 } 528 529 # stack binds together 530 $new_attrs->{bind} = [ @{ $old_attrs->{bind} || [] }, @{ $call_attrs->{bind} || [] } ]; 531 } 532 533 534 for ($old_where, $call_cond) { 535 if (defined $_) { 536 $new_attrs->{where} = $self->_stack_cond ( 537 $_, $new_attrs->{where} 538 ); 539 } 540 } 541 542 if (defined $old_having) { 543 $new_attrs->{having} = $self->_stack_cond ( 544 $old_having, $new_attrs->{having} 545 ) 546 } 547 548 my $rs = (ref $self)->new($rsrc, $new_attrs); 549 550 $rs->set_cache($cache) if ($cache); 551 552 return $rs; 553} 554 555my $dark_sel_dumper; 556sub _normalize_selection { 557 my ($self, $attrs) = @_; 558 559 # legacy syntax 560 if ( exists $attrs->{include_columns} ) { 561 carp_unique( "Resultset attribute 'include_columns' is deprecated, use '+columns' instead" ); 562 $attrs->{'+columns'} = $self->_merge_attr( 563 $attrs->{'+columns'}, delete $attrs->{include_columns} 564 ); 565 } 566 567 # columns are always placed first, however 568 569 # Keep the X vs +X separation until _resolved_attrs time - this allows to 570 # delay the decision on whether to use a default select list ($rsrc->columns) 571 # allowing stuff like the remove_columns helper to work 572 # 573 # select/as +select/+as pairs need special handling - the amount of select/as 574 # elements in each pair does *not* have to be equal (think multicolumn 575 # selectors like distinct(foo, bar) ). If the selector is bare (no 'as' 576 # supplied at all) - try to infer the alias, either from the -as parameter 577 # of the selector spec, or use the parameter whole if it looks like a column 578 # name (ugly legacy heuristic). If all fails - leave the selector bare (which 579 # is ok as well), but make sure no more additions to the 'as' chain take place 580 for my $pref ('', '+') { 581 582 my ($sel, $as) = map { 583 my $key = "${pref}${_}"; 584 585 my $val = [ ref $attrs->{$key} eq 'ARRAY' 586 ? @{$attrs->{$key}} 587 : $attrs->{$key} || () 588 ]; 589 delete $attrs->{$key}; 590 $val; 591 } qw/select as/; 592 593 if (! @$as and ! @$sel ) { 594 next; 595 } 596 elsif (@$as and ! @$sel) { 597 $self->throw_exception( 598 "Unable to handle ${pref}as specification (@$as) without a corresponding ${pref}select" 599 ); 600 } 601 elsif( ! @$as ) { 602 # no as part supplied at all - try to deduce (unless explicit end of named selection is declared) 603 # if any @$as has been supplied we assume the user knows what (s)he is doing 604 # and blindly keep stacking up pieces 605 unless ($attrs->{_dark_selector}) { 606 SELECTOR: 607 for (@$sel) { 608 if ( ref $_ eq 'HASH' and exists $_->{-as} ) { 609 push @$as, $_->{-as}; 610 } 611 # assume any plain no-space, no-parenthesis string to be a column spec 612 # FIXME - this is retarded but is necessary to support shit like 'count(foo)' 613 elsif ( ! ref $_ and $_ =~ /^ [^\s\(\)]+ $/x) { 614 push @$as, $_; 615 } 616 # if all else fails - raise a flag that no more aliasing will be allowed 617 else { 618 $attrs->{_dark_selector} = { 619 plus_stage => $pref, 620 string => ($dark_sel_dumper ||= do { 621 require Data::Dumper::Concise; 622 Data::Dumper::Concise::DumperObject()->Indent(0); 623 })->Values([$_])->Dump 624 , 625 }; 626 last SELECTOR; 627 } 628 } 629 } 630 } 631 elsif (@$as < @$sel) { 632 $self->throw_exception( 633 "Unable to handle an ${pref}as specification (@$as) with less elements than the corresponding ${pref}select" 634 ); 635 } 636 elsif ($pref and $attrs->{_dark_selector}) { 637 $self->throw_exception( 638 "Unable to process named '+select', resultset contains an unnamed selector $attrs->{_dark_selector}{string}" 639 ); 640 } 641 642 643 # merge result 644 $attrs->{"${pref}select"} = $self->_merge_attr($attrs->{"${pref}select"}, $sel); 645 $attrs->{"${pref}as"} = $self->_merge_attr($attrs->{"${pref}as"}, $as); 646 } 647} 648 649sub _stack_cond { 650 my ($self, $left, $right) = @_; 651 652 ( 653 (ref $_ eq 'ARRAY' and !@$_) 654 or 655 (ref $_ eq 'HASH' and ! keys %$_) 656 ) and $_ = undef for ($left, $right); 657 658 # either one of the two undef 659 if ( (defined $left) xor (defined $right) ) { 660 return defined $left ? $left : $right; 661 } 662 # both undef 663 elsif ( ! defined $left ) { 664 return undef 665 } 666 else { 667 return $self->result_source->schema->storage->_collapse_cond({ -and => [$left, $right] }); 668 } 669} 670 671=head2 search_literal 672 673B<CAVEAT>: C<search_literal> is provided for Class::DBI compatibility and 674should only be used in that context. C<search_literal> is a convenience 675method. It is equivalent to calling C<< $schema->search(\[]) >>, but if you 676want to ensure columns are bound correctly, use L</search>. 677 678See L<DBIx::Class::Manual::Cookbook/SEARCHING> and 679L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not 680require C<search_literal>. 681 682=over 4 683 684=item Arguments: $sql_fragment, @standalone_bind_values 685 686=item Return Value: L<$resultset|/search> (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context) 687 688=back 689 690 my @cds = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/); 691 my $newrs = $artist_rs->search_literal('name = ?', 'Metallica'); 692 693Pass a literal chunk of SQL to be added to the conditional part of the 694resultset query. 695 696Example of how to use C<search> instead of C<search_literal> 697 698 my @cds = $cd_rs->search_literal('cdid = ? AND (artist = ? OR artist = ?)', (2, 1, 2)); 699 my @cds = $cd_rs->search(\[ 'cdid = ? AND (artist = ? OR artist = ?)', [ 'cdid', 2 ], [ 'artist', 1 ], [ 'artist', 2 ] ]); 700 701=cut 702 703sub search_literal { 704 my ($self, $sql, @bind) = @_; 705 my $attr; 706 if ( @bind && ref($bind[-1]) eq 'HASH' ) { 707 $attr = pop @bind; 708 } 709 return $self->search(\[ $sql, map [ {} => $_ ], @bind ], ($attr || () )); 710} 711 712=head2 find 713 714=over 4 715 716=item Arguments: \%columns_values | @pk_values, { key => $unique_constraint, L<%attrs|/ATTRIBUTES> }? 717 718=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | undef 719 720=back 721 722Finds and returns a single row based on supplied criteria. Takes either a 723hashref with the same format as L</create> (including inference of foreign 724keys from related objects), or a list of primary key values in the same 725order as the L<primary columns|DBIx::Class::ResultSource/primary_columns> 726declaration on the L</result_source>. 727 728In either case an attempt is made to combine conditions already existing on 729the resultset with the condition passed to this method. 730 731To aid with preparing the correct query for the storage you may supply the 732C<key> attribute, which is the name of a 733L<unique constraint|DBIx::Class::ResultSource/add_unique_constraint> (the 734unique constraint corresponding to the 735L<primary columns|DBIx::Class::ResultSource/primary_columns> is always named 736C<primary>). If the C<key> attribute has been supplied, and DBIC is unable 737to construct a query that satisfies the named unique constraint fully ( 738non-NULL values for each column member of the constraint) an exception is 739thrown. 740 741If no C<key> is specified, the search is carried over all unique constraints 742which are fully defined by the available condition. 743 744If no such constraint is found, C<find> currently defaults to a simple 745C<< search->(\%column_values) >> which may or may not do what you expect. 746Note that this fallback behavior may be deprecated in further versions. If 747you need to search with arbitrary conditions - use L</search>. If the query 748resulting from this fallback produces more than one row, a warning to the 749effect is issued, though only the first row is constructed and returned as 750C<$result_object>. 751 752In addition to C<key>, L</find> recognizes and applies standard 753L<resultset attributes|/ATTRIBUTES> in the same way as L</search> does. 754 755Note that if you have extra concerns about the correctness of the resulting 756query you need to specify the C<key> attribute and supply the entire condition 757as an argument to find (since it is not always possible to perform the 758combination of the resultset condition with the supplied one, especially if 759the resultset condition contains literal sql). 760 761For example, to find a row by its primary key: 762 763 my $cd = $schema->resultset('CD')->find(5); 764 765You can also find a row by a specific unique constraint: 766 767 my $cd = $schema->resultset('CD')->find( 768 { 769 artist => 'Massive Attack', 770 title => 'Mezzanine', 771 }, 772 { key => 'cd_artist_title' } 773 ); 774 775See also L</find_or_create> and L</update_or_create>. 776 777=cut 778 779sub find { 780 my $self = shift; 781 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); 782 783 my $rsrc = $self->result_source; 784 785 my $constraint_name; 786 if (exists $attrs->{key}) { 787 $constraint_name = defined $attrs->{key} 788 ? $attrs->{key} 789 : $self->throw_exception("An undefined 'key' resultset attribute makes no sense") 790 ; 791 } 792 793 # Parse out the condition from input 794 my $call_cond; 795 796 if (ref $_[0] eq 'HASH') { 797 $call_cond = { %{$_[0]} }; 798 } 799 else { 800 # if only values are supplied we need to default to 'primary' 801 $constraint_name = 'primary' unless defined $constraint_name; 802 803 my @c_cols = $rsrc->unique_constraint_columns($constraint_name); 804 805 $self->throw_exception( 806 "No constraint columns, maybe a malformed '$constraint_name' constraint?" 807 ) unless @c_cols; 808 809 $self->throw_exception ( 810 'find() expects either a column/value hashref, or a list of values ' 811 . "corresponding to the columns of the specified unique constraint '$constraint_name'" 812 ) unless @c_cols == @_; 813 814 @{$call_cond}{@c_cols} = @_; 815 } 816 817 # process relationship data if any 818 for my $key (keys %$call_cond) { 819 if ( 820 length ref($call_cond->{$key}) 821 and 822 my $relinfo = $rsrc->relationship_info($key) 823 and 824 # implicitly skip has_many's (likely MC) 825 (ref (my $val = delete $call_cond->{$key}) ne 'ARRAY' ) 826 ) { 827 my ($rel_cond, $crosstable) = $rsrc->_resolve_condition( 828 $relinfo->{cond}, $val, $key, $key 829 ); 830 831 $self->throw_exception("Complex condition via relationship '$key' is unsupported in find()") 832 if $crosstable or ref($rel_cond) ne 'HASH'; 833 834 # supplement condition 835 # relationship conditions take precedence (?) 836 @{$call_cond}{keys %$rel_cond} = values %$rel_cond; 837 } 838 } 839 840 my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias}; 841 my $final_cond; 842 if (defined $constraint_name) { 843 $final_cond = $self->_qualify_cond_columns ( 844 845 $self->result_source->_minimal_valueset_satisfying_constraint( 846 constraint_name => $constraint_name, 847 values => ($self->_merge_with_rscond($call_cond))[0], 848 carp_on_nulls => 1, 849 ), 850 851 $alias, 852 ); 853 } 854 elsif ($self->{attrs}{accessor} and $self->{attrs}{accessor} eq 'single') { 855 # This means that we got here after a merger of relationship conditions 856 # in ::Relationship::Base::search_related (the row method), and furthermore 857 # the relationship is of the 'single' type. This means that the condition 858 # provided by the relationship (already attached to $self) is sufficient, 859 # as there can be only one row in the database that would satisfy the 860 # relationship 861 } 862 else { 863 my (@unique_queries, %seen_column_combinations, $ci, @fc_exceptions); 864 865 # no key was specified - fall down to heuristics mode: 866 # run through all unique queries registered on the resultset, and 867 # 'OR' all qualifying queries together 868 # 869 # always start from 'primary' if it exists at all 870 for my $c_name ( sort { 871 $a eq 'primary' ? -1 872 : $b eq 'primary' ? 1 873 : $a cmp $b 874 } $rsrc->unique_constraint_names) { 875 876 next if $seen_column_combinations{ 877 join "\x00", sort $rsrc->unique_constraint_columns($c_name) 878 }++; 879 880 try { 881 push @unique_queries, $self->_qualify_cond_columns( 882 $self->result_source->_minimal_valueset_satisfying_constraint( 883 constraint_name => $c_name, 884 values => ($self->_merge_with_rscond($call_cond))[0], 885 columns_info => ($ci ||= $self->result_source->columns_info), 886 ), 887 $alias 888 ); 889 } 890 catch { 891 push @fc_exceptions, $_ if $_ =~ /\bFilterColumn\b/; 892 }; 893 } 894 895 $final_cond = 896 @unique_queries ? \@unique_queries 897 : @fc_exceptions ? $self->throw_exception(join "; ", map { $_ =~ /(.*) at .+ line \d+$/s } @fc_exceptions ) 898 : $self->_non_unique_find_fallback ($call_cond, $attrs) 899 ; 900 } 901 902 # Run the query, passing the result_class since it should propagate for find 903 my $rs = $self->search ($final_cond, {result_class => $self->result_class, %$attrs}); 904 if ($rs->_resolved_attrs->{collapse}) { 905 my $row = $rs->next; 906 carp "Query returned more than one row" if $rs->next; 907 return $row; 908 } 909 else { 910 return $rs->single; 911 } 912} 913 914# This is a stop-gap method as agreed during the discussion on find() cleanup: 915# http://lists.scsys.co.uk/pipermail/dbix-class/2010-October/009535.html 916# 917# It is invoked when find() is called in legacy-mode with insufficiently-unique 918# condition. It is provided for overrides until a saner way forward is devised 919# 920# *NOTE* This is not a public method, and it's *GUARANTEED* to disappear down 921# the road. Please adjust your tests accordingly to catch this situation early 922# DBIx::Class::ResultSet->can('_non_unique_find_fallback') is reasonable 923# 924# The method will not be removed without an adequately complete replacement 925# for strict-mode enforcement 926sub _non_unique_find_fallback { 927 my ($self, $cond, $attrs) = @_; 928 929 return $self->_qualify_cond_columns( 930 $cond, 931 exists $attrs->{alias} 932 ? $attrs->{alias} 933 : $self->{attrs}{alias} 934 ); 935} 936 937 938sub _qualify_cond_columns { 939 my ($self, $cond, $alias) = @_; 940 941 my %aliased = %$cond; 942 for (keys %aliased) { 943 $aliased{"$alias.$_"} = delete $aliased{$_} 944 if $_ !~ /\./; 945 } 946 947 return \%aliased; 948} 949 950sub _build_unique_cond { 951 carp_unique sprintf 952 '_build_unique_cond is a private method, and moreover is about to go ' 953 . 'away. Please contact the development team at %s if you believe you ' 954 . 'have a genuine use for this method, in order to discuss alternatives.', 955 DBIx::Class::_ENV_::HELP_URL, 956 ; 957 958 my ($self, $constraint_name, $cond, $croak_on_null) = @_; 959 960 $self->result_source->_minimal_valueset_satisfying_constraint( 961 constraint_name => $constraint_name, 962 values => $cond, 963 carp_on_nulls => !$croak_on_null 964 ); 965} 966 967=head2 search_related 968 969=over 4 970 971=item Arguments: $rel_name, $cond?, L<\%attrs?|/ATTRIBUTES> 972 973=item Return Value: L<$resultset|/search> (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context) 974 975=back 976 977 $new_rs = $cd_rs->search_related('artist', { 978 name => 'Emo-R-Us', 979 }); 980 981Searches the specified relationship, optionally specifying a condition and 982attributes for matching records. See L</ATTRIBUTES> for more information. 983 984In list context, C<< ->all() >> is called implicitly on the resultset, thus 985returning a list of result objects instead. To avoid that, use L</search_related_rs>. 986 987See also L</search_related_rs>. 988 989=cut 990 991sub search_related { 992 return shift->related_resultset(shift)->search(@_); 993} 994 995=head2 search_related_rs 996 997This method works exactly the same as search_related, except that 998it guarantees a resultset, even in list context. 999 1000=cut 1001 1002sub search_related_rs { 1003 return shift->related_resultset(shift)->search_rs(@_); 1004} 1005 1006=head2 cursor 1007 1008=over 4 1009 1010=item Arguments: none 1011 1012=item Return Value: L<$cursor|DBIx::Class::Cursor> 1013 1014=back 1015 1016Returns a storage-driven cursor to the given resultset. See 1017L<DBIx::Class::Cursor> for more information. 1018 1019=cut 1020 1021sub cursor { 1022 my $self = shift; 1023 1024 return $self->{cursor} ||= do { 1025 my $attrs = $self->_resolved_attrs; 1026 $self->result_source->storage->select( 1027 $attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs 1028 ); 1029 }; 1030} 1031 1032=head2 single 1033 1034=over 4 1035 1036=item Arguments: L<$cond?|DBIx::Class::SQLMaker> 1037 1038=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | undef 1039 1040=back 1041 1042 my $cd = $schema->resultset('CD')->single({ year => 2001 }); 1043 1044Inflates the first result without creating a cursor if the resultset has 1045any records in it; if not returns C<undef>. Used by L</find> as a lean version 1046of L</search>. 1047 1048While this method can take an optional search condition (just like L</search>) 1049being a fast-code-path it does not recognize search attributes. If you need to 1050add extra joins or similar, call L</search> and then chain-call L</single> on the 1051L<DBIx::Class::ResultSet> returned. 1052 1053=over 1054 1055=item B<Note> 1056 1057As of 0.08100, this method enforces the assumption that the preceding 1058query returns only one row. If more than one row is returned, you will receive 1059a warning: 1060 1061 Query returned more than one row 1062 1063In this case, you should be using L</next> or L</find> instead, or if you really 1064know what you are doing, use the L</rows> attribute to explicitly limit the size 1065of the resultset. 1066 1067This method will also throw an exception if it is called on a resultset prefetching 1068has_many, as such a prefetch implies fetching multiple rows from the database in 1069order to assemble the resulting object. 1070 1071=back 1072 1073=cut 1074 1075sub single { 1076 my ($self, $where) = @_; 1077 if(@_ > 2) { 1078 $self->throw_exception('single() only takes search conditions, no attributes. You want ->search( $cond, $attrs )->single()'); 1079 } 1080 1081 my $attrs = { %{$self->_resolved_attrs} }; 1082 1083 $self->throw_exception( 1084 'single() can not be used on resultsets collapsing a has_many. Use find( \%cond ) or next() instead' 1085 ) if $attrs->{collapse}; 1086 1087 if ($where) { 1088 if (defined $attrs->{where}) { 1089 $attrs->{where} = { 1090 '-and' => 1091 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ } 1092 $where, delete $attrs->{where} ] 1093 }; 1094 } else { 1095 $attrs->{where} = $where; 1096 } 1097 } 1098 1099 my $data = [ $self->result_source->storage->select_single( 1100 $attrs->{from}, $attrs->{select}, 1101 $attrs->{where}, $attrs 1102 )]; 1103 1104 return undef unless @$data; 1105 $self->{_stashed_rows} = [ $data ]; 1106 $self->_construct_results->[0]; 1107} 1108 1109=head2 get_column 1110 1111=over 4 1112 1113=item Arguments: L<$cond?|DBIx::Class::SQLMaker> 1114 1115=item Return Value: L<$resultsetcolumn|DBIx::Class::ResultSetColumn> 1116 1117=back 1118 1119 my $max_length = $rs->get_column('length')->max; 1120 1121Returns a L<DBIx::Class::ResultSetColumn> instance for a column of the ResultSet. 1122 1123=cut 1124 1125sub get_column { 1126 my ($self, $column) = @_; 1127 my $new = DBIx::Class::ResultSetColumn->new($self, $column); 1128 return $new; 1129} 1130 1131=head2 search_like 1132 1133=over 4 1134 1135=item Arguments: L<$cond|DBIx::Class::SQLMaker>, L<\%attrs?|/ATTRIBUTES> 1136 1137=item Return Value: L<$resultset|/search> (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context) 1138 1139=back 1140 1141 # WHERE title LIKE '%blue%' 1142 $cd_rs = $rs->search_like({ title => '%blue%'}); 1143 1144Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note 1145that this is simply a convenience method retained for ex Class::DBI users. 1146You most likely want to use L</search> with specific operators. 1147 1148For more information, see L<DBIx::Class::Manual::Cookbook>. 1149 1150This method is deprecated and will be removed in 0.09. Use L<search()|/search> 1151instead. An example conversion is: 1152 1153 ->search_like({ foo => 'bar' }); 1154 1155 # Becomes 1156 1157 ->search({ foo => { like => 'bar' } }); 1158 1159=cut 1160 1161sub search_like { 1162 my $class = shift; 1163 carp_unique ( 1164 'search_like() is deprecated and will be removed in DBIC version 0.09.' 1165 .' Instead use ->search({ x => { -like => "y%" } })' 1166 .' (note the outer pair of {}s - they are important!)' 1167 ); 1168 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); 1169 my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_}; 1170 $query->{$_} = { 'like' => $query->{$_} } for keys %$query; 1171 return $class->search($query, { %$attrs }); 1172} 1173 1174=head2 slice 1175 1176=over 4 1177 1178=item Arguments: $first, $last 1179 1180=item Return Value: L<$resultset|/search> (scalar context) | L<@result_objs|DBIx::Class::Manual::ResultClass> (list context) 1181 1182=back 1183 1184Returns a resultset or object list representing a subset of elements from the 1185resultset slice is called on. Indexes are from 0, i.e., to get the first 1186three records, call: 1187 1188 my ($one, $two, $three) = $rs->slice(0, 2); 1189 1190=cut 1191 1192sub slice { 1193 my ($self, $min, $max) = @_; 1194 my $attrs = {}; # = { %{ $self->{attrs} || {} } }; 1195 $attrs->{offset} = $self->{attrs}{offset} || 0; 1196 $attrs->{offset} += $min; 1197 $attrs->{rows} = ($max ? ($max - $min + 1) : 1); 1198 return $self->search(undef, $attrs); 1199} 1200 1201=head2 next 1202 1203=over 4 1204 1205=item Arguments: none 1206 1207=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | undef 1208 1209=back 1210 1211Returns the next element in the resultset (C<undef> is there is none). 1212 1213Can be used to efficiently iterate over records in the resultset: 1214 1215 my $rs = $schema->resultset('CD')->search; 1216 while (my $cd = $rs->next) { 1217 print $cd->title; 1218 } 1219 1220Note that you need to store the resultset object, and call C<next> on it. 1221Calling C<< resultset('Table')->next >> repeatedly will always return the 1222first record from the resultset. 1223 1224=cut 1225 1226sub next { 1227 my ($self) = @_; 1228 1229 if (my $cache = $self->get_cache) { 1230 $self->{all_cache_position} ||= 0; 1231 return $cache->[$self->{all_cache_position}++]; 1232 } 1233 1234 if ($self->{attrs}{cache}) { 1235 delete $self->{pager}; 1236 $self->{all_cache_position} = 1; 1237 return ($self->all)[0]; 1238 } 1239 1240 return shift(@{$self->{_stashed_results}}) if @{ $self->{_stashed_results}||[] }; 1241 1242 $self->{_stashed_results} = $self->_construct_results 1243 or return undef; 1244 1245 return shift @{$self->{_stashed_results}}; 1246} 1247 1248# Constructs as many results as it can in one pass while respecting 1249# cursor laziness. Several modes of operation: 1250# 1251# * Always builds everything present in @{$self->{_stashed_rows}} 1252# * If called with $fetch_all true - pulls everything off the cursor and 1253# builds all result structures (or objects) in one pass 1254# * If $self->_resolved_attrs->{collapse} is true, checks the order_by 1255# and if the resultset is ordered properly by the left side: 1256# * Fetches stuff off the cursor until the "master object" changes, 1257# and saves the last extra row (if any) in @{$self->{_stashed_rows}} 1258# OR 1259# * Just fetches, and collapses/constructs everything as if $fetch_all 1260# was requested (there is no other way to collapse except for an 1261# eager cursor) 1262# * If no collapse is requested - just get the next row, construct and 1263# return 1264sub _construct_results { 1265 my ($self, $fetch_all) = @_; 1266 1267 my $rsrc = $self->result_source; 1268 my $attrs = $self->_resolved_attrs; 1269 1270 if ( 1271 ! $fetch_all 1272 and 1273 ! $attrs->{order_by} 1274 and 1275 $attrs->{collapse} 1276 and 1277 my @pcols = $rsrc->primary_columns 1278 ) { 1279 # default order for collapsing unless the user asked for something 1280 $attrs->{order_by} = [ map { join '.', $attrs->{alias}, $_} @pcols ]; 1281 $attrs->{_ordered_for_collapse} = 1; 1282 $attrs->{_order_is_artificial} = 1; 1283 } 1284 1285 # this will be used as both initial raw-row collector AND as a RV of 1286 # _construct_results. Not regrowing the array twice matters a lot... 1287 # a surprising amount actually 1288 my $rows = delete $self->{_stashed_rows}; 1289 1290 my $cursor; # we may not need one at all 1291 1292 my $did_fetch_all = $fetch_all; 1293 1294 if ($fetch_all) { 1295 # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref 1296 $rows = [ ($rows ? @$rows : ()), $self->cursor->all ]; 1297 } 1298 elsif( $attrs->{collapse} ) { 1299 1300 # a cursor will need to be closed over in case of collapse 1301 $cursor = $self->cursor; 1302 1303 $attrs->{_ordered_for_collapse} = ( 1304 ( 1305 $attrs->{order_by} 1306 and 1307 $rsrc->schema 1308 ->storage 1309 ->_extract_colinfo_of_stable_main_source_order_by_portion($attrs) 1310 ) ? 1 : 0 1311 ) unless defined $attrs->{_ordered_for_collapse}; 1312 1313 if (! $attrs->{_ordered_for_collapse}) { 1314 $did_fetch_all = 1; 1315 1316 # instead of looping over ->next, use ->all in stealth mode 1317 # *without* calling a ->reset afterwards 1318 # FIXME ENCAPSULATION - encapsulation breach, cursor method additions pending 1319 if (! $cursor->{_done}) { 1320 $rows = [ ($rows ? @$rows : ()), $cursor->all ]; 1321 $cursor->{_done} = 1; 1322 } 1323 } 1324 } 1325 1326 if (! $did_fetch_all and ! @{$rows||[]} ) { 1327 # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref 1328 $cursor ||= $self->cursor; 1329 if (scalar (my @r = $cursor->next) ) { 1330 $rows = [ \@r ]; 1331 } 1332 } 1333 1334 return undef unless @{$rows||[]}; 1335 1336 # sanity check - people are too clever for their own good 1337 if ($attrs->{collapse} and my $aliastypes = $attrs->{_last_sqlmaker_alias_map} ) { 1338 1339 my $multiplied_selectors; 1340 for my $sel_alias ( grep { $_ ne $attrs->{alias} } keys %{ $aliastypes->{selecting} } ) { 1341 if ( 1342 $aliastypes->{multiplying}{$sel_alias} 1343 or 1344 $aliastypes->{premultiplied}{$sel_alias} 1345 ) { 1346 $multiplied_selectors->{$_} = 1 for values %{$aliastypes->{selecting}{$sel_alias}{-seen_columns}} 1347 } 1348 } 1349 1350 for my $i (0 .. $#{$attrs->{as}} ) { 1351 my $sel = $attrs->{select}[$i]; 1352 1353 if (ref $sel eq 'SCALAR') { 1354 $sel = $$sel; 1355 } 1356 elsif( ref $sel eq 'REF' and ref $$sel eq 'ARRAY' ) { 1357 $sel = $$sel->[0]; 1358 } 1359 1360 $self->throw_exception( 1361 'Result collapse not possible - selection from a has_many source redirected to the main object' 1362 ) if ($multiplied_selectors->{$sel} and $attrs->{as}[$i] !~ /\./); 1363 } 1364 } 1365 1366 # hotspot - skip the setter 1367 my $res_class = $self->_result_class; 1368 1369 my $inflator_cref = $self->{_result_inflator}{cref} ||= do { 1370 $res_class->can ('inflate_result') 1371 or $self->throw_exception("Inflator $res_class does not provide an inflate_result() method"); 1372 }; 1373 1374 my $infmap = $attrs->{as}; 1375 1376 $self->{_result_inflator}{is_core_row} = ( ( 1377 $inflator_cref 1378 == 1379 ( \&DBIx::Class::Row::inflate_result || die "No ::Row::inflate_result() - can't happen" ) 1380 ) ? 1 : 0 ) unless defined $self->{_result_inflator}{is_core_row}; 1381 1382 $self->{_result_inflator}{is_hri} = ( ( 1383 ! $self->{_result_inflator}{is_core_row} 1384 and 1385 $inflator_cref == ( 1386 require DBIx::Class::ResultClass::HashRefInflator 1387 && 1388 DBIx::Class::ResultClass::HashRefInflator->can('inflate_result') 1389 ) 1390 ) ? 1 : 0 ) unless defined $self->{_result_inflator}{is_hri}; 1391 1392 1393 if ($attrs->{_simple_passthrough_construction}) { 1394 # construct a much simpler array->hash folder for the one-table HRI cases right here 1395 if ($self->{_result_inflator}{is_hri}) { 1396 for my $r (@$rows) { 1397 $r = { map { $infmap->[$_] => $r->[$_] } 0..$#$infmap }; 1398 } 1399 } 1400 # FIXME SUBOPTIMAL this is a very very very hot spot 1401 # while rather optimal we can *still* do much better, by 1402 # building a smarter Row::inflate_result(), and 1403 # switch to feeding it data via a much leaner interface 1404 # 1405 # crude unscientific benchmarking indicated the shortcut eval is not worth it for 1406 # this particular resultset size 1407 elsif ( $self->{_result_inflator}{is_core_row} and @$rows < 60 ) { 1408 for my $r (@$rows) { 1409 $r = $inflator_cref->($res_class, $rsrc, { map { $infmap->[$_] => $r->[$_] } (0..$#$infmap) } ); 1410 } 1411 } 1412 else { 1413 eval sprintf ( 1414 ( $self->{_result_inflator}{is_core_row} 1415 ? '$_ = $inflator_cref->($res_class, $rsrc, { %s }) for @$rows' 1416 # a custom inflator may be a multiplier/reductor - put it in direct list ctx 1417 : '@$rows = map { $inflator_cref->($res_class, $rsrc, { %s } ) } @$rows' 1418 ), 1419 ( join (', ', map { "\$infmap->[$_] => \$_->[$_]" } 0..$#$infmap ) ) 1420 ) . '; 1' or die; 1421 } 1422 } 1423 else { 1424 my $parser_type = 1425 $self->{_result_inflator}{is_hri} ? 'hri' 1426 : $self->{_result_inflator}{is_core_row} ? 'classic_pruning' 1427 : 'classic_nonpruning' 1428 ; 1429 1430 # $args and $attrs to _mk_row_parser are separated to delineate what is 1431 # core collapser stuff and what is dbic $rs specific 1432 @{$self->{_row_parser}{$parser_type}}{qw(cref nullcheck)} = $rsrc->_mk_row_parser({ 1433 eval => 1, 1434 inflate_map => $infmap, 1435 collapse => $attrs->{collapse}, 1436 premultiplied => $attrs->{_main_source_premultiplied}, 1437 hri_style => $self->{_result_inflator}{is_hri}, 1438 prune_null_branches => $self->{_result_inflator}{is_hri} || $self->{_result_inflator}{is_core_row}, 1439 }, $attrs) unless $self->{_row_parser}{$parser_type}{cref}; 1440 1441 # column_info metadata historically hasn't been too reliable. 1442 # We need to start fixing this somehow (the collapse resolver 1443 # can't work without it). Add an explicit check for the *main* 1444 # result, hopefully this will gradually weed out such errors 1445 # 1446 # FIXME - this is a temporary kludge that reduces performance 1447 # It is however necessary for the time being 1448 my ($unrolled_non_null_cols_to_check, $err); 1449 1450 if (my $check_non_null_cols = $self->{_row_parser}{$parser_type}{nullcheck} ) { 1451 1452 $err = 1453 'Collapse aborted due to invalid ResultSource metadata - the following ' 1454 . 'selections are declared non-nullable but NULLs were retrieved: ' 1455 ; 1456 1457 my @violating_idx; 1458 COL: for my $i (@$check_non_null_cols) { 1459 ! defined $_->[$i] and push @violating_idx, $i and next COL for @$rows; 1460 } 1461 1462 $self->throw_exception( $err . join (', ', map { "'$infmap->[$_]'" } @violating_idx ) ) 1463 if @violating_idx; 1464 1465 $unrolled_non_null_cols_to_check = join (',', @$check_non_null_cols); 1466 1467 utf8::upgrade($unrolled_non_null_cols_to_check) 1468 if DBIx::Class::_ENV_::STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE; 1469 } 1470 1471 my $next_cref = 1472 ($did_fetch_all or ! $attrs->{collapse}) ? undef 1473 : defined $unrolled_non_null_cols_to_check ? eval sprintf <<'EOS', $unrolled_non_null_cols_to_check 1474sub { 1475 # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref 1476 my @r = $cursor->next or return; 1477 if (my @violating_idx = grep { ! defined $r[$_] } (%s) ) { 1478 $self->throw_exception( $err . join (', ', map { "'$infmap->[$_]'" } @violating_idx ) ) 1479 } 1480 \@r 1481} 1482EOS 1483 : sub { 1484 # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref 1485 my @r = $cursor->next or return; 1486 \@r 1487 } 1488 ; 1489 1490 $self->{_row_parser}{$parser_type}{cref}->( 1491 $rows, 1492 $next_cref ? ( $next_cref, $self->{_stashed_rows} = [] ) : (), 1493 ); 1494 1495 # simple in-place substitution, does not regrow $rows 1496 if ($self->{_result_inflator}{is_core_row}) { 1497 $_ = $inflator_cref->($res_class, $rsrc, @$_) for @$rows 1498 } 1499 # Special-case multi-object HRI - there is no $inflator_cref pass at all 1500 elsif ( ! $self->{_result_inflator}{is_hri} ) { 1501 # the inflator may be a multiplier/reductor - put it in list ctx 1502 @$rows = map { $inflator_cref->($res_class, $rsrc, @$_) } @$rows; 1503 } 1504 } 1505 1506 # The @$rows check seems odd at first - why wouldn't we want to warn 1507 # regardless? The issue is things like find() etc, where the user 1508 # *knows* only one result will come back. In these cases the ->all 1509 # is not a pessimization, but rather something we actually want 1510 carp_unique( 1511 'Unable to properly collapse has_many results in iterator mode due ' 1512 . 'to order criteria - performed an eager cursor slurp underneath. ' 1513 . 'Consider using ->all() instead' 1514 ) if ( ! $fetch_all and @$rows > 1 ); 1515 1516 return $rows; 1517} 1518 1519=head2 result_source 1520 1521=over 4 1522 1523=item Arguments: L<$result_source?|DBIx::Class::ResultSource> 1524 1525=item Return Value: L<$result_source|DBIx::Class::ResultSource> 1526 1527=back 1528 1529An accessor for the primary ResultSource object from which this ResultSet 1530is derived. 1531 1532=head2 result_class 1533 1534=over 4 1535 1536=item Arguments: $result_class? 1537 1538=item Return Value: $result_class 1539 1540=back 1541 1542An accessor for the class to use when creating result objects. Defaults to 1543C<< result_source->result_class >> - which in most cases is the name of the 1544L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class. 1545 1546Note that changing the result_class will also remove any components 1547that were originally loaded in the source class via 1548L<load_components|Class::C3::Componentised/load_components( @comps )>. 1549Any overloaded methods in the original source class will not run. 1550 1551=cut 1552 1553sub result_class { 1554 my ($self, $result_class) = @_; 1555 if ($result_class) { 1556 1557 # don't fire this for an object 1558 $self->ensure_class_loaded($result_class) 1559 unless ref($result_class); 1560 1561 if ($self->get_cache) { 1562 carp_unique('Changing the result_class of a ResultSet instance with cached results is a noop - the cache contents will not be altered'); 1563 } 1564 # FIXME ENCAPSULATION - encapsulation breach, cursor method additions pending 1565 elsif ($self->{cursor} && $self->{cursor}{_pos}) { 1566 $self->throw_exception('Changing the result_class of a ResultSet instance with an active cursor is not supported'); 1567 } 1568 1569 $self->_result_class($result_class); 1570 1571 delete $self->{_result_inflator}; 1572 } 1573 $self->_result_class; 1574} 1575 1576=head2 count 1577 1578=over 4 1579 1580=item Arguments: L<$cond|DBIx::Class::SQLMaker>, L<\%attrs?|/ATTRIBUTES> 1581 1582=item Return Value: $count 1583 1584=back 1585 1586Performs an SQL C<COUNT> with the same query as the resultset was built 1587with to find the number of elements. Passing arguments is equivalent to 1588C<< $rs->search ($cond, \%attrs)->count >> 1589 1590=cut 1591 1592sub count { 1593 my $self = shift; 1594 return $self->search(@_)->count if @_ and defined $_[0]; 1595 return scalar @{ $self->get_cache } if $self->get_cache; 1596 1597 my $attrs = { %{ $self->_resolved_attrs } }; 1598 1599 # this is a little optimization - it is faster to do the limit 1600 # adjustments in software, instead of a subquery 1601 my ($rows, $offset) = delete @{$attrs}{qw/rows offset/}; 1602 1603 my $crs; 1604 if ($self->_has_resolved_attr (qw/collapse group_by/)) { 1605 $crs = $self->_count_subq_rs ($attrs); 1606 } 1607 else { 1608 $crs = $self->_count_rs ($attrs); 1609 } 1610 my $count = $crs->next; 1611 1612 $count -= $offset if $offset; 1613 $count = $rows if $rows and $rows < $count; 1614 $count = 0 if ($count < 0); 1615 1616 return $count; 1617} 1618 1619=head2 count_rs 1620 1621=over 4 1622 1623=item Arguments: L<$cond|DBIx::Class::SQLMaker>, L<\%attrs?|/ATTRIBUTES> 1624 1625=item Return Value: L<$count_rs|DBIx::Class::ResultSetColumn> 1626 1627=back 1628 1629Same as L</count> but returns a L<DBIx::Class::ResultSetColumn> object. 1630This can be very handy for subqueries: 1631 1632 ->search( { amount => $some_rs->count_rs->as_query } ) 1633 1634As with regular resultsets the SQL query will be executed only after 1635the resultset is accessed via L</next> or L</all>. That would return 1636the same single value obtainable via L</count>. 1637 1638=cut 1639 1640sub count_rs { 1641 my $self = shift; 1642 return $self->search(@_)->count_rs if @_; 1643 1644 # this may look like a lack of abstraction (count() does about the same) 1645 # but in fact an _rs *must* use a subquery for the limits, as the 1646 # software based limiting can not be ported if this $rs is to be used 1647 # in a subquery itself (i.e. ->as_query) 1648 if ($self->_has_resolved_attr (qw/collapse group_by offset rows/)) { 1649 return $self->_count_subq_rs($self->{_attrs}); 1650 } 1651 else { 1652 return $self->_count_rs($self->{_attrs}); 1653 } 1654} 1655 1656# 1657# returns a ResultSetColumn object tied to the count query 1658# 1659sub _count_rs { 1660 my ($self, $attrs) = @_; 1661 1662 my $rsrc = $self->result_source; 1663 1664 my $tmp_attrs = { %$attrs }; 1665 # take off any limits, record_filter is cdbi, and no point of ordering nor locking a count 1666 delete @{$tmp_attrs}{qw/rows offset order_by record_filter for/}; 1667 1668 # overwrite the selector (supplied by the storage) 1669 $rsrc->resultset_class->new($rsrc, { 1670 %$tmp_attrs, 1671 select => $rsrc->storage->_count_select ($rsrc, $attrs), 1672 as => 'count', 1673 })->get_column ('count'); 1674} 1675 1676# 1677# same as above but uses a subquery 1678# 1679sub _count_subq_rs { 1680 my ($self, $attrs) = @_; 1681 1682 my $rsrc = $self->result_source; 1683 1684 my $sub_attrs = { %$attrs }; 1685 # extra selectors do not go in the subquery and there is no point of ordering it, nor locking it 1686 delete @{$sub_attrs}{qw/collapse columns as select order_by for/}; 1687 1688 # if we multi-prefetch we group_by something unique, as this is what we would 1689 # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless 1690 if ( $attrs->{collapse} ) { 1691 $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } @{ 1692 $rsrc->_identifying_column_set || $self->throw_exception( 1693 'Unable to construct a unique group_by criteria properly collapsing the ' 1694 . 'has_many prefetch before count()' 1695 ); 1696 } ] 1697 } 1698 1699 # Calculate subquery selector 1700 if (my $g = $sub_attrs->{group_by}) { 1701 1702 my $sql_maker = $rsrc->storage->sql_maker; 1703 1704 # necessary as the group_by may refer to aliased functions 1705 my $sel_index; 1706 for my $sel (@{$attrs->{select}}) { 1707 $sel_index->{$sel->{-as}} = $sel 1708 if (ref $sel eq 'HASH' and $sel->{-as}); 1709 } 1710 1711 # anything from the original select mentioned on the group-by needs to make it to the inner selector 1712 # also look for named aggregates referred in the having clause 1713 # having often contains scalarrefs - thus parse it out entirely 1714 my @parts = @$g; 1715 if ($attrs->{having}) { 1716 local $sql_maker->{having_bind}; 1717 local $sql_maker->{quote_char} = $sql_maker->{quote_char}; 1718 local $sql_maker->{name_sep} = $sql_maker->{name_sep}; 1719 unless (defined $sql_maker->{quote_char} and length $sql_maker->{quote_char}) { 1720 $sql_maker->{quote_char} = [ "\x00", "\xFF" ]; 1721 # if we don't unset it we screw up retarded but unfortunately working 1722 # 'MAX(foo.bar)' => { '>', 3 } 1723 $sql_maker->{name_sep} = ''; 1724 } 1725 1726 my ($lquote, $rquote, $sep) = map { quotemeta $_ } ($sql_maker->_quote_chars, $sql_maker->name_sep); 1727 1728 my $having_sql = $sql_maker->_parse_rs_attrs ({ having => $attrs->{having} }); 1729 my %seen_having; 1730 1731 # search for both a proper quoted qualified string, for a naive unquoted scalarref 1732 # and if all fails for an utterly naive quoted scalar-with-function 1733 while ($having_sql =~ / 1734 $rquote $sep $lquote (.+?) $rquote 1735 | 1736 [\s,] \w+ \. (\w+) [\s,] 1737 | 1738 [\s,] $lquote (.+?) $rquote [\s,] 1739 /gx) { 1740 my $part = $1 || $2 || $3; # one of them matched if we got here 1741 unless ($seen_having{$part}++) { 1742 push @parts, $part; 1743 } 1744 } 1745 } 1746 1747 for (@parts) { 1748 my $colpiece = $sel_index->{$_} || $_; 1749 1750 # unqualify join-based group_by's. Arcane but possible query 1751 # also horrible horrible hack to alias a column (not a func.) 1752 if ($colpiece =~ /\./ && $colpiece !~ /^$attrs->{alias}\./) { 1753 my $as = $colpiece; 1754 $as =~ s/\./__/; 1755 $colpiece = \ sprintf ('%s AS %s', map { $sql_maker->_quote ($_) } ($colpiece, $as) ); 1756 } 1757 push @{$sub_attrs->{select}}, $colpiece; 1758 } 1759 } 1760 else { 1761 my @pcols = map { "$attrs->{alias}.$_" } ($rsrc->primary_columns); 1762 $sub_attrs->{select} = @pcols ? \@pcols : [ 1 ]; 1763 } 1764 1765 return $rsrc->resultset_class 1766 ->new ($rsrc, $sub_attrs) 1767 ->as_subselect_rs 1768 ->search ({}, { columns => { count => $rsrc->storage->_count_select ($rsrc, $attrs) } }) 1769 ->get_column ('count'); 1770} 1771 1772 1773=head2 count_literal 1774 1775B<CAVEAT>: C<count_literal> is provided for Class::DBI compatibility and 1776should only be used in that context. See L</search_literal> for further info. 1777 1778=over 4 1779 1780=item Arguments: $sql_fragment, @standalone_bind_values 1781 1782=item Return Value: $count 1783 1784=back 1785 1786Counts the results in a literal query. Equivalent to calling L</search_literal> 1787with the passed arguments, then L</count>. 1788 1789=cut 1790 1791sub count_literal { shift->search_literal(@_)->count; } 1792 1793=head2 all 1794 1795=over 4 1796 1797=item Arguments: none 1798 1799=item Return Value: L<@result_objs|DBIx::Class::Manual::ResultClass> 1800 1801=back 1802 1803Returns all elements in the resultset. 1804 1805=cut 1806 1807sub all { 1808 my $self = shift; 1809 if(@_) { 1810 $self->throw_exception("all() doesn't take any arguments, you probably wanted ->search(...)->all()"); 1811 } 1812 1813 delete @{$self}{qw/_stashed_rows _stashed_results/}; 1814 1815 if (my $c = $self->get_cache) { 1816 return @$c; 1817 } 1818 1819 $self->cursor->reset; 1820 1821 my $objs = $self->_construct_results('fetch_all') || []; 1822 1823 $self->set_cache($objs) if $self->{attrs}{cache}; 1824 1825 return @$objs; 1826} 1827 1828=head2 reset 1829 1830=over 4 1831 1832=item Arguments: none 1833 1834=item Return Value: $self 1835 1836=back 1837 1838Resets the resultset's cursor, so you can iterate through the elements again. 1839Implicitly resets the storage cursor, so a subsequent L</next> will trigger 1840another query. 1841 1842=cut 1843 1844sub reset { 1845 my ($self) = @_; 1846 1847 delete @{$self}{qw/_stashed_rows _stashed_results/}; 1848 $self->{all_cache_position} = 0; 1849 $self->cursor->reset; 1850 return $self; 1851} 1852 1853=head2 first 1854 1855=over 4 1856 1857=item Arguments: none 1858 1859=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> | undef 1860 1861=back 1862 1863L<Resets|/reset> the resultset (causing a fresh query to storage) and returns 1864an object for the first result (or C<undef> if the resultset is empty). 1865 1866=cut 1867 1868sub first { 1869 return $_[0]->reset->next; 1870} 1871 1872 1873# _rs_update_delete 1874# 1875# Determines whether and what type of subquery is required for the $rs operation. 1876# If grouping is necessary either supplies its own, or verifies the current one 1877# After all is done delegates to the proper storage method. 1878 1879sub _rs_update_delete { 1880 my ($self, $op, $values) = @_; 1881 1882 my $rsrc = $self->result_source; 1883 my $storage = $rsrc->schema->storage; 1884 1885 my $attrs = { %{$self->_resolved_attrs} }; 1886 1887 my $join_classifications; 1888 my ($existing_group_by) = delete @{$attrs}{qw(group_by _grouped_by_distinct)}; 1889 1890 # do we need a subquery for any reason? 1891 my $needs_subq = ( 1892 defined $existing_group_by 1893 or 1894 # if {from} is unparseable wrap a subq 1895 ref($attrs->{from}) ne 'ARRAY' 1896 or 1897 # limits call for a subq 1898 $self->_has_resolved_attr(qw/rows offset/) 1899 ); 1900 1901 # simplify the joinmap, so we can further decide if a subq is necessary 1902 if (!$needs_subq and @{$attrs->{from}} > 1) { 1903 1904 ($attrs->{from}, $join_classifications) = 1905 $storage->_prune_unused_joins ($attrs); 1906 1907 # any non-pruneable non-local restricting joins imply subq 1908 $needs_subq = grep { $_ ne $attrs->{alias} } keys %{ $join_classifications->{restricting} || {} }; 1909 } 1910 1911 # check if the head is composite (by now all joins are thrown out unless $needs_subq) 1912 $needs_subq ||= ( 1913 (ref $attrs->{from}[0]) ne 'HASH' 1914 or 1915 ref $attrs->{from}[0]{ $attrs->{from}[0]{-alias} } 1916 ); 1917 1918 my ($cond, $guard); 1919 # do we need anything like a subquery? 1920 if (! $needs_subq) { 1921 # Most databases do not allow aliasing of tables in UPDATE/DELETE. Thus 1922 # a condition containing 'me' or other table prefixes will not work 1923 # at all. Tell SQLMaker to dequalify idents via a gross hack. 1924 $cond = do { 1925 my $sqla = $rsrc->storage->sql_maker; 1926 local $sqla->{_dequalify_idents} = 1; 1927 \[ $sqla->_recurse_where($self->{cond}) ]; 1928 }; 1929 } 1930 else { 1931 # we got this far - means it is time to wrap a subquery 1932 my $idcols = $rsrc->_identifying_column_set || $self->throw_exception( 1933 sprintf( 1934 "Unable to perform complex resultset %s() without an identifying set of columns on source '%s'", 1935 $op, 1936 $rsrc->source_name, 1937 ) 1938 ); 1939 1940 # make a new $rs selecting only the PKs (that's all we really need for the subq) 1941 delete $attrs->{$_} for qw/select as collapse/; 1942 $attrs->{columns} = [ map { "$attrs->{alias}.$_" } @$idcols ]; 1943 1944 # this will be consumed by the pruner waaaaay down the stack 1945 $attrs->{_force_prune_multiplying_joins} = 1; 1946 1947 my $subrs = (ref $self)->new($rsrc, $attrs); 1948 1949 if (@$idcols == 1) { 1950 $cond = { $idcols->[0] => { -in => $subrs->as_query } }; 1951 } 1952 elsif ($storage->_use_multicolumn_in) { 1953 # no syntax for calling this properly yet 1954 # !!! EXPERIMENTAL API !!! WILL CHANGE !!! 1955 $cond = $storage->sql_maker->_where_op_multicolumn_in ( 1956 $idcols, # how do I convey a list of idents...? can binds reside on lhs? 1957 $subrs->as_query 1958 ), 1959 } 1960 else { 1961 # if all else fails - get all primary keys and operate over a ORed set 1962 # wrap in a transaction for consistency 1963 # this is where the group_by/multiplication starts to matter 1964 if ( 1965 $existing_group_by 1966 or 1967 # we do not need to check pre-multipliers, since if the premulti is there, its 1968 # parent (who is multi) will be there too 1969 keys %{ $join_classifications->{multiplying} || {} } 1970 ) { 1971 # make sure if there is a supplied group_by it matches the columns compiled above 1972 # perfectly. Anything else can not be sanely executed on most databases so croak 1973 # right then and there 1974 if ($existing_group_by) { 1975 my @current_group_by = map 1976 { $_ =~ /\./ ? $_ : "$attrs->{alias}.$_" } 1977 @$existing_group_by 1978 ; 1979 1980 if ( 1981 join ("\x00", sort @current_group_by) 1982 ne 1983 join ("\x00", sort @{$attrs->{columns}} ) 1984 ) { 1985 $self->throw_exception ( 1986 "You have just attempted a $op operation on a resultset which does group_by" 1987 . ' on columns other than the primary keys, while DBIC internally needs to retrieve' 1988 . ' the primary keys in a subselect. All sane RDBMS engines do not support this' 1989 . ' kind of queries. Please retry the operation with a modified group_by or' 1990 . ' without using one at all.' 1991 ); 1992 } 1993 } 1994 1995 $subrs = $subrs->search({}, { group_by => $attrs->{columns} }); 1996 } 1997 1998 $guard = $storage->txn_scope_guard; 1999 2000 for my $row ($subrs->cursor->all) { 2001 push @$cond, { map 2002 { $idcols->[$_] => $row->[$_] } 2003 (0 .. $#$idcols) 2004 }; 2005 } 2006 } 2007 } 2008 2009 my $res = $cond ? $storage->$op ( 2010 $rsrc, 2011 $op eq 'update' ? $values : (), 2012 $cond, 2013 ) : '0E0'; 2014 2015 $guard->commit if $guard; 2016 2017 return $res; 2018} 2019 2020=head2 update 2021 2022=over 4 2023 2024=item Arguments: \%values 2025 2026=item Return Value: $underlying_storage_rv 2027 2028=back 2029 2030Sets the specified columns in the resultset to the supplied values in a 2031single query. Note that this will not run any accessor/set_column/update 2032triggers, nor will it update any result object instances derived from this 2033resultset (this includes the contents of the L<resultset cache|/set_cache> 2034if any). See L</update_all> if you need to execute any on-update 2035triggers or cascades defined either by you or a 2036L<result component|DBIx::Class::Manual::Component/WHAT IS A COMPONENT>. 2037 2038The return value is a pass through of what the underlying 2039storage backend returned, and may vary. See L<DBI/execute> for the most 2040common case. 2041 2042=head3 CAVEAT 2043 2044Note that L</update> does not process/deflate any of the values passed in. 2045This is unlike the corresponding L<DBIx::Class::Row/update>. The user must 2046ensure manually that any value passed to this method will stringify to 2047something the RDBMS knows how to deal with. A notable example is the 2048handling of L<DateTime> objects, for more info see: 2049L<DBIx::Class::Manual::Cookbook/Formatting DateTime objects in queries>. 2050 2051=cut 2052 2053sub update { 2054 my ($self, $values) = @_; 2055 $self->throw_exception('Values for update must be a hash') 2056 unless ref $values eq 'HASH'; 2057 2058 return $self->_rs_update_delete ('update', $values); 2059} 2060 2061=head2 update_all 2062 2063=over 4 2064 2065=item Arguments: \%values 2066 2067=item Return Value: 1 2068 2069=back 2070 2071Fetches all objects and updates them one at a time via 2072L<DBIx::Class::Row/update>. Note that C<update_all> will run DBIC defined 2073triggers, while L</update> will not. 2074 2075=cut 2076 2077sub update_all { 2078 my ($self, $values) = @_; 2079 $self->throw_exception('Values for update_all must be a hash') 2080 unless ref $values eq 'HASH'; 2081 2082 my $guard = $self->result_source->schema->txn_scope_guard; 2083 $_->update({%$values}) for $self->all; # shallow copy - update will mangle it 2084 $guard->commit; 2085 return 1; 2086} 2087 2088=head2 delete 2089 2090=over 4 2091 2092=item Arguments: none 2093 2094=item Return Value: $underlying_storage_rv 2095 2096=back 2097 2098Deletes the rows matching this resultset in a single query. Note that this 2099will not run any delete triggers, nor will it alter the 2100L<in_storage|DBIx::Class::Row/in_storage> status of any result object instances 2101derived from this resultset (this includes the contents of the 2102L<resultset cache|/set_cache> if any). See L</delete_all> if you need to 2103execute any on-delete triggers or cascades defined either by you or a 2104L<result component|DBIx::Class::Manual::Component/WHAT IS A COMPONENT>. 2105 2106The return value is a pass through of what the underlying storage backend 2107returned, and may vary. See L<DBI/execute> for the most common case. 2108 2109=cut 2110 2111sub delete { 2112 my $self = shift; 2113 $self->throw_exception('delete does not accept any arguments') 2114 if @_; 2115 2116 return $self->_rs_update_delete ('delete'); 2117} 2118 2119=head2 delete_all 2120 2121=over 4 2122 2123=item Arguments: none 2124 2125=item Return Value: 1 2126 2127=back 2128 2129Fetches all objects and deletes them one at a time via 2130L<DBIx::Class::Row/delete>. Note that C<delete_all> will run DBIC defined 2131triggers, while L</delete> will not. 2132 2133=cut 2134 2135sub delete_all { 2136 my $self = shift; 2137 $self->throw_exception('delete_all does not accept any arguments') 2138 if @_; 2139 2140 my $guard = $self->result_source->schema->txn_scope_guard; 2141 $_->delete for $self->all; 2142 $guard->commit; 2143 return 1; 2144} 2145 2146=head2 populate 2147 2148=over 4 2149 2150=item Arguments: [ \@column_list, \@row_values+ ] | [ \%col_data+ ] 2151 2152=item Return Value: L<\@result_objects|DBIx::Class::Manual::ResultClass> (scalar context) | L<@result_objects|DBIx::Class::Manual::ResultClass> (list context) 2153 2154=back 2155 2156Accepts either an arrayref of hashrefs or alternatively an arrayref of 2157arrayrefs. 2158 2159=over 2160 2161=item NOTE 2162 2163The context of this method call has an important effect on what is 2164submitted to storage. In void context data is fed directly to fastpath 2165insertion routines provided by the underlying storage (most often 2166L<DBI/execute_for_fetch>), bypassing the L<new|DBIx::Class::Row/new> and 2167L<insert|DBIx::Class::Row/insert> calls on the 2168L<Result|DBIx::Class::Manual::ResultClass> class, including any 2169augmentation of these methods provided by components. For example if you 2170are using something like L<DBIx::Class::UUIDColumns> to create primary 2171keys for you, you will find that your PKs are empty. In this case you 2172will have to explicitly force scalar or list context in order to create 2173those values. 2174 2175=back 2176 2177In non-void (scalar or list) context, this method is simply a wrapper 2178for L</create>. Depending on list or scalar context either a list of 2179L<Result|DBIx::Class::Manual::ResultClass> objects or an arrayref 2180containing these objects is returned. 2181 2182When supplying data in "arrayref of arrayrefs" invocation style, the 2183first element should be a list of column names and each subsequent 2184element should be a data value in the earlier specified column order. 2185For example: 2186 2187 $schema->resultset("Artist")->populate([ 2188 [ qw( artistid name ) ], 2189 [ 100, 'A Formally Unknown Singer' ], 2190 [ 101, 'A singer that jumped the shark two albums ago' ], 2191 [ 102, 'An actually cool singer' ], 2192 ]); 2193 2194For the arrayref of hashrefs style each hashref should be a structure 2195suitable for passing to L</create>. Multi-create is also permitted with 2196this syntax. 2197 2198 $schema->resultset("Artist")->populate([ 2199 { artistid => 4, name => 'Manufactured Crap', cds => [ 2200 { title => 'My First CD', year => 2006 }, 2201 { title => 'Yet More Tweeny-Pop crap', year => 2007 }, 2202 ], 2203 }, 2204 { artistid => 5, name => 'Angsty-Whiny Girl', cds => [ 2205 { title => 'My parents sold me to a record company', year => 2005 }, 2206 { title => 'Why Am I So Ugly?', year => 2006 }, 2207 { title => 'I Got Surgery and am now Popular', year => 2007 } 2208 ], 2209 }, 2210 ]); 2211 2212If you attempt a void-context multi-create as in the example above (each 2213Artist also has the related list of CDs), and B<do not> supply the 2214necessary autoinc foreign key information, this method will proxy to the 2215less efficient L</create>, and then throw the Result objects away. In this 2216case there are obviously no benefits to using this method over L</create>. 2217 2218=cut 2219 2220sub populate { 2221 my $self = shift; 2222 2223 # this is naive and just a quick check 2224 # the types will need to be checked more thoroughly when the 2225 # multi-source populate gets added 2226 my $data = ( 2227 ref $_[0] eq 'ARRAY' 2228 and 2229 ( @{$_[0]} or return ) 2230 and 2231 ( ref $_[0][0] eq 'HASH' or ref $_[0][0] eq 'ARRAY' ) 2232 and 2233 $_[0] 2234 ) or $self->throw_exception('Populate expects an arrayref of hashrefs or arrayref of arrayrefs'); 2235 2236 # FIXME - no cref handling 2237 # At this point assume either hashes or arrays 2238 2239 if(defined wantarray) { 2240 my (@results, $guard); 2241 2242 if (ref $data->[0] eq 'ARRAY') { 2243 # column names only, nothing to do 2244 return if @$data == 1; 2245 2246 $guard = $self->result_source->schema->storage->txn_scope_guard 2247 if @$data > 2; 2248 2249 @results = map 2250 { my $vals = $_; $self->new_result({ map { $data->[0][$_] => $vals->[$_] } 0..$#{$data->[0]} })->insert } 2251 @{$data}[1 .. $#$data] 2252 ; 2253 } 2254 else { 2255 2256 $guard = $self->result_source->schema->storage->txn_scope_guard 2257 if @$data > 1; 2258 2259 @results = map { $self->new_result($_)->insert } @$data; 2260 } 2261 2262 $guard->commit if $guard; 2263 return wantarray ? @results : \@results; 2264 } 2265 2266 # we have to deal with *possibly incomplete* related data 2267 # this means we have to walk the data structure twice 2268 # whether we want this or not 2269 # jnap, I hate you ;) 2270 my $rsrc = $self->result_source; 2271 my $rel_info = { map { $_ => $rsrc->relationship_info($_) } $rsrc->relationships }; 2272 2273 my ($colinfo, $colnames, $slices_with_rels); 2274 my $data_start = 0; 2275 2276 DATA_SLICE: 2277 for my $i (0 .. $#$data) { 2278 2279 my $current_slice_seen_rel_infos; 2280 2281### Determine/Supplement collists 2282### BEWARE - This is a hot piece of code, a lot of weird idioms were used 2283 if( ref $data->[$i] eq 'ARRAY' ) { 2284 2285 # positional(!) explicit column list 2286 if ($i == 0) { 2287 # column names only, nothing to do 2288 return if @$data == 1; 2289 2290 $colinfo->{$data->[0][$_]} = { pos => $_, name => $data->[0][$_] } and push @$colnames, $data->[0][$_] 2291 for 0 .. $#{$data->[0]}; 2292 2293 $data_start = 1; 2294 2295 next DATA_SLICE; 2296 } 2297 else { 2298 for (values %$colinfo) { 2299 if ($_->{is_rel} ||= ( 2300 $rel_info->{$_->{name}} 2301 and 2302 ( 2303 ref $data->[$i][$_->{pos}] eq 'ARRAY' 2304 or 2305 ref $data->[$i][$_->{pos}] eq 'HASH' 2306 or 2307 ( defined blessed $data->[$i][$_->{pos}] and $data->[$i][$_->{pos}]->isa('DBIx::Class::Row') ) 2308 ) 2309 and 2310 1 2311 )) { 2312 2313 # moar sanity check... sigh 2314 for ( ref $data->[$i][$_->{pos}] eq 'ARRAY' ? @{$data->[$i][$_->{pos}]} : $data->[$i][$_->{pos}] ) { 2315 if ( defined blessed $_ and $_->isa('DBIx::Class::Row' ) ) { 2316 carp_unique("Fast-path populate() with supplied related objects is not possible - falling back to regular create()"); 2317 return my $throwaway = $self->populate(@_); 2318 } 2319 } 2320 2321 push @$current_slice_seen_rel_infos, $rel_info->{$_->{name}}; 2322 } 2323 } 2324 } 2325 2326 if ($current_slice_seen_rel_infos) { 2327 push @$slices_with_rels, { map { $colnames->[$_] => $data->[$i][$_] } 0 .. $#$colnames }; 2328 2329 # this is needed further down to decide whether or not to fallback to create() 2330 $colinfo->{$colnames->[$_]}{seen_null} ||= ! defined $data->[$i][$_] 2331 for 0 .. $#$colnames; 2332 } 2333 } 2334 elsif( ref $data->[$i] eq 'HASH' ) { 2335 2336 for ( sort keys %{$data->[$i]} ) { 2337 2338 $colinfo->{$_} ||= do { 2339 2340 $self->throw_exception("Column '$_' must be present in supplied explicit column list") 2341 if $data_start; # it will be 0 on AoH, 1 on AoA 2342 2343 push @$colnames, $_; 2344 2345 # RV 2346 { pos => $#$colnames, name => $_ } 2347 }; 2348 2349 if ($colinfo->{$_}{is_rel} ||= ( 2350 $rel_info->{$_} 2351 and 2352 ( 2353 ref $data->[$i]{$_} eq 'ARRAY' 2354 or 2355 ref $data->[$i]{$_} eq 'HASH' 2356 or 2357 ( defined blessed $data->[$i]{$_} and $data->[$i]{$_}->isa('DBIx::Class::Row') ) 2358 ) 2359 and 2360 1 2361 )) { 2362 2363 # moar sanity check... sigh 2364 for ( ref $data->[$i]{$_} eq 'ARRAY' ? @{$data->[$i]{$_}} : $data->[$i]{$_} ) { 2365 if ( defined blessed $_ and $_->isa('DBIx::Class::Row' ) ) { 2366 carp_unique("Fast-path populate() with supplied related objects is not possible - falling back to regular create()"); 2367 return my $throwaway = $self->populate(@_); 2368 } 2369 } 2370 2371 push @$current_slice_seen_rel_infos, $rel_info->{$_}; 2372 } 2373 } 2374 2375 if ($current_slice_seen_rel_infos) { 2376 push @$slices_with_rels, $data->[$i]; 2377 2378 # this is needed further down to decide whether or not to fallback to create() 2379 $colinfo->{$_}{seen_null} ||= ! defined $data->[$i]{$_} 2380 for keys %{$data->[$i]}; 2381 } 2382 } 2383 else { 2384 $self->throw_exception('Unexpected populate() data structure member type: ' . ref $data->[$i] ); 2385 } 2386 2387 if ( grep 2388 { $_->{attrs}{is_depends_on} } 2389 @{ $current_slice_seen_rel_infos || [] } 2390 ) { 2391 carp_unique("Fast-path populate() of belongs_to relationship data is not possible - falling back to regular create()"); 2392 return my $throwaway = $self->populate(@_); 2393 } 2394 } 2395 2396 if( $slices_with_rels ) { 2397 2398 # need to exclude the rel "columns" 2399 $colnames = [ grep { ! $colinfo->{$_}{is_rel} } @$colnames ]; 2400 2401 # extra sanity check - ensure the main source is in fact identifiable 2402 # the localizing of nullability is insane, but oh well... the use-case is legit 2403 my $ci = $rsrc->columns_info($colnames); 2404 2405 $ci->{$_} = { %{$ci->{$_}}, is_nullable => 0 } 2406 for grep { ! $colinfo->{$_}{seen_null} } keys %$ci; 2407 2408 unless( $rsrc->_identifying_column_set($ci) ) { 2409 carp_unique("Fast-path populate() of non-uniquely identifiable rows with related data is not possible - falling back to regular create()"); 2410 return my $throwaway = $self->populate(@_); 2411 } 2412 } 2413 2414### inherit the data locked in the conditions of the resultset 2415 my ($rs_data) = $self->_merge_with_rscond({}); 2416 delete @{$rs_data}{@$colnames}; # passed-in stuff takes precedence 2417 2418 # if anything left - decompose rs_data 2419 my $rs_data_vals; 2420 if (keys %$rs_data) { 2421 push @$rs_data_vals, $rs_data->{$_} 2422 for sort keys %$rs_data; 2423 } 2424 2425### start work 2426 my $guard; 2427 $guard = $rsrc->schema->storage->txn_scope_guard 2428 if $slices_with_rels; 2429 2430### main source data 2431 # FIXME - need to switch entirely to a coderef-based thing, 2432 # so that large sets aren't copied several times... I think 2433 $rsrc->storage->_insert_bulk( 2434 $rsrc, 2435 [ @$colnames, sort keys %$rs_data ], 2436 [ map { 2437 ref $data->[$_] eq 'ARRAY' 2438 ? ( 2439 $slices_with_rels ? [ @{$data->[$_]}[0..$#$colnames], @{$rs_data_vals||[]} ] # the collist changed 2440 : $rs_data_vals ? [ @{$data->[$_]}, @$rs_data_vals ] 2441 : $data->[$_] 2442 ) 2443 : [ @{$data->[$_]}{@$colnames}, @{$rs_data_vals||[]} ] 2444 } $data_start .. $#$data ], 2445 ); 2446 2447### do the children relationships 2448 if ( $slices_with_rels ) { 2449 my @rels = grep { $colinfo->{$_}{is_rel} } keys %$colinfo 2450 or die 'wtf... please report a bug with DBIC_TRACE=1 output (stacktrace)'; 2451 2452 for my $sl (@$slices_with_rels) { 2453 2454 my ($main_proto, $main_proto_rs); 2455 for my $rel (@rels) { 2456 next unless defined $sl->{$rel}; 2457 2458 $main_proto ||= { 2459 %$rs_data, 2460 (map { $_ => $sl->{$_} } @$colnames), 2461 }; 2462 2463 unless (defined $colinfo->{$rel}{rs}) { 2464 2465 $colinfo->{$rel}{rs} = $rsrc->related_source($rel)->resultset; 2466 2467 $colinfo->{$rel}{fk_map} = { reverse %{ $rsrc->_resolve_relationship_condition( 2468 rel_name => $rel, 2469 self_alias => "\xFE", # irrelevant 2470 foreign_alias => "\xFF", # irrelevant 2471 )->{identity_map} || {} } }; 2472 2473 } 2474 2475 $colinfo->{$rel}{rs}->search({ map # only so that we inherit them values properly, no actual search 2476 { 2477 $_ => { '=' => 2478 ( $main_proto_rs ||= $rsrc->resultset->search($main_proto) ) 2479 ->get_column( $colinfo->{$rel}{fk_map}{$_} ) 2480 ->as_query 2481 } 2482 } 2483 keys %{$colinfo->{$rel}{fk_map}} 2484 })->populate( ref $sl->{$rel} eq 'ARRAY' ? $sl->{$rel} : [ $sl->{$rel} ] ); 2485 2486 1; 2487 } 2488 } 2489 } 2490 2491 $guard->commit if $guard; 2492} 2493 2494=head2 pager 2495 2496=over 4 2497 2498=item Arguments: none 2499 2500=item Return Value: L<$pager|DBIx::Class::ResultSet::Pager> 2501 2502=back 2503 2504Returns a L<DBIx::Class::ResultSet::Pager> object tied to the current 2505resultset. Requires the C<page> attribute to have been previously set on 2506the resultset object, usually via a call to L</page>. 2507 2508To get the full count of entries for a paged resultset, call 2509L<total_entries|DBIx::Class::ResultSet::Pager/total_entries> on the pager 2510object. 2511 2512=cut 2513 2514sub pager { 2515 my ($self) = @_; 2516 2517 return $self->{pager} if $self->{pager}; 2518 2519 my $attrs = $self->{attrs}; 2520 if (!defined $attrs->{page}) { 2521 $self->throw_exception("Can't create pager for non-paged rs, you need to call page(\$num) first"); 2522 } 2523 elsif ($attrs->{page} <= 0) { 2524 $self->throw_exception('Invalid page number (page-numbers are 1-based)'); 2525 } 2526 $attrs->{rows} ||= 10; 2527 2528 # throw away the paging flags and re-run the count (possibly 2529 # with a subselect) to get the real total count 2530 my $count_attrs = { %$attrs }; 2531 delete @{$count_attrs}{qw/rows offset page pager/}; 2532 2533 my $total_rs = (ref $self)->new($self->result_source, $count_attrs); 2534 2535 require DBIx::Class::ResultSet::Pager; 2536 return $self->{pager} = DBIx::Class::ResultSet::Pager->new( 2537 sub { $total_rs->count }, #lazy-get the total 2538 $attrs->{rows}, 2539 $self->{attrs}{page}, 2540 ); 2541} 2542 2543=head2 page 2544 2545=over 4 2546 2547=item Arguments: $page_number 2548 2549=item Return Value: L<$resultset|/search> 2550 2551=back 2552 2553Returns a resultset for the $page_number page of the resultset on which page 2554is called, where each page contains a number of rows equal to the 'rows' 2555attribute set on the resultset (10 by default). 2556 2557=cut 2558 2559sub page { 2560 my ($self, $page) = @_; 2561 return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page }); 2562} 2563 2564=head2 new_result 2565 2566=over 4 2567 2568=item Arguments: \%col_data 2569 2570=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 2571 2572=back 2573 2574Creates a new result object in the resultset's result class and returns 2575it. The row is not inserted into the database at this point, call 2576L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage> 2577will tell you whether the result object has been inserted or not. 2578 2579Passes the hashref of input on to L<DBIx::Class::Row/new>. 2580 2581=cut 2582 2583sub new_result { 2584 my ($self, $values) = @_; 2585 2586 $self->throw_exception( "new_result takes only one argument - a hashref of values" ) 2587 if @_ > 2; 2588 2589 $self->throw_exception( "Result object instantiation requires a hashref as argument" ) 2590 unless (ref $values eq 'HASH'); 2591 2592 my ($merged_cond, $cols_from_relations) = $self->_merge_with_rscond($values); 2593 2594 my $new = $self->result_class->new({ 2595 %$merged_cond, 2596 ( @$cols_from_relations 2597 ? (-cols_from_relations => $cols_from_relations) 2598 : () 2599 ), 2600 -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED 2601 }); 2602 2603 if ( 2604 reftype($new) eq 'HASH' 2605 and 2606 ! keys %$new 2607 and 2608 blessed($new) 2609 ) { 2610 carp_unique (sprintf ( 2611 "%s->new returned a blessed empty hashref - a strong indicator something is wrong with its inheritance chain", 2612 $self->result_class, 2613 )); 2614 } 2615 2616 $new; 2617} 2618 2619# _merge_with_rscond 2620# 2621# Takes a simple hash of K/V data and returns its copy merged with the 2622# condition already present on the resultset. Additionally returns an 2623# arrayref of value/condition names, which were inferred from related 2624# objects (this is needed for in-memory related objects) 2625sub _merge_with_rscond { 2626 my ($self, $data) = @_; 2627 2628 my ($implied_data, @cols_from_relations); 2629 2630 my $alias = $self->{attrs}{alias}; 2631 2632 if (! defined $self->{cond}) { 2633 # just massage $data below 2634 } 2635 elsif ($self->{cond} eq UNRESOLVABLE_CONDITION) { 2636 $implied_data = $self->{attrs}{related_objects}; # nothing might have been inserted yet 2637 @cols_from_relations = keys %{ $implied_data || {} }; 2638 } 2639 else { 2640 my $eqs = $self->result_source->schema->storage->_extract_fixed_condition_columns($self->{cond}, 'consider_nulls'); 2641 $implied_data = { map { 2642 ( ($eqs->{$_}||'') eq UNRESOLVABLE_CONDITION ) ? () : ( $_ => $eqs->{$_} ) 2643 } keys %$eqs }; 2644 } 2645 2646 return ( 2647 { map 2648 { %{ $self->_remove_alias($_, $alias) } } 2649 # precedence must be given to passed values over values inherited from 2650 # the cond, so the order here is important. 2651 ( $implied_data||(), $data) 2652 }, 2653 \@cols_from_relations 2654 ); 2655} 2656 2657# _has_resolved_attr 2658# 2659# determines if the resultset defines at least one 2660# of the attributes supplied 2661# 2662# used to determine if a subquery is necessary 2663# 2664# supports some virtual attributes: 2665# -join 2666# This will scan for any joins being present on the resultset. 2667# It is not a mere key-search but a deep inspection of {from} 2668# 2669 2670sub _has_resolved_attr { 2671 my ($self, @attr_names) = @_; 2672 2673 my $attrs = $self->_resolved_attrs; 2674 2675 my %extra_checks; 2676 2677 for my $n (@attr_names) { 2678 if (grep { $n eq $_ } (qw/-join/) ) { 2679 $extra_checks{$n}++; 2680 next; 2681 } 2682 2683 my $attr = $attrs->{$n}; 2684 2685 next if not defined $attr; 2686 2687 if (ref $attr eq 'HASH') { 2688 return 1 if keys %$attr; 2689 } 2690 elsif (ref $attr eq 'ARRAY') { 2691 return 1 if @$attr; 2692 } 2693 else { 2694 return 1 if $attr; 2695 } 2696 } 2697 2698 # a resolved join is expressed as a multi-level from 2699 return 1 if ( 2700 $extra_checks{-join} 2701 and 2702 ref $attrs->{from} eq 'ARRAY' 2703 and 2704 @{$attrs->{from}} > 1 2705 ); 2706 2707 return 0; 2708} 2709 2710# _remove_alias 2711# 2712# Remove the specified alias from the specified query hash. A copy is made so 2713# the original query is not modified. 2714 2715sub _remove_alias { 2716 my ($self, $query, $alias) = @_; 2717 2718 my %orig = %{ $query || {} }; 2719 my %unaliased; 2720 2721 foreach my $key (keys %orig) { 2722 if ($key !~ /\./) { 2723 $unaliased{$key} = $orig{$key}; 2724 next; 2725 } 2726 $unaliased{$1} = $orig{$key} 2727 if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/; 2728 } 2729 2730 return \%unaliased; 2731} 2732 2733=head2 as_query 2734 2735=over 4 2736 2737=item Arguments: none 2738 2739=item Return Value: \[ $sql, L<@bind_values|/DBIC BIND VALUES> ] 2740 2741=back 2742 2743Returns the SQL query and bind vars associated with the invocant. 2744 2745This is generally used as the RHS for a subquery. 2746 2747=cut 2748 2749sub as_query { 2750 my $self = shift; 2751 2752 my $attrs = { %{ $self->_resolved_attrs } }; 2753 2754 my $aq = $self->result_source->storage->_select_args_to_query ( 2755 $attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs 2756 ); 2757 2758 $aq; 2759} 2760 2761=head2 find_or_new 2762 2763=over 4 2764 2765=item Arguments: \%col_data, { key => $unique_constraint, L<%attrs|/ATTRIBUTES> }? 2766 2767=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 2768 2769=back 2770 2771 my $artist = $schema->resultset('Artist')->find_or_new( 2772 { artist => 'fred' }, { key => 'artists' }); 2773 2774 $cd->cd_to_producer->find_or_new({ producer => $producer }, 2775 { key => 'primary' }); 2776 2777Find an existing record from this resultset using L</find>. if none exists, 2778instantiate a new result object and return it. The object will not be saved 2779into your storage until you call L<DBIx::Class::Row/insert> on it. 2780 2781You most likely want this method when looking for existing rows using a unique 2782constraint that is not the primary key, or looking for related rows. 2783 2784If you want objects to be saved immediately, use L</find_or_create> instead. 2785 2786B<Note>: Make sure to read the documentation of L</find> and understand the 2787significance of the C<key> attribute, as its lack may skew your search, and 2788subsequently result in spurious new objects. 2789 2790B<Note>: Take care when using C<find_or_new> with a table having 2791columns with default values that you intend to be automatically 2792supplied by the database (e.g. an auto_increment primary key column). 2793In normal usage, the value of such columns should NOT be included at 2794all in the call to C<find_or_new>, even when set to C<undef>. 2795 2796=cut 2797 2798sub find_or_new { 2799 my $self = shift; 2800 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); 2801 my $hash = ref $_[0] eq 'HASH' ? shift : {@_}; 2802 if (keys %$hash and my $row = $self->find($hash, $attrs) ) { 2803 return $row; 2804 } 2805 return $self->new_result($hash); 2806} 2807 2808=head2 create 2809 2810=over 4 2811 2812=item Arguments: \%col_data 2813 2814=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 2815 2816=back 2817 2818Attempt to create a single new row or a row with multiple related rows 2819in the table represented by the resultset (and related tables). This 2820will not check for duplicate rows before inserting, use 2821L</find_or_create> to do that. 2822 2823To create one row for this resultset, pass a hashref of key/value 2824pairs representing the columns of the table and the values you wish to 2825store. If the appropriate relationships are set up, foreign key fields 2826can also be passed an object representing the foreign row, and the 2827value will be set to its primary key. 2828 2829To create related objects, pass a hashref of related-object column values 2830B<keyed on the relationship name>. If the relationship is of type C<multi> 2831(L<DBIx::Class::Relationship/has_many>) - pass an arrayref of hashrefs. 2832The process will correctly identify columns holding foreign keys, and will 2833transparently populate them from the keys of the corresponding relation. 2834This can be applied recursively, and will work correctly for a structure 2835with an arbitrary depth and width, as long as the relationships actually 2836exists and the correct column data has been supplied. 2837 2838Instead of hashrefs of plain related data (key/value pairs), you may 2839also pass new or inserted objects. New objects (not inserted yet, see 2840L</new_result>), will be inserted into their appropriate tables. 2841 2842Effectively a shortcut for C<< ->new_result(\%col_data)->insert >>. 2843 2844Example of creating a new row. 2845 2846 $person_rs->create({ 2847 name=>"Some Person", 2848 email=>"somebody@someplace.com" 2849 }); 2850 2851Example of creating a new row and also creating rows in a related C<has_many> 2852or C<has_one> resultset. Note Arrayref. 2853 2854 $artist_rs->create( 2855 { artistid => 4, name => 'Manufactured Crap', cds => [ 2856 { title => 'My First CD', year => 2006 }, 2857 { title => 'Yet More Tweeny-Pop crap', year => 2007 }, 2858 ], 2859 }, 2860 ); 2861 2862Example of creating a new row and also creating a row in a related 2863C<belongs_to> resultset. Note Hashref. 2864 2865 $cd_rs->create({ 2866 title=>"Music for Silly Walks", 2867 year=>2000, 2868 artist => { 2869 name=>"Silly Musician", 2870 } 2871 }); 2872 2873=over 2874 2875=item WARNING 2876 2877When subclassing ResultSet never attempt to override this method. Since 2878it is a simple shortcut for C<< $self->new_result($attrs)->insert >>, a 2879lot of the internals simply never call it, so your override will be 2880bypassed more often than not. Override either L<DBIx::Class::Row/new> 2881or L<DBIx::Class::Row/insert> depending on how early in the 2882L</create> process you need to intervene. See also warning pertaining to 2883L</new>. 2884 2885=back 2886 2887=cut 2888 2889sub create { 2890 #my ($self, $col_data) = @_; 2891 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call; 2892 return shift->new_result(shift)->insert; 2893} 2894 2895=head2 find_or_create 2896 2897=over 4 2898 2899=item Arguments: \%col_data, { key => $unique_constraint, L<%attrs|/ATTRIBUTES> }? 2900 2901=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 2902 2903=back 2904 2905 $cd->cd_to_producer->find_or_create({ producer => $producer }, 2906 { key => 'primary' }); 2907 2908Tries to find a record based on its primary key or unique constraints; if none 2909is found, creates one and returns that instead. 2910 2911 my $cd = $schema->resultset('CD')->find_or_create({ 2912 cdid => 5, 2913 artist => 'Massive Attack', 2914 title => 'Mezzanine', 2915 year => 2005, 2916 }); 2917 2918Also takes an optional C<key> attribute, to search by a specific key or unique 2919constraint. For example: 2920 2921 my $cd = $schema->resultset('CD')->find_or_create( 2922 { 2923 artist => 'Massive Attack', 2924 title => 'Mezzanine', 2925 }, 2926 { key => 'cd_artist_title' } 2927 ); 2928 2929B<Note>: Make sure to read the documentation of L</find> and understand the 2930significance of the C<key> attribute, as its lack may skew your search, and 2931subsequently result in spurious row creation. 2932 2933B<Note>: Because find_or_create() reads from the database and then 2934possibly inserts based on the result, this method is subject to a race 2935condition. Another process could create a record in the table after 2936the find has completed and before the create has started. To avoid 2937this problem, use find_or_create() inside a transaction. 2938 2939B<Note>: Take care when using C<find_or_create> with a table having 2940columns with default values that you intend to be automatically 2941supplied by the database (e.g. an auto_increment primary key column). 2942In normal usage, the value of such columns should NOT be included at 2943all in the call to C<find_or_create>, even when set to C<undef>. 2944 2945See also L</find> and L</update_or_create>. For information on how to declare 2946unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>. 2947 2948If you need to know if an existing row was found or a new one created use 2949L</find_or_new> and L<DBIx::Class::Row/in_storage> instead. Don't forget 2950to call L<DBIx::Class::Row/insert> to save the newly created row to the 2951database! 2952 2953 my $cd = $schema->resultset('CD')->find_or_new({ 2954 cdid => 5, 2955 artist => 'Massive Attack', 2956 title => 'Mezzanine', 2957 year => 2005, 2958 }); 2959 2960 if( !$cd->in_storage ) { 2961 # do some stuff 2962 $cd->insert; 2963 } 2964 2965=cut 2966 2967sub find_or_create { 2968 my $self = shift; 2969 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); 2970 my $hash = ref $_[0] eq 'HASH' ? shift : {@_}; 2971 if (keys %$hash and my $row = $self->find($hash, $attrs) ) { 2972 return $row; 2973 } 2974 return $self->new_result($hash)->insert; 2975} 2976 2977=head2 update_or_create 2978 2979=over 4 2980 2981=item Arguments: \%col_data, { key => $unique_constraint, L<%attrs|/ATTRIBUTES> }? 2982 2983=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 2984 2985=back 2986 2987 $resultset->update_or_create({ col => $val, ... }); 2988 2989Like L</find_or_create>, but if a row is found it is immediately updated via 2990C<< $found_row->update (\%col_data) >>. 2991 2992 2993Takes an optional C<key> attribute to search on a specific unique constraint. 2994For example: 2995 2996 # In your application 2997 my $cd = $schema->resultset('CD')->update_or_create( 2998 { 2999 artist => 'Massive Attack', 3000 title => 'Mezzanine', 3001 year => 1998, 3002 }, 3003 { key => 'cd_artist_title' } 3004 ); 3005 3006 $cd->cd_to_producer->update_or_create({ 3007 producer => $producer, 3008 name => 'harry', 3009 }, { 3010 key => 'primary', 3011 }); 3012 3013B<Note>: Make sure to read the documentation of L</find> and understand the 3014significance of the C<key> attribute, as its lack may skew your search, and 3015subsequently result in spurious row creation. 3016 3017B<Note>: Take care when using C<update_or_create> with a table having 3018columns with default values that you intend to be automatically 3019supplied by the database (e.g. an auto_increment primary key column). 3020In normal usage, the value of such columns should NOT be included at 3021all in the call to C<update_or_create>, even when set to C<undef>. 3022 3023See also L</find> and L</find_or_create>. For information on how to declare 3024unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>. 3025 3026If you need to know if an existing row was updated or a new one created use 3027L</update_or_new> and L<DBIx::Class::Row/in_storage> instead. Don't forget 3028to call L<DBIx::Class::Row/insert> to save the newly created row to the 3029database! 3030 3031=cut 3032 3033sub update_or_create { 3034 my $self = shift; 3035 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); 3036 my $cond = ref $_[0] eq 'HASH' ? shift : {@_}; 3037 3038 my $row = $self->find($cond, $attrs); 3039 if (defined $row) { 3040 $row->update($cond); 3041 return $row; 3042 } 3043 3044 return $self->new_result($cond)->insert; 3045} 3046 3047=head2 update_or_new 3048 3049=over 4 3050 3051=item Arguments: \%col_data, { key => $unique_constraint, L<%attrs|/ATTRIBUTES> }? 3052 3053=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> 3054 3055=back 3056 3057 $resultset->update_or_new({ col => $val, ... }); 3058 3059Like L</find_or_new> but if a row is found it is immediately updated via 3060C<< $found_row->update (\%col_data) >>. 3061 3062For example: 3063 3064 # In your application 3065 my $cd = $schema->resultset('CD')->update_or_new( 3066 { 3067 artist => 'Massive Attack', 3068 title => 'Mezzanine', 3069 year => 1998, 3070 }, 3071 { key => 'cd_artist_title' } 3072 ); 3073 3074 if ($cd->in_storage) { 3075 # the cd was updated 3076 } 3077 else { 3078 # the cd is not yet in the database, let's insert it 3079 $cd->insert; 3080 } 3081 3082B<Note>: Make sure to read the documentation of L</find> and understand the 3083significance of the C<key> attribute, as its lack may skew your search, and 3084subsequently result in spurious new objects. 3085 3086B<Note>: Take care when using C<update_or_new> with a table having 3087columns with default values that you intend to be automatically 3088supplied by the database (e.g. an auto_increment primary key column). 3089In normal usage, the value of such columns should NOT be included at 3090all in the call to C<update_or_new>, even when set to C<undef>. 3091 3092See also L</find>, L</find_or_create> and L</find_or_new>. 3093 3094=cut 3095 3096sub update_or_new { 3097 my $self = shift; 3098 my $attrs = ( @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {} ); 3099 my $cond = ref $_[0] eq 'HASH' ? shift : {@_}; 3100 3101 my $row = $self->find( $cond, $attrs ); 3102 if ( defined $row ) { 3103 $row->update($cond); 3104 return $row; 3105 } 3106 3107 return $self->new_result($cond); 3108} 3109 3110=head2 get_cache 3111 3112=over 4 3113 3114=item Arguments: none 3115 3116=item Return Value: L<\@result_objs|DBIx::Class::Manual::ResultClass> | undef 3117 3118=back 3119 3120Gets the contents of the cache for the resultset, if the cache is set. 3121 3122The cache is populated either by using the L</prefetch> attribute to 3123L</search> or by calling L</set_cache>. 3124 3125=cut 3126 3127sub get_cache { 3128 shift->{all_cache}; 3129} 3130 3131=head2 set_cache 3132 3133=over 4 3134 3135=item Arguments: L<\@result_objs|DBIx::Class::Manual::ResultClass> 3136 3137=item Return Value: L<\@result_objs|DBIx::Class::Manual::ResultClass> 3138 3139=back 3140 3141Sets the contents of the cache for the resultset. Expects an arrayref 3142of objects of the same class as those produced by the resultset. Note that 3143if the cache is set, the resultset will return the cached objects rather 3144than re-querying the database even if the cache attr is not set. 3145 3146The contents of the cache can also be populated by using the 3147L</prefetch> attribute to L</search>. 3148 3149=cut 3150 3151sub set_cache { 3152 my ( $self, $data ) = @_; 3153 $self->throw_exception("set_cache requires an arrayref") 3154 if defined($data) && (ref $data ne 'ARRAY'); 3155 $self->{all_cache} = $data; 3156} 3157 3158=head2 clear_cache 3159 3160=over 4 3161 3162=item Arguments: none 3163 3164=item Return Value: undef 3165 3166=back 3167 3168Clears the cache for the resultset. 3169 3170=cut 3171 3172sub clear_cache { 3173 shift->set_cache(undef); 3174} 3175 3176=head2 is_paged 3177 3178=over 4 3179 3180=item Arguments: none 3181 3182=item Return Value: true, if the resultset has been paginated 3183 3184=back 3185 3186=cut 3187 3188sub is_paged { 3189 my ($self) = @_; 3190 return !!$self->{attrs}{page}; 3191} 3192 3193=head2 is_ordered 3194 3195=over 4 3196 3197=item Arguments: none 3198 3199=item Return Value: true, if the resultset has been ordered with C<order_by>. 3200 3201=back 3202 3203=cut 3204 3205sub is_ordered { 3206 my ($self) = @_; 3207 return scalar $self->result_source->storage->_extract_order_criteria($self->{attrs}{order_by}); 3208} 3209 3210=head2 related_resultset 3211 3212=over 4 3213 3214=item Arguments: $rel_name 3215 3216=item Return Value: L<$resultset|/search> 3217 3218=back 3219 3220Returns a related resultset for the supplied relationship name. 3221 3222 $artist_rs = $schema->resultset('CD')->related_resultset('Artist'); 3223 3224=cut 3225 3226sub related_resultset { 3227 my ($self, $rel) = @_; 3228 3229 return $self->{related_resultsets}{$rel} 3230 if defined $self->{related_resultsets}{$rel}; 3231 3232 return $self->{related_resultsets}{$rel} = do { 3233 my $rsrc = $self->result_source; 3234 my $rel_info = $rsrc->relationship_info($rel); 3235 3236 $self->throw_exception( 3237 "search_related: result source '" . $rsrc->source_name . 3238 "' has no such relationship $rel") 3239 unless $rel_info; 3240 3241 my $attrs = $self->_chain_relationship($rel); 3242 3243 my $join_count = $attrs->{seen_join}{$rel}; 3244 3245 my $alias = $self->result_source->storage 3246 ->relname_to_table_alias($rel, $join_count); 3247 3248 # since this is search_related, and we already slid the select window inwards 3249 # (the select/as attrs were deleted in the beginning), we need to flip all 3250 # left joins to inner, so we get the expected results 3251 # read the comment on top of the actual function to see what this does 3252 $attrs->{from} = $rsrc->schema->storage->_inner_join_to_node ($attrs->{from}, $alias); 3253 3254 3255 #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi 3256 delete @{$attrs}{qw(result_class alias)}; 3257 3258 my $rel_source = $rsrc->related_source($rel); 3259 3260 my $new = do { 3261 3262 # The reason we do this now instead of passing the alias to the 3263 # search_rs below is that if you wrap/overload resultset on the 3264 # source you need to know what alias it's -going- to have for things 3265 # to work sanely (e.g. RestrictWithObject wants to be able to add 3266 # extra query restrictions, and these may need to be $alias.) 3267 3268 my $rel_attrs = $rel_source->resultset_attributes; 3269 local $rel_attrs->{alias} = $alias; 3270 3271 $rel_source->resultset 3272 ->search_rs( 3273 undef, { 3274 %$attrs, 3275 where => $attrs->{where}, 3276 }); 3277 }; 3278 3279 if (my $cache = $self->get_cache) { 3280 my @related_cache = map 3281 { $_->related_resultset($rel)->get_cache || () } 3282 @$cache 3283 ; 3284 3285 $new->set_cache([ map @$_, @related_cache ]) if @related_cache == @$cache; 3286 } 3287 3288 $new; 3289 }; 3290} 3291 3292=head2 current_source_alias 3293 3294=over 4 3295 3296=item Arguments: none 3297 3298=item Return Value: $source_alias 3299 3300=back 3301 3302Returns the current table alias for the result source this resultset is built 3303on, that will be used in the SQL query. Usually it is C<me>. 3304 3305Currently the source alias that refers to the result set returned by a 3306L</search>/L</find> family method depends on how you got to the resultset: it's 3307C<me> by default, but eg. L</search_related> aliases it to the related result 3308source name (and keeps C<me> referring to the original result set). The long 3309term goal is to make L<DBIx::Class> always alias the current resultset as C<me> 3310(and make this method unnecessary). 3311 3312Thus it's currently necessary to use this method in predefined queries (see 3313L<DBIx::Class::Manual::Cookbook/Predefined searches>) when referring to the 3314source alias of the current result set: 3315 3316 # in a result set class 3317 sub modified_by { 3318 my ($self, $user) = @_; 3319 3320 my $me = $self->current_source_alias; 3321 3322 return $self->search({ 3323 "$me.modified" => $user->id, 3324 }); 3325 } 3326 3327The alias of L<newly created resultsets|/search> can be altered by the 3328L<alias attribute|/alias>. 3329 3330=cut 3331 3332sub current_source_alias { 3333 return (shift->{attrs} || {})->{alias} || 'me'; 3334} 3335 3336=head2 as_subselect_rs 3337 3338=over 4 3339 3340=item Arguments: none 3341 3342=item Return Value: L<$resultset|/search> 3343 3344=back 3345 3346Act as a barrier to SQL symbols. The resultset provided will be made into a 3347"virtual view" by including it as a subquery within the from clause. From this 3348point on, any joined tables are inaccessible to ->search on the resultset (as if 3349it were simply where-filtered without joins). For example: 3350 3351 my $rs = $schema->resultset('Bar')->search({'x.name' => 'abc'},{ join => 'x' }); 3352 3353 # 'x' now pollutes the query namespace 3354 3355 # So the following works as expected 3356 my $ok_rs = $rs->search({'x.other' => 1}); 3357 3358 # But this doesn't: instead of finding a 'Bar' related to two x rows (abc and 3359 # def) we look for one row with contradictory terms and join in another table 3360 # (aliased 'x_2') which we never use 3361 my $broken_rs = $rs->search({'x.name' => 'def'}); 3362 3363 my $rs2 = $rs->as_subselect_rs; 3364 3365 # doesn't work - 'x' is no longer accessible in $rs2, having been sealed away 3366 my $not_joined_rs = $rs2->search({'x.other' => 1}); 3367 3368 # works as expected: finds a 'table' row related to two x rows (abc and def) 3369 my $correctly_joined_rs = $rs2->search({'x.name' => 'def'}); 3370 3371Another example of when one might use this would be to select a subset of 3372columns in a group by clause: 3373 3374 my $rs = $schema->resultset('Bar')->search(undef, { 3375 group_by => [qw{ id foo_id baz_id }], 3376 })->as_subselect_rs->search(undef, { 3377 columns => [qw{ id foo_id }] 3378 }); 3379 3380In the above example normally columns would have to be equal to the group by, 3381but because we isolated the group by into a subselect the above works. 3382 3383=cut 3384 3385sub as_subselect_rs { 3386 my $self = shift; 3387 3388 my $attrs = $self->_resolved_attrs; 3389 3390 my $fresh_rs = (ref $self)->new ( 3391 $self->result_source, 3392 {}, 3393 ); 3394 3395 # these pieces will be locked in the subquery 3396 delete $fresh_rs->{cond}; 3397 delete @{$fresh_rs->{attrs}}{qw/where bind/}; 3398 3399 return $fresh_rs->search( {}, { 3400 from => [{ 3401 $attrs->{alias} => $self->as_query, 3402 -alias => $attrs->{alias}, 3403 -rsrc => $self->result_source, 3404 }], 3405 alias => $attrs->{alias}, 3406 }); 3407} 3408 3409# This code is called by search_related, and makes sure there 3410# is clear separation between the joins before, during, and 3411# after the relationship. This information is needed later 3412# in order to properly resolve prefetch aliases (any alias 3413# with a relation_chain_depth less than the depth of the 3414# current prefetch is not considered) 3415# 3416# The increments happen twice per join. An even number means a 3417# relationship specified via a search_related, whereas an odd 3418# number indicates a join/prefetch added via attributes 3419# 3420# Also this code will wrap the current resultset (the one we 3421# chain to) in a subselect IFF it contains limiting attributes 3422sub _chain_relationship { 3423 my ($self, $rel) = @_; 3424 my $source = $self->result_source; 3425 my $attrs = { %{$self->{attrs}||{}} }; 3426 3427 # we need to take the prefetch the attrs into account before we 3428 # ->_resolve_join as otherwise they get lost - captainL 3429 my $join = $self->_merge_joinpref_attr( $attrs->{join}, $attrs->{prefetch} ); 3430 3431 delete @{$attrs}{qw/join prefetch collapse group_by distinct _grouped_by_distinct select as columns +select +as +columns/}; 3432 3433 my $seen = { %{ (delete $attrs->{seen_join}) || {} } }; 3434 3435 my $from; 3436 my @force_subq_attrs = qw/offset rows group_by having/; 3437 3438 if ( 3439 ($attrs->{from} && ref $attrs->{from} ne 'ARRAY') 3440 || 3441 $self->_has_resolved_attr (@force_subq_attrs) 3442 ) { 3443 # Nuke the prefetch (if any) before the new $rs attrs 3444 # are resolved (prefetch is useless - we are wrapping 3445 # a subquery anyway). 3446 my $rs_copy = $self->search; 3447 $rs_copy->{attrs}{join} = $self->_merge_joinpref_attr ( 3448 $rs_copy->{attrs}{join}, 3449 delete $rs_copy->{attrs}{prefetch}, 3450 ); 3451 3452 $from = [{ 3453 -rsrc => $source, 3454 -alias => $attrs->{alias}, 3455 $attrs->{alias} => $rs_copy->as_query, 3456 }]; 3457 delete @{$attrs}{@force_subq_attrs, qw/where bind/}; 3458 $seen->{-relation_chain_depth} = 0; 3459 } 3460 elsif ($attrs->{from}) { #shallow copy suffices 3461 $from = [ @{$attrs->{from}} ]; 3462 } 3463 else { 3464 $from = [{ 3465 -rsrc => $source, 3466 -alias => $attrs->{alias}, 3467 $attrs->{alias} => $source->from, 3468 }]; 3469 } 3470 3471 my $jpath = ($seen->{-relation_chain_depth}) 3472 ? $from->[-1][0]{-join_path} 3473 : []; 3474 3475 my @requested_joins = $source->_resolve_join( 3476 $join, 3477 $attrs->{alias}, 3478 $seen, 3479 $jpath, 3480 ); 3481 3482 push @$from, @requested_joins; 3483 3484 $seen->{-relation_chain_depth}++; 3485 3486 # if $self already had a join/prefetch specified on it, the requested 3487 # $rel might very well be already included. What we do in this case 3488 # is effectively a no-op (except that we bump up the chain_depth on 3489 # the join in question so we could tell it *is* the search_related) 3490 my $already_joined; 3491 3492 # we consider the last one thus reverse 3493 for my $j (reverse @requested_joins) { 3494 my ($last_j) = keys %{$j->[0]{-join_path}[-1]}; 3495 if ($rel eq $last_j) { 3496 $j->[0]{-relation_chain_depth}++; 3497 $already_joined++; 3498 last; 3499 } 3500 } 3501 3502 unless ($already_joined) { 3503 push @$from, $source->_resolve_join( 3504 $rel, 3505 $attrs->{alias}, 3506 $seen, 3507 $jpath, 3508 ); 3509 } 3510 3511 $seen->{-relation_chain_depth}++; 3512 3513 return {%$attrs, from => $from, seen_join => $seen}; 3514} 3515 3516sub _resolved_attrs { 3517 my $self = shift; 3518 return $self->{_attrs} if $self->{_attrs}; 3519 3520 my $attrs = { %{ $self->{attrs} || {} } }; 3521 my $source = $attrs->{result_source} = $self->result_source; 3522 my $alias = $attrs->{alias}; 3523 3524 $self->throw_exception("Specifying distinct => 1 in conjunction with collapse => 1 is unsupported") 3525 if $attrs->{collapse} and $attrs->{distinct}; 3526 3527 # default selection list 3528 $attrs->{columns} = [ $source->columns ] 3529 unless grep { exists $attrs->{$_} } qw/columns cols select as/; 3530 3531 # merge selectors together 3532 for (qw/columns select as/) { 3533 $attrs->{$_} = $self->_merge_attr($attrs->{$_}, delete $attrs->{"+$_"}) 3534 if $attrs->{$_} or $attrs->{"+$_"}; 3535 } 3536 3537 # disassemble columns 3538 my (@sel, @as); 3539 if (my $cols = delete $attrs->{columns}) { 3540 for my $c (ref $cols eq 'ARRAY' ? @$cols : $cols) { 3541 if (ref $c eq 'HASH') { 3542 for my $as (sort keys %$c) { 3543 push @sel, $c->{$as}; 3544 push @as, $as; 3545 } 3546 } 3547 else { 3548 push @sel, $c; 3549 push @as, $c; 3550 } 3551 } 3552 } 3553 3554 # when trying to weed off duplicates later do not go past this point - 3555 # everything added from here on is unbalanced "anyone's guess" stuff 3556 my $dedup_stop_idx = $#as; 3557 3558 push @as, @{ ref $attrs->{as} eq 'ARRAY' ? $attrs->{as} : [ $attrs->{as} ] } 3559 if $attrs->{as}; 3560 push @sel, @{ ref $attrs->{select} eq 'ARRAY' ? $attrs->{select} : [ $attrs->{select} ] } 3561 if $attrs->{select}; 3562 3563 # assume all unqualified selectors to apply to the current alias (legacy stuff) 3564 $_ = (ref $_ or $_ =~ /\./) ? $_ : "$alias.$_" for @sel; 3565 3566 # disqualify all $alias.col as-bits (inflate-map mandated) 3567 $_ = ($_ =~ /^\Q$alias.\E(.+)$/) ? $1 : $_ for @as; 3568 3569 # de-duplicate the result (remove *identical* select/as pairs) 3570 # and also die on duplicate {as} pointing to different {select}s 3571 # not using a c-style for as the condition is prone to shrinkage 3572 my $seen; 3573 my $i = 0; 3574 while ($i <= $dedup_stop_idx) { 3575 if ($seen->{"$sel[$i] \x00\x00 $as[$i]"}++) { 3576 splice @sel, $i, 1; 3577 splice @as, $i, 1; 3578 $dedup_stop_idx--; 3579 } 3580 elsif ($seen->{$as[$i]}++) { 3581 $self->throw_exception( 3582 "inflate_result() alias '$as[$i]' specified twice with different SQL-side {select}-ors" 3583 ); 3584 } 3585 else { 3586 $i++; 3587 } 3588 } 3589 3590 $attrs->{select} = \@sel; 3591 $attrs->{as} = \@as; 3592 3593 $attrs->{from} ||= [{ 3594 -rsrc => $source, 3595 -alias => $self->{attrs}{alias}, 3596 $self->{attrs}{alias} => $source->from, 3597 }]; 3598 3599 if ( $attrs->{join} || $attrs->{prefetch} ) { 3600 3601 $self->throw_exception ('join/prefetch can not be used with a custom {from}') 3602 if ref $attrs->{from} ne 'ARRAY'; 3603 3604 my $join = (delete $attrs->{join}) || {}; 3605 3606 if ( defined $attrs->{prefetch} ) { 3607 $join = $self->_merge_joinpref_attr( $join, $attrs->{prefetch} ); 3608 } 3609 3610 $attrs->{from} = # have to copy here to avoid corrupting the original 3611 [ 3612 @{ $attrs->{from} }, 3613 $source->_resolve_join( 3614 $join, 3615 $alias, 3616 { %{ $attrs->{seen_join} || {} } }, 3617 ( $attrs->{seen_join} && keys %{$attrs->{seen_join}}) 3618 ? $attrs->{from}[-1][0]{-join_path} 3619 : [] 3620 , 3621 ) 3622 ]; 3623 } 3624 3625 for my $attr (qw(order_by group_by)) { 3626 3627 if ( defined $attrs->{$attr} ) { 3628 $attrs->{$attr} = ( 3629 ref( $attrs->{$attr} ) eq 'ARRAY' 3630 ? [ @{ $attrs->{$attr} } ] 3631 : [ $attrs->{$attr} || () ] 3632 ); 3633 3634 delete $attrs->{$attr} unless @{$attrs->{$attr}}; 3635 } 3636 } 3637 3638 # generate selections based on the prefetch helper 3639 my ($prefetch, @prefetch_select, @prefetch_as); 3640 $prefetch = $self->_merge_joinpref_attr( {}, delete $attrs->{prefetch} ) 3641 if defined $attrs->{prefetch}; 3642 3643 if ($prefetch) { 3644 3645 $self->throw_exception("Unable to prefetch, resultset contains an unnamed selector $attrs->{_dark_selector}{string}") 3646 if $attrs->{_dark_selector}; 3647 3648 $self->throw_exception("Specifying prefetch in conjunction with an explicit collapse => 0 is unsupported") 3649 if defined $attrs->{collapse} and ! $attrs->{collapse}; 3650 3651 $attrs->{collapse} = 1; 3652 3653 # this is a separate structure (we don't look in {from} directly) 3654 # as the resolver needs to shift things off the lists to work 3655 # properly (identical-prefetches on different branches) 3656 my $join_map = {}; 3657 if (ref $attrs->{from} eq 'ARRAY') { 3658 3659 my $start_depth = $attrs->{seen_join}{-relation_chain_depth} || 0; 3660 3661 for my $j ( @{$attrs->{from}}[1 .. $#{$attrs->{from}} ] ) { 3662 next unless $j->[0]{-alias}; 3663 next unless $j->[0]{-join_path}; 3664 next if ($j->[0]{-relation_chain_depth} || 0) < $start_depth; 3665 3666 my @jpath = map { keys %$_ } @{$j->[0]{-join_path}}; 3667 3668 my $p = $join_map; 3669 $p = $p->{$_} ||= {} for @jpath[ ($start_depth/2) .. $#jpath]; #only even depths are actual jpath boundaries 3670 push @{$p->{-join_aliases} }, $j->[0]{-alias}; 3671 } 3672 } 3673 3674 my @prefetch = $source->_resolve_prefetch( $prefetch, $alias, $join_map ); 3675 3676 # save these for after distinct resolution 3677 @prefetch_select = map { $_->[0] } @prefetch; 3678 @prefetch_as = map { $_->[1] } @prefetch; 3679 } 3680 3681 # run through the resulting joinstructure (starting from our current slot) 3682 # and unset collapse if proven unnecessary 3683 # 3684 # also while we are at it find out if the current root source has 3685 # been premultiplied by previous related_source chaining 3686 # 3687 # this allows to predict whether a root object with all other relation 3688 # data set to NULL is in fact unique 3689 if ($attrs->{collapse}) { 3690 3691 if (ref $attrs->{from} eq 'ARRAY') { 3692 3693 if (@{$attrs->{from}} == 1) { 3694 # no joins - no collapse 3695 $attrs->{collapse} = 0; 3696 } 3697 else { 3698 # find where our table-spec starts 3699 my @fromlist = @{$attrs->{from}}; 3700 while (@fromlist) { 3701 my $t = shift @fromlist; 3702 3703 my $is_multi; 3704 # me vs join from-spec distinction - a ref means non-root 3705 if (ref $t eq 'ARRAY') { 3706 $t = $t->[0]; 3707 $is_multi ||= ! $t->{-is_single}; 3708 } 3709 last if ($t->{-alias} && $t->{-alias} eq $alias); 3710 $attrs->{_main_source_premultiplied} ||= $is_multi; 3711 } 3712 3713 # no non-singles remaining, nor any premultiplication - nothing to collapse 3714 if ( 3715 ! $attrs->{_main_source_premultiplied} 3716 and 3717 ! grep { ! $_->[0]{-is_single} } @fromlist 3718 ) { 3719 $attrs->{collapse} = 0; 3720 } 3721 } 3722 } 3723 3724 else { 3725 # if we can not analyze the from - err on the side of safety 3726 $attrs->{_main_source_premultiplied} = 1; 3727 } 3728 } 3729 3730 # generate the distinct induced group_by before injecting the prefetched select/as parts 3731 if (delete $attrs->{distinct}) { 3732 if ($attrs->{group_by}) { 3733 carp_unique ("Useless use of distinct on a grouped resultset ('distinct' is ignored when a 'group_by' is present)"); 3734 } 3735 else { 3736 $attrs->{_grouped_by_distinct} = 1; 3737 # distinct affects only the main selection part, not what prefetch may add below 3738 ($attrs->{group_by}, my $new_order) = $source->storage->_group_over_selection($attrs); 3739 3740 # FIXME possibly ignore a rewritten order_by (may turn out to be an issue) 3741 # The thinking is: if we are collapsing the subquerying prefetch engine will 3742 # rip stuff apart for us anyway, and we do not want to have a potentially 3743 # function-converted external order_by 3744 # ( there is an explicit if ( collapse && _grouped_by_distinct ) check in DBIHacks ) 3745 $attrs->{order_by} = $new_order unless $attrs->{collapse}; 3746 } 3747 } 3748 3749 # inject prefetch-bound selection (if any) 3750 push @{$attrs->{select}}, @prefetch_select; 3751 push @{$attrs->{as}}, @prefetch_as; 3752 3753 $attrs->{_simple_passthrough_construction} = !( 3754 $attrs->{collapse} 3755 or 3756 grep { $_ =~ /\./ } @{$attrs->{as}} 3757 ); 3758 3759 # if both page and offset are specified, produce a combined offset 3760 # even though it doesn't make much sense, this is what pre 081xx has 3761 # been doing 3762 if (my $page = delete $attrs->{page}) { 3763 $attrs->{offset} = 3764 ($attrs->{rows} * ($page - 1)) 3765 + 3766 ($attrs->{offset} || 0) 3767 ; 3768 } 3769 3770 return $self->{_attrs} = $attrs; 3771} 3772 3773sub _rollout_attr { 3774 my ($self, $attr) = @_; 3775 3776 if (ref $attr eq 'HASH') { 3777 return $self->_rollout_hash($attr); 3778 } elsif (ref $attr eq 'ARRAY') { 3779 return $self->_rollout_array($attr); 3780 } else { 3781 return [$attr]; 3782 } 3783} 3784 3785sub _rollout_array { 3786 my ($self, $attr) = @_; 3787 3788 my @rolled_array; 3789 foreach my $element (@{$attr}) { 3790 if (ref $element eq 'HASH') { 3791 push( @rolled_array, @{ $self->_rollout_hash( $element ) } ); 3792 } elsif (ref $element eq 'ARRAY') { 3793 # XXX - should probably recurse here 3794 push( @rolled_array, @{$self->_rollout_array($element)} ); 3795 } else { 3796 push( @rolled_array, $element ); 3797 } 3798 } 3799 return \@rolled_array; 3800} 3801 3802sub _rollout_hash { 3803 my ($self, $attr) = @_; 3804 3805 my @rolled_array; 3806 foreach my $key (keys %{$attr}) { 3807 push( @rolled_array, { $key => $attr->{$key} } ); 3808 } 3809 return \@rolled_array; 3810} 3811 3812sub _calculate_score { 3813 my ($self, $a, $b) = @_; 3814 3815 if (defined $a xor defined $b) { 3816 return 0; 3817 } 3818 elsif (not defined $a) { 3819 return 1; 3820 } 3821 3822 if (ref $b eq 'HASH') { 3823 my ($b_key) = keys %{$b}; 3824 $b_key = '' if ! defined $b_key; 3825 if (ref $a eq 'HASH') { 3826 my ($a_key) = keys %{$a}; 3827 $a_key = '' if ! defined $a_key; 3828 if ($a_key eq $b_key) { 3829 return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} )); 3830 } else { 3831 return 0; 3832 } 3833 } else { 3834 return ($a eq $b_key) ? 1 : 0; 3835 } 3836 } else { 3837 if (ref $a eq 'HASH') { 3838 my ($a_key) = keys %{$a}; 3839 return ($b eq $a_key) ? 1 : 0; 3840 } else { 3841 return ($b eq $a) ? 1 : 0; 3842 } 3843 } 3844} 3845 3846sub _merge_joinpref_attr { 3847 my ($self, $orig, $import) = @_; 3848 3849 return $import unless defined($orig); 3850 return $orig unless defined($import); 3851 3852 $orig = $self->_rollout_attr($orig); 3853 $import = $self->_rollout_attr($import); 3854 3855 my $seen_keys; 3856 foreach my $import_element ( @{$import} ) { 3857 # find best candidate from $orig to merge $b_element into 3858 my $best_candidate = { position => undef, score => 0 }; my $position = 0; 3859 foreach my $orig_element ( @{$orig} ) { 3860 my $score = $self->_calculate_score( $orig_element, $import_element ); 3861 if ($score > $best_candidate->{score}) { 3862 $best_candidate->{position} = $position; 3863 $best_candidate->{score} = $score; 3864 } 3865 $position++; 3866 } 3867 my ($import_key) = ( ref $import_element eq 'HASH' ) ? keys %{$import_element} : ($import_element); 3868 $import_key = '' if not defined $import_key; 3869 3870 if ($best_candidate->{score} == 0 || exists $seen_keys->{$import_key}) { 3871 push( @{$orig}, $import_element ); 3872 } else { 3873 my $orig_best = $orig->[$best_candidate->{position}]; 3874 # merge orig_best and b_element together and replace original with merged 3875 if (ref $orig_best ne 'HASH') { 3876 $orig->[$best_candidate->{position}] = $import_element; 3877 } elsif (ref $import_element eq 'HASH') { 3878 my ($key) = keys %{$orig_best}; 3879 $orig->[$best_candidate->{position}] = { $key => $self->_merge_joinpref_attr($orig_best->{$key}, $import_element->{$key}) }; 3880 } 3881 } 3882 $seen_keys->{$import_key} = 1; # don't merge the same key twice 3883 } 3884 3885 return @$orig ? $orig : (); 3886} 3887 3888{ 3889 my $hm; 3890 3891 sub _merge_attr { 3892 $hm ||= do { 3893 my $hm = Hash::Merge->new; 3894 3895 $hm->specify_behavior({ 3896 SCALAR => { 3897 SCALAR => sub { 3898 my ($defl, $defr) = map { defined $_ } (@_[0,1]); 3899 3900 if ($defl xor $defr) { 3901 return [ $defl ? $_[0] : $_[1] ]; 3902 } 3903 elsif (! $defl) { 3904 return []; 3905 } 3906 elsif (__HM_DEDUP and $_[0] eq $_[1]) { 3907 return [ $_[0] ]; 3908 } 3909 else { 3910 return [$_[0], $_[1]]; 3911 } 3912 }, 3913 ARRAY => sub { 3914 return $_[1] if !defined $_[0]; 3915 return $_[1] if __HM_DEDUP and grep { $_ eq $_[0] } @{$_[1]}; 3916 return [$_[0], @{$_[1]}] 3917 }, 3918 HASH => sub { 3919 return [] if !defined $_[0] and !keys %{$_[1]}; 3920 return [ $_[1] ] if !defined $_[0]; 3921 return [ $_[0] ] if !keys %{$_[1]}; 3922 return [$_[0], $_[1]] 3923 }, 3924 }, 3925 ARRAY => { 3926 SCALAR => sub { 3927 return $_[0] if !defined $_[1]; 3928 return $_[0] if __HM_DEDUP and grep { $_ eq $_[1] } @{$_[0]}; 3929 return [@{$_[0]}, $_[1]] 3930 }, 3931 ARRAY => sub { 3932 my @ret = @{$_[0]} or return $_[1]; 3933 return [ @ret, @{$_[1]} ] unless __HM_DEDUP; 3934 my %idx = map { $_ => 1 } @ret; 3935 push @ret, grep { ! defined $idx{$_} } (@{$_[1]}); 3936 \@ret; 3937 }, 3938 HASH => sub { 3939 return [ $_[1] ] if ! @{$_[0]}; 3940 return $_[0] if !keys %{$_[1]}; 3941 return $_[0] if __HM_DEDUP and grep { $_ eq $_[1] } @{$_[0]}; 3942 return [ @{$_[0]}, $_[1] ]; 3943 }, 3944 }, 3945 HASH => { 3946 SCALAR => sub { 3947 return [] if !keys %{$_[0]} and !defined $_[1]; 3948 return [ $_[0] ] if !defined $_[1]; 3949 return [ $_[1] ] if !keys %{$_[0]}; 3950 return [$_[0], $_[1]] 3951 }, 3952 ARRAY => sub { 3953 return [] if !keys %{$_[0]} and !@{$_[1]}; 3954 return [ $_[0] ] if !@{$_[1]}; 3955 return $_[1] if !keys %{$_[0]}; 3956 return $_[1] if __HM_DEDUP and grep { $_ eq $_[0] } @{$_[1]}; 3957 return [ $_[0], @{$_[1]} ]; 3958 }, 3959 HASH => sub { 3960 return [] if !keys %{$_[0]} and !keys %{$_[1]}; 3961 return [ $_[0] ] if !keys %{$_[1]}; 3962 return [ $_[1] ] if !keys %{$_[0]}; 3963 return [ $_[0] ] if $_[0] eq $_[1]; 3964 return [ $_[0], $_[1] ]; 3965 }, 3966 } 3967 } => 'DBIC_RS_ATTR_MERGER'); 3968 $hm; 3969 }; 3970 3971 return $hm->merge ($_[1], $_[2]); 3972 } 3973} 3974 3975sub STORABLE_freeze { 3976 my ($self, $cloning) = @_; 3977 my $to_serialize = { %$self }; 3978 3979 # A cursor in progress can't be serialized (and would make little sense anyway) 3980 # the parser can be regenerated (and can't be serialized) 3981 delete @{$to_serialize}{qw/cursor _row_parser _result_inflator/}; 3982 3983 # nor is it sensical to store a not-yet-fired-count pager 3984 if ($to_serialize->{pager} and ref $to_serialize->{pager}{total_entries} eq 'CODE') { 3985 delete $to_serialize->{pager}; 3986 } 3987 3988 Storable::nfreeze($to_serialize); 3989} 3990 3991# need this hook for symmetry 3992sub STORABLE_thaw { 3993 my ($self, $cloning, $serialized) = @_; 3994 3995 %$self = %{ Storable::thaw($serialized) }; 3996 3997 $self; 3998} 3999 4000 4001=head2 throw_exception 4002 4003See L<DBIx::Class::Schema/throw_exception> for details. 4004 4005=cut 4006 4007sub throw_exception { 4008 my $self=shift; 4009 4010 if (ref $self and my $rsrc = $self->result_source) { 4011 $rsrc->throw_exception(@_) 4012 } 4013 else { 4014 DBIx::Class::Exception->throw(@_); 4015 } 4016} 4017 40181; 4019 4020__END__ 4021 4022# XXX: FIXME: Attributes docs need clearing up 4023 4024=head1 ATTRIBUTES 4025 4026Attributes are used to refine a ResultSet in various ways when 4027searching for data. They can be passed to any method which takes an 4028C<\%attrs> argument. See L</search>, L</search_rs>, L</find>, 4029L</count>. 4030 4031Default attributes can be set on the result class using 4032L<DBIx::Class::ResultSource/resultset_attributes>. (Please read 4033the CAVEATS on that feature before using it!) 4034 4035These are in no particular order: 4036 4037=head2 order_by 4038 4039=over 4 4040 4041=item Value: ( $order_by | \@order_by | \%order_by ) 4042 4043=back 4044 4045Which column(s) to order the results by. 4046 4047[The full list of suitable values is documented in 4048L<SQL::Abstract::Classic/"ORDER BY CLAUSES">; the following is a summary of 4049common options.] 4050 4051If a single column name, or an arrayref of names is supplied, the 4052argument is passed through directly to SQL. The hashref syntax allows 4053for connection-agnostic specification of ordering direction: 4054 4055 For descending order: 4056 4057 order_by => { -desc => [qw/col1 col2 col3/] } 4058 4059 For explicit ascending order: 4060 4061 order_by => { -asc => 'col' } 4062 4063The old scalarref syntax (i.e. order_by => \'year DESC') is still 4064supported, although you are strongly encouraged to use the hashref 4065syntax as outlined above. 4066 4067=head2 columns 4068 4069=over 4 4070 4071=item Value: \@columns | \%columns | $column 4072 4073=back 4074 4075Shortcut to request a particular set of columns to be retrieved. Each 4076column spec may be a string (a table column name), or a hash (in which 4077case the key is the C<as> value, and the value is used as the C<select> 4078expression). Adds the L</current_source_alias> onto the start of any column without a C<.> in 4079it and sets C<select> from that, then auto-populates C<as> from 4080C<select> as normal. (You may also use the C<cols> attribute, as in 4081earlier versions of DBIC, but this is deprecated) 4082 4083Essentially C<columns> does the same as L</select> and L</as>. 4084 4085 columns => [ 'some_column', { dbic_slot => 'another_column' } ] 4086 4087is the same as 4088 4089 select => [qw(some_column another_column)], 4090 as => [qw(some_column dbic_slot)] 4091 4092If you want to individually retrieve related columns (in essence perform 4093manual L</prefetch>) you have to make sure to specify the correct inflation slot 4094chain such that it matches existing relationships: 4095 4096 my $rs = $schema->resultset('Artist')->search({}, { 4097 # required to tell DBIC to collapse has_many relationships 4098 collapse => 1, 4099 join => { cds => 'tracks' }, 4100 '+columns' => { 4101 'cds.cdid' => 'cds.cdid', 4102 'cds.tracks.title' => 'tracks.title', 4103 }, 4104 }); 4105 4106Like elsewhere, literal SQL or literal values can be included by using a 4107scalar reference or a literal bind value, and these values will be available 4108in the result with C<get_column> (see also 4109L<SQL::Abstract::Classic>/Literal SQL and value type operators>): 4110 4111 # equivalent SQL: SELECT 1, 'a string', IF(my_column,?,?) ... 4112 # bind values: $true_value, $false_value 4113 columns => [ 4114 { 4115 foo => \1, 4116 bar => \q{'a string'}, 4117 baz => \[ 'IF(my_column,?,?)', $true_value, $false_value ], 4118 } 4119 ] 4120 4121=head2 +columns 4122 4123B<NOTE:> You B<MUST> explicitly quote C<'+columns'> when using this attribute. 4124Not doing so causes Perl to incorrectly interpret C<+columns> as a bareword 4125with a unary plus operator before it, which is the same as simply C<columns>. 4126 4127=over 4 4128 4129=item Value: \@extra_columns 4130 4131=back 4132 4133Indicates additional columns to be selected from storage. Works the same as 4134L</columns> but adds columns to the current selection. (You may also use the 4135C<include_columns> attribute, as in earlier versions of DBIC, but this is 4136deprecated) 4137 4138 $schema->resultset('CD')->search(undef, { 4139 '+columns' => ['artist.name'], 4140 join => ['artist'] 4141 }); 4142 4143would return all CDs and include a 'name' column to the information 4144passed to object inflation. Note that the 'artist' is the name of the 4145column (or relationship) accessor, and 'name' is the name of the column 4146accessor in the related table. 4147 4148=head2 select 4149 4150=over 4 4151 4152=item Value: \@select_columns 4153 4154=back 4155 4156Indicates which columns should be selected from the storage. You can use 4157column names, or in the case of RDBMS back ends, function or stored procedure 4158names: 4159 4160 $rs = $schema->resultset('Employee')->search(undef, { 4161 select => [ 4162 'name', 4163 { count => 'employeeid' }, 4164 { max => { length => 'name' }, -as => 'longest_name' } 4165 ] 4166 }); 4167 4168 # Equivalent SQL 4169 SELECT name, COUNT( employeeid ), MAX( LENGTH( name ) ) AS longest_name FROM employee 4170 4171B<NOTE:> You will almost always need a corresponding L</as> attribute when you 4172use L</select>, to instruct DBIx::Class how to store the result of the column. 4173 4174Also note that the L</as> attribute has B<nothing to do> with the SQL-side 4175C<AS> identifier aliasing. You B<can> alias a function (so you can use it e.g. 4176in an C<ORDER BY> clause), however this is done via the C<-as> B<select 4177function attribute> supplied as shown in the example above. 4178 4179=head2 +select 4180 4181B<NOTE:> You B<MUST> explicitly quote C<'+select'> when using this attribute. 4182Not doing so causes Perl to incorrectly interpret C<+select> as a bareword 4183with a unary plus operator before it, which is the same as simply C<select>. 4184 4185=over 4 4186 4187=item Value: \@extra_select_columns 4188 4189=back 4190 4191Indicates additional columns to be selected from storage. Works the same as 4192L</select> but adds columns to the current selection, instead of specifying 4193a new explicit list. 4194 4195=head2 as 4196 4197=over 4 4198 4199=item Value: \@inflation_names 4200 4201=back 4202 4203Indicates DBIC-side names for object inflation. That is L</as> indicates the 4204slot name in which the column value will be stored within the 4205L<Row|DBIx::Class::Row> object. The value will then be accessible via this 4206identifier by the C<get_column> method (or via the object accessor B<if one 4207with the same name already exists>) as shown below. 4208 4209The L</as> attribute has B<nothing to do> with the SQL-side identifier 4210aliasing C<AS>. See L</select> for details. 4211 4212 $rs = $schema->resultset('Employee')->search(undef, { 4213 select => [ 4214 'name', 4215 { count => 'employeeid' }, 4216 { max => { length => 'name' }, -as => 'longest_name' } 4217 ], 4218 as => [qw/ 4219 name 4220 employee_count 4221 max_name_length 4222 /], 4223 }); 4224 4225If the object against which the search is performed already has an accessor 4226matching a column name specified in C<as>, the value can be retrieved using 4227the accessor as normal: 4228 4229 my $name = $employee->name(); 4230 4231If on the other hand an accessor does not exist in the object, you need to 4232use C<get_column> instead: 4233 4234 my $employee_count = $employee->get_column('employee_count'); 4235 4236You can create your own accessors if required - see 4237L<DBIx::Class::Manual::Cookbook> for details. 4238 4239=head2 +as 4240 4241B<NOTE:> You B<MUST> explicitly quote C<'+as'> when using this attribute. 4242Not doing so causes Perl to incorrectly interpret C<+as> as a bareword 4243with a unary plus operator before it, which is the same as simply C<as>. 4244 4245=over 4 4246 4247=item Value: \@extra_inflation_names 4248 4249=back 4250 4251Indicates additional inflation names for selectors added via L</+select>. See L</as>. 4252 4253=head2 join 4254 4255=over 4 4256 4257=item Value: ($rel_name | \@rel_names | \%rel_names) 4258 4259=back 4260 4261Contains a list of relationships that should be joined for this query. For 4262example: 4263 4264 # Get CDs by Nine Inch Nails 4265 my $rs = $schema->resultset('CD')->search( 4266 { 'artist.name' => 'Nine Inch Nails' }, 4267 { join => 'artist' } 4268 ); 4269 4270Can also contain a hash reference to refer to the other relation's relations. 4271For example: 4272 4273 package MyApp::Schema::Track; 4274 use base qw/DBIx::Class/; 4275 __PACKAGE__->table('track'); 4276 __PACKAGE__->add_columns(qw/trackid cd position title/); 4277 __PACKAGE__->set_primary_key('trackid'); 4278 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD'); 4279 1; 4280 4281 # In your application 4282 my $rs = $schema->resultset('Artist')->search( 4283 { 'track.title' => 'Teardrop' }, 4284 { 4285 join => { cd => 'track' }, 4286 order_by => 'artist.name', 4287 } 4288 ); 4289 4290You need to use the relationship (not the table) name in conditions, 4291because they are aliased as such. The current table is aliased as "me", so 4292you need to use me.column_name in order to avoid ambiguity. For example: 4293 4294 # Get CDs from 1984 with a 'Foo' track 4295 my $rs = $schema->resultset('CD')->search( 4296 { 4297 'me.year' => 1984, 4298 'tracks.name' => 'Foo' 4299 }, 4300 { join => 'tracks' } 4301 ); 4302 4303If the same join is supplied twice, it will be aliased to <rel>_2 (and 4304similarly for a third time). For e.g. 4305 4306 my $rs = $schema->resultset('Artist')->search({ 4307 'cds.title' => 'Down to Earth', 4308 'cds_2.title' => 'Popular', 4309 }, { 4310 join => [ qw/cds cds/ ], 4311 }); 4312 4313will return a set of all artists that have both a cd with title 'Down 4314to Earth' and a cd with title 'Popular'. 4315 4316If you want to fetch related objects from other tables as well, see L</prefetch> 4317below. 4318 4319 NOTE: An internal join-chain pruner will discard certain joins while 4320 constructing the actual SQL query, as long as the joins in question do not 4321 affect the retrieved result. This for example includes 1:1 left joins 4322 that are not part of the restriction specification (WHERE/HAVING) nor are 4323 a part of the query selection. 4324 4325For more help on using joins with search, see L<DBIx::Class::Manual::Joining>. 4326 4327=head2 collapse 4328 4329=over 4 4330 4331=item Value: (0 | 1) 4332 4333=back 4334 4335When set to a true value, indicates that any rows fetched from joined has_many 4336relationships are to be aggregated into the corresponding "parent" object. For 4337example, the resultset: 4338 4339 my $rs = $schema->resultset('CD')->search({}, { 4340 '+columns' => [ qw/ tracks.title tracks.position / ], 4341 join => 'tracks', 4342 collapse => 1, 4343 }); 4344 4345While executing the following query: 4346 4347 SELECT me.*, tracks.title, tracks.position 4348 FROM cd me 4349 LEFT JOIN track tracks 4350 ON tracks.cdid = me.cdid 4351 4352Will return only as many objects as there are rows in the CD source, even 4353though the result of the query may span many rows. Each of these CD objects 4354will in turn have multiple "Track" objects hidden behind the has_many 4355generated accessor C<tracks>. Without C<< collapse => 1 >>, the return values 4356of this resultset would be as many CD objects as there are tracks (a "Cartesian 4357product"), with each CD object containing exactly one of all fetched Track data. 4358 4359When a collapse is requested on a non-ordered resultset, an order by some 4360unique part of the main source (the left-most table) is inserted automatically. 4361This is done so that the resultset is allowed to be "lazy" - calling 4362L<< $rs->next|/next >> will fetch only as many rows as it needs to build the next 4363object with all of its related data. 4364 4365If an L</order_by> is already declared, and orders the resultset in a way that 4366makes collapsing as described above impossible (e.g. C<< ORDER BY 4367has_many_rel.column >> or C<ORDER BY RANDOM()>), DBIC will automatically 4368switch to "eager" mode and slurp the entire resultset before constructing the 4369first object returned by L</next>. 4370 4371Setting this attribute on a resultset that does not join any has_many 4372relations is a no-op. 4373 4374For a more in-depth discussion, see L</PREFETCHING>. 4375 4376=head2 prefetch 4377 4378=over 4 4379 4380=item Value: ($rel_name | \@rel_names | \%rel_names) 4381 4382=back 4383 4384This attribute is a shorthand for specifying a L</join> spec, adding all 4385columns from the joined related sources as L</+columns> and setting 4386L</collapse> to a true value. It can be thought of as a rough B<superset> 4387of the L</join> attribute. 4388 4389For example, the following two queries are equivalent: 4390 4391 my $rs = $schema->resultset('Artist')->search({}, { 4392 prefetch => { cds => ['genre', 'tracks' ] }, 4393 }); 4394 4395and 4396 4397 my $rs = $schema->resultset('Artist')->search({}, { 4398 join => { cds => ['genre', 'tracks' ] }, 4399 collapse => 1, 4400 '+columns' => [ 4401 (map 4402 { +{ "cds.$_" => "cds.$_" } } 4403 $schema->source('Artist')->related_source('cds')->columns 4404 ), 4405 (map 4406 { +{ "cds.genre.$_" => "genre.$_" } } 4407 $schema->source('Artist')->related_source('cds')->related_source('genre')->columns 4408 ), 4409 (map 4410 { +{ "cds.tracks.$_" => "tracks.$_" } } 4411 $schema->source('Artist')->related_source('cds')->related_source('tracks')->columns 4412 ), 4413 ], 4414 }); 4415 4416Both producing the following SQL: 4417 4418 SELECT me.artistid, me.name, me.rank, me.charfield, 4419 cds.cdid, cds.artist, cds.title, cds.year, cds.genreid, cds.single_track, 4420 genre.genreid, genre.name, 4421 tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at 4422 FROM artist me 4423 LEFT JOIN cd cds 4424 ON cds.artist = me.artistid 4425 LEFT JOIN genre genre 4426 ON genre.genreid = cds.genreid 4427 LEFT JOIN track tracks 4428 ON tracks.cd = cds.cdid 4429 ORDER BY me.artistid 4430 4431While L</prefetch> implies a L</join>, it is ok to mix the two together, as 4432the arguments are properly merged and generally do the right thing. For 4433example, you may want to do the following: 4434 4435 my $artists_and_cds_without_genre = $schema->resultset('Artist')->search( 4436 { 'genre.genreid' => undef }, 4437 { 4438 join => { cds => 'genre' }, 4439 prefetch => 'cds', 4440 } 4441 ); 4442 4443Which generates the following SQL: 4444 4445 SELECT me.artistid, me.name, me.rank, me.charfield, 4446 cds.cdid, cds.artist, cds.title, cds.year, cds.genreid, cds.single_track 4447 FROM artist me 4448 LEFT JOIN cd cds 4449 ON cds.artist = me.artistid 4450 LEFT JOIN genre genre 4451 ON genre.genreid = cds.genreid 4452 WHERE genre.genreid IS NULL 4453 ORDER BY me.artistid 4454 4455For a more in-depth discussion, see L</PREFETCHING>. 4456 4457=head2 alias 4458 4459=over 4 4460 4461=item Value: $source_alias 4462 4463=back 4464 4465Sets the source alias for the query. Normally, this defaults to C<me>, but 4466nested search queries (sub-SELECTs) might need specific aliases set to 4467reference inner queries. For example: 4468 4469 my $q = $rs 4470 ->related_resultset('CDs') 4471 ->related_resultset('Tracks') 4472 ->search({ 4473 'track.id' => { -ident => 'none_search.id' }, 4474 }) 4475 ->as_query; 4476 4477 my $ids = $self->search({ 4478 -not_exists => $q, 4479 }, { 4480 alias => 'none_search', 4481 group_by => 'none_search.id', 4482 })->get_column('id')->as_query; 4483 4484 $self->search({ id => { -in => $ids } }) 4485 4486This attribute is directly tied to L</current_source_alias>. 4487 4488=head2 page 4489 4490=over 4 4491 4492=item Value: $page 4493 4494=back 4495 4496Makes the resultset paged and specifies the page to retrieve. Effectively 4497identical to creating a non-pages resultset and then calling ->page($page) 4498on it. 4499 4500If L</rows> attribute is not specified it defaults to 10 rows per page. 4501 4502When you have a paged resultset, L</count> will only return the number 4503of rows in the page. To get the total, use the L</pager> and call 4504C<total_entries> on it. 4505 4506=head2 rows 4507 4508=over 4 4509 4510=item Value: $rows 4511 4512=back 4513 4514Specifies the maximum number of rows for direct retrieval or the number of 4515rows per page if the page attribute or method is used. 4516 4517=head2 offset 4518 4519=over 4 4520 4521=item Value: $offset 4522 4523=back 4524 4525Specifies the (zero-based) row number for the first row to be returned, or the 4526of the first row of the first page if paging is used. 4527 4528=head2 software_limit 4529 4530=over 4 4531 4532=item Value: (0 | 1) 4533 4534=back 4535 4536When combined with L</rows> and/or L</offset> the generated SQL will not 4537include any limit dialect stanzas. Instead the entire result will be selected 4538as if no limits were specified, and DBIC will perform the limit locally, by 4539artificially advancing and finishing the resulting L</cursor>. 4540 4541This is the recommended way of performing resultset limiting when no sane RDBMS 4542implementation is available (e.g. 4543L<Sybase ASE|DBIx::Class::Storage::DBI::Sybase::ASE> using the 4544L<Generic Sub Query|DBIx::Class::SQLMaker::LimitDialects/GenericSubQ> hack) 4545 4546=head2 group_by 4547 4548=over 4 4549 4550=item Value: \@columns 4551 4552=back 4553 4554A arrayref of columns to group by. Can include columns of joined tables. 4555 4556 group_by => [qw/ column1 column2 ... /] 4557 4558=head2 having 4559 4560=over 4 4561 4562=item Value: $condition 4563 4564=back 4565 4566The HAVING operator specifies a B<secondary> condition applied to the set 4567after the grouping calculations have been done. In other words it is a 4568constraint just like L</where> (and accepting the same 4569L<SQL::Abstract::Classic syntax|SQL::Abstract::Classic/WHERE CLAUSES>) applied 4570to the data as it exists after GROUP BY has taken place. Specifying L</having> 4571without L</group_by> is a logical mistake, and a fatal error on most RDBMS 4572engines. 4573 4574E.g. 4575 4576 having => { 'count_employee' => { '>=', 100 } } 4577 4578or with an in-place function in which case literal SQL is required: 4579 4580 having => \[ 'count(employee) >= ?', 100 ] 4581 4582=head2 distinct 4583 4584=over 4 4585 4586=item Value: (0 | 1) 4587 4588=back 4589 4590Set to 1 to automatically generate a L</group_by> clause based on the selection 4591(including intelligent handling of L</order_by> contents). Note that the group 4592criteria calculation takes place over the B<final> selection. This includes 4593any L</+columns>, L</+select> or L</order_by> additions in subsequent 4594L</search> calls, and standalone columns selected via 4595L<DBIx::Class::ResultSetColumn> (L</get_column>). A notable exception are the 4596extra selections specified via L</prefetch> - such selections are explicitly 4597excluded from group criteria calculations. 4598 4599If the final ResultSet also explicitly defines a L</group_by> attribute, this 4600setting is ignored and an appropriate warning is issued. 4601 4602=head2 where 4603 4604=over 4 4605 4606Adds to the WHERE clause. 4607 4608 # only return rows WHERE deleted IS NULL for all searches 4609 __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); 4610 4611Can be overridden by passing C<< { where => undef } >> as an attribute 4612to a resultset. 4613 4614For more complicated where clauses see L<SQL::Abstract::Classic/WHERE CLAUSES>. 4615 4616=back 4617 4618=head2 cache 4619 4620Set to 1 to cache search results. This prevents extra SQL queries if you 4621revisit rows in your ResultSet: 4622 4623 my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } ); 4624 4625 while( my $artist = $resultset->next ) { 4626 ... do stuff ... 4627 } 4628 4629 $rs->first; # without cache, this would issue a query 4630 4631By default, searches are not cached. 4632 4633For more examples of using these attributes, see 4634L<DBIx::Class::Manual::Cookbook>. 4635 4636=head2 for 4637 4638=over 4 4639 4640=item Value: ( 'update' | 'shared' | \$scalar ) 4641 4642=back 4643 4644Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT 4645... FOR SHARED. If \$scalar is passed, this is taken directly and embedded in the 4646query. 4647 4648=head1 PREFETCHING 4649 4650DBIx::Class supports arbitrary related data prefetching from multiple related 4651sources. Any combination of relationship types and column sets are supported. 4652If L<collapsing|/collapse> is requested, there is an additional requirement of 4653selecting enough data to make every individual object uniquely identifiable. 4654 4655Here are some more involved examples, based on the following relationship map: 4656 4657 # Assuming: 4658 My::Schema::CD->belongs_to( artist => 'My::Schema::Artist' ); 4659 My::Schema::CD->might_have( liner_note => 'My::Schema::LinerNotes' ); 4660 My::Schema::CD->has_many( tracks => 'My::Schema::Track' ); 4661 4662 My::Schema::Artist->belongs_to( record_label => 'My::Schema::RecordLabel' ); 4663 4664 My::Schema::Track->has_many( guests => 'My::Schema::Guest' ); 4665 4666 4667 4668 my $rs = $schema->resultset('Tag')->search( 4669 undef, 4670 { 4671 prefetch => { 4672 cd => 'artist' 4673 } 4674 } 4675 ); 4676 4677The initial search results in SQL like the following: 4678 4679 SELECT tag.*, cd.*, artist.* FROM tag 4680 JOIN cd ON tag.cd = cd.cdid 4681 JOIN artist ON cd.artist = artist.artistid 4682 4683L<DBIx::Class> has no need to go back to the database when we access the 4684C<cd> or C<artist> relationships, which saves us two SQL statements in this 4685case. 4686 4687Simple prefetches will be joined automatically, so there is no need 4688for a C<join> attribute in the above search. 4689 4690The L</prefetch> attribute can be used with any of the relationship types 4691and multiple prefetches can be specified together. Below is a more complex 4692example that prefetches a CD's artist, its liner notes (if present), 4693the cover image, the tracks on that CD, and the guests on those 4694tracks. 4695 4696 my $rs = $schema->resultset('CD')->search( 4697 undef, 4698 { 4699 prefetch => [ 4700 { artist => 'record_label'}, # belongs_to => belongs_to 4701 'liner_note', # might_have 4702 'cover_image', # has_one 4703 { tracks => 'guests' }, # has_many => has_many 4704 ] 4705 } 4706 ); 4707 4708This will produce SQL like the following: 4709 4710 SELECT cd.*, artist.*, record_label.*, liner_note.*, cover_image.*, 4711 tracks.*, guests.* 4712 FROM cd me 4713 JOIN artist artist 4714 ON artist.artistid = me.artistid 4715 JOIN record_label record_label 4716 ON record_label.labelid = artist.labelid 4717 LEFT JOIN track tracks 4718 ON tracks.cdid = me.cdid 4719 LEFT JOIN guest guests 4720 ON guests.trackid = track.trackid 4721 LEFT JOIN liner_notes liner_note 4722 ON liner_note.cdid = me.cdid 4723 JOIN cd_artwork cover_image 4724 ON cover_image.cdid = me.cdid 4725 ORDER BY tracks.cd 4726 4727Now the C<artist>, C<record_label>, C<liner_note>, C<cover_image>, 4728C<tracks>, and C<guests> of the CD will all be available through the 4729relationship accessors without the need for additional queries to the 4730database. 4731 4732=head3 CAVEATS 4733 4734Prefetch does a lot of deep magic. As such, it may not behave exactly 4735as you might expect. 4736 4737=over 4 4738 4739=item * 4740 4741Prefetch uses the L</cache> to populate the prefetched relationships. This 4742may or may not be what you want. 4743 4744=item * 4745 4746If you specify a condition on a prefetched relationship, ONLY those 4747rows that match the prefetched condition will be fetched into that relationship. 4748This means that adding prefetch to a search() B<may alter> what is returned by 4749traversing a relationship. So, if you have C<< Artist->has_many(CDs) >> and you do 4750 4751 my $artist_rs = $schema->resultset('Artist')->search({ 4752 'cds.year' => 2008, 4753 }, { 4754 join => 'cds', 4755 }); 4756 4757 my $count = $artist_rs->first->cds->count; 4758 4759 my $artist_rs_prefetch = $artist_rs->search( {}, { prefetch => 'cds' } ); 4760 4761 my $prefetch_count = $artist_rs_prefetch->first->cds->count; 4762 4763 cmp_ok( $count, '==', $prefetch_count, "Counts should be the same" ); 4764 4765That cmp_ok() may or may not pass depending on the datasets involved. In other 4766words the C<WHERE> condition would apply to the entire dataset, just like 4767it would in regular SQL. If you want to add a condition only to the "right side" 4768of a C<LEFT JOIN> - consider declaring and using a L<relationship with a custom 4769condition|DBIx::Class::Relationship::Base/condition> 4770 4771=back 4772 4773=head1 DBIC BIND VALUES 4774 4775Because DBIC may need more information to bind values than just the column name 4776and value itself, it uses a special format for both passing and receiving bind 4777values. Each bind value should be composed of an arrayref of 4778C<< [ \%args => $val ] >>. The format of C<< \%args >> is currently: 4779 4780=over 4 4781 4782=item dbd_attrs 4783 4784If present (in any form), this is what is being passed directly to bind_param. 4785Note that different DBD's expect different bind args. (e.g. DBD::SQLite takes 4786a single numerical type, while DBD::Pg takes a hashref if bind options.) 4787 4788If this is specified, all other bind options described below are ignored. 4789 4790=item sqlt_datatype 4791 4792If present, this is used to infer the actual bind attribute by passing to 4793C<< $resolved_storage->bind_attribute_by_data_type() >>. Defaults to the 4794"data_type" from the L<add_columns column info|DBIx::Class::ResultSource/add_columns>. 4795 4796Note that the data type is somewhat freeform (hence the sqlt_ prefix); 4797currently drivers are expected to "Do the Right Thing" when given a common 4798datatype name. (Not ideal, but that's what we got at this point.) 4799 4800=item sqlt_size 4801 4802Currently used to correctly allocate buffers for bind_param_inout(). 4803Defaults to "size" from the L<add_columns column info|DBIx::Class::ResultSource/add_columns>, 4804or to a sensible value based on the "data_type". 4805 4806=item dbic_colname 4807 4808Used to fill in missing sqlt_datatype and sqlt_size attributes (if they are 4809explicitly specified they are never overridden). Also used by some weird DBDs, 4810where the column name should be available at bind_param time (e.g. Oracle). 4811 4812=back 4813 4814For backwards compatibility and convenience, the following shortcuts are 4815supported: 4816 4817 [ $name => $val ] === [ { dbic_colname => $name }, $val ] 4818 [ \$dt => $val ] === [ { sqlt_datatype => $dt }, $val ] 4819 [ undef, $val ] === [ {}, $val ] 4820 $val === [ {}, $val ] 4821 4822=head1 FURTHER QUESTIONS? 4823 4824Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>. 4825 4826=head1 COPYRIGHT AND LICENSE 4827 4828This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE> 4829by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can 4830redistribute it and/or modify it under the same terms as the 4831L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>. 4832 4833=cut 4834