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