Added remove_column(s) from ResultSource/ResultSourceProxy
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
CommitLineData
9c992ba1 1package DBIx::Class::ResultSource;
2
3use strict;
4use warnings;
5
6use DBIx::Class::ResultSet;
701da8c4 7use Carp::Clan qw/^DBIx::Class/;
6da5894c 8use Storable;
9
9c992ba1 10use base qw/DBIx::Class/;
11__PACKAGE__->load_components(qw/AccessorGroup/);
12
aa1088bf 13__PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
14 _columns _primaries _unique_constraints name resultset_attributes
15 schema from _relationships/);
16
17__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
18 result_class/);
9c992ba1 19
75d07914 20=head1 NAME
9c992ba1 21
22DBIx::Class::ResultSource - Result source object
23
24=head1 SYNOPSIS
25
26=head1 DESCRIPTION
27
28A ResultSource is a component of a schema from which results can be directly
29retrieved, most usually a table (see L<DBIx::Class::ResultSource::Table>)
30
31=head1 METHODS
32
33=cut
34
35sub new {
36 my ($class, $attrs) = @_;
37 $class = ref $class if ref $class;
1225fc4d 38 my $new = bless({ %{$attrs || {}}, _resultset => undef }, $class);
9c992ba1 39 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
5ac6a044 40 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
6da5894c 41 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
42 $new->{_columns} = { %{$new->{_columns}||{}} };
43 $new->{_relationships} = { %{$new->{_relationships}||{}} };
9c992ba1 44 $new->{name} ||= "!!NAME NOT SET!!";
5afa2a15 45 $new->{_columns_info_loaded} ||= 0;
9c992ba1 46 return $new;
47}
48
988bf309 49=pod
50
5ac6a044 51=head2 add_columns
52
53 $table->add_columns(qw/col1 col2 col3/);
54
55 $table->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
56
2053ab2a 57Adds columns to the result source. If supplied key => hashref pairs, uses
58the hashref as the column_info for that column. Repeated calls of this
59method will add more columns, not replace them.
5ac6a044 60
2053ab2a 61The contents of the column_info are not set in stone. The following
62keys are currently recognised/used by DBIx::Class:
988bf309 63
64=over 4
65
75d07914 66=item accessor
988bf309 67
68Use this to set the name of the accessor for this column. If unset,
69the name of the column will be used.
70
71=item data_type
72
2053ab2a 73This contains the column type. It is automatically filled by the
988bf309 74L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
2053ab2a 75L<DBIx::Class::Schema::Loader> module. If you do not enter a
988bf309 76data_type, DBIx::Class will attempt to retrieve it from the
2053ab2a 77database for you, using L<DBI>'s column_info method. The values of this
988bf309 78key are typically upper-cased.
79
2053ab2a 80Currently there is no standard set of values for the data_type. Use
81whatever your database supports.
988bf309 82
83=item size
84
85The length of your column, if it is a column type that can have a size
75d07914 86restriction. This is currently not used by DBIx::Class.
988bf309 87
88=item is_nullable
89
2053ab2a 90Set this to a true value for a columns that is allowed to contain
91NULL values. This is currently not used by DBIx::Class.
988bf309 92
93=item is_auto_increment
94
2053ab2a 95Set this to a true value for a column whose value is somehow
96automatically set. This is used to determine which columns to empty
e666492c 97when cloning objects using C<copy>.
988bf309 98
99=item is_foreign_key
100
2053ab2a 101Set this to a true value for a column that contains a key from a
988bf309 102foreign table. This is currently not used by DBIx::Class.
103
104=item default_value
105
2053ab2a 106Set this to the default value which will be inserted into a column
107by the database. Can contain either a value or a function. This is
75d07914 108currently not used by DBIx::Class.
988bf309 109
110=item sequence
111
2053ab2a 112Set this on a primary key column to the name of the sequence used to
113generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
114will attempt to retrieve the name of the sequence from the database
115automatically.
988bf309 116
117=back
118
5ac6a044 119=head2 add_column
120
121 $table->add_column('col' => \%info?);
122
2053ab2a 123Convenience alias to add_columns.
5ac6a044 124
125=cut
126
9c992ba1 127sub add_columns {
128 my ($self, @cols) = @_;
8e04bf91 129 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
002a359a 130
20518cb4 131 my @added;
132 my $columns = $self->_columns;
9c992ba1 133 while (my $col = shift @cols) {
8e04bf91 134 # If next entry is { ... } use that for the column info, if not
135 # use an empty hashref
30126ac7 136 my $column_info = ref $cols[0] ? shift(@cols) : {};
20518cb4 137 push(@added, $col) unless exists $columns->{$col};
20518cb4 138 $columns->{$col} = $column_info;
9c992ba1 139 }
20518cb4 140 push @{ $self->_ordered_columns }, @added;
30126ac7 141 return $self;
9c992ba1 142}
143
144*add_column = \&add_columns;
145
3842b955 146=head2 has_column
147
988bf309 148 if ($obj->has_column($col)) { ... }
149
2053ab2a 150Returns true if the source has a column of this name, false otherwise.
988bf309 151
152=cut
9c992ba1 153
154sub has_column {
155 my ($self, $column) = @_;
156 return exists $self->_columns->{$column};
157}
158
87c4e602 159=head2 column_info
9c992ba1 160
988bf309 161 my $info = $obj->column_info($col);
9c992ba1 162
988bf309 163Returns the column metadata hashref for a column. See the description
164of add_column for information on the contents of the hashref.
9c992ba1 165
988bf309 166=cut
9c992ba1 167
168sub column_info {
169 my ($self, $column) = @_;
75d07914 170 $self->throw_exception("No such column $column")
701da8c4 171 unless exists $self->_columns->{$column};
5afa2a15 172 #warn $self->{_columns_info_loaded}, "\n";
75d07914 173 if ( ! $self->_columns->{$column}{data_type}
174 and ! $self->{_columns_info_loaded}
8e04bf91 175 and $self->schema and $self->storage )
176 {
177 $self->{_columns_info_loaded}++;
178 my $info;
75d07914 179 # eval for the case of storage without table
8e04bf91 180 eval { $info = $self->storage->columns_info_for($self->from) };
181 unless ($@) {
182 foreach my $col ( keys %{$self->_columns} ) {
183 foreach my $i ( keys %{$info->{$col}} ) {
184 $self->_columns->{$col}{$i} = $info->{$col}{$i};
185 }
a953d8d9 186 }
8e04bf91 187 }
a953d8d9 188 }
9c992ba1 189 return $self->_columns->{$column};
190}
191
192=head2 columns
193
20518cb4 194 my @column_names = $obj->columns;
195
2053ab2a 196Returns all column names in the order they were declared to add_columns.
87f0da6a 197
198=cut
9c992ba1 199
200sub columns {
8e04bf91 201 my $self = shift;
aa1088bf 202 $self->throw_exception(
203 "columns() is a read-only accessor, did you mean add_columns()?"
204 ) if (@_ > 1);
701da8c4 205 return @{$self->{_ordered_columns}||[]};
571dced3 206}
207
002a359a 208=head2 remove_columns
209
210 $table->remove_columns(qw/col1 col2 col3/);
211
212Removes columns from the result source.
213
214=head2 remove_column
215
216 $table->remove_column('col');
217
218Convenience alias to remove_columns.
219
220=cut
221
222sub remove_columns {
223 my ($self, @cols) = @_;
224
225 return unless $self->_ordered_columns;
226
227 my $columns = $self->_columns;
228 my @remaining;
229
230 foreach my $col (@{$self->_ordered_columns}) {
231 push @remaining, $col unless grep(/$col/, @cols);
232 }
233
234 foreach (@cols) {
235 undef $columns->{$_};
236 };
237
238 $self->_ordered_columns(\@remaining);
239}
240
241*remove_column = \&remove_columns;
242
87c4e602 243=head2 set_primary_key
244
27f01d1f 245=over 4
246
ebc77b53 247=item Arguments: @cols
27f01d1f 248
249=back
87f0da6a 250
9c992ba1 251Defines one or more columns as primary key for this source. Should be
252called after C<add_columns>.
87f0da6a 253
254Additionally, defines a unique constraint named C<primary>.
255
988bf309 256The primary key columns are used by L<DBIx::Class::PK::Auto> to
75d07914 257retrieve automatically created values from the database.
988bf309 258
87f0da6a 259=cut
9c992ba1 260
261sub set_primary_key {
262 my ($self, @cols) = @_;
263 # check if primary key columns are valid columns
8e04bf91 264 foreach my $col (@cols) {
265 $self->throw_exception("No such column $col on table " . $self->name)
266 unless $self->has_column($col);
9c992ba1 267 }
268 $self->_primaries(\@cols);
87f0da6a 269
270 $self->add_unique_constraint(primary => \@cols);
9c992ba1 271}
272
87f0da6a 273=head2 primary_columns
274
9c992ba1 275Read-only accessor which returns the list of primary keys.
30126ac7 276
87f0da6a 277=cut
9c992ba1 278
279sub primary_columns {
280 return @{shift->_primaries||[]};
281}
282
87f0da6a 283=head2 add_unique_constraint
284
285Declare a unique constraint on this source. Call once for each unique
988bf309 286constraint. Unique constraints are used when you call C<find> on a
2053ab2a 287L<DBIx::Class::ResultSet>. Only columns in the constraint are searched,
288for example:
27f01d1f 289
290 # For UNIQUE (column1, column2)
291 __PACKAGE__->add_unique_constraint(
292 constraint_name => [ qw/column1 column2/ ],
293 );
87f0da6a 294
295=cut
296
297sub add_unique_constraint {
298 my ($self, $name, $cols) = @_;
299
8e04bf91 300 foreach my $col (@$cols) {
301 $self->throw_exception("No such column $col on table " . $self->name)
302 unless $self->has_column($col);
87f0da6a 303 }
304
305 my %unique_constraints = $self->unique_constraints;
306 $unique_constraints{$name} = $cols;
307 $self->_unique_constraints(\%unique_constraints);
308}
309
310=head2 unique_constraints
311
312Read-only accessor which returns the list of unique constraints on this source.
313
314=cut
315
316sub unique_constraints {
317 return %{shift->_unique_constraints||{}};
318}
319
9c992ba1 320=head2 from
321
322Returns an expression of the source to be supplied to storage to specify
2053ab2a 323retrieval from this source. In the case of a database, the required FROM
324clause contents.
9c992ba1 325
326=cut
327
328=head2 storage
329
75d07914 330Returns the storage handle for the current schema.
988bf309 331
332See also: L<DBIx::Class::Storage>
9c992ba1 333
334=cut
335
336sub storage { shift->schema->storage; }
337
8452e496 338=head2 add_relationship
339
340 $source->add_relationship('relname', 'related_source', $cond, $attrs);
341
24d67825 342The relationship name can be arbitrary, but must be unique for each
343relationship attached to this result source. 'related_source' should
344be the name with which the related result source was registered with
345the current schema. For example:
8452e496 346
24d67825 347 $schema->source('Book')->add_relationship('reviews', 'Review', {
348 'foreign.book_id' => 'self.id',
349 });
350
2053ab2a 351The condition C<$cond> needs to be an L<SQL::Abstract>-style
24d67825 352representation of the join between the tables. For example, if you're
353creating a rel from Author to Book,
988bf309 354
355 { 'foreign.author_id' => 'self.id' }
356
357will result in the JOIN clause
358
359 author me JOIN book foreign ON foreign.author_id = me.id
360
8452e496 361You can specify as many foreign => self mappings as necessary.
362
988bf309 363Valid attributes are as follows:
364
365=over 4
366
367=item join_type
368
369Explicitly specifies the type of join to use in the relationship. Any
370SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
371the SQL command immediately before C<JOIN>.
372
373=item proxy
374
24d67825 375An arrayref containing a list of accessors in the foreign class to proxy in
376the main class. If, for example, you do the following:
002a359a 377
24d67825 378 CD->might_have(liner_notes => 'LinerNotes', undef, {
379 proxy => [ qw/notes/ ],
380 });
002a359a 381
24d67825 382Then, assuming LinerNotes has an accessor named notes, you can do:
988bf309 383
24d67825 384 my $cd = CD->find(1);
2053ab2a 385 # set notes -- LinerNotes object is created if it doesn't exist
386 $cd->notes('Notes go here');
988bf309 387
388=item accessor
389
390Specifies the type of accessor that should be created for the
75d07914 391relationship. Valid values are C<single> (for when there is only a single
392related object), C<multi> (when there can be many), and C<filter> (for
393when there is a single related object, but you also want the relationship
394accessor to double as a column accessor). For C<multi> accessors, an
395add_to_* method is also created, which calls C<create_related> for the
988bf309 396relationship.
397
8452e496 398=back
399
400=cut
401
402sub add_relationship {
403 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
27f01d1f 404 $self->throw_exception("Can't create relationship without join condition")
405 unless $cond;
8452e496 406 $attrs ||= {};
87772e46 407
8452e496 408 my %rels = %{ $self->_relationships };
409 $rels{$rel} = { class => $f_source_name,
87772e46 410 source => $f_source_name,
8452e496 411 cond => $cond,
412 attrs => $attrs };
413 $self->_relationships(\%rels);
414
30126ac7 415 return $self;
87772e46 416
953a18ef 417 # XXX disabled. doesn't work properly currently. skip in tests.
418
8452e496 419 my $f_source = $self->schema->source($f_source_name);
420 unless ($f_source) {
421 eval "require $f_source_name;";
422 if ($@) {
423 die $@ unless $@ =~ /Can't locate/;
424 }
425 $f_source = $f_source_name->result_source;
87772e46 426 #my $s_class = ref($self->schema);
427 #$f_source_name =~ m/^${s_class}::(.*)$/;
428 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
429 #$f_source = $self->schema->source($f_source_name);
8452e496 430 }
431 return unless $f_source; # Can't test rel without f_source
432
433 eval { $self->resolve_join($rel, 'me') };
434
435 if ($@) { # If the resolve failed, back out and re-throw the error
75d07914 436 delete $rels{$rel}; #
8452e496 437 $self->_relationships(\%rels);
701da8c4 438 $self->throw_exception("Error creating relationship $rel: $@");
8452e496 439 }
440 1;
441}
442
87c4e602 443=head2 relationships
8452e496 444
2053ab2a 445Returns all relationship names for this source.
8452e496 446
447=cut
448
449sub relationships {
450 return keys %{shift->_relationships};
451}
452
87c4e602 453=head2 relationship_info
454
27f01d1f 455=over 4
456
ebc77b53 457=item Arguments: $relname
27f01d1f 458
459=back
8452e496 460
2053ab2a 461Returns a hash of relationship information for the specified relationship
462name.
8452e496 463
464=cut
465
466sub relationship_info {
467 my ($self, $rel) = @_;
468 return $self->_relationships->{$rel};
75d07914 469}
8452e496 470
87c4e602 471=head2 has_relationship
472
27f01d1f 473=over 4
474
ebc77b53 475=item Arguments: $rel
27f01d1f 476
477=back
953a18ef 478
2053ab2a 479Returns true if the source has a relationship of this name, false otherwise.
988bf309 480
481=cut
953a18ef 482
483sub has_relationship {
484 my ($self, $rel) = @_;
485 return exists $self->_relationships->{$rel};
486}
487
87c4e602 488=head2 resolve_join
489
27f01d1f 490=over 4
491
ebc77b53 492=item Arguments: $relation
27f01d1f 493
494=back
8452e496 495
2053ab2a 496Returns the join structure required for the related result source.
8452e496 497
498=cut
499
500sub resolve_join {
489709af 501 my ($self, $join, $alias, $seen) = @_;
502 $seen ||= {};
87772e46 503 if (ref $join eq 'ARRAY') {
489709af 504 return map { $self->resolve_join($_, $alias, $seen) } @$join;
87772e46 505 } elsif (ref $join eq 'HASH') {
489709af 506 return
887ce227 507 map {
508 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
509 ($self->resolve_join($_, $alias, $seen),
510 $self->related_source($_)->resolve_join($join->{$_}, $as, $seen));
511 } keys %$join;
87772e46 512 } elsif (ref $join) {
701da8c4 513 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
87772e46 514 } else {
489709af 515 my $count = ++$seen->{$join};
516 #use Data::Dumper; warn Dumper($seen);
517 my $as = ($count > 1 ? "${join}_${count}" : $join);
3842b955 518 my $rel_info = $self->relationship_info($join);
701da8c4 519 $self->throw_exception("No such relationship ${join}") unless $rel_info;
3842b955 520 my $type = $rel_info->{attrs}{join_type} || '';
489709af 521 return [ { $as => $self->related_source($join)->from,
953a18ef 522 -join_type => $type },
489709af 523 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
953a18ef 524 }
525}
526
87c4e602 527=head2 resolve_condition
528
27f01d1f 529=over 4
530
ebc77b53 531=item Arguments: $cond, $as, $alias|$object
27f01d1f 532
533=back
953a18ef 534
3842b955 535Resolves the passed condition to a concrete query fragment. If given an alias,
953a18ef 536returns a join condition; if given an object, inverts that object to produce
537a related conditional from that object.
538
539=cut
540
541sub resolve_condition {
489709af 542 my ($self, $cond, $as, $for) = @_;
953a18ef 543 #warn %$cond;
544 if (ref $cond eq 'HASH') {
545 my %ret;
546 while (my ($k, $v) = each %{$cond}) {
547 # XXX should probably check these are valid columns
27f01d1f 548 $k =~ s/^foreign\.// ||
75d07914 549 $self->throw_exception("Invalid rel cond key ${k}");
27f01d1f 550 $v =~ s/^self\.// ||
75d07914 551 $self->throw_exception("Invalid rel cond val ${v}");
953a18ef 552 if (ref $for) { # Object
3842b955 553 #warn "$self $k $for $v";
554 $ret{$k} = $for->get_column($v);
555 #warn %ret;
fde6e28e 556 } elsif (ref $as) { # reverse object
557 $ret{$v} = $as->get_column($k);
953a18ef 558 } else {
489709af 559 $ret{"${as}.${k}"} = "${for}.${v}";
953a18ef 560 }
953a18ef 561 }
562 return \%ret;
5efe4c79 563 } elsif (ref $cond eq 'ARRAY') {
489709af 564 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
953a18ef 565 } else {
566 die("Can't handle this yet :(");
87772e46 567 }
568}
569
87c4e602 570=head2 resolve_prefetch
571
27f01d1f 572=over 4
573
ebc77b53 574=item Arguments: hashref/arrayref/scalar
27f01d1f 575
576=back
988bf309 577
b3e8ac9b 578Accepts one or more relationships for the current source and returns an
579array of column names for each of those relationships. Column names are
580prefixed relative to the current source, in accordance with where they appear
581in the supplied relationships. Examples:
582
5ac6a044 583 my $source = $schema->resultset('Tag')->source;
b3e8ac9b 584 @columns = $source->resolve_prefetch( { cd => 'artist' } );
585
586 # @columns =
587 #(
588 # 'cd.cdid',
589 # 'cd.artist',
590 # 'cd.title',
591 # 'cd.year',
592 # 'cd.artist.artistid',
593 # 'cd.artist.name'
594 #)
595
596 @columns = $source->resolve_prefetch( qw[/ cd /] );
597
598 # @columns =
599 #(
600 # 'cd.cdid',
601 # 'cd.artist',
602 # 'cd.title',
603 # 'cd.year'
604 #)
605
606 $source = $schema->resultset('CD')->source;
607 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
608
609 # @columns =
610 #(
611 # 'artist.artistid',
612 # 'artist.name',
613 # 'producer.producerid',
614 # 'producer.name'
75d07914 615 #)
988bf309 616
b3e8ac9b 617=cut
618
619sub resolve_prefetch {
0f66a01b 620 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
489709af 621 $seen ||= {};
b3e8ac9b 622 #$alias ||= $self->name;
623 #warn $alias, Dumper $pre;
624 if( ref $pre eq 'ARRAY' ) {
0f66a01b 625 return
626 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
627 @$pre;
b3e8ac9b 628 }
629 elsif( ref $pre eq 'HASH' ) {
630 my @ret =
631 map {
0f66a01b 632 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
489709af 633 $self->related_source($_)->resolve_prefetch(
0f66a01b 634 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
635 } keys %$pre;
b3e8ac9b 636 #die Dumper \@ret;
637 return @ret;
638 }
639 elsif( ref $pre ) {
a86b1efe 640 $self->throw_exception(
641 "don't know how to resolve prefetch reftype ".ref($pre));
b3e8ac9b 642 }
643 else {
489709af 644 my $count = ++$seen->{$pre};
645 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
b3e8ac9b 646 my $rel_info = $self->relationship_info( $pre );
a86b1efe 647 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
648 unless $rel_info;
37f23589 649 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
a86b1efe 650 my $rel_source = $self->related_source($pre);
0f66a01b 651
652 if (exists $rel_info->{attrs}{accessor}
653 && $rel_info->{attrs}{accessor} eq 'multi') {
654 $self->throw_exception(
655 "Can't prefetch has_many ${pre} (join cond too complex)")
656 unless ref($rel_info->{cond}) eq 'HASH';
37f23589 657 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
0f66a01b 658 keys %{$rel_info->{cond}};
659 $collapse->{"${as_prefix}${pre}"} = \@key;
5a5bec6c 660 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
661 ? @{$rel_info->{attrs}{order_by}}
662 : (defined $rel_info->{attrs}{order_by}
663 ? ($rel_info->{attrs}{order_by})
664 : ()));
665 push(@$order, map { "${as}.$_" } (@key, @ord));
0f66a01b 666 }
667
489709af 668 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
a86b1efe 669 $rel_source->columns;
b3e8ac9b 670 #warn $alias, Dumper (\@ret);
489709af 671 #return @ret;
b3e8ac9b 672 }
673}
953a18ef 674
87c4e602 675=head2 related_source
676
27f01d1f 677=over 4
678
ebc77b53 679=item Arguments: $relname
27f01d1f 680
681=back
87772e46 682
2053ab2a 683Returns the result source object for the given relationship.
87772e46 684
685=cut
686
687sub related_source {
688 my ($self, $rel) = @_;
aea52c85 689 if( !$self->has_relationship( $rel ) ) {
701da8c4 690 $self->throw_exception("No such relationship '$rel'");
aea52c85 691 }
87772e46 692 return $self->schema->source($self->relationship_info($rel)->{source});
8452e496 693}
694
77254782 695=head2 related_class
696
27f01d1f 697=over 4
698
ebc77b53 699=item Arguments: $relname
27f01d1f 700
701=back
77254782 702
2053ab2a 703Returns the class name for objects in the given relationship.
77254782 704
705=cut
706
707sub related_class {
708 my ($self, $rel) = @_;
709 if( !$self->has_relationship( $rel ) ) {
710 $self->throw_exception("No such relationship '$rel'");
711 }
712 return $self->schema->class($self->relationship_info($rel)->{source});
713}
714
5ac6a044 715=head2 resultset
716
bcc5a210 717Returns a resultset for the given source. This will initially be created
718on demand by calling
5ac6a044 719
988bf309 720 $self->resultset_class->new($self, $self->resultset_attributes)
5ac6a044 721
bcc5a210 722but is cached from then on unless resultset_class changes.
723
5ac6a044 724=head2 resultset_class
725
988bf309 726Set the class of the resultset, this is useful if you want to create your
727own resultset methods. Create your own class derived from
728L<DBIx::Class::ResultSet>, and set it here.
5ac6a044 729
730=head2 resultset_attributes
731
988bf309 732Specify here any attributes you wish to pass to your specialised resultset.
5ac6a044 733
734=cut
735
736sub resultset {
737 my $self = shift;
27f01d1f 738 $self->throw_exception(
739 'resultset does not take any arguments. If you want another resultset, '.
740 'call it on the schema instead.'
741 ) if scalar @_;
742 return $self->{_resultset}
743 if ref $self->{_resultset} eq $self->resultset_class;
744 return $self->{_resultset} = $self->resultset_class->new(
745 $self, $self->{resultset_attributes}
746 );
5ac6a044 747}
748
701da8c4 749=head2 throw_exception
750
2053ab2a 751See L<DBIx::Class::Schema/"throw_exception">.
701da8c4 752
753=cut
754
755sub throw_exception {
756 my $self = shift;
75d07914 757 if (defined $self->schema) {
701da8c4 758 $self->schema->throw_exception(@_);
759 } else {
760 croak(@_);
761 }
762}
763
9c992ba1 764=head1 AUTHORS
765
766Matt S. Trout <mst@shadowcatsystems.co.uk>
767
768=head1 LICENSE
769
770You may distribute this code under the same terms as Perl itself.
771
772=cut
773