added search_related_rs at resultset
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use overload
6         '0+'     => "count",
7         'bool'   => "_bool",
8         fallback => 1;
9 use Carp::Clan qw/^DBIx::Class/;
10 use Data::Page;
11 use Storable;
12 use DBIx::Class::ResultSetColumn;
13 use DBIx::Class::ResultSourceHandle;
14 use List::Util ();
15 use base qw/DBIx::Class/;
16
17 __PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/);
18
19 =head1 NAME
20
21 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
22
23 =head1 SYNOPSIS
24
25   my $rs   = $schema->resultset('User')->search(registered => 1);
26   my @rows = $schema->resultset('CD')->search(year => 2005);
27
28 =head1 DESCRIPTION
29
30 The resultset is also known as an iterator. It is responsible for handling
31 queries that may return an arbitrary number of rows, e.g. via L</search>
32 or a C<has_many> relationship.
33
34 In the examples below, the following table classes are used:
35
36   package MyApp::Schema::Artist;
37   use base qw/DBIx::Class/;
38   __PACKAGE__->load_components(qw/Core/);
39   __PACKAGE__->table('artist');
40   __PACKAGE__->add_columns(qw/artistid name/);
41   __PACKAGE__->set_primary_key('artistid');
42   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
43   1;
44
45   package MyApp::Schema::CD;
46   use base qw/DBIx::Class/;
47   __PACKAGE__->load_components(qw/Core/);
48   __PACKAGE__->table('cd');
49   __PACKAGE__->add_columns(qw/cdid artist title year/);
50   __PACKAGE__->set_primary_key('cdid');
51   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
52   1;
53
54 =head1 OVERLOADING
55
56 If a resultset is used as a number it returns the C<count()>.  However, if it is used as a boolean it is always true.  So if you want to check if a result set has any results use C<if $rs != 0>.  C<if $rs> will always be true.
57
58 =head1 METHODS
59
60 =head2 new
61
62 =over 4
63
64 =item Arguments: $source, \%$attrs
65
66 =item Return Value: $rs
67
68 =back
69
70 The resultset constructor. Takes a source object (usually a
71 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
72 L</ATTRIBUTES> below).  Does not perform any queries -- these are
73 executed as needed by the other methods.
74
75 Generally you won't need to construct a resultset manually.  You'll
76 automatically get one from e.g. a L</search> called in scalar context:
77
78   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
79
80 IMPORTANT: If called on an object, proxies to new_result instead so
81
82   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
83
84 will return a CD object, not a ResultSet.
85
86 =cut
87
88 sub new {
89   my $class = shift;
90   return $class->new_result(@_) if ref $class;
91
92   my ($source, $attrs) = @_;
93   $source = $source->handle 
94     unless $source->isa('DBIx::Class::ResultSourceHandle');
95   $attrs = { %{$attrs||{}} };
96
97   if ($attrs->{page}) {
98     $attrs->{rows} ||= 10;
99   }
100
101   $attrs->{alias} ||= 'me';
102
103   # Creation of {} and bless separated to mitigate RH perl bug
104   # see https://bugzilla.redhat.com/show_bug.cgi?id=196836
105   my $self = {
106     _source_handle => $source,
107     result_class => $attrs->{result_class} || $source->resolve->result_class,
108     cond => $attrs->{where},
109     count => undef,
110     pager => undef,
111     attrs => $attrs
112   };
113
114   bless $self, $class;
115
116   return $self;
117 }
118
119 =head2 search
120
121 =over 4
122
123 =item Arguments: $cond, \%attrs?
124
125 =item Return Value: $resultset (scalar context), @row_objs (list context)
126
127 =back
128
129   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
130   my $new_rs = $cd_rs->search({ year => 2005 });
131
132   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
133                  # year = 2005 OR year = 2004
134
135 If you need to pass in additional attributes but no additional condition,
136 call it as C<search(undef, \%attrs)>.
137
138   # "SELECT name, artistid FROM $artist_table"
139   my @all_artists = $schema->resultset('Artist')->search(undef, {
140     columns => [qw/name artistid/],
141   });
142
143 For a list of attributes that can be passed to C<search>, see
144 L</ATTRIBUTES>. For more examples of using this function, see
145 L<Searching|DBIx::Class::Manual::Cookbook/Searching>. For a complete
146 documentation for the first argument, see L<SQL::Abstract>.
147
148 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
149
150 =cut
151
152 sub search {
153   my $self = shift;
154   my $rs = $self->search_rs( @_ );
155   return (wantarray ? $rs->all : $rs);
156 }
157
158 =head2 search_rs
159
160 =over 4
161
162 =item Arguments: $cond, \%attrs?
163
164 =item Return Value: $resultset
165
166 =back
167
168 This method does the same exact thing as search() except it will
169 always return a resultset, even in list context.
170
171 =cut
172
173 sub search_rs {
174   my $self = shift;
175
176   my $attrs = {};
177   $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
178   my $our_attrs = { %{$self->{attrs}} };
179   my $having = delete $our_attrs->{having};
180   my $where = delete $our_attrs->{where};
181
182   my $rows;
183
184   my %safe = (alias => 1, cache => 1);
185
186   unless (
187     (@_ && defined($_[0])) # @_ == () or (undef)
188     || 
189     (keys %$attrs # empty attrs or only 'safe' attrs
190     && List::Util::first { !$safe{$_} } keys %$attrs)
191   ) {
192     # no search, effectively just a clone
193     $rows = $self->get_cache;
194   }
195
196   my $new_attrs = { %{$our_attrs}, %{$attrs} };
197
198   # merge new attrs into inherited
199   foreach my $key (qw/join prefetch/) {
200     next unless exists $attrs->{$key};
201     $new_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
202   }
203
204   my $cond = (@_
205     ? (
206         (@_ == 1 || ref $_[0] eq "HASH")
207           ? (
208               (ref $_[0] eq 'HASH')
209                 ? (
210                     (keys %{ $_[0] }  > 0)
211                       ? shift
212                       : undef
213                    )
214                 :  shift
215              )
216           : (
217               (@_ % 2)
218                 ? $self->throw_exception("Odd number of arguments to search")
219                 : {@_}
220              )
221       )
222     : undef
223   );
224
225   if (defined $where) {
226     $new_attrs->{where} = (
227       defined $new_attrs->{where}
228         ? { '-and' => [
229               map {
230                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
231               } $where, $new_attrs->{where}
232             ]
233           }
234         : $where);
235   }
236
237   if (defined $cond) {
238     $new_attrs->{where} = (
239       defined $new_attrs->{where}
240         ? { '-and' => [
241               map {
242                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
243               } $cond, $new_attrs->{where}
244             ]
245           }
246         : $cond);
247   }
248
249   if (defined $having) {
250     $new_attrs->{having} = (
251       defined $new_attrs->{having}
252         ? { '-and' => [
253               map {
254                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
255               } $having, $new_attrs->{having}
256             ]
257           }
258         : $having);
259   }
260
261   my $rs = (ref $self)->new($self->result_source, $new_attrs);
262   if ($rows) {
263     $rs->set_cache($rows);
264   }
265   return $rs;
266 }
267
268 =head2 search_literal
269
270 =over 4
271
272 =item Arguments: $sql_fragment, @bind_values
273
274 =item Return Value: $resultset (scalar context), @row_objs (list context)
275
276 =back
277
278   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
279   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
280
281 Pass a literal chunk of SQL to be added to the conditional part of the
282 resultset query.
283
284 CAVEAT: C<search_literal> is provided for Class::DBI compatibility and should
285 only be used in that context. There are known problems using C<search_literal>
286 in chained queries; it can result in bind values in the wrong order.  See
287 L<DBIx::Class::Manual::Cookbook/Searching> and
288 L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not
289 require C<search_literal>.
290
291 =cut
292
293 sub search_literal {
294   my ($self, $cond, @vals) = @_;
295   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
296   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
297   return $self->search(\$cond, $attrs);
298 }
299
300 =head2 find
301
302 =over 4
303
304 =item Arguments: @values | \%cols, \%attrs?
305
306 =item Return Value: $row_object
307
308 =back
309
310 Finds a row based on its primary key or unique constraint. For example, to find
311 a row by its primary key:
312
313   my $cd = $schema->resultset('CD')->find(5);
314
315 You can also find a row by a specific unique constraint using the C<key>
316 attribute. For example:
317
318   my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', {
319     key => 'cd_artist_title'
320   });
321
322 Additionally, you can specify the columns explicitly by name:
323
324   my $cd = $schema->resultset('CD')->find(
325     {
326       artist => 'Massive Attack',
327       title  => 'Mezzanine',
328     },
329     { key => 'cd_artist_title' }
330   );
331
332 If the C<key> is specified as C<primary>, it searches only on the primary key.
333
334 If no C<key> is specified, it searches on all unique constraints defined on the
335 source, including the primary key.
336
337 If your table does not have a primary key, you B<must> provide a value for the
338 C<key> attribute matching one of the unique constraints on the source.
339
340 See also L</find_or_create> and L</update_or_create>. For information on how to
341 declare unique constraints, see
342 L<DBIx::Class::ResultSource/add_unique_constraint>.
343
344 =cut
345
346 sub find {
347   my $self = shift;
348   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
349
350   # Default to the primary key, but allow a specific key
351   my @cols = exists $attrs->{key}
352     ? $self->result_source->unique_constraint_columns($attrs->{key})
353     : $self->result_source->primary_columns;
354   $self->throw_exception(
355     "Can't find unless a primary key is defined or unique constraint is specified"
356   ) unless @cols;
357
358   # Parse out a hashref from input
359   my $input_query;
360   if (ref $_[0] eq 'HASH') {
361     $input_query = { %{$_[0]} };
362   }
363   elsif (@_ == @cols) {
364     $input_query = {};
365     @{$input_query}{@cols} = @_;
366   }
367   else {
368     # Compatibility: Allow e.g. find(id => $value)
369     carp "Find by key => value deprecated; please use a hashref instead";
370     $input_query = {@_};
371   }
372
373   my (%related, $info);
374
375   KEY: foreach my $key (keys %$input_query) {
376     if (ref($input_query->{$key})
377         && ($info = $self->result_source->relationship_info($key))) {
378       my $val = delete $input_query->{$key};
379       next KEY if (ref($val) eq 'ARRAY'); # has_many for multi_create
380       my $rel_q = $self->result_source->resolve_condition(
381                     $info->{cond}, $val, $key
382                   );
383       die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY';
384       @related{keys %$rel_q} = values %$rel_q;
385     }
386   }
387   if (my @keys = keys %related) {
388     @{$input_query}{@keys} = values %related;
389   }
390
391   my @unique_queries = $self->_unique_queries($input_query, $attrs);
392
393   # Build the final query: Default to the disjunction of the unique queries,
394   # but allow the input query in case the ResultSet defines the query or the
395   # user is abusing find
396   my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias};
397   my $query = @unique_queries
398     ? [ map { $self->_add_alias($_, $alias) } @unique_queries ]
399     : $self->_add_alias($input_query, $alias);
400
401   # Run the query
402   if (keys %$attrs) {
403     my $rs = $self->search($query, $attrs);
404     return keys %{$rs->_resolved_attrs->{collapse}} ? $rs->next : $rs->single;
405   }
406   else {
407     return keys %{$self->_resolved_attrs->{collapse}}
408       ? $self->search($query)->next
409       : $self->single($query);
410   }
411 }
412
413 # _add_alias
414 #
415 # Add the specified alias to the specified query hash. A copy is made so the
416 # original query is not modified.
417
418 sub _add_alias {
419   my ($self, $query, $alias) = @_;
420
421   my %aliased = %$query;
422   foreach my $col (grep { ! m/\./ } keys %aliased) {
423     $aliased{"$alias.$col"} = delete $aliased{$col};
424   }
425
426   return \%aliased;
427 }
428
429 # _unique_queries
430 #
431 # Build a list of queries which satisfy unique constraints.
432
433 sub _unique_queries {
434   my ($self, $query, $attrs) = @_;
435
436   my @constraint_names = exists $attrs->{key}
437     ? ($attrs->{key})
438     : $self->result_source->unique_constraint_names;
439
440   my $where = $self->_collapse_cond($self->{attrs}{where} || {});
441   my $num_where = scalar keys %$where;
442
443   my @unique_queries;
444   foreach my $name (@constraint_names) {
445     my @unique_cols = $self->result_source->unique_constraint_columns($name);
446     my $unique_query = $self->_build_unique_query($query, \@unique_cols);
447
448     my $num_cols = scalar @unique_cols;
449     my $num_query = scalar keys %$unique_query;
450
451     my $total = $num_query + $num_where;
452     if ($num_query && ($num_query == $num_cols || $total == $num_cols)) {
453       # The query is either unique on its own or is unique in combination with
454       # the existing where clause
455       push @unique_queries, $unique_query;
456     }
457   }
458
459   return @unique_queries;
460 }
461
462 # _build_unique_query
463 #
464 # Constrain the specified query hash based on the specified column names.
465
466 sub _build_unique_query {
467   my ($self, $query, $unique_cols) = @_;
468
469   return {
470     map  { $_ => $query->{$_} }
471     grep { exists $query->{$_} }
472       @$unique_cols
473   };
474 }
475
476 =head2 search_related
477
478 =over 4
479
480 =item Arguments: $rel, $cond, \%attrs?
481
482 =item Return Value: $new_resultset
483
484 =back
485
486   $new_rs = $cd_rs->search_related('artist', {
487     name => 'Emo-R-Us',
488   });
489
490 Searches the specified relationship, optionally specifying a condition and
491 attributes for matching records. See L</ATTRIBUTES> for more information.
492
493 =cut
494
495 sub search_related {
496   return shift->related_resultset(shift)->search(@_);
497 }
498
499 =head2 search_related_rs
500
501 This method works exactly the same as search_related, except that
502 it garauntees a restultset, even in list context.
503
504 =cut
505
506 sub search_related_rs {
507   return shift->related_resultset(shift)->search_rs(@_);
508 }
509
510 =head2 cursor
511
512 =over 4
513
514 =item Arguments: none
515
516 =item Return Value: $cursor
517
518 =back
519
520 Returns a storage-driven cursor to the given resultset. See
521 L<DBIx::Class::Cursor> for more information.
522
523 =cut
524
525 sub cursor {
526   my ($self) = @_;
527
528   my $attrs = { %{$self->_resolved_attrs} };
529   return $self->{cursor}
530     ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
531           $attrs->{where},$attrs);
532 }
533
534 =head2 single
535
536 =over 4
537
538 =item Arguments: $cond?
539
540 =item Return Value: $row_object?
541
542 =back
543
544   my $cd = $schema->resultset('CD')->single({ year => 2001 });
545
546 Inflates the first result without creating a cursor if the resultset has
547 any records in it; if not returns nothing. Used by L</find> as an optimisation.
548
549 Can optionally take an additional condition *only* - this is a fast-code-path
550 method; if you need to add extra joins or similar call ->search and then
551 ->single without a condition on the $rs returned from that.
552
553 =cut
554
555 sub single {
556   my ($self, $where) = @_;
557   my $attrs = { %{$self->_resolved_attrs} };
558   if ($where) {
559     if (defined $attrs->{where}) {
560       $attrs->{where} = {
561         '-and' =>
562             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
563                $where, delete $attrs->{where} ]
564       };
565     } else {
566       $attrs->{where} = $where;
567     }
568   }
569
570 #  XXX: Disabled since it doesn't infer uniqueness in all cases
571 #  unless ($self->_is_unique_query($attrs->{where})) {
572 #    carp "Query not guaranteed to return a single row"
573 #      . "; please declare your unique constraints or use search instead";
574 #  }
575
576   my @data = $self->result_source->storage->select_single(
577     $attrs->{from}, $attrs->{select},
578     $attrs->{where}, $attrs
579   );
580
581   return (@data ? ($self->_construct_object(@data))[0] : undef);
582 }
583
584 # _is_unique_query
585 #
586 # Try to determine if the specified query is guaranteed to be unique, based on
587 # the declared unique constraints.
588
589 sub _is_unique_query {
590   my ($self, $query) = @_;
591
592   my $collapsed = $self->_collapse_query($query);
593   my $alias = $self->{attrs}{alias};
594
595   foreach my $name ($self->result_source->unique_constraint_names) {
596     my @unique_cols = map {
597       "$alias.$_"
598     } $self->result_source->unique_constraint_columns($name);
599
600     # Count the values for each unique column
601     my %seen = map { $_ => 0 } @unique_cols;
602
603     foreach my $key (keys %$collapsed) {
604       my $aliased = $key =~ /\./ ? $key : "$alias.$key";
605       next unless exists $seen{$aliased};  # Additional constraints are okay
606       $seen{$aliased} = scalar keys %{ $collapsed->{$key} };
607     }
608
609     # If we get 0 or more than 1 value for a column, it's not necessarily unique
610     return 1 unless grep { $_ != 1 } values %seen;
611   }
612
613   return 0;
614 }
615
616 # _collapse_query
617 #
618 # Recursively collapse the query, accumulating values for each column.
619
620 sub _collapse_query {
621   my ($self, $query, $collapsed) = @_;
622
623   $collapsed ||= {};
624
625   if (ref $query eq 'ARRAY') {
626     foreach my $subquery (@$query) {
627       next unless ref $subquery;  # -or
628 #      warn "ARRAY: " . Dumper $subquery;
629       $collapsed = $self->_collapse_query($subquery, $collapsed);
630     }
631   }
632   elsif (ref $query eq 'HASH') {
633     if (keys %$query and (keys %$query)[0] eq '-and') {
634       foreach my $subquery (@{$query->{-and}}) {
635 #        warn "HASH: " . Dumper $subquery;
636         $collapsed = $self->_collapse_query($subquery, $collapsed);
637       }
638     }
639     else {
640 #      warn "LEAF: " . Dumper $query;
641       foreach my $col (keys %$query) {
642         my $value = $query->{$col};
643         $collapsed->{$col}{$value}++;
644       }
645     }
646   }
647
648   return $collapsed;
649 }
650
651 =head2 get_column
652
653 =over 4
654
655 =item Arguments: $cond?
656
657 =item Return Value: $resultsetcolumn
658
659 =back
660
661   my $max_length = $rs->get_column('length')->max;
662
663 Returns a L<DBIx::Class::ResultSetColumn> instance for a column of the ResultSet.
664
665 =cut
666
667 sub get_column {
668   my ($self, $column) = @_;
669   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
670   return $new;
671 }
672
673 =head2 search_like
674
675 =over 4
676
677 =item Arguments: $cond, \%attrs?
678
679 =item Return Value: $resultset (scalar context), @row_objs (list context)
680
681 =back
682
683   # WHERE title LIKE '%blue%'
684   $cd_rs = $rs->search_like({ title => '%blue%'});
685
686 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
687 that this is simply a convenience method. You most likely want to use
688 L</search> with specific operators.
689
690 For more information, see L<DBIx::Class::Manual::Cookbook>.
691
692 =cut
693
694 sub search_like {
695   my $class = shift;
696   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
697   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
698   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
699   return $class->search($query, { %$attrs });
700 }
701
702 =head2 slice
703
704 =over 4
705
706 =item Arguments: $first, $last
707
708 =item Return Value: $resultset (scalar context), @row_objs (list context)
709
710 =back
711
712 Returns a resultset or object list representing a subset of elements from the
713 resultset slice is called on. Indexes are from 0, i.e., to get the first
714 three records, call:
715
716   my ($one, $two, $three) = $rs->slice(0, 2);
717
718 =cut
719
720 sub slice {
721   my ($self, $min, $max) = @_;
722   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
723   $attrs->{offset} = $self->{attrs}{offset} || 0;
724   $attrs->{offset} += $min;
725   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
726   return $self->search(undef(), $attrs);
727   #my $slice = (ref $self)->new($self->result_source, $attrs);
728   #return (wantarray ? $slice->all : $slice);
729 }
730
731 =head2 next
732
733 =over 4
734
735 =item Arguments: none
736
737 =item Return Value: $result?
738
739 =back
740
741 Returns the next element in the resultset (C<undef> is there is none).
742
743 Can be used to efficiently iterate over records in the resultset:
744
745   my $rs = $schema->resultset('CD')->search;
746   while (my $cd = $rs->next) {
747     print $cd->title;
748   }
749
750 Note that you need to store the resultset object, and call C<next> on it.
751 Calling C<< resultset('Table')->next >> repeatedly will always return the
752 first record from the resultset.
753
754 =cut
755
756 sub next {
757   my ($self) = @_;
758   if (my $cache = $self->get_cache) {
759     $self->{all_cache_position} ||= 0;
760     return $cache->[$self->{all_cache_position}++];
761   }
762   if ($self->{attrs}{cache}) {
763     $self->{all_cache_position} = 1;
764     return ($self->all)[0];
765   }
766   if ($self->{stashed_objects}) {
767     my $obj = shift(@{$self->{stashed_objects}});
768     delete $self->{stashed_objects} unless @{$self->{stashed_objects}};
769     return $obj;
770   }
771   my @row = (
772     exists $self->{stashed_row}
773       ? @{delete $self->{stashed_row}}
774       : $self->cursor->next
775   );
776   return undef unless (@row);
777   my ($row, @more) = $self->_construct_object(@row);
778   $self->{stashed_objects} = \@more if @more;
779   return $row;
780 }
781
782 sub _construct_object {
783   my ($self, @row) = @_;
784   my $info = $self->_collapse_result($self->{_attrs}{as}, \@row);
785   my @new = $self->result_class->inflate_result($self->result_source, @$info);
786   @new = $self->{_attrs}{record_filter}->(@new)
787     if exists $self->{_attrs}{record_filter};
788   return @new;
789 }
790
791 sub _collapse_result {
792   my ($self, $as_proto, $row) = @_;
793
794   my @copy = @$row;
795
796   # 'foo'         => [ undef, 'foo' ]
797   # 'foo.bar'     => [ 'foo', 'bar' ]
798   # 'foo.bar.baz' => [ 'foo.bar', 'baz' ]
799
800   my @construct_as = map { [ (/^(?:(.*)\.)?([^.]+)$/) ] } @$as_proto;
801
802   my %collapse = %{$self->{_attrs}{collapse}||{}};
803
804   my @pri_index;
805
806   # if we're doing collapsing (has_many prefetch) we need to grab records
807   # until the PK changes, so fill @pri_index. if not, we leave it empty so
808   # we know we don't have to bother.
809
810   # the reason for not using the collapse stuff directly is because if you
811   # had for e.g. two artists in a row with no cds, the collapse info for
812   # both would be NULL (undef) so you'd lose the second artist
813
814   # store just the index so we can check the array positions from the row
815   # without having to contruct the full hash
816
817   if (keys %collapse) {
818     my %pri = map { ($_ => 1) } $self->result_source->primary_columns;
819     foreach my $i (0 .. $#construct_as) {
820       next if defined($construct_as[$i][0]); # only self table
821       if (delete $pri{$construct_as[$i][1]}) {
822         push(@pri_index, $i);
823       }
824       last unless keys %pri; # short circuit (Johnny Five Is Alive!)
825     }
826   }
827
828   # no need to do an if, it'll be empty if @pri_index is empty anyway
829
830   my %pri_vals = map { ($_ => $copy[$_]) } @pri_index;
831
832   my @const_rows;
833
834   do { # no need to check anything at the front, we always want the first row
835
836     my %const;
837   
838     foreach my $this_as (@construct_as) {
839       $const{$this_as->[0]||''}{$this_as->[1]} = shift(@copy);
840     }
841
842     push(@const_rows, \%const);
843
844   } until ( # no pri_index => no collapse => drop straight out
845       !@pri_index
846     or
847       do { # get another row, stash it, drop out if different PK
848
849         @copy = $self->cursor->next;
850         $self->{stashed_row} = \@copy;
851
852         # last thing in do block, counts as true if anything doesn't match
853
854         # check xor defined first for NULL vs. NOT NULL then if one is
855         # defined the other must be so check string equality
856
857         grep {
858           (defined $pri_vals{$_} ^ defined $copy[$_])
859           || (defined $pri_vals{$_} && ($pri_vals{$_} ne $copy[$_]))
860         } @pri_index;
861       }
862   );
863
864   my $alias = $self->{attrs}{alias};
865   my $info = [];
866
867   my %collapse_pos;
868
869   my @const_keys;
870
871   foreach my $const (@const_rows) {
872     scalar @const_keys or do {
873       @const_keys = sort { length($a) <=> length($b) } keys %$const;
874     };
875     foreach my $key (@const_keys) {
876       if (length $key) {
877         my $target = $info;
878         my @parts = split(/\./, $key);
879         my $cur = '';
880         my $data = $const->{$key};
881         foreach my $p (@parts) {
882           $target = $target->[1]->{$p} ||= [];
883           $cur .= ".${p}";
884           if ($cur eq ".${key}" && (my @ckey = @{$collapse{$cur}||[]})) { 
885             # collapsing at this point and on final part
886             my $pos = $collapse_pos{$cur};
887             CK: foreach my $ck (@ckey) {
888               if (!defined $pos->{$ck} || $pos->{$ck} ne $data->{$ck}) {
889                 $collapse_pos{$cur} = $data;
890                 delete @collapse_pos{ # clear all positioning for sub-entries
891                   grep { m/^\Q${cur}.\E/ } keys %collapse_pos
892                 };
893                 push(@$target, []);
894                 last CK;
895               }
896             }
897           }
898           if (exists $collapse{$cur}) {
899             $target = $target->[-1];
900           }
901         }
902         $target->[0] = $data;
903       } else {
904         $info->[0] = $const->{$key};
905       }
906     }
907   }
908
909   return $info;
910 }
911
912 =head2 result_source
913
914 =over 4
915
916 =item Arguments: $result_source?
917
918 =item Return Value: $result_source
919
920 =back
921
922 An accessor for the primary ResultSource object from which this ResultSet
923 is derived.
924
925 =head2 result_class
926
927 =over 4
928
929 =item Arguments: $result_class?
930
931 =item Return Value: $result_class
932
933 =back
934
935 An accessor for the class to use when creating row objects. Defaults to 
936 C<< result_source->result_class >> - which in most cases is the name of the 
937 L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class.
938
939 =cut
940
941
942 =head2 count
943
944 =over 4
945
946 =item Arguments: $cond, \%attrs??
947
948 =item Return Value: $count
949
950 =back
951
952 Performs an SQL C<COUNT> with the same query as the resultset was built
953 with to find the number of elements. If passed arguments, does a search
954 on the resultset and counts the results of that.
955
956 Note: When using C<count> with C<group_by>, L<DBIx::Class> emulates C<GROUP BY>
957 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
958 not support C<DISTINCT> with multiple columns. If you are using such a
959 database, you should only use columns from the main table in your C<group_by>
960 clause.
961
962 =cut
963
964 sub count {
965   my $self = shift;
966   return $self->search(@_)->count if @_ and defined $_[0];
967   return scalar @{ $self->get_cache } if $self->get_cache;
968   my $count = $self->_count;
969   return 0 unless $count;
970
971   # need to take offset from resolved attrs
972
973   $count -= $self->{_attrs}{offset} if $self->{_attrs}{offset};
974   $count = $self->{attrs}{rows} if
975     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
976   $count = 0 if ($count < 0);
977   return $count;
978 }
979
980 sub _count { # Separated out so pager can get the full count
981   my $self = shift;
982   my $select = { count => '*' };
983
984   my $attrs = { %{$self->_resolved_attrs} };
985   if (my $group_by = delete $attrs->{group_by}) {
986     delete $attrs->{having};
987     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
988     # todo: try CONCAT for multi-column pk
989     my @pk = $self->result_source->primary_columns;
990     if (@pk == 1) {
991       my $alias = $attrs->{alias};
992       foreach my $column (@distinct) {
993         if ($column =~ qr/^(?:\Q${alias}.\E)?$pk[0]$/) {
994           @distinct = ($column);
995           last;
996         }
997       }
998     }
999
1000     $select = { count => { distinct => \@distinct } };
1001   }
1002
1003   $attrs->{select} = $select;
1004   $attrs->{as} = [qw/count/];
1005
1006   # offset, order by and page are not needed to count. record_filter is cdbi
1007   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
1008
1009   my $tmp_rs = (ref $self)->new($self->result_source, $attrs);
1010   my ($count) = $tmp_rs->cursor->next;
1011   return $count;
1012 }
1013
1014 sub _bool {
1015   return 1;
1016 }
1017
1018 =head2 count_literal
1019
1020 =over 4
1021
1022 =item Arguments: $sql_fragment, @bind_values
1023
1024 =item Return Value: $count
1025
1026 =back
1027
1028 Counts the results in a literal query. Equivalent to calling L</search_literal>
1029 with the passed arguments, then L</count>.
1030
1031 =cut
1032
1033 sub count_literal { shift->search_literal(@_)->count; }
1034
1035 =head2 all
1036
1037 =over 4
1038
1039 =item Arguments: none
1040
1041 =item Return Value: @objects
1042
1043 =back
1044
1045 Returns all elements in the resultset. Called implicitly if the resultset
1046 is returned in list context.
1047
1048 =cut
1049
1050 sub all {
1051   my ($self) = @_;
1052   return @{ $self->get_cache } if $self->get_cache;
1053
1054   my @obj;
1055
1056   # TODO: don't call resolve here
1057   if (keys %{$self->_resolved_attrs->{collapse}}) {
1058 #  if ($self->{attrs}{prefetch}) {
1059       # Using $self->cursor->all is really just an optimisation.
1060       # If we're collapsing has_many prefetches it probably makes
1061       # very little difference, and this is cleaner than hacking
1062       # _construct_object to survive the approach
1063     my @row = $self->cursor->next;
1064     while (@row) {
1065       push(@obj, $self->_construct_object(@row));
1066       @row = (exists $self->{stashed_row}
1067                ? @{delete $self->{stashed_row}}
1068                : $self->cursor->next);
1069     }
1070   } else {
1071     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
1072   }
1073
1074   $self->set_cache(\@obj) if $self->{attrs}{cache};
1075   return @obj;
1076 }
1077
1078 =head2 reset
1079
1080 =over 4
1081
1082 =item Arguments: none
1083
1084 =item Return Value: $self
1085
1086 =back
1087
1088 Resets the resultset's cursor, so you can iterate through the elements again.
1089
1090 =cut
1091
1092 sub reset {
1093   my ($self) = @_;
1094   delete $self->{_attrs} if exists $self->{_attrs};
1095   $self->{all_cache_position} = 0;
1096   $self->cursor->reset;
1097   return $self;
1098 }
1099
1100 =head2 first
1101
1102 =over 4
1103
1104 =item Arguments: none
1105
1106 =item Return Value: $object?
1107
1108 =back
1109
1110 Resets the resultset and returns an object for the first result (if the
1111 resultset returns anything).
1112
1113 =cut
1114
1115 sub first {
1116   return $_[0]->reset->next;
1117 }
1118
1119 # _cond_for_update_delete
1120 #
1121 # update/delete require the condition to be modified to handle
1122 # the differing SQL syntax available.  This transforms the $self->{cond}
1123 # appropriately, returning the new condition.
1124
1125 sub _cond_for_update_delete {
1126   my ($self, $full_cond) = @_;
1127   my $cond = {};
1128
1129   $full_cond ||= $self->{cond};
1130   # No-op. No condition, we're updating/deleting everything
1131   return $cond unless ref $full_cond;
1132
1133   if (ref $full_cond eq 'ARRAY') {
1134     $cond = [
1135       map {
1136         my %hash;
1137         foreach my $key (keys %{$_}) {
1138           $key =~ /([^.]+)$/;
1139           $hash{$1} = $_->{$key};
1140         }
1141         \%hash;
1142       } @{$full_cond}
1143     ];
1144   }
1145   elsif (ref $full_cond eq 'HASH') {
1146     if ((keys %{$full_cond})[0] eq '-and') {
1147       $cond->{-and} = [];
1148
1149       my @cond = @{$full_cond->{-and}};
1150       for (my $i = 0; $i < @cond; $i++) {
1151         my $entry = $cond[$i];
1152
1153         my $hash;
1154         if (ref $entry eq 'HASH') {
1155           $hash = $self->_cond_for_update_delete($entry);
1156         }
1157         else {
1158           $entry =~ /([^.]+)$/;
1159           $hash->{$1} = $cond[++$i];
1160         }
1161
1162         push @{$cond->{-and}}, $hash;
1163       }
1164     }
1165     else {
1166       foreach my $key (keys %{$full_cond}) {
1167         $key =~ /([^.]+)$/;
1168         $cond->{$1} = $full_cond->{$key};
1169       }
1170     }
1171   }
1172   else {
1173     $self->throw_exception(
1174       "Can't update/delete on resultset with condition unless hash or array"
1175     );
1176   }
1177
1178   return $cond;
1179 }
1180
1181
1182 =head2 update
1183
1184 =over 4
1185
1186 =item Arguments: \%values
1187
1188 =item Return Value: $storage_rv
1189
1190 =back
1191
1192 Sets the specified columns in the resultset to the supplied values in a
1193 single query. Return value will be true if the update succeeded or false
1194 if no records were updated; exact type of success value is storage-dependent.
1195
1196 =cut
1197
1198 sub update {
1199   my ($self, $values) = @_;
1200   $self->throw_exception("Values for update must be a hash")
1201     unless ref $values eq 'HASH';
1202
1203   my $cond = $self->_cond_for_update_delete;
1204    
1205   return $self->result_source->storage->update(
1206     $self->result_source, $values, $cond
1207   );
1208 }
1209
1210 =head2 update_all
1211
1212 =over 4
1213
1214 =item Arguments: \%values
1215
1216 =item Return Value: 1
1217
1218 =back
1219
1220 Fetches all objects and updates them one at a time. Note that C<update_all>
1221 will run DBIC cascade triggers, while L</update> will not.
1222
1223 =cut
1224
1225 sub update_all {
1226   my ($self, $values) = @_;
1227   $self->throw_exception("Values for update must be a hash")
1228     unless ref $values eq 'HASH';
1229   foreach my $obj ($self->all) {
1230     $obj->set_columns($values)->update;
1231   }
1232   return 1;
1233 }
1234
1235 =head2 delete
1236
1237 =over 4
1238
1239 =item Arguments: none
1240
1241 =item Return Value: 1
1242
1243 =back
1244
1245 Deletes the contents of the resultset from its result source. Note that this
1246 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1247 to run. See also L<DBIx::Class::Row/delete>.
1248
1249 =cut
1250
1251 sub delete {
1252   my ($self) = @_;
1253
1254   my $cond = $self->_cond_for_update_delete;
1255
1256   $self->result_source->storage->delete($self->result_source, $cond);
1257   return 1;
1258 }
1259
1260 =head2 delete_all
1261
1262 =over 4
1263
1264 =item Arguments: none
1265
1266 =item Return Value: 1
1267
1268 =back
1269
1270 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1271 will run DBIC cascade triggers, while L</delete> will not.
1272
1273 =cut
1274
1275 sub delete_all {
1276   my ($self) = @_;
1277   $_->delete for $self->all;
1278   return 1;
1279 }
1280
1281 =head2 populate
1282
1283 =over 4
1284
1285 =item Arguments: \@data;
1286
1287 =back
1288
1289 Pass an arrayref of hashrefs. Each hashref should be a structure suitable for
1290 submitting to a $resultset->create(...) method.
1291
1292 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
1293 to insert the data, as this is a faster method.  
1294
1295 Otherwise, each set of data is inserted into the database using
1296 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
1297 objects is returned.
1298
1299 Example:  Assuming an Artist Class that has many CDs Classes relating:
1300
1301   my $Artist_rs = $schema->resultset("Artist");
1302   
1303   ## Void Context Example 
1304   $Artist_rs->populate([
1305      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1306         { title => 'My First CD', year => 2006 },
1307         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1308       ],
1309      },
1310      { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
1311         { title => 'My parents sold me to a record company' ,year => 2005 },
1312         { title => 'Why Am I So Ugly?', year => 2006 },
1313         { title => 'I Got Surgery and am now Popular', year => 2007 }
1314       ],
1315      },
1316   ]);
1317   
1318   ## Array Context Example
1319   my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
1320     { name => "Artist One"},
1321     { name => "Artist Two"},
1322     { name => "Artist Three", cds=> [
1323     { title => "First CD", year => 2007},
1324     { title => "Second CD", year => 2008},
1325   ]}
1326   ]);
1327   
1328   print $ArtistOne->name; ## response is 'Artist One'
1329   print $ArtistThree->cds->count ## reponse is '2'
1330   
1331 Please note an important effect on your data when choosing between void and
1332 wantarray context. Since void context goes straight to C<insert_bulk> in 
1333 L<DBIx::Class::Storage::DBI> this will skip any component that is overriding
1334 c<insert>.  So if you are using something like L<DBIx-Class-UUIDColumns> to 
1335 create primary keys for you, you will find that your PKs are empty.  In this 
1336 case you will have to use the wantarray context in order to create those 
1337 values.
1338
1339 =cut
1340
1341 sub populate {
1342   my ($self, $data) = @_;
1343   
1344   if(defined wantarray) {
1345     my @created;
1346     foreach my $item (@$data) {
1347       push(@created, $self->create($item));
1348     }
1349     return @created;
1350   } else {
1351     my ($first, @rest) = @$data;
1352
1353     my @names = grep {!ref $first->{$_}} keys %$first;
1354     my @rels = grep { $self->result_source->has_relationship($_) } keys %$first;
1355     my @pks = $self->result_source->primary_columns;  
1356
1357     ## do the belongs_to relationships  
1358     foreach my $index (0..$#$data) {
1359       if( grep { !defined $data->[$index]->{$_} } @pks ) {
1360         my @ret = $self->populate($data);
1361         return;
1362       }
1363     
1364       foreach my $rel (@rels) {
1365         next unless $data->[$index]->{$rel} && ref $data->[$index]->{$rel} eq "HASH";
1366         my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
1367         my ($reverse) = keys %{$self->result_source->reverse_relationship_info($rel)};
1368         my $related = $result->result_source->resolve_condition(
1369           $result->result_source->relationship_info($reverse)->{cond},
1370           $self,        
1371           $result,        
1372         );
1373
1374         delete $data->[$index]->{$rel};
1375         $data->[$index] = {%{$data->[$index]}, %$related};
1376       
1377         push @names, keys %$related if $index == 0;
1378       }
1379     }
1380
1381     ## do bulk insert on current row
1382     my @values = map { [ @$_{@names} ] } @$data;
1383
1384     $self->result_source->storage->insert_bulk(
1385       $self->result_source, 
1386       \@names, 
1387       \@values,
1388     );
1389
1390     ## do the has_many relationships
1391     foreach my $item (@$data) {
1392
1393       foreach my $rel (@rels) {
1394         next unless $item->{$rel} && ref $item->{$rel} eq "ARRAY";
1395
1396         my $parent = $self->find(map {{$_=>$item->{$_}} } @pks) 
1397      || $self->throw_exception('Cannot find the relating object.');
1398      
1399         my $child = $parent->$rel;
1400     
1401         my $related = $child->result_source->resolve_condition(
1402           $parent->result_source->relationship_info($rel)->{cond},
1403           $child,
1404           $parent,
1405         );
1406
1407         my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
1408         my @populate = map { {%$_, %$related} } @rows_to_add;
1409
1410         $child->populate( \@populate );
1411       }
1412     }
1413   }
1414 }
1415
1416 =head2 pager
1417
1418 =over 4
1419
1420 =item Arguments: none
1421
1422 =item Return Value: $pager
1423
1424 =back
1425
1426 Return Value a L<Data::Page> object for the current resultset. Only makes
1427 sense for queries with a C<page> attribute.
1428
1429 =cut
1430
1431 sub pager {
1432   my ($self) = @_;
1433   my $attrs = $self->{attrs};
1434   $self->throw_exception("Can't create pager for non-paged rs")
1435     unless $self->{attrs}{page};
1436   $attrs->{rows} ||= 10;
1437   return $self->{pager} ||= Data::Page->new(
1438     $self->_count, $attrs->{rows}, $self->{attrs}{page});
1439 }
1440
1441 =head2 page
1442
1443 =over 4
1444
1445 =item Arguments: $page_number
1446
1447 =item Return Value: $rs
1448
1449 =back
1450
1451 Returns a resultset for the $page_number page of the resultset on which page
1452 is called, where each page contains a number of rows equal to the 'rows'
1453 attribute set on the resultset (10 by default).
1454
1455 =cut
1456
1457 sub page {
1458   my ($self, $page) = @_;
1459   return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
1460 }
1461
1462 =head2 new_result
1463
1464 =over 4
1465
1466 =item Arguments: \%vals
1467
1468 =item Return Value: $object
1469
1470 =back
1471
1472 Creates a new row object in the resultset's result class and returns
1473 it. The row is not inserted into the database at this point, call
1474 L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
1475 will tell you whether the row object has been inserted or not.
1476
1477 Passes the hashref of input on to L<DBIx::Class::Row/new>.
1478
1479 =cut
1480
1481 sub new_result {
1482   my ($self, $values) = @_;
1483   $self->throw_exception( "new_result needs a hash" )
1484     unless (ref $values eq 'HASH');
1485   $self->throw_exception(
1486     "Can't abstract implicit construct, condition not a hash"
1487   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1488
1489   my $alias = $self->{attrs}{alias};
1490   my $collapsed_cond = $self->{cond} ? $self->_collapse_cond($self->{cond}) : {};
1491
1492   # precendence must be given to passed values over values inherited from the cond, 
1493   # so the order here is important.
1494   my %new = (
1495     %{ $self->_remove_alias($collapsed_cond, $alias) },
1496     %{ $self->_remove_alias($values, $alias) },
1497     -source_handle => $self->_source_handle,
1498     -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
1499   );
1500
1501   return $self->result_class->new(\%new);
1502 }
1503
1504 # _collapse_cond
1505 #
1506 # Recursively collapse the condition.
1507
1508 sub _collapse_cond {
1509   my ($self, $cond, $collapsed) = @_;
1510
1511   $collapsed ||= {};
1512
1513   if (ref $cond eq 'ARRAY') {
1514     foreach my $subcond (@$cond) {
1515       next unless ref $subcond;  # -or
1516 #      warn "ARRAY: " . Dumper $subcond;
1517       $collapsed = $self->_collapse_cond($subcond, $collapsed);
1518     }
1519   }
1520   elsif (ref $cond eq 'HASH') {
1521     if (keys %$cond and (keys %$cond)[0] eq '-and') {
1522       foreach my $subcond (@{$cond->{-and}}) {
1523 #        warn "HASH: " . Dumper $subcond;
1524         $collapsed = $self->_collapse_cond($subcond, $collapsed);
1525       }
1526     }
1527     else {
1528 #      warn "LEAF: " . Dumper $cond;
1529       foreach my $col (keys %$cond) {
1530         my $value = $cond->{$col};
1531         $collapsed->{$col} = $value;
1532       }
1533     }
1534   }
1535
1536   return $collapsed;
1537 }
1538
1539 # _remove_alias
1540 #
1541 # Remove the specified alias from the specified query hash. A copy is made so
1542 # the original query is not modified.
1543
1544 sub _remove_alias {
1545   my ($self, $query, $alias) = @_;
1546
1547   my %orig = %{ $query || {} };
1548   my %unaliased;
1549
1550   foreach my $key (keys %orig) {
1551     if ($key !~ /\./) {
1552       $unaliased{$key} = $orig{$key};
1553       next;
1554     }
1555     $unaliased{$1} = $orig{$key}
1556       if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
1557   }
1558
1559   return \%unaliased;
1560 }
1561
1562 =head2 find_or_new
1563
1564 =over 4
1565
1566 =item Arguments: \%vals, \%attrs?
1567
1568 =item Return Value: $object
1569
1570 =back
1571
1572 Find an existing record from this resultset. If none exists, instantiate a new
1573 result object and return it. The object will not be saved into your storage
1574 until you call L<DBIx::Class::Row/insert> on it.
1575
1576 If you want objects to be saved immediately, use L</find_or_create> instead.
1577
1578 =cut
1579
1580 sub find_or_new {
1581   my $self     = shift;
1582   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1583   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1584   my $exists   = $self->find($hash, $attrs);
1585   return defined $exists ? $exists : $self->new_result($hash);
1586 }
1587
1588 =head2 create
1589
1590 =over 4
1591
1592 =item Arguments: \%vals
1593
1594 =item Return Value: a L<DBIx::Class::Row> $object
1595
1596 =back
1597
1598 Attempt to create a single new row or a row with multiple related rows
1599 in the table represented by the resultset (and related tables). This
1600 will not check for duplicate rows before inserting, use
1601 L</find_or_create> to do that.
1602
1603 To create one row for this resultset, pass a hashref of key/value
1604 pairs representing the columns of the table and the values you wish to
1605 store. If the appropriate relationships are set up, foreign key fields
1606 can also be passed an object representing the foreign row, and the
1607 value will be set to it's primary key.
1608
1609 To create related objects, pass a hashref for the value if the related
1610 item is a foreign key relationship (L<DBIx::Class::Relationship/belongs_to>),
1611 and use the name of the relationship as the key. (NOT the name of the field,
1612 necessarily). For C<has_many> and C<has_one> relationships, pass an arrayref
1613 of hashrefs containing the data for each of the rows to create in the foreign
1614 tables, again using the relationship name as the key.
1615
1616 Instead of hashrefs of plain related data (key/value pairs), you may
1617 also pass new or inserted objects. New objects (not inserted yet, see
1618 L</new>), will be inserted into their appropriate tables.
1619
1620 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1621
1622 Example of creating a new row.
1623
1624   $person_rs->create({
1625     name=>"Some Person",
1626         email=>"somebody@someplace.com"
1627   });
1628   
1629 Example of creating a new row and also creating rows in a related C<has_many>
1630 or C<has_one> resultset.  Note Arrayref.
1631
1632   $artist_rs->create(
1633      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1634         { title => 'My First CD', year => 2006 },
1635         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1636       ],
1637      },
1638   );
1639
1640 Example of creating a new row and also creating a row in a related
1641 C<belongs_to>resultset. Note Hashref.
1642
1643   $cd_rs->create({
1644     title=>"Music for Silly Walks",
1645         year=>2000,
1646         artist => {
1647           name=>"Silly Musician",
1648         }
1649   });
1650
1651 =cut
1652
1653 sub create {
1654   my ($self, $attrs) = @_;
1655   $self->throw_exception( "create needs a hashref" )
1656     unless ref $attrs eq 'HASH';
1657   return $self->new_result($attrs)->insert;
1658 }
1659
1660 =head2 find_or_create
1661
1662 =over 4
1663
1664 =item Arguments: \%vals, \%attrs?
1665
1666 =item Return Value: $object
1667
1668 =back
1669
1670   $class->find_or_create({ key => $val, ... });
1671
1672 Tries to find a record based on its primary key or unique constraint; if none
1673 is found, creates one and returns that instead.
1674
1675   my $cd = $schema->resultset('CD')->find_or_create({
1676     cdid   => 5,
1677     artist => 'Massive Attack',
1678     title  => 'Mezzanine',
1679     year   => 2005,
1680   });
1681
1682 Also takes an optional C<key> attribute, to search by a specific key or unique
1683 constraint. For example:
1684
1685   my $cd = $schema->resultset('CD')->find_or_create(
1686     {
1687       artist => 'Massive Attack',
1688       title  => 'Mezzanine',
1689     },
1690     { key => 'cd_artist_title' }
1691   );
1692
1693 See also L</find> and L</update_or_create>. For information on how to declare
1694 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1695
1696 =cut
1697
1698 sub find_or_create {
1699   my $self     = shift;
1700   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1701   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1702   my $exists   = $self->find($hash, $attrs);
1703   return defined $exists ? $exists : $self->create($hash);
1704 }
1705
1706 =head2 update_or_create
1707
1708 =over 4
1709
1710 =item Arguments: \%col_values, { key => $unique_constraint }?
1711
1712 =item Return Value: $object
1713
1714 =back
1715
1716   $class->update_or_create({ col => $val, ... });
1717
1718 First, searches for an existing row matching one of the unique constraints
1719 (including the primary key) on the source of this resultset. If a row is
1720 found, updates it with the other given column values. Otherwise, creates a new
1721 row.
1722
1723 Takes an optional C<key> attribute to search on a specific unique constraint.
1724 For example:
1725
1726   # In your application
1727   my $cd = $schema->resultset('CD')->update_or_create(
1728     {
1729       artist => 'Massive Attack',
1730       title  => 'Mezzanine',
1731       year   => 1998,
1732     },
1733     { key => 'cd_artist_title' }
1734   );
1735
1736 If no C<key> is specified, it searches on all unique constraints defined on the
1737 source, including the primary key.
1738
1739 If the C<key> is specified as C<primary>, it searches only on the primary key.
1740
1741 See also L</find> and L</find_or_create>. For information on how to declare
1742 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1743
1744 =cut
1745
1746 sub update_or_create {
1747   my $self = shift;
1748   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1749   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
1750
1751   my $row = $self->find($cond, $attrs);
1752   if (defined $row) {
1753     $row->update($cond);
1754     return $row;
1755   }
1756
1757   return $self->create($cond);
1758 }
1759
1760 =head2 get_cache
1761
1762 =over 4
1763
1764 =item Arguments: none
1765
1766 =item Return Value: \@cache_objects?
1767
1768 =back
1769
1770 Gets the contents of the cache for the resultset, if the cache is set.
1771
1772 =cut
1773
1774 sub get_cache {
1775   shift->{all_cache};
1776 }
1777
1778 =head2 set_cache
1779
1780 =over 4
1781
1782 =item Arguments: \@cache_objects
1783
1784 =item Return Value: \@cache_objects
1785
1786 =back
1787
1788 Sets the contents of the cache for the resultset. Expects an arrayref
1789 of objects of the same class as those produced by the resultset. Note that
1790 if the cache is set the resultset will return the cached objects rather
1791 than re-querying the database even if the cache attr is not set.
1792
1793 =cut
1794
1795 sub set_cache {
1796   my ( $self, $data ) = @_;
1797   $self->throw_exception("set_cache requires an arrayref")
1798       if defined($data) && (ref $data ne 'ARRAY');
1799   $self->{all_cache} = $data;
1800 }
1801
1802 =head2 clear_cache
1803
1804 =over 4
1805
1806 =item Arguments: none
1807
1808 =item Return Value: []
1809
1810 =back
1811
1812 Clears the cache for the resultset.
1813
1814 =cut
1815
1816 sub clear_cache {
1817   shift->set_cache(undef);
1818 }
1819
1820 =head2 related_resultset
1821
1822 =over 4
1823
1824 =item Arguments: $relationship_name
1825
1826 =item Return Value: $resultset
1827
1828 =back
1829
1830 Returns a related resultset for the supplied relationship name.
1831
1832   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1833
1834 =cut
1835
1836 sub related_resultset {
1837   my ($self, $rel) = @_;
1838
1839   $self->{related_resultsets} ||= {};
1840   return $self->{related_resultsets}{$rel} ||= do {
1841     my $rel_obj = $self->result_source->relationship_info($rel);
1842
1843     $self->throw_exception(
1844       "search_related: result source '" . $self->result_source->source_name .
1845         "' has no such relationship $rel")
1846       unless $rel_obj;
1847     
1848     my ($from,$seen) = $self->_resolve_from($rel);
1849
1850     my $join_count = $seen->{$rel};
1851     my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
1852
1853     #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
1854     my %attrs = %{$self->{attrs}||{}};
1855     delete @attrs{qw(result_class alias)};
1856
1857     my $new_cache;
1858
1859     if (my $cache = $self->get_cache) {
1860       if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
1861         $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
1862                         @$cache ];
1863       }
1864     }
1865
1866     my $rel_source = $self->result_source->related_source($rel);
1867
1868     my $new = do {
1869
1870       # The reason we do this now instead of passing the alias to the
1871       # search_rs below is that if you wrap/overload resultset on the
1872       # source you need to know what alias it's -going- to have for things
1873       # to work sanely (e.g. RestrictWithObject wants to be able to add
1874       # extra query restrictions, and these may need to be $alias.)
1875
1876       my $attrs = $rel_source->resultset_attributes;
1877       local $attrs->{alias} = $alias;
1878
1879       $rel_source->resultset
1880                  ->search_rs(
1881                      undef, {
1882                        %attrs,
1883                        join => undef,
1884                        prefetch => undef,
1885                        select => undef,
1886                        as => undef,
1887                        where => $self->{cond},
1888                        seen_join => $seen,
1889                        from => $from,
1890                    });
1891     };
1892     $new->set_cache($new_cache) if $new_cache;
1893     $new;
1894   };
1895 }
1896
1897 sub _resolve_from {
1898   my ($self, $extra_join) = @_;
1899   my $source = $self->result_source;
1900   my $attrs = $self->{attrs};
1901   
1902   my $from = $attrs->{from}
1903     || [ { $attrs->{alias} => $source->from } ];
1904     
1905   my $seen = { %{$attrs->{seen_join}||{}} };
1906
1907   my $join = ($attrs->{join}
1908                ? [ $attrs->{join}, $extra_join ]
1909                : $extra_join);
1910
1911   # we need to take the prefetch the attrs into account before we 
1912   # ->resolve_join as otherwise they get lost - captainL
1913   my $merged = $self->_merge_attr( $join, $attrs->{prefetch} );
1914
1915   $from = [
1916     @$from,
1917     ($join ? $source->resolve_join($merged, $attrs->{alias}, $seen) : ()),
1918   ];
1919
1920   return ($from,$seen);
1921 }
1922
1923 sub _resolved_attrs {
1924   my $self = shift;
1925   return $self->{_attrs} if $self->{_attrs};
1926
1927   my $attrs = { %{$self->{attrs}||{}} };
1928   my $source = $self->result_source;
1929   my $alias = $attrs->{alias};
1930
1931   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
1932   if ($attrs->{columns}) {
1933     delete $attrs->{as};
1934   } elsif (!$attrs->{select}) {
1935     $attrs->{columns} = [ $source->columns ];
1936   }
1937  
1938   $attrs->{select} = 
1939     ($attrs->{select}
1940       ? (ref $attrs->{select} eq 'ARRAY'
1941           ? [ @{$attrs->{select}} ]
1942           : [ $attrs->{select} ])
1943       : [ map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}} ]
1944     );
1945   $attrs->{as} =
1946     ($attrs->{as}
1947       ? (ref $attrs->{as} eq 'ARRAY'
1948           ? [ @{$attrs->{as}} ]
1949           : [ $attrs->{as} ])
1950       : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}} ]
1951     );
1952   
1953   my $adds;
1954   if ($adds = delete $attrs->{include_columns}) {
1955     $adds = [$adds] unless ref $adds eq 'ARRAY';
1956     push(@{$attrs->{select}}, @$adds);
1957     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1 } @$adds);
1958   }
1959   if ($adds = delete $attrs->{'+select'}) {
1960     $adds = [$adds] unless ref $adds eq 'ARRAY';
1961     push(@{$attrs->{select}},
1962            map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds);
1963   }
1964   if (my $adds = delete $attrs->{'+as'}) {
1965     $adds = [$adds] unless ref $adds eq 'ARRAY';
1966     push(@{$attrs->{as}}, @$adds);
1967   }
1968
1969   $attrs->{from} ||= [ { 'me' => $source->from } ];
1970
1971   if (exists $attrs->{join} || exists $attrs->{prefetch}) {
1972     my $join = delete $attrs->{join} || {};
1973
1974     if (defined $attrs->{prefetch}) {
1975       $join = $self->_merge_attr(
1976         $join, $attrs->{prefetch}
1977       );
1978       
1979     }
1980
1981     $attrs->{from} =   # have to copy here to avoid corrupting the original
1982       [
1983         @{$attrs->{from}}, 
1984         $source->resolve_join($join, $alias, { %{$attrs->{seen_join}||{}} })
1985       ];
1986
1987   }
1988
1989   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
1990   if ($attrs->{order_by}) {
1991     $attrs->{order_by} = (ref($attrs->{order_by}) eq 'ARRAY'
1992                            ? [ @{$attrs->{order_by}} ]
1993                            : [ $attrs->{order_by} ]);
1994   } else {
1995     $attrs->{order_by} = [];    
1996   }
1997
1998   my $collapse = $attrs->{collapse} || {};
1999   if (my $prefetch = delete $attrs->{prefetch}) {
2000     $prefetch = $self->_merge_attr({}, $prefetch);
2001     my @pre_order;
2002     my $seen = $attrs->{seen_join} || {};
2003     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
2004       # bring joins back to level of current class
2005       my @prefetch = $source->resolve_prefetch(
2006         $p, $alias, $seen, \@pre_order, $collapse
2007       );
2008       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
2009       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
2010     }
2011     push(@{$attrs->{order_by}}, @pre_order);
2012   }
2013   $attrs->{collapse} = $collapse;
2014
2015   if ($attrs->{page}) {
2016     $attrs->{offset} ||= 0;
2017     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
2018   }
2019
2020   return $self->{_attrs} = $attrs;
2021 }
2022
2023 sub _rollout_attr {
2024   my ($self, $attr) = @_;
2025   
2026   if (ref $attr eq 'HASH') {
2027     return $self->_rollout_hash($attr);
2028   } elsif (ref $attr eq 'ARRAY') {
2029     return $self->_rollout_array($attr);
2030   } else {
2031     return [$attr];
2032   }
2033 }
2034
2035 sub _rollout_array {
2036   my ($self, $attr) = @_;
2037
2038   my @rolled_array;
2039   foreach my $element (@{$attr}) {
2040     if (ref $element eq 'HASH') {
2041       push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
2042     } elsif (ref $element eq 'ARRAY') {
2043       #  XXX - should probably recurse here
2044       push( @rolled_array, @{$self->_rollout_array($element)} );
2045     } else {
2046       push( @rolled_array, $element );
2047     }
2048   }
2049   return \@rolled_array;
2050 }
2051
2052 sub _rollout_hash {
2053   my ($self, $attr) = @_;
2054
2055   my @rolled_array;
2056   foreach my $key (keys %{$attr}) {
2057     push( @rolled_array, { $key => $attr->{$key} } );
2058   }
2059   return \@rolled_array;
2060 }
2061
2062 sub _calculate_score {
2063   my ($self, $a, $b) = @_;
2064
2065   if (ref $b eq 'HASH') {
2066     my ($b_key) = keys %{$b};
2067     if (ref $a eq 'HASH') {
2068       my ($a_key) = keys %{$a};
2069       if ($a_key eq $b_key) {
2070         return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
2071       } else {
2072         return 0;
2073       }
2074     } else {
2075       return ($a eq $b_key) ? 1 : 0;
2076     }       
2077   } else {
2078     if (ref $a eq 'HASH') {
2079       my ($a_key) = keys %{$a};
2080       return ($b eq $a_key) ? 1 : 0;
2081     } else {
2082       return ($b eq $a) ? 1 : 0;
2083     }
2084   }
2085 }
2086
2087 sub _merge_attr {
2088   my ($self, $a, $b) = @_;
2089
2090   return $b unless defined($a);
2091   return $a unless defined($b);
2092   
2093   $a = $self->_rollout_attr($a);
2094   $b = $self->_rollout_attr($b);
2095
2096   my $seen_keys;
2097   foreach my $b_element ( @{$b} ) {
2098     # find best candidate from $a to merge $b_element into
2099     my $best_candidate = { position => undef, score => 0 }; my $position = 0;
2100     foreach my $a_element ( @{$a} ) {
2101       my $score = $self->_calculate_score( $a_element, $b_element );
2102       if ($score > $best_candidate->{score}) {
2103         $best_candidate->{position} = $position;
2104         $best_candidate->{score} = $score;
2105       }
2106       $position++;
2107     }
2108     my ($b_key) = ( ref $b_element eq 'HASH' ) ? keys %{$b_element} : ($b_element);
2109
2110     if ($best_candidate->{score} == 0 || exists $seen_keys->{$b_key}) {
2111       push( @{$a}, $b_element );
2112     } else {
2113       my $a_best = $a->[$best_candidate->{position}];
2114       # merge a_best and b_element together and replace original with merged
2115       if (ref $a_best ne 'HASH') {
2116         $a->[$best_candidate->{position}] = $b_element;
2117       } elsif (ref $b_element eq 'HASH') {
2118         my ($key) = keys %{$a_best};
2119         $a->[$best_candidate->{position}] = { $key => $self->_merge_attr($a_best->{$key}, $b_element->{$key}) };
2120       }
2121     }
2122     $seen_keys->{$b_key} = 1; # don't merge the same key twice
2123   }
2124
2125   return $a;
2126 }
2127
2128 sub result_source {
2129     my $self = shift;
2130
2131     if (@_) {
2132         $self->_source_handle($_[0]->handle);
2133     } else {
2134         $self->_source_handle->resolve;
2135     }
2136 }
2137
2138 =head2 throw_exception
2139
2140 See L<DBIx::Class::Schema/throw_exception> for details.
2141
2142 =cut
2143
2144 sub throw_exception {
2145   my $self=shift;
2146   if (ref $self && $self->_source_handle->schema) {
2147     $self->_source_handle->schema->throw_exception(@_)
2148   } else {
2149     croak(@_);
2150   }
2151
2152 }
2153
2154 # XXX: FIXME: Attributes docs need clearing up
2155
2156 =head1 ATTRIBUTES
2157
2158 The resultset takes various attributes that modify its behavior. Here's an
2159 overview of them:
2160
2161 =head2 order_by
2162
2163 =over 4
2164
2165 =item Value: ($order_by | \@order_by)
2166
2167 =back
2168
2169 Which column(s) to order the results by. This is currently passed
2170 through directly to SQL, so you can give e.g. C<year DESC> for a
2171 descending order on the column `year'.
2172
2173 Please note that if you have C<quote_char> enabled (see
2174 L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
2175 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
2176 so you will need to manually quote things as appropriate.)
2177
2178 =head2 columns
2179
2180 =over 4
2181
2182 =item Value: \@columns
2183
2184 =back
2185
2186 Shortcut to request a particular set of columns to be retrieved.  Adds
2187 C<me.> onto the start of any column without a C<.> in it and sets C<select>
2188 from that, then auto-populates C<as> from C<select> as normal. (You may also
2189 use the C<cols> attribute, as in earlier versions of DBIC.)
2190
2191 =head2 include_columns
2192
2193 =over 4
2194
2195 =item Value: \@columns
2196
2197 =back
2198
2199 Shortcut to include additional columns in the returned results - for example
2200
2201   $schema->resultset('CD')->search(undef, {
2202     include_columns => ['artist.name'],
2203     join => ['artist']
2204   });
2205
2206 would return all CDs and include a 'name' column to the information
2207 passed to object inflation. Note that the 'artist' is the name of the
2208 column (or relationship) accessor, and 'name' is the name of the column
2209 accessor in the related table.
2210
2211 =head2 select
2212
2213 =over 4
2214
2215 =item Value: \@select_columns
2216
2217 =back
2218
2219 Indicates which columns should be selected from the storage. You can use
2220 column names, or in the case of RDBMS back ends, function or stored procedure
2221 names:
2222
2223   $rs = $schema->resultset('Employee')->search(undef, {
2224     select => [
2225       'name',
2226       { count => 'employeeid' },
2227       { sum => 'salary' }
2228     ]
2229   });
2230
2231 When you use function/stored procedure names and do not supply an C<as>
2232 attribute, the column names returned are storage-dependent. E.g. MySQL would
2233 return a column named C<count(employeeid)> in the above example.
2234
2235 =head2 +select
2236
2237 =over 4
2238
2239 Indicates additional columns to be selected from storage.  Works the same as
2240 L</select> but adds columns to the selection.
2241
2242 =back
2243
2244 =head2 +as
2245
2246 =over 4
2247
2248 Indicates additional column names for those added via L</+select>.
2249
2250 =back
2251
2252 =head2 as
2253
2254 =over 4
2255
2256 =item Value: \@inflation_names
2257
2258 =back
2259
2260 Indicates column names for object inflation. That is, C<as>
2261 indicates the name that the column can be accessed as via the
2262 C<get_column> method (or via the object accessor, B<if one already
2263 exists>).  It has nothing to do with the SQL code C<SELECT foo AS bar>.
2264
2265 The C<as> attribute is used in conjunction with C<select>,
2266 usually when C<select> contains one or more function or stored
2267 procedure names:
2268
2269   $rs = $schema->resultset('Employee')->search(undef, {
2270     select => [
2271       'name',
2272       { count => 'employeeid' }
2273     ],
2274     as => ['name', 'employee_count'],
2275   });
2276
2277   my $employee = $rs->first(); # get the first Employee
2278
2279 If the object against which the search is performed already has an accessor
2280 matching a column name specified in C<as>, the value can be retrieved using
2281 the accessor as normal:
2282
2283   my $name = $employee->name();
2284
2285 If on the other hand an accessor does not exist in the object, you need to
2286 use C<get_column> instead:
2287
2288   my $employee_count = $employee->get_column('employee_count');
2289
2290 You can create your own accessors if required - see
2291 L<DBIx::Class::Manual::Cookbook> for details.
2292
2293 Please note: This will NOT insert an C<AS employee_count> into the SQL
2294 statement produced, it is used for internal access only. Thus
2295 attempting to use the accessor in an C<order_by> clause or similar
2296 will fail miserably.
2297
2298 To get around this limitation, you can supply literal SQL to your
2299 C<select> attibute that contains the C<AS alias> text, eg:
2300
2301   select => [\'myfield AS alias']
2302
2303 =head2 join
2304
2305 =over 4
2306
2307 =item Value: ($rel_name | \@rel_names | \%rel_names)
2308
2309 =back
2310
2311 Contains a list of relationships that should be joined for this query.  For
2312 example:
2313
2314   # Get CDs by Nine Inch Nails
2315   my $rs = $schema->resultset('CD')->search(
2316     { 'artist.name' => 'Nine Inch Nails' },
2317     { join => 'artist' }
2318   );
2319
2320 Can also contain a hash reference to refer to the other relation's relations.
2321 For example:
2322
2323   package MyApp::Schema::Track;
2324   use base qw/DBIx::Class/;
2325   __PACKAGE__->table('track');
2326   __PACKAGE__->add_columns(qw/trackid cd position title/);
2327   __PACKAGE__->set_primary_key('trackid');
2328   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
2329   1;
2330
2331   # In your application
2332   my $rs = $schema->resultset('Artist')->search(
2333     { 'track.title' => 'Teardrop' },
2334     {
2335       join     => { cd => 'track' },
2336       order_by => 'artist.name',
2337     }
2338   );
2339
2340 You need to use the relationship (not the table) name in  conditions, 
2341 because they are aliased as such. The current table is aliased as "me", so 
2342 you need to use me.column_name in order to avoid ambiguity. For example:
2343
2344   # Get CDs from 1984 with a 'Foo' track 
2345   my $rs = $schema->resultset('CD')->search(
2346     { 
2347       'me.year' => 1984,
2348       'tracks.name' => 'Foo'
2349     },
2350     { join => 'tracks' }
2351   );
2352   
2353 If the same join is supplied twice, it will be aliased to <rel>_2 (and
2354 similarly for a third time). For e.g.
2355
2356   my $rs = $schema->resultset('Artist')->search({
2357     'cds.title'   => 'Down to Earth',
2358     'cds_2.title' => 'Popular',
2359   }, {
2360     join => [ qw/cds cds/ ],
2361   });
2362
2363 will return a set of all artists that have both a cd with title 'Down
2364 to Earth' and a cd with title 'Popular'.
2365
2366 If you want to fetch related objects from other tables as well, see C<prefetch>
2367 below.
2368
2369 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
2370
2371 =head2 prefetch
2372
2373 =over 4
2374
2375 =item Value: ($rel_name | \@rel_names | \%rel_names)
2376
2377 =back
2378
2379 Contains one or more relationships that should be fetched along with
2380 the main query (when they are accessed afterwards the data will
2381 already be available, without extra queries to the database).  This is
2382 useful for when you know you will need the related objects, because it
2383 saves at least one query:
2384
2385   my $rs = $schema->resultset('Tag')->search(
2386     undef,
2387     {
2388       prefetch => {
2389         cd => 'artist'
2390       }
2391     }
2392   );
2393
2394 The initial search results in SQL like the following:
2395
2396   SELECT tag.*, cd.*, artist.* FROM tag
2397   JOIN cd ON tag.cd = cd.cdid
2398   JOIN artist ON cd.artist = artist.artistid
2399
2400 L<DBIx::Class> has no need to go back to the database when we access the
2401 C<cd> or C<artist> relationships, which saves us two SQL statements in this
2402 case.
2403
2404 Simple prefetches will be joined automatically, so there is no need
2405 for a C<join> attribute in the above search. If you're prefetching to
2406 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
2407 specify the join as well.
2408
2409 C<prefetch> can be used with the following relationship types: C<belongs_to>,
2410 C<has_one> (or if you're using C<add_relationship>, any relationship declared
2411 with an accessor type of 'single' or 'filter').
2412
2413 =head2 page
2414
2415 =over 4
2416
2417 =item Value: $page
2418
2419 =back
2420
2421 Makes the resultset paged and specifies the page to retrieve. Effectively
2422 identical to creating a non-pages resultset and then calling ->page($page)
2423 on it.
2424
2425 If L<rows> attribute is not specified it defualts to 10 rows per page.
2426
2427 =head2 rows
2428
2429 =over 4
2430
2431 =item Value: $rows
2432
2433 =back
2434
2435 Specifes the maximum number of rows for direct retrieval or the number of
2436 rows per page if the page attribute or method is used.
2437
2438 =head2 offset
2439
2440 =over 4
2441
2442 =item Value: $offset
2443
2444 =back
2445
2446 Specifies the (zero-based) row number for the  first row to be returned, or the
2447 of the first row of the first page if paging is used.
2448
2449 =head2 group_by
2450
2451 =over 4
2452
2453 =item Value: \@columns
2454
2455 =back
2456
2457 A arrayref of columns to group by. Can include columns of joined tables.
2458
2459   group_by => [qw/ column1 column2 ... /]
2460
2461 =head2 having
2462
2463 =over 4
2464
2465 =item Value: $condition
2466
2467 =back
2468
2469 HAVING is a select statement attribute that is applied between GROUP BY and
2470 ORDER BY. It is applied to the after the grouping calculations have been
2471 done.
2472
2473   having => { 'count(employee)' => { '>=', 100 } }
2474
2475 =head2 distinct
2476
2477 =over 4
2478
2479 =item Value: (0 | 1)
2480
2481 =back
2482
2483 Set to 1 to group by all columns.
2484
2485 =head2 where
2486
2487 =over 4
2488
2489 Adds to the WHERE clause.
2490
2491   # only return rows WHERE deleted IS NULL for all searches
2492   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
2493
2494 Can be overridden by passing C<{ where => undef }> as an attribute
2495 to a resulset.
2496
2497 =back
2498
2499 =head2 cache
2500
2501 Set to 1 to cache search results. This prevents extra SQL queries if you
2502 revisit rows in your ResultSet:
2503
2504   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
2505
2506   while( my $artist = $resultset->next ) {
2507     ... do stuff ...
2508   }
2509
2510   $rs->first; # without cache, this would issue a query
2511
2512 By default, searches are not cached.
2513
2514 For more examples of using these attributes, see
2515 L<DBIx::Class::Manual::Cookbook>.
2516
2517 =head2 from
2518
2519 =over 4
2520
2521 =item Value: \@from_clause
2522
2523 =back
2524
2525 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
2526 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
2527 clauses.
2528
2529 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
2530
2531 C<join> will usually do what you need and it is strongly recommended that you
2532 avoid using C<from> unless you cannot achieve the desired result using C<join>.
2533 And we really do mean "cannot", not just tried and failed. Attempting to use
2534 this because you're having problems with C<join> is like trying to use x86
2535 ASM because you've got a syntax error in your C. Trust us on this.
2536
2537 Now, if you're still really, really sure you need to use this (and if you're
2538 not 100% sure, ask the mailing list first), here's an explanation of how this
2539 works.
2540
2541 The syntax is as follows -
2542
2543   [
2544     { <alias1> => <table1> },
2545     [
2546       { <alias2> => <table2>, -join_type => 'inner|left|right' },
2547       [], # nested JOIN (optional)
2548       { <table1.column1> => <table2.column2>, ... (more conditions) },
2549     ],
2550     # More of the above [ ] may follow for additional joins
2551   ]
2552
2553   <table1> <alias1>
2554   JOIN
2555     <table2> <alias2>
2556     [JOIN ...]
2557   ON <table1.column1> = <table2.column2>
2558   <more joins may follow>
2559
2560 An easy way to follow the examples below is to remember the following:
2561
2562     Anything inside "[]" is a JOIN
2563     Anything inside "{}" is a condition for the enclosing JOIN
2564
2565 The following examples utilize a "person" table in a family tree application.
2566 In order to express parent->child relationships, this table is self-joined:
2567
2568     # Person->belongs_to('father' => 'Person');
2569     # Person->belongs_to('mother' => 'Person');
2570
2571 C<from> can be used to nest joins. Here we return all children with a father,
2572 then search against all mothers of those children:
2573
2574   $rs = $schema->resultset('Person')->search(
2575       undef,
2576       {
2577           alias => 'mother', # alias columns in accordance with "from"
2578           from => [
2579               { mother => 'person' },
2580               [
2581                   [
2582                       { child => 'person' },
2583                       [
2584                           { father => 'person' },
2585                           { 'father.person_id' => 'child.father_id' }
2586                       ]
2587                   ],
2588                   { 'mother.person_id' => 'child.mother_id' }
2589               ],
2590           ]
2591       },
2592   );
2593
2594   # Equivalent SQL:
2595   # SELECT mother.* FROM person mother
2596   # JOIN (
2597   #   person child
2598   #   JOIN person father
2599   #   ON ( father.person_id = child.father_id )
2600   # )
2601   # ON ( mother.person_id = child.mother_id )
2602
2603 The type of any join can be controlled manually. To search against only people
2604 with a father in the person table, we could explicitly use C<INNER JOIN>:
2605
2606     $rs = $schema->resultset('Person')->search(
2607         undef,
2608         {
2609             alias => 'child', # alias columns in accordance with "from"
2610             from => [
2611                 { child => 'person' },
2612                 [
2613                     { father => 'person', -join_type => 'inner' },
2614                     { 'father.id' => 'child.father_id' }
2615                 ],
2616             ]
2617         },
2618     );
2619
2620     # Equivalent SQL:
2621     # SELECT child.* FROM person child
2622     # INNER JOIN person father ON child.father_id = father.id
2623
2624 =cut
2625
2626 1;