Refactor update_or_create
[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'   => sub { 1; },
8         fallback => 1;
9 use Data::Page;
10 use Storable;
11 use Scalar::Util qw/weaken/;
12
13 use DBIx::Class::ResultSetColumn;
14 use base qw/DBIx::Class/;
15 __PACKAGE__->load_components(qw/AccessorGroup/);
16 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
17
18 =head1 NAME
19
20 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
21
22 =head1 SYNOPSIS
23
24   my $rs   = $schema->resultset('User')->search(registered => 1);
25   my @rows = $schema->resultset('CD')->search(year => 2005);
26
27 =head1 DESCRIPTION
28
29 The resultset is also known as an iterator. It is responsible for handling
30 queries that may return an arbitrary number of rows, e.g. via L</search>
31 or a C<has_many> relationship.
32
33 In the examples below, the following table classes are used:
34
35   package MyApp::Schema::Artist;
36   use base qw/DBIx::Class/;
37   __PACKAGE__->load_components(qw/Core/);
38   __PACKAGE__->table('artist');
39   __PACKAGE__->add_columns(qw/artistid name/);
40   __PACKAGE__->set_primary_key('artistid');
41   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
42   1;
43
44   package MyApp::Schema::CD;
45   use base qw/DBIx::Class/;
46   __PACKAGE__->load_components(qw/Core/);
47   __PACKAGE__->table('cd');
48   __PACKAGE__->add_columns(qw/cdid artist title year/);
49   __PACKAGE__->set_primary_key('cdid');
50   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
51   1;
52
53 =head1 METHODS
54
55 =head2 new
56
57 =over 4
58
59 =item Arguments: $source, \%$attrs
60
61 =item Return Value: $rs
62
63 =back
64
65 The resultset constructor. Takes a source object (usually a
66 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
67 L</ATTRIBUTES> below).  Does not perform any queries -- these are
68 executed as needed by the other methods.
69
70 Generally you won't need to construct a resultset manually.  You'll
71 automatically get one from e.g. a L</search> called in scalar context:
72
73   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
74
75 IMPORTANT: If called on an object, proxies to new_result instead so
76
77   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
78
79 will return a CD object, not a ResultSet.
80
81 =cut
82
83 sub new {
84   my $class = shift;
85   return $class->new_result(@_) if ref $class;
86   
87   my ($source, $attrs) = @_;
88   weaken $source;
89   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
90   #use Data::Dumper; warn Dumper($attrs);
91   my $alias = ($attrs->{alias} ||= 'me');
92   
93   $attrs->{columns} ||= delete $attrs->{cols} if $attrs->{cols};
94   delete $attrs->{as} if $attrs->{columns};
95   $attrs->{columns} ||= [ $source->columns ] unless $attrs->{select};
96   $attrs->{select} = [
97     map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}}
98   ] if $attrs->{columns};
99   $attrs->{as} ||= [
100     map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}}
101   ];
102   if (my $include = delete $attrs->{include_columns}) {
103     push(@{$attrs->{select}}, @$include);
104     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1; } @$include);
105   }
106   #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
107
108   $attrs->{from} ||= [ { $alias => $source->from } ];
109   $attrs->{seen_join} ||= {};
110   my %seen;
111   if (my $join = delete $attrs->{join}) {
112     foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
113       if (ref $j eq 'HASH') {
114         $seen{$_} = 1 foreach keys %$j;
115       } else {
116         $seen{$j} = 1;
117       }
118     }
119     push(@{$attrs->{from}}, $source->resolve_join(
120       $join, $attrs->{alias}, $attrs->{seen_join})
121     );
122   }
123   
124   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
125   $attrs->{order_by} = [ $attrs->{order_by} ] if
126     $attrs->{order_by} and !ref($attrs->{order_by});
127   $attrs->{order_by} ||= [];
128
129   my $collapse = $attrs->{collapse} || {};
130   if (my $prefetch = delete $attrs->{prefetch}) {
131     my @pre_order;
132     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
133       if ( ref $p eq 'HASH' ) {
134         foreach my $key (keys %$p) {
135           push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
136             unless $seen{$key};
137         }
138       } else {
139         push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
140             unless $seen{$p};
141       }
142       my @prefetch = $source->resolve_prefetch(
143            $p, $attrs->{alias}, {}, \@pre_order, $collapse);
144       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
145       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
146     }
147     push(@{$attrs->{order_by}}, @pre_order);
148   }
149   $attrs->{collapse} = $collapse;
150 #  use Data::Dumper; warn Dumper($collapse) if keys %{$collapse};
151
152   if ($attrs->{page}) {
153     $attrs->{rows} ||= 10;
154     $attrs->{offset} ||= 0;
155     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
156   }
157
158   bless {
159     result_source => $source,
160     result_class => $attrs->{result_class} || $source->result_class,
161     cond => $attrs->{where},
162     from => $attrs->{from},
163     collapse => $collapse,
164     count => undef,
165     page => delete $attrs->{page},
166     pager => undef,
167     attrs => $attrs
168   }, $class;
169 }
170
171 =head2 search
172
173 =over 4
174
175 =item Arguments: $cond, \%attrs?
176
177 =item Return Value: $resultset (scalar context), @row_objs (list context)
178
179 =back
180
181   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
182   my $new_rs = $cd_rs->search({ year => 2005 });
183
184   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
185                  # year = 2005 OR year = 2004
186
187 If you need to pass in additional attributes but no additional condition,
188 call it as C<search(undef, \%attrs)>.
189
190   # "SELECT name, artistid FROM $artist_table"
191   my @all_artists = $schema->resultset('Artist')->search(undef, {
192     columns => [qw/name artistid/],
193   });
194
195 =cut
196
197 sub search {
198   my $self = shift;
199
200   my $rs;
201   if( @_ ) {
202     
203     my $attrs = { %{$self->{attrs}} };
204     my $having = delete $attrs->{having};
205     $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH';
206
207     my $where = (@_
208                   ? ((@_ == 1 || ref $_[0] eq "HASH")
209                       ? shift
210                       : ((@_ % 2)
211                           ? $self->throw_exception(
212                               "Odd number of arguments to search")
213                           : {@_}))
214                   : undef());
215     if (defined $where) {
216       $attrs->{where} = (defined $attrs->{where}
217                 ? { '-and' =>
218                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
219                         $where, $attrs->{where} ] }
220                 : $where);
221     }
222
223     if (defined $having) {
224       $attrs->{having} = (defined $attrs->{having}
225                 ? { '-and' =>
226                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
227                         $having, $attrs->{having} ] }
228                 : $having);
229     }
230
231     $rs = (ref $self)->new($self->result_source, $attrs);
232   }
233   else {
234     $rs = $self;
235     $rs->reset;
236   }
237   return (wantarray ? $rs->all : $rs);
238 }
239
240 =head2 search_literal
241
242 =over 4
243
244 =item Arguments: $sql_fragment, @bind_values
245
246 =item Return Value: $resultset (scalar context), @row_objs (list context)
247
248 =back
249
250   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
251   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
252
253 Pass a literal chunk of SQL to be added to the conditional part of the
254 resultset query.
255
256 =cut
257
258 sub search_literal {
259   my ($self, $cond, @vals) = @_;
260   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
261   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
262   return $self->search(\$cond, $attrs);
263 }
264
265 =head2 find
266
267 =over 4
268
269 =item Arguments: @values | \%cols, \%attrs?
270
271 =item Return Value: $row_object
272
273 =back
274
275 Finds a row based on its primary key or unique constraint. For example:
276
277   my $cd = $schema->resultset('CD')->find(5);
278
279 Also takes an optional C<key> attribute, to search by a specific key or unique
280 constraint. For example:
281
282   my $cd = $schema->resultset('CD')->find(
283     {
284       artist => 'Massive Attack',
285       title  => 'Mezzanine',
286     },
287     { key => 'artist_title' }
288   );
289
290 See also L</find_or_create> and L</update_or_create>.
291
292 =cut
293
294 sub find {
295   my ($self, @vals) = @_;
296   my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
297
298   my %unique_constraints = $self->result_source->unique_constraints;
299   $self->throw_exception(
300     "Can't find unless a primary key or unique constraint is defined"
301   ) unless %unique_constraints;
302
303   my @constraint_names = keys %unique_constraints;
304   if (exists $attrs->{key}) {
305     $self->throw_exception(
306       "Unknown key $attrs->{key} on '" . $self->result_source->name . "'"
307     ) unless exists $unique_constraints{$attrs->{key}};
308
309     @constraint_names = ($attrs->{key});
310   }
311
312   my @unique_hashes;
313   foreach my $name (@constraint_names) {
314     my @unique_cols = @{ $unique_constraints{$name} };
315     my %unique_hash;
316     if (ref $vals[0] eq 'HASH') {
317       %unique_hash =
318         map  { $_ => $vals[0]->{$_} }
319         grep { exists $vals[0]->{$_} }
320         @unique_cols;
321     }
322     elsif (@unique_cols == @vals) {
323       # Assume the argument order corresponds to the constraint definition
324       @unique_hash{@unique_cols} = @vals;
325     }
326     elsif (@vals % 2 == 0) {
327       # Fix for CDBI calling with a hash
328       %unique_hash = @vals;
329     }
330
331     foreach my $key (grep { ! m/\./ } keys %unique_hash) {
332       $unique_hash{"$self->{attrs}{alias}.$key"} = delete $unique_hash{$key};
333     }
334
335     #use Data::Dumper; warn Dumper \@vals, \@unique_cols, \%unique_hash;
336     push @unique_hashes, \%unique_hash if %unique_hash;
337   }
338
339   # Handle cases where the ResultSet already defines the query
340   my $query = @unique_hashes ? \@unique_hashes : undef;
341
342   if (keys %$attrs) {
343     my $rs = $self->search($query,$attrs);
344     return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
345   } else {
346     return keys %{$self->{collapse}}
347       ? $self->search($query)->next
348       : $self->single($query);
349   }
350 }
351
352 =head2 search_related
353
354 =over 4
355
356 =item Arguments: $cond, \%attrs?
357
358 =item Return Value: $new_resultset
359
360 =back
361
362   $new_rs = $cd_rs->search_related('artist', {
363     name => 'Emo-R-Us',
364   });
365
366 Searches the specified relationship, optionally specifying a condition and
367 attributes for matching records. See L</ATTRIBUTES> for more information.
368
369 =cut
370
371 sub search_related {
372   return shift->related_resultset(shift)->search(@_);
373 }
374
375 =head2 cursor
376
377 =over 4
378
379 =item Arguments: none
380
381 =item Return Value: $cursor
382
383 =back
384
385 Returns a storage-driven cursor to the given resultset. See
386 L<DBIx::Class::Cursor> for more information.
387
388 =cut
389
390 sub cursor {
391   my ($self) = @_;
392   my $attrs = { %{$self->{attrs}} };
393   return $self->{cursor}
394     ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
395           $attrs->{where},$attrs);
396 }
397
398 =head2 single
399
400 =over 4
401
402 =item Arguments: $cond?
403
404 =item Return Value: $row_object?
405
406 =back
407
408   my $cd = $schema->resultset('CD')->single({ year => 2001 });
409
410 Inflates the first result without creating a cursor if the resultset has
411 any records in it; if not returns nothing. Used by find() as an optimisation.
412
413 =cut
414
415 sub single {
416   my ($self, $where) = @_;
417   my $attrs = { %{$self->{attrs}} };
418   if ($where) {
419     if (defined $attrs->{where}) {
420       $attrs->{where} = {
421         '-and' =>
422             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
423                $where, delete $attrs->{where} ]
424       };
425     } else {
426       $attrs->{where} = $where;
427     }
428   }
429   my @data = $self->result_source->storage->select_single(
430           $self->{from}, $attrs->{select},
431           $attrs->{where},$attrs);
432   return (@data ? $self->_construct_object(@data) : ());
433 }
434
435 =head2 get_column
436
437 =over 4
438
439 =item Arguments: $cond?
440
441 =item Return Value: $resultsetcolumn
442
443 =back
444
445   my $max_length = $rs->get_column('length')->max;
446
447 Returns a ResultSetColumn instance for $column based on $self
448
449 =cut
450
451 sub get_column {
452   my ($self, $column) = @_;
453
454   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
455   return $new;
456 }
457
458 =head2 search_like
459
460 =over 4
461
462 =item Arguments: $cond, \%attrs?
463
464 =item Return Value: $resultset (scalar context), @row_objs (list context)
465
466 =back
467
468   # WHERE title LIKE '%blue%'
469   $cd_rs = $rs->search_like({ title => '%blue%'});
470
471 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
472 that this is simply a convenience method. You most likely want to use
473 L</search> with specific operators.
474
475 For more information, see L<DBIx::Class::Manual::Cookbook>.
476
477 =cut
478
479 sub search_like {
480   my $class = shift;
481   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
482   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
483   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
484   return $class->search($query, { %$attrs });
485 }
486
487 =head2 slice
488
489 =over 4
490
491 =item Arguments: $first, $last
492
493 =item Return Value: $resultset (scalar context), @row_objs (list context)
494
495 =back
496
497 Returns a resultset or object list representing a subset of elements from the
498 resultset slice is called on. Indexes are from 0, i.e., to get the first
499 three records, call:
500
501   my ($one, $two, $three) = $rs->slice(0, 2);
502
503 =cut
504
505 sub slice {
506   my ($self, $min, $max) = @_;
507   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
508   $attrs->{offset} = $self->{attrs}{offset} || 0;
509   $attrs->{offset} += $min;
510   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
511   return $self->search(undef(), $attrs);
512   #my $slice = (ref $self)->new($self->result_source, $attrs);
513   #return (wantarray ? $slice->all : $slice);
514 }
515
516 =head2 next
517
518 =over 4
519
520 =item Arguments: none
521
522 =item Return Value: $result?
523
524 =back
525
526 Returns the next element in the resultset (C<undef> is there is none).
527
528 Can be used to efficiently iterate over records in the resultset:
529
530   my $rs = $schema->resultset('CD')->search;
531   while (my $cd = $rs->next) {
532     print $cd->title;
533   }
534
535 Note that you need to store the resultset object, and call C<next> on it. 
536 Calling C<< resultset('Table')->next >> repeatedly will always return the
537 first record from the resultset.
538
539 =cut
540
541 sub next {
542   my ($self) = @_;
543   if (@{$self->{all_cache} || []}) {
544     $self->{all_cache_position} ||= 0;
545     return $self->{all_cache}->[$self->{all_cache_position}++];
546   }
547   if ($self->{attrs}{cache}) {
548     $self->{all_cache_position} = 1;
549     return ($self->all)[0];
550   }
551   my @row = (exists $self->{stashed_row} ?
552                @{delete $self->{stashed_row}} :
553                $self->cursor->next
554   );
555 #  warn Dumper(\@row); use Data::Dumper;
556   return unless (@row);
557   return $self->_construct_object(@row);
558 }
559
560 sub _construct_object {
561   my ($self, @row) = @_;
562   my @as = @{ $self->{attrs}{as} };
563   
564   my $info = $self->_collapse_result(\@as, \@row);
565   
566   my $new = $self->result_class->inflate_result($self->result_source, @$info);
567   
568   $new = $self->{attrs}{record_filter}->($new)
569     if exists $self->{attrs}{record_filter};
570   return $new;
571 }
572
573 sub _collapse_result {
574   my ($self, $as, $row, $prefix) = @_;
575
576   my %const;
577
578   my @copy = @$row;
579   foreach my $this_as (@$as) {
580     my $val = shift @copy;
581     if (defined $prefix) {
582       if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
583         my $remain = $1;
584         $remain =~ /^(?:(.*)\.)?([^.]+)$/;
585         $const{$1||''}{$2} = $val;
586       }
587     } else {
588       $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
589       $const{$1||''}{$2} = $val;
590     }
591   }
592
593   my $info = [ {}, {} ];
594   foreach my $key (keys %const) {
595     if (length $key) {
596       my $target = $info;
597       my @parts = split(/\./, $key);
598       foreach my $p (@parts) {
599         $target = $target->[1]->{$p} ||= [];
600       }
601       $target->[0] = $const{$key};
602     } else {
603       $info->[0] = $const{$key};
604     }
605   }
606
607   my @collapse;
608   if (defined $prefix) {
609     @collapse = map {
610         m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
611     } keys %{$self->{collapse}}
612   } else {
613     @collapse = keys %{$self->{collapse}};
614   };
615
616   if (@collapse) {
617     my ($c) = sort { length $a <=> length $b } @collapse;
618     my $target = $info;
619     foreach my $p (split(/\./, $c)) {
620       $target = $target->[1]->{$p} ||= [];
621     }
622     my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
623     my @co_key = @{$self->{collapse}{$c_prefix}};
624     my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
625     my $tree = $self->_collapse_result($as, $row, $c_prefix);
626     my (@final, @raw);
627     while ( !(grep {
628                 !defined($tree->[0]->{$_}) ||
629                 $co_check{$_} ne $tree->[0]->{$_}
630               } @co_key) ) {
631       push(@final, $tree);
632       last unless (@raw = $self->cursor->next);
633       $row = $self->{stashed_row} = \@raw;
634       $tree = $self->_collapse_result($as, $row, $c_prefix);
635       #warn Data::Dumper::Dumper($tree, $row);
636     }
637     @$target = @final;
638   }
639
640   return $info;
641 }
642
643 =head2 result_source
644
645 =over 4
646
647 =item Arguments: $result_source?
648
649 =item Return Value: $result_source
650
651 =back
652
653 An accessor for the primary ResultSource object from which this ResultSet
654 is derived.
655
656 =cut
657
658
659 =head2 count
660
661 =over 4
662
663 =item Arguments: $cond, \%attrs??
664
665 =item Return Value: $count
666
667 =back
668
669 Performs an SQL C<COUNT> with the same query as the resultset was built
670 with to find the number of elements. If passed arguments, does a search
671 on the resultset and counts the results of that.
672
673 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
674 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
675 not support C<DISTINCT> with multiple columns. If you are using such a
676 database, you should only use columns from the main table in your C<group_by>
677 clause.
678
679 =cut
680
681 sub count {
682   my $self = shift;
683   return $self->search(@_)->count if @_ and defined $_[0];
684   return scalar @{ $self->get_cache } if @{ $self->get_cache };
685
686   my $count = $self->_count;
687   return 0 unless $count;
688
689   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
690   $count = $self->{attrs}{rows} if
691     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
692   return $count;
693 }
694
695 sub _count { # Separated out so pager can get the full count
696   my $self = shift;
697   my $select = { count => '*' };
698   my $attrs = { %{ $self->{attrs} } };
699   if (my $group_by = delete $attrs->{group_by}) {
700     delete $attrs->{having};
701     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
702     # todo: try CONCAT for multi-column pk
703     my @pk = $self->result_source->primary_columns;
704     if (@pk == 1) {
705       foreach my $column (@distinct) {
706         if ($column =~ qr/^(?:\Q$attrs->{alias}.\E)?$pk[0]$/) {
707           @distinct = ($column);
708           last;
709         }
710       }
711     }
712
713     $select = { count => { distinct => \@distinct } };
714     #use Data::Dumper; die Dumper $select;
715   }
716
717   $attrs->{select} = $select;
718   $attrs->{as} = [qw/count/];
719
720   # offset, order by and page are not needed to count. record_filter is cdbi
721   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
722         
723   my ($count) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
724   return $count;
725 }
726
727 =head2 count_literal
728
729 =over 4
730
731 =item Arguments: $sql_fragment, @bind_values
732
733 =item Return Value: $count
734
735 =back
736
737 Counts the results in a literal query. Equivalent to calling L</search_literal>
738 with the passed arguments, then L</count>.
739
740 =cut
741
742 sub count_literal { shift->search_literal(@_)->count; }
743
744 =head2 all
745
746 =over 4
747
748 =item Arguments: none
749
750 =item Return Value: @objects
751
752 =back
753
754 Returns all elements in the resultset. Called implicitly if the resultset
755 is returned in list context.
756
757 =cut
758
759 sub all {
760   my ($self) = @_;
761   return @{ $self->get_cache } if @{ $self->get_cache };
762
763   my @obj;
764
765   if (keys %{$self->{collapse}}) {
766       # Using $self->cursor->all is really just an optimisation.
767       # If we're collapsing has_many prefetches it probably makes
768       # very little difference, and this is cleaner than hacking
769       # _construct_object to survive the approach
770     $self->cursor->reset;
771     my @row = $self->cursor->next;
772     while (@row) {
773       push(@obj, $self->_construct_object(@row));
774       @row = (exists $self->{stashed_row}
775                ? @{delete $self->{stashed_row}}
776                : $self->cursor->next);
777     }
778   } else {
779     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
780   }
781
782   $self->set_cache(\@obj) if $self->{attrs}{cache};
783   return @obj;
784 }
785
786 =head2 reset
787
788 =over 4
789
790 =item Arguments: none
791
792 =item Return Value: $self
793
794 =back
795
796 Resets the resultset's cursor, so you can iterate through the elements again.
797
798 =cut
799
800 sub reset {
801   my ($self) = @_;
802   $self->{all_cache_position} = 0;
803   $self->cursor->reset;
804   return $self;
805 }
806
807 =head2 first
808
809 =over 4
810
811 =item Arguments: none
812
813 =item Return Value: $object?
814
815 =back
816
817 Resets the resultset and returns an object for the first result (if the
818 resultset returns anything).
819
820 =cut
821
822 sub first {
823   return $_[0]->reset->next;
824 }
825
826 # _cond_for_update_delete
827 #
828 # update/delete require the condition to be modified to handle
829 # the differing SQL syntax available.  This transforms the $self->{cond}
830 # appropriately, returning the new condition.
831
832 sub _cond_for_update_delete {
833   my ($self) = @_;
834   my $cond = {};
835
836   if (!ref($self->{cond})) {
837     # No-op. No condition, we're updating/deleting everything
838   }
839   elsif (ref $self->{cond} eq 'ARRAY') {
840     $cond = [
841       map {
842         my %hash;
843         foreach my $key (keys %{$_}) {
844           $key =~ /([^.]+)$/;
845           $hash{$1} = $_->{$key};
846         }
847         \%hash;
848       } @{$self->{cond}}
849     ];
850   }
851   elsif (ref $self->{cond} eq 'HASH') {
852     if ((keys %{$self->{cond}})[0] eq '-and') {
853       $cond->{-and} = [];
854
855       my @cond = @{$self->{cond}{-and}};
856       for (my $i = 0; $i < @cond - 1; $i++) {
857         my $entry = $cond[$i];
858
859         my %hash;
860         if (ref $entry eq 'HASH') {
861           foreach my $key (keys %{$entry}) {
862             $key =~ /([^.]+)$/;
863             $hash{$1} = $entry->{$key};
864           }
865         }
866         else {
867           $entry =~ /([^.]+)$/;
868           $hash{$entry} = $cond[++$i];
869         }
870
871         push @{$cond->{-and}}, \%hash;
872       }
873     }
874     else {
875       foreach my $key (keys %{$self->{cond}}) {
876         $key =~ /([^.]+)$/;
877         $cond->{$1} = $self->{cond}{$key};
878       }
879     }
880   }
881   else {
882     $self->throw_exception(
883       "Can't update/delete on resultset with condition unless hash or array"
884     );
885   }
886
887   return $cond;
888 }
889
890
891 =head2 update
892
893 =over 4
894
895 =item Arguments: \%values
896
897 =item Return Value: $storage_rv
898
899 =back
900
901 Sets the specified columns in the resultset to the supplied values in a
902 single query. Return value will be true if the update succeeded or false
903 if no records were updated; exact type of success value is storage-dependent.
904
905 =cut
906
907 sub update {
908   my ($self, $values) = @_;
909   $self->throw_exception("Values for update must be a hash")
910     unless ref $values eq 'HASH';
911
912   my $cond = $self->_cond_for_update_delete;
913
914   return $self->result_source->storage->update(
915     $self->result_source->from, $values, $cond
916   );
917 }
918
919 =head2 update_all
920
921 =over 4
922
923 =item Arguments: \%values
924
925 =item Return Value: 1
926
927 =back
928
929 Fetches all objects and updates them one at a time. Note that C<update_all>
930 will run DBIC cascade triggers, while L</update> will not.
931
932 =cut
933
934 sub update_all {
935   my ($self, $values) = @_;
936   $self->throw_exception("Values for update must be a hash")
937     unless ref $values eq 'HASH';
938   foreach my $obj ($self->all) {
939     $obj->set_columns($values)->update;
940   }
941   return 1;
942 }
943
944 =head2 delete
945
946 =over 4
947
948 =item Arguments: none
949
950 =item Return Value: 1
951
952 =back
953
954 Deletes the contents of the resultset from its result source. Note that this
955 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
956 to run.
957
958 =cut
959
960 sub delete {
961   my ($self) = @_;
962   my $del = {};
963
964   my $cond = $self->_cond_for_update_delete;
965
966   $self->result_source->storage->delete($self->result_source->from, $cond);
967   return 1;
968 }
969
970 =head2 delete_all
971
972 =over 4
973
974 =item Arguments: none
975
976 =item Return Value: 1
977
978 =back
979
980 Fetches all objects and deletes them one at a time. Note that C<delete_all>
981 will run DBIC cascade triggers, while L</delete> will not.
982
983 =cut
984
985 sub delete_all {
986   my ($self) = @_;
987   $_->delete for $self->all;
988   return 1;
989 }
990
991 =head2 pager
992
993 =over 4
994
995 =item Arguments: none
996
997 =item Return Value: $pager
998
999 =back
1000
1001 Return Value a L<Data::Page> object for the current resultset. Only makes
1002 sense for queries with a C<page> attribute.
1003
1004 =cut
1005
1006 sub pager {
1007   my ($self) = @_;
1008   my $attrs = $self->{attrs};
1009   $self->throw_exception("Can't create pager for non-paged rs")
1010     unless $self->{page};
1011   $attrs->{rows} ||= 10;
1012   return $self->{pager} ||= Data::Page->new(
1013     $self->_count, $attrs->{rows}, $self->{page});
1014 }
1015
1016 =head2 page
1017
1018 =over 4
1019
1020 =item Arguments: $page_number
1021
1022 =item Return Value: $rs
1023
1024 =back
1025
1026 Returns a resultset for the $page_number page of the resultset on which page
1027 is called, where each page contains a number of rows equal to the 'rows'
1028 attribute set on the resultset (10 by default).
1029
1030 =cut
1031
1032 sub page {
1033   my ($self, $page) = @_;
1034   my $attrs = { %{$self->{attrs}} };
1035   $attrs->{page} = $page;
1036   return (ref $self)->new($self->result_source, $attrs);
1037 }
1038
1039 =head2 new_result
1040
1041 =over 4
1042
1043 =item Arguments: \%vals
1044
1045 =item Return Value: $object
1046
1047 =back
1048
1049 Creates an object in the resultset's result class and returns it.
1050
1051 =cut
1052
1053 sub new_result {
1054   my ($self, $values) = @_;
1055   $self->throw_exception( "new_result needs a hash" )
1056     unless (ref $values eq 'HASH');
1057   $self->throw_exception(
1058     "Can't abstract implicit construct, condition not a hash"
1059   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1060   my %new = %$values;
1061   my $alias = $self->{attrs}{alias};
1062   foreach my $key (keys %{$self->{cond}||{}}) {
1063     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:\Q${alias}.\E)?([^.]+)$/);
1064   }
1065   my $obj = $self->result_class->new(\%new);
1066   $obj->result_source($self->result_source) if $obj->can('result_source');
1067   return $obj;
1068 }
1069
1070 =head2 create
1071
1072 =over 4
1073
1074 =item Arguments: \%vals
1075
1076 =item Return Value: $object
1077
1078 =back
1079
1080 Inserts a record into the resultset and returns the object representing it.
1081
1082 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1083
1084 =cut
1085
1086 sub create {
1087   my ($self, $attrs) = @_;
1088   $self->throw_exception( "create needs a hashref" )
1089     unless ref $attrs eq 'HASH';
1090   return $self->new_result($attrs)->insert;
1091 }
1092
1093 =head2 find_or_create
1094
1095 =over 4
1096
1097 =item Arguments: \%vals, \%attrs?
1098
1099 =item Return Value: $object
1100
1101 =back
1102
1103   $class->find_or_create({ key => $val, ... });
1104
1105 Searches for a record matching the search condition; if it doesn't find one,
1106 creates one and returns that instead.
1107
1108   my $cd = $schema->resultset('CD')->find_or_create({
1109     cdid   => 5,
1110     artist => 'Massive Attack',
1111     title  => 'Mezzanine',
1112     year   => 2005,
1113   });
1114
1115 Also takes an optional C<key> attribute, to search by a specific key or unique
1116 constraint. For example:
1117
1118   my $cd = $schema->resultset('CD')->find_or_create(
1119     {
1120       artist => 'Massive Attack',
1121       title  => 'Mezzanine',
1122     },
1123     { key => 'artist_title' }
1124   );
1125
1126 See also L</find> and L</update_or_create>.
1127
1128 =cut
1129
1130 sub find_or_create {
1131   my $self     = shift;
1132   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1133   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1134   my $exists   = $self->find($hash, $attrs);
1135   return defined $exists ? $exists : $self->create($hash);
1136 }
1137
1138 =head2 update_or_create
1139
1140 =over 4
1141
1142 =item Arguments: \%col_values, { key => $unique_constraint }?
1143
1144 =item Return Value: $object
1145
1146 =back
1147
1148   $class->update_or_create({ col => $val, ... });
1149
1150 First, searches for an existing row matching one of the unique constraints
1151 (including the primary key) on the source of this resultset. If a row is
1152 found, updates it with the other given column values. Otherwise, creates a new
1153 row.
1154
1155 Takes an optional C<key> attribute to search on a specific unique constraint.
1156 For example:
1157
1158   # In your application
1159   my $cd = $schema->resultset('CD')->update_or_create(
1160     {
1161       artist => 'Massive Attack',
1162       title  => 'Mezzanine',
1163       year   => 1998,
1164     },
1165     { key => 'artist_title' }
1166   );
1167
1168 If no C<key> is specified, it searches on all unique constraints defined on the
1169 source, including the primary key.
1170
1171 If the C<key> is specified as C<primary>, it searches only on the primary key.
1172
1173 See also L</find> and L</find_or_create>.
1174
1175 =cut
1176
1177 sub update_or_create {
1178   my $self = shift;
1179   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1180   my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1181
1182   my $row = $self->find($hash, $attrs);
1183   if (defined $row) {
1184     $row->set_columns($hash);
1185     $row->update;
1186     return $row;
1187   }
1188
1189   return $self->create($hash);
1190 }
1191
1192 =head2 get_cache
1193
1194 =over 4
1195
1196 =item Arguments: none
1197
1198 =item Return Value: \@cache_objects?
1199
1200 =back
1201
1202 Gets the contents of the cache for the resultset, if the cache is set.
1203
1204 =cut
1205
1206 sub get_cache {
1207   shift->{all_cache} || [];
1208 }
1209
1210 =head2 set_cache
1211
1212 =over 4
1213
1214 =item Arguments: \@cache_objects
1215
1216 =item Return Value: \@cache_objects
1217
1218 =back
1219
1220 Sets the contents of the cache for the resultset. Expects an arrayref
1221 of objects of the same class as those produced by the resultset. Note that
1222 if the cache is set the resultset will return the cached objects rather
1223 than re-querying the database even if the cache attr is not set.
1224
1225 =cut
1226
1227 sub set_cache {
1228   my ( $self, $data ) = @_;
1229   $self->throw_exception("set_cache requires an arrayref")
1230     if ref $data ne 'ARRAY';
1231   my $result_class = $self->result_class;
1232   foreach( @$data ) {
1233     $self->throw_exception(
1234       "cannot cache object of type '$_', expected '$result_class'"
1235     ) if ref $_ ne $result_class;
1236   }
1237   $self->{all_cache} = $data;
1238 }
1239
1240 =head2 clear_cache
1241
1242 =over 4
1243
1244 =item Arguments: none
1245
1246 =item Return Value: []
1247
1248 =back
1249
1250 Clears the cache for the resultset.
1251
1252 =cut
1253
1254 sub clear_cache {
1255   shift->set_cache([]);
1256 }
1257
1258 =head2 related_resultset
1259
1260 =over 4
1261
1262 =item Arguments: $relationship_name
1263
1264 =item Return Value: $resultset
1265
1266 =back
1267
1268 Returns a related resultset for the supplied relationship name.
1269
1270   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1271
1272 =cut
1273
1274 sub related_resultset {
1275   my ( $self, $rel ) = @_;
1276   $self->{related_resultsets} ||= {};
1277   return $self->{related_resultsets}{$rel} ||= do {
1278       #warn "fetching related resultset for rel '$rel'";
1279       my $rel_obj = $self->result_source->relationship_info($rel);
1280       $self->throw_exception(
1281         "search_related: result source '" . $self->result_source->name .
1282         "' has no such relationship ${rel}")
1283         unless $rel_obj; #die Dumper $self->{attrs};
1284
1285       my $rs = $self->search(undef, { join => $rel });
1286       my $alias = defined $rs->{attrs}{seen_join}{$rel}
1287                     && $rs->{attrs}{seen_join}{$rel} > 1
1288                   ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
1289                   : $rel;
1290
1291       $self->result_source->schema->resultset($rel_obj->{class}
1292            )->search( undef,
1293              { %{$rs->{attrs}},
1294                alias => $alias,
1295                select => undef,
1296                as => undef }
1297            );
1298   };
1299 }
1300
1301 =head2 throw_exception
1302
1303 See L<DBIx::Class::Schema/throw_exception> for details.
1304
1305 =cut
1306
1307 sub throw_exception {
1308   my $self=shift;
1309   $self->result_source->schema->throw_exception(@_);
1310 }
1311
1312 # XXX: FIXME: Attributes docs need clearing up
1313
1314 =head1 ATTRIBUTES
1315
1316 The resultset takes various attributes that modify its behavior. Here's an
1317 overview of them:
1318
1319 =head2 order_by
1320
1321 =over 4
1322
1323 =item Value: ($order_by | \@order_by)
1324
1325 =back
1326
1327 Which column(s) to order the results by. This is currently passed
1328 through directly to SQL, so you can give e.g. C<year DESC> for a
1329 descending order on the column `year'.
1330
1331 =head2 columns
1332
1333 =over 4
1334
1335 =item Value: \@columns
1336
1337 =back
1338
1339 Shortcut to request a particular set of columns to be retrieved.  Adds
1340 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1341 from that, then auto-populates C<as> from C<select> as normal. (You may also
1342 use the C<cols> attribute, as in earlier versions of DBIC.)
1343
1344 =head2 include_columns
1345
1346 =over 4
1347
1348 =item Value: \@columns
1349
1350 =back
1351
1352 Shortcut to include additional columns in the returned results - for example
1353
1354   $schema->resultset('CD')->search(undef, {
1355     include_columns => ['artist.name'],
1356     join => ['artist']
1357   });
1358
1359 would return all CDs and include a 'name' column to the information
1360 passed to object inflation
1361
1362 =head2 select
1363
1364 =over 4
1365
1366 =item Value: \@select_columns
1367
1368 =back
1369
1370 Indicates which columns should be selected from the storage. You can use
1371 column names, or in the case of RDBMS back ends, function or stored procedure
1372 names:
1373
1374   $rs = $schema->resultset('Employee')->search(undef, {
1375     select => [
1376       'name',
1377       { count => 'employeeid' },
1378       { sum => 'salary' }
1379     ]
1380   });
1381
1382 When you use function/stored procedure names and do not supply an C<as>
1383 attribute, the column names returned are storage-dependent. E.g. MySQL would
1384 return a column named C<count(employeeid)> in the above example.
1385
1386 =head2 as
1387
1388 =over 4
1389
1390 =item Value: \@inflation_names
1391
1392 =back
1393
1394 Indicates column names for object inflation. This is used in conjunction with
1395 C<select>, usually when C<select> contains one or more function or stored
1396 procedure names:
1397
1398   $rs = $schema->resultset('Employee')->search(undef, {
1399     select => [
1400       'name',
1401       { count => 'employeeid' }
1402     ],
1403     as => ['name', 'employee_count'],
1404   });
1405
1406   my $employee = $rs->first(); # get the first Employee
1407
1408 If the object against which the search is performed already has an accessor
1409 matching a column name specified in C<as>, the value can be retrieved using
1410 the accessor as normal:
1411
1412   my $name = $employee->name();
1413
1414 If on the other hand an accessor does not exist in the object, you need to
1415 use C<get_column> instead:
1416
1417   my $employee_count = $employee->get_column('employee_count');
1418
1419 You can create your own accessors if required - see
1420 L<DBIx::Class::Manual::Cookbook> for details.
1421
1422 =head2 join
1423
1424 =over 4
1425
1426 =item Value: ($rel_name | \@rel_names | \%rel_names)
1427
1428 =back
1429
1430 Contains a list of relationships that should be joined for this query.  For
1431 example:
1432
1433   # Get CDs by Nine Inch Nails
1434   my $rs = $schema->resultset('CD')->search(
1435     { 'artist.name' => 'Nine Inch Nails' },
1436     { join => 'artist' }
1437   );
1438
1439 Can also contain a hash reference to refer to the other relation's relations.
1440 For example:
1441
1442   package MyApp::Schema::Track;
1443   use base qw/DBIx::Class/;
1444   __PACKAGE__->table('track');
1445   __PACKAGE__->add_columns(qw/trackid cd position title/);
1446   __PACKAGE__->set_primary_key('trackid');
1447   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1448   1;
1449
1450   # In your application
1451   my $rs = $schema->resultset('Artist')->search(
1452     { 'track.title' => 'Teardrop' },
1453     {
1454       join     => { cd => 'track' },
1455       order_by => 'artist.name',
1456     }
1457   );
1458
1459 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1460 similarly for a third time). For e.g.
1461
1462   my $rs = $schema->resultset('Artist')->search({
1463     'cds.title'   => 'Down to Earth',
1464     'cds_2.title' => 'Popular',
1465   }, {
1466     join => [ qw/cds cds/ ],
1467   });
1468
1469 will return a set of all artists that have both a cd with title 'Down
1470 to Earth' and a cd with title 'Popular'.
1471
1472 If you want to fetch related objects from other tables as well, see C<prefetch>
1473 below.
1474
1475 =head2 prefetch
1476
1477 =over 4
1478
1479 =item Value: ($rel_name | \@rel_names | \%rel_names)
1480
1481 =back
1482
1483 Contains one or more relationships that should be fetched along with the main
1484 query (when they are accessed afterwards they will have already been
1485 "prefetched").  This is useful for when you know you will need the related
1486 objects, because it saves at least one query:
1487
1488   my $rs = $schema->resultset('Tag')->search(
1489     undef,
1490     {
1491       prefetch => {
1492         cd => 'artist'
1493       }
1494     }
1495   );
1496
1497 The initial search results in SQL like the following:
1498
1499   SELECT tag.*, cd.*, artist.* FROM tag
1500   JOIN cd ON tag.cd = cd.cdid
1501   JOIN artist ON cd.artist = artist.artistid
1502
1503 L<DBIx::Class> has no need to go back to the database when we access the
1504 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1505 case.
1506
1507 Simple prefetches will be joined automatically, so there is no need
1508 for a C<join> attribute in the above search. If you're prefetching to
1509 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1510 specify the join as well.
1511
1512 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1513 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1514 with an accessor type of 'single' or 'filter').
1515
1516 =head2 from
1517
1518 =over 4
1519
1520 =item Value: \@from_clause
1521
1522 =back
1523
1524 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1525 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1526 clauses.
1527
1528 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1529 C<join> will usually do what you need and it is strongly recommended that you
1530 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1531
1532 In simple terms, C<from> works as follows:
1533
1534     [
1535         { <alias> => <table>, -join_type => 'inner|left|right' }
1536         [] # nested JOIN (optional)
1537         { <table.column> => <foreign_table.foreign_key> }
1538     ]
1539
1540     JOIN
1541         <alias> <table>
1542         [JOIN ...]
1543     ON <table.column> = <foreign_table.foreign_key>
1544
1545 An easy way to follow the examples below is to remember the following:
1546
1547     Anything inside "[]" is a JOIN
1548     Anything inside "{}" is a condition for the enclosing JOIN
1549
1550 The following examples utilize a "person" table in a family tree application.
1551 In order to express parent->child relationships, this table is self-joined:
1552
1553     # Person->belongs_to('father' => 'Person');
1554     # Person->belongs_to('mother' => 'Person');
1555
1556 C<from> can be used to nest joins. Here we return all children with a father,
1557 then search against all mothers of those children:
1558
1559   $rs = $schema->resultset('Person')->search(
1560       undef,
1561       {
1562           alias => 'mother', # alias columns in accordance with "from"
1563           from => [
1564               { mother => 'person' },
1565               [
1566                   [
1567                       { child => 'person' },
1568                       [
1569                           { father => 'person' },
1570                           { 'father.person_id' => 'child.father_id' }
1571                       ]
1572                   ],
1573                   { 'mother.person_id' => 'child.mother_id' }
1574               ],
1575           ]
1576       },
1577   );
1578
1579   # Equivalent SQL:
1580   # SELECT mother.* FROM person mother
1581   # JOIN (
1582   #   person child
1583   #   JOIN person father
1584   #   ON ( father.person_id = child.father_id )
1585   # )
1586   # ON ( mother.person_id = child.mother_id )
1587
1588 The type of any join can be controlled manually. To search against only people
1589 with a father in the person table, we could explicitly use C<INNER JOIN>:
1590
1591     $rs = $schema->resultset('Person')->search(
1592         undef,
1593         {
1594             alias => 'child', # alias columns in accordance with "from"
1595             from => [
1596                 { child => 'person' },
1597                 [
1598                     { father => 'person', -join_type => 'inner' },
1599                     { 'father.id' => 'child.father_id' }
1600                 ],
1601             ]
1602         },
1603     );
1604
1605     # Equivalent SQL:
1606     # SELECT child.* FROM person child
1607     # INNER JOIN person father ON child.father_id = father.id
1608
1609 =head2 page
1610
1611 =over 4
1612
1613 =item Value: $page
1614
1615 =back
1616
1617 Makes the resultset paged and specifies the page to retrieve. Effectively
1618 identical to creating a non-pages resultset and then calling ->page($page)
1619 on it.
1620
1621 =head2 rows
1622
1623 =over 4
1624
1625 =item Value: $rows
1626
1627 =back
1628
1629 Specifes the maximum number of rows for direct retrieval or the number of
1630 rows per page if the page attribute or method is used.
1631
1632 =head2 group_by
1633
1634 =over 4
1635
1636 =item Value: \@columns
1637
1638 =back
1639
1640 A arrayref of columns to group by. Can include columns of joined tables.
1641
1642   group_by => [qw/ column1 column2 ... /]
1643
1644 =head2 having
1645
1646 =over 4
1647
1648 =item Value: $condition
1649
1650 =back
1651
1652 HAVING is a select statement attribute that is applied between GROUP BY and
1653 ORDER BY. It is applied to the after the grouping calculations have been
1654 done. 
1655
1656   having => { 'count(employee)' => { '>=', 100 } }
1657
1658 =head2 distinct
1659
1660 =over 4
1661
1662 =item Value: (0 | 1)
1663
1664 =back
1665
1666 Set to 1 to group by all columns.
1667
1668 =head2 cache
1669
1670 Set to 1 to cache search results. This prevents extra SQL queries if you
1671 revisit rows in your ResultSet:
1672
1673   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1674   
1675   while( my $artist = $resultset->next ) {
1676     ... do stuff ...
1677   }
1678
1679   $rs->first; # without cache, this would issue a query
1680
1681 By default, searches are not cached.
1682
1683 For more examples of using these attributes, see
1684 L<DBIx::Class::Manual::Cookbook>.
1685
1686 =cut
1687
1688 1;