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