Spellcheck (jawnsy++)
[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;
aec3eff1 7use DBIx::Class::ResultSourceHandle;
1a58752c 8
9use DBIx::Class::Exception;
701da8c4 10use Carp::Clan qw/^DBIx::Class/;
6da5894c 11
9c992ba1 12use base qw/DBIx::Class/;
9c992ba1 13
aa1088bf 14__PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
15 _columns _primaries _unique_constraints name resultset_attributes
acbe81cf 16 schema from _relationships column_info_from_storage source_info
f89bb832 17 source_name sqlt_deploy_callback/);
aa1088bf 18
fac560c2 19__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
b0dd0e03 20 result_class/);
9c992ba1 21
75d07914 22=head1 NAME
9c992ba1 23
24DBIx::Class::ResultSource - Result source object
25
26=head1 SYNOPSIS
27
16ccb4fe 28 # Create a table based result source, in a result class.
29
30 package MyDB::Schema::Result::Artist;
d88ecca6 31 use base qw/DBIx::Class::Core/;
16ccb4fe 32
16ccb4fe 33 __PACKAGE__->table('artist');
34 __PACKAGE__->add_columns(qw/ artistid name /);
35 __PACKAGE__->set_primary_key('artistid');
36 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
37
38 1;
39
40 # Create a query (view) based result source, in a result class
41 package MyDB::Schema::Result::Year2000CDs;
d88ecca6 42 use base qw/DBIx::Class::Core/;
16ccb4fe 43
d88ecca6 44 __PACKAGE__->load_components('InflateColumn::DateTime');
16ccb4fe 45 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
46
47 __PACKAGE__->table('year2000cds');
48 __PACKAGE__->result_source_instance->is_virtual(1);
49 __PACKAGE__->result_source_instance->view_definition(
50 "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
51 );
52
53
9c992ba1 54=head1 DESCRIPTION
55
16ccb4fe 56A ResultSource is an object that represents a source of data for querying.
57
58This class is a base class for various specialised types of result
59sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
60default result source type, so one is created for you when defining a
61result class as described in the synopsis above.
62
d88ecca6 63More specifically, the L<DBIx::Class::Core> base class pulls in the
64L<DBIx::Class::ResultSourceProxy::Table> component, which defines
65the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
66When called, C<table> creates and stores an instance of
16ccb4fe 67L<DBIx::Class::ResultSoure::Table>. Luckily, to use tables as result
68sources, you don't need to remember any of this.
69
70Result sources representing select queries, or views, can also be
71created, see L<DBIx::Class::ResultSource::View> for full details.
72
73=head2 Finding result source objects
74
75As mentioned above, a result source instance is created and stored for
76you when you define a L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
77
78You can retrieve the result source at runtime in the following ways:
79
80=over
81
82=item From a Schema object:
83
84 $schema->source($source_name);
85
86=item From a Row object:
9c992ba1 87
16ccb4fe 88 $row->result_source;
89
90=item From a ResultSet object:
91
92 $rs->result_source;
93
94=back
00be2e0b 95
9c992ba1 96=head1 METHODS
97
7eb4ecc8 98=pod
99
9c992ba1 100=cut
101
102sub new {
103 my ($class, $attrs) = @_;
104 $class = ref $class if ref $class;
04786a4c 105
6b051e14 106 my $new = bless { %{$attrs || {}} }, $class;
9c992ba1 107 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
5ac6a044 108 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
6da5894c 109 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
110 $new->{_columns} = { %{$new->{_columns}||{}} };
111 $new->{_relationships} = { %{$new->{_relationships}||{}} };
9c992ba1 112 $new->{name} ||= "!!NAME NOT SET!!";
5afa2a15 113 $new->{_columns_info_loaded} ||= 0;
f89bb832 114 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
9c992ba1 115 return $new;
116}
117
988bf309 118=pod
119
5ac6a044 120=head2 add_columns
121
391ccf38 122=over
123
124=item Arguments: @columns
125
126=item Return value: The ResultSource object
127
128=back
129
843f6bc1 130 $source->add_columns(qw/col1 col2 col3/);
5ac6a044 131
843f6bc1 132 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
5ac6a044 133
16ccb4fe 134Adds columns to the result source. If supplied colname => hashref
135pairs, uses the hashref as the L</column_info> for that column. Repeated
136calls of this method will add more columns, not replace them.
5ac6a044 137
5d9d9e87 138The column names given will be created as accessor methods on your
7e51afbf 139L<DBIx::Class::Row> objects. You can change the name of the accessor
5d9d9e87 140by supplying an L</accessor> in the column_info hash.
141
2053ab2a 142The contents of the column_info are not set in stone. The following
143keys are currently recognised/used by DBIx::Class:
988bf309 144
145=over 4
146
75d07914 147=item accessor
988bf309 148
16ccb4fe 149 { accessor => '_name' }
150
151 # example use, replace standard accessor with one of your own:
152 sub name {
153 my ($self, $value) = @_;
154
155 die "Name cannot contain digits!" if($value =~ /\d/);
156 $self->_name($value);
157
158 return $self->_name();
159 }
160
5d9d9e87 161Use this to set the name of the accessor method for this column. If unset,
988bf309 162the name of the column will be used.
163
164=item data_type
165
16ccb4fe 166 { data_type => 'integer' }
167
168This contains the column type. It is automatically filled if you use the
169L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
170L<DBIx::Class::Schema::Loader> module.
988bf309 171
2053ab2a 172Currently there is no standard set of values for the data_type. Use
173whatever your database supports.
988bf309 174
175=item size
176
16ccb4fe 177 { size => 20 }
178
988bf309 179The length of your column, if it is a column type that can have a size
16ccb4fe 180restriction. This is currently only used to create tables from your
181schema, see L<DBIx::Class::Schema/deploy>.
988bf309 182
183=item is_nullable
184
16ccb4fe 185 { is_nullable => 1 }
186
187Set this to a true value for a columns that is allowed to contain NULL
188values, default is false. This is currently only used to create tables
189from your schema, see L<DBIx::Class::Schema/deploy>.
988bf309 190
191=item is_auto_increment
192
16ccb4fe 193 { is_auto_increment => 1 }
194
2053ab2a 195Set this to a true value for a column whose value is somehow
16ccb4fe 196automatically set, defaults to false. This is used to determine which
197columns to empty when cloning objects using
198L<DBIx::Class::Row/copy>. It is also used by
d7be2784 199L<DBIx::Class::Schema/deploy>.
988bf309 200
26a29815 201=item is_numeric
202
16ccb4fe 203 { is_numeric => 1 }
204
26a29815 205Set this to a true or false value (not C<undef>) to explicitly specify
206if this column contains numeric data. This controls how set_column
207decides whether to consider a column dirty after an update: if
0bad1823 208C<is_numeric> is true a numeric comparison C<< != >> will take place
26a29815 209instead of the usual C<eq>
210
211If not specified the storage class will attempt to figure this out on
212first access to the column, based on the column C<data_type>. The
213result will be cached in this attribute.
214
988bf309 215=item is_foreign_key
216
16ccb4fe 217 { is_foreign_key => 1 }
218
2053ab2a 219Set this to a true value for a column that contains a key from a
16ccb4fe 220foreign table, defaults to false. This is currently only used to
221create tables from your schema, see L<DBIx::Class::Schema/deploy>.
988bf309 222
223=item default_value
224
16ccb4fe 225 { default_value => \'now()' }
226
227Set this to the default value which will be inserted into a column by
228the database. Can contain either a value or a function (use a
4858fea7 229reference to a scalar e.g. C<\'now()'> if you want a function). This
16ccb4fe 230is currently only used to create tables from your schema, see
231L<DBIx::Class::Schema/deploy>.
988bf309 232
a4fcda00 233See the note on L<DBIx::Class::Row/new> for more information about possible
234issues related to db-side default values.
235
988bf309 236=item sequence
237
16ccb4fe 238 { sequence => 'my_table_seq' }
239
2053ab2a 240Set this on a primary key column to the name of the sequence used to
241generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
242will attempt to retrieve the name of the sequence from the database
243automatically.
988bf309 244
838ef78d 245=item auto_nextval
246
ca791b95 247Set this to a true value for a column whose value is retrieved automatically
248from a sequence or function (if supported by your Storage driver.) For a
249sequence, if you do not use a trigger to get the nextval, you have to set the
250L</sequence> value as well.
251
252Also set this for MSSQL columns with the 'uniqueidentifier'
253L<DBIx::Class::ResultSource/data_type> whose values you want to automatically
254generate using C<NEWID()>, unless they are a primary key in which case this will
255be done anyway.
838ef78d 256
190615a7 257=item extra
d7be2784 258
259This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
190615a7 260to add extra non-generic data to the column. For example: C<< extra
d7be2784 261=> { unsigned => 1} >> is used by the MySQL producer to set an integer
262column to unsigned. For more details, see
263L<SQL::Translator::Producer::MySQL>.
264
988bf309 265=back
266
5ac6a044 267=head2 add_column
268
391ccf38 269=over
270
16ccb4fe 271=item Arguments: $colname, \%columninfo?
391ccf38 272
273=item Return value: 1/0 (true/false)
274
275=back
276
16ccb4fe 277 $source->add_column('col' => \%info);
5ac6a044 278
391ccf38 279Add a single column and optional column info. Uses the same column
280info keys as L</add_columns>.
5ac6a044 281
282=cut
283
9c992ba1 284sub add_columns {
285 my ($self, @cols) = @_;
8e04bf91 286 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
002a359a 287
20518cb4 288 my @added;
289 my $columns = $self->_columns;
9c992ba1 290 while (my $col = shift @cols) {
8e04bf91 291 # If next entry is { ... } use that for the column info, if not
292 # use an empty hashref
30126ac7 293 my $column_info = ref $cols[0] ? shift(@cols) : {};
20518cb4 294 push(@added, $col) unless exists $columns->{$col};
20518cb4 295 $columns->{$col} = $column_info;
9c992ba1 296 }
20518cb4 297 push @{ $self->_ordered_columns }, @added;
30126ac7 298 return $self;
9c992ba1 299}
300
b25e9fa0 301sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
9c992ba1 302
3842b955 303=head2 has_column
304
391ccf38 305=over
306
307=item Arguments: $colname
308
309=item Return value: 1/0 (true/false)
310
311=back
312
843f6bc1 313 if ($source->has_column($colname)) { ... }
988bf309 314
2053ab2a 315Returns true if the source has a column of this name, false otherwise.
988bf309 316
317=cut
9c992ba1 318
319sub has_column {
320 my ($self, $column) = @_;
321 return exists $self->_columns->{$column};
322}
323
87c4e602 324=head2 column_info
9c992ba1 325
391ccf38 326=over
327
328=item Arguments: $colname
329
330=item Return value: Hashref of info
331
332=back
333
843f6bc1 334 my $info = $source->column_info($col);
9c992ba1 335
391ccf38 336Returns the column metadata hashref for a column, as originally passed
16ccb4fe 337to L</add_columns>. See L</add_columns> above for information on the
338contents of the hashref.
9c992ba1 339
988bf309 340=cut
9c992ba1 341
342sub column_info {
343 my ($self, $column) = @_;
75d07914 344 $self->throw_exception("No such column $column")
701da8c4 345 unless exists $self->_columns->{$column};
5afa2a15 346 #warn $self->{_columns_info_loaded}, "\n";
75d07914 347 if ( ! $self->_columns->{$column}{data_type}
6eda9bcf 348 and $self->column_info_from_storage
75d07914 349 and ! $self->{_columns_info_loaded}
8e04bf91 350 and $self->schema and $self->storage )
351 {
352 $self->{_columns_info_loaded}++;
d51f93c8 353 my $info = {};
354 my $lc_info = {};
75d07914 355 # eval for the case of storage without table
955f1590 356 eval { $info = $self->storage->columns_info_for( $self->from ) };
8e04bf91 357 unless ($@) {
0b88a5bb 358 for my $realcol ( keys %{$info} ) {
359 $lc_info->{lc $realcol} = $info->{$realcol};
360 }
8e04bf91 361 foreach my $col ( keys %{$self->_columns} ) {
d51f93c8 362 $self->_columns->{$col} = {
363 %{ $self->_columns->{$col} },
364 %{ $info->{$col} || $lc_info->{lc $col} || {} }
365 };
a953d8d9 366 }
8e04bf91 367 }
a953d8d9 368 }
9c992ba1 369 return $self->_columns->{$column};
370}
371
372=head2 columns
373
391ccf38 374=over
375
376=item Arguments: None
377
378=item Return value: Ordered list of column names
379
380=back
381
382 my @column_names = $source->columns;
20518cb4 383
391ccf38 384Returns all column names in the order they were declared to L</add_columns>.
87f0da6a 385
386=cut
9c992ba1 387
388sub columns {
8e04bf91 389 my $self = shift;
aa1088bf 390 $self->throw_exception(
391 "columns() is a read-only accessor, did you mean add_columns()?"
9851dada 392 ) if @_;
701da8c4 393 return @{$self->{_ordered_columns}||[]};
571dced3 394}
395
002a359a 396=head2 remove_columns
397
391ccf38 398=over
002a359a 399
391ccf38 400=item Arguments: @colnames
401
402=item Return value: undefined
403
404=back
405
406 $source->remove_columns(qw/col1 col2 col3/);
407
408Removes the given list of columns by name, from the result source.
409
410B<Warning>: Removing a column that is also used in the sources primary
411key, or in one of the sources unique constraints, B<will> result in a
412broken result source.
002a359a 413
414=head2 remove_column
415
391ccf38 416=over
417
418=item Arguments: $colname
419
420=item Return value: undefined
421
422=back
002a359a 423
391ccf38 424 $source->remove_column('col');
425
426Remove a single column by name from the result source, similar to
427L</remove_columns>.
428
429B<Warning>: Removing a column that is also used in the sources primary
430key, or in one of the sources unique constraints, B<will> result in a
431broken result source.
002a359a 432
433=cut
434
435sub remove_columns {
4738027b 436 my ($self, @to_remove) = @_;
002a359a 437
4738027b 438 my $columns = $self->_columns
439 or return;
002a359a 440
4738027b 441 my %to_remove;
442 for (@to_remove) {
a918d901 443 delete $columns->{$_};
4738027b 444 ++$to_remove{$_};
445 }
002a359a 446
4738027b 447 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
002a359a 448}
449
b25e9fa0 450sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
002a359a 451
87c4e602 452=head2 set_primary_key
453
27f01d1f 454=over 4
455
ebc77b53 456=item Arguments: @cols
27f01d1f 457
391ccf38 458=item Return value: undefined
459
27f01d1f 460=back
87f0da6a 461
16ccb4fe 462Defines one or more columns as primary key for this source. Must be
391ccf38 463called after L</add_columns>.
87f0da6a 464
391ccf38 465Additionally, defines a L<unique constraint|add_unique_constraint>
466named C<primary>.
87f0da6a 467
988bf309 468The primary key columns are used by L<DBIx::Class::PK::Auto> to
16ccb4fe 469retrieve automatically created values from the database. They are also
470used as default joining columns when specifying relationships, see
471L<DBIx::Class::Relationship>.
988bf309 472
87f0da6a 473=cut
9c992ba1 474
475sub set_primary_key {
476 my ($self, @cols) = @_;
477 # check if primary key columns are valid columns
8e04bf91 478 foreach my $col (@cols) {
479 $self->throw_exception("No such column $col on table " . $self->name)
480 unless $self->has_column($col);
9c992ba1 481 }
482 $self->_primaries(\@cols);
87f0da6a 483
484 $self->add_unique_constraint(primary => \@cols);
9c992ba1 485}
486
87f0da6a 487=head2 primary_columns
488
391ccf38 489=over 4
490
491=item Arguments: None
492
493=item Return value: Ordered list of primary column names
494
495=back
496
497Read-only accessor which returns the list of primary keys, supplied by
498L</set_primary_key>.
30126ac7 499
87f0da6a 500=cut
9c992ba1 501
502sub primary_columns {
503 return @{shift->_primaries||[]};
504}
505
87f0da6a 506=head2 add_unique_constraint
507
391ccf38 508=over 4
509
16ccb4fe 510=item Arguments: $name?, \@colnames
391ccf38 511
512=item Return value: undefined
513
514=back
515
87f0da6a 516Declare a unique constraint on this source. Call once for each unique
58b5bb8c 517constraint.
27f01d1f 518
519 # For UNIQUE (column1, column2)
520 __PACKAGE__->add_unique_constraint(
521 constraint_name => [ qw/column1 column2/ ],
522 );
87f0da6a 523
368a5228 524Alternatively, you can specify only the columns:
525
526 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
527
16ccb4fe 528This will result in a unique constraint named
529C<table_column1_column2>, where C<table> is replaced with the table
530name.
368a5228 531
16ccb4fe 532Unique constraints are used, for example, when you pass the constraint
533name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
534only columns in the constraint are searched.
58b5bb8c 535
391ccf38 536Throws an error if any of the given column names do not yet exist on
537the result source.
538
87f0da6a 539=cut
540
541sub add_unique_constraint {
368a5228 542 my $self = shift;
543 my $cols = pop @_;
544 my $name = shift;
545
546 $name ||= $self->name_unique_constraint($cols);
87f0da6a 547
8e04bf91 548 foreach my $col (@$cols) {
549 $self->throw_exception("No such column $col on table " . $self->name)
550 unless $self->has_column($col);
87f0da6a 551 }
552
553 my %unique_constraints = $self->unique_constraints;
554 $unique_constraints{$name} = $cols;
555 $self->_unique_constraints(\%unique_constraints);
556}
557
d9c74322 558=head2 name_unique_constraint
368a5228 559
391ccf38 560=over 4
561
562=item Arguments: @colnames
563
564=item Return value: Constraint name
565
566=back
567
568 $source->table('mytable');
569 $source->name_unique_constraint('col1', 'col2');
570 # returns
571 'mytable_col1_col2'
572
573Return a name for a unique constraint containing the specified
574columns. The name is created by joining the table name and each column
575name, using an underscore character.
368a5228 576
577For example, a constraint on a table named C<cd> containing the columns
578C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
579
391ccf38 580This is used by L</add_unique_constraint> if you do not specify the
581optional constraint name.
582
368a5228 583=cut
584
585sub name_unique_constraint {
586 my ($self, $cols) = @_;
587
3e6c1131 588 my $name = $self->name;
4678e9da 589 $name = $$name if (ref $name eq 'SCALAR');
3e6c1131 590
591 return join '_', $name, @$cols;
368a5228 592}
593
87f0da6a 594=head2 unique_constraints
595
391ccf38 596=over 4
597
598=item Arguments: None
599
600=item Return value: Hash of unique constraint data
601
602=back
603
604 $source->unique_constraints();
605
16ccb4fe 606Read-only accessor which returns a hash of unique constraints on this
607source.
391ccf38 608
609The hash is keyed by constraint name, and contains an arrayref of
610column names as values.
87f0da6a 611
612=cut
613
614sub unique_constraints {
615 return %{shift->_unique_constraints||{}};
616}
617
e6a0e17c 618=head2 unique_constraint_names
619
391ccf38 620=over 4
621
622=item Arguments: None
623
624=item Return value: Unique constraint names
625
626=back
627
628 $source->unique_constraint_names();
629
e6a0e17c 630Returns the list of unique constraint names defined on this source.
631
632=cut
633
634sub unique_constraint_names {
635 my ($self) = @_;
636
637 my %unique_constraints = $self->unique_constraints;
638
639 return keys %unique_constraints;
640}
641
642=head2 unique_constraint_columns
643
391ccf38 644=over 4
645
646=item Arguments: $constraintname
647
648=item Return value: List of constraint columns
649
650=back
651
652 $source->unique_constraint_columns('myconstraint');
653
e6a0e17c 654Returns the list of columns that make up the specified unique constraint.
655
656=cut
657
658sub unique_constraint_columns {
659 my ($self, $constraint_name) = @_;
660
661 my %unique_constraints = $self->unique_constraints;
662
663 $self->throw_exception(
664 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
665 ) unless exists $unique_constraints{$constraint_name};
666
667 return @{ $unique_constraints{$constraint_name} };
668}
669
880c075b 670=head2 sqlt_deploy_callback
671
672=over
673
674=item Arguments: $callback
675
676=back
677
678 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
679
680An accessor to set a callback to be called during deployment of
681the schema via L<DBIx::Class::Schema/create_ddl_dir> or
682L<DBIx::Class::Schema/deploy>.
683
684The callback can be set as either a code reference or the name of a
685method in the current result class.
686
687If not set, the L</default_sqlt_deploy_hook> is called.
688
689Your callback will be passed the $source object representing the
690ResultSource instance being deployed, and the
691L<SQL::Translator::Schema::Table> object being created from it. The
692callback can be used to manipulate the table object or add your own
693customised indexes. If you need to manipulate a non-table object, use
694the L<DBIx::Class::Schema/sqlt_deploy_hook>.
695
696See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
697Your SQL> for examples.
698
699This sqlt deployment callback can only be used to manipulate
700SQL::Translator objects as they get turned into SQL. To execute
701post-deploy statements which SQL::Translator does not currently
702handle, override L<DBIx::Class::Schema/deploy> in your Schema class
703and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
704
705=head2 default_sqlt_deploy_hook
706
707=over
708
709=item Arguments: $source, $sqlt_table
710
711=item Return value: undefined
712
713=back
714
715This is the sensible default for L</sqlt_deploy_callback>.
716
717If a method named C<sqlt_deploy_hook> exists in your Result class, it
718will be called and passed the current C<$source> and the
719C<$sqlt_table> being deployed.
720
721=cut
722
723sub default_sqlt_deploy_hook {
724 my $self = shift;
725
726 my $class = $self->result_class;
727
728 if ($class and $class->can('sqlt_deploy_hook')) {
729 $class->sqlt_deploy_hook(@_);
730 }
731}
732
733sub _invoke_sqlt_deploy_hook {
734 my $self = shift;
735 if ( my $hook = $self->sqlt_deploy_callback) {
736 $self->$hook(@_);
737 }
738}
739
843f6bc1 740=head2 resultset
741
742=over 4
743
744=item Arguments: None
745
746=item Return value: $resultset
747
748=back
749
750Returns a resultset for the given source. This will initially be created
751on demand by calling
752
753 $self->resultset_class->new($self, $self->resultset_attributes)
754
755but is cached from then on unless resultset_class changes.
756
757=head2 resultset_class
758
759=over 4
760
761=item Arguments: $classname
762
763=item Return value: $classname
764
765=back
766
16ccb4fe 767 package My::Schema::ResultSet::Artist;
843f6bc1 768 use base 'DBIx::Class::ResultSet';
769 ...
770
16ccb4fe 771 # In the result class
772 __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
773
774 # Or in code
775 $source->resultset_class('My::Schema::ResultSet::Artist');
843f6bc1 776
7e51afbf 777Set the class of the resultset. This is useful if you want to create your
843f6bc1 778own resultset methods. Create your own class derived from
779L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
780this method returns the name of the existing resultset class, if one
781exists.
782
783=head2 resultset_attributes
784
785=over 4
786
787=item Arguments: \%attrs
788
789=item Return value: \%attrs
790
791=back
792
16ccb4fe 793 # In the result class
794 __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
795
796 # Or in code
843f6bc1 797 $source->resultset_attributes({ order_by => [ 'id' ] });
798
799Store a collection of resultset attributes, that will be set on every
800L<DBIx::Class::ResultSet> produced from this result source. For a full
801list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
802
803=cut
804
805sub resultset {
806 my $self = shift;
807 $self->throw_exception(
808 'resultset does not take any arguments. If you want another resultset, '.
809 'call it on the schema instead.'
810 ) if scalar @_;
811
812 return $self->resultset_class->new(
813 $self,
814 {
815 %{$self->{resultset_attributes}},
816 %{$self->schema->default_resultset_attributes}
817 },
818 );
819}
820
821=head2 source_name
822
823=over 4
824
825=item Arguments: $source_name
826
827=item Result value: $source_name
828
829=back
830
831Set an alternate name for the result source when it is loaded into a schema.
832This is useful if you want to refer to a result source by a name other than
833its class name.
834
835 package ArchivedBooks;
836 use base qw/DBIx::Class/;
837 __PACKAGE__->table('books_archive');
838 __PACKAGE__->source_name('Books');
839
840 # from your schema...
841 $schema->resultset('Books')->find(1);
842
9c992ba1 843=head2 from
844
391ccf38 845=over 4
846
847=item Arguments: None
848
849=item Return value: FROM clause
850
851=back
852
853 my $from_clause = $source->from();
854
9c992ba1 855Returns an expression of the source to be supplied to storage to specify
2053ab2a 856retrieval from this source. In the case of a database, the required FROM
857clause contents.
9c992ba1 858
f9b7bd6e 859=head2 schema
860
391ccf38 861=over 4
862
863=item Arguments: None
864
865=item Return value: A schema object
866
867=back
868
869 my $schema = $source->schema();
870
f9b7bd6e 871Returns the L<DBIx::Class::Schema> object that this result source
391ccf38 872belongs to.
9c992ba1 873
874=head2 storage
875
391ccf38 876=over 4
877
878=item Arguments: None
879
880=item Return value: A Storage object
881
882=back
883
884 $source->storage->debug(1);
885
75d07914 886Returns the storage handle for the current schema.
988bf309 887
888See also: L<DBIx::Class::Storage>
9c992ba1 889
890=cut
891
892sub storage { shift->schema->storage; }
893
8452e496 894=head2 add_relationship
895
391ccf38 896=over 4
897
898=item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
899
900=item Return value: 1/true if it succeeded
901
902=back
903
8452e496 904 $source->add_relationship('relname', 'related_source', $cond, $attrs);
905
391ccf38 906L<DBIx::Class::Relationship> describes a series of methods which
907create pre-defined useful types of relationships. Look there first
908before using this method directly.
909
24d67825 910The relationship name can be arbitrary, but must be unique for each
911relationship attached to this result source. 'related_source' should
912be the name with which the related result source was registered with
913the current schema. For example:
8452e496 914
24d67825 915 $schema->source('Book')->add_relationship('reviews', 'Review', {
916 'foreign.book_id' => 'self.id',
917 });
918
2053ab2a 919The condition C<$cond> needs to be an L<SQL::Abstract>-style
24d67825 920representation of the join between the tables. For example, if you're
391ccf38 921creating a relation from Author to Book,
988bf309 922
923 { 'foreign.author_id' => 'self.id' }
924
925will result in the JOIN clause
926
927 author me JOIN book foreign ON foreign.author_id = me.id
928
8452e496 929You can specify as many foreign => self mappings as necessary.
930
988bf309 931Valid attributes are as follows:
932
933=over 4
934
935=item join_type
936
937Explicitly specifies the type of join to use in the relationship. Any
938SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
939the SQL command immediately before C<JOIN>.
940
941=item proxy
942
24d67825 943An arrayref containing a list of accessors in the foreign class to proxy in
944the main class. If, for example, you do the following:
002a359a 945
24d67825 946 CD->might_have(liner_notes => 'LinerNotes', undef, {
947 proxy => [ qw/notes/ ],
948 });
002a359a 949
24d67825 950Then, assuming LinerNotes has an accessor named notes, you can do:
988bf309 951
24d67825 952 my $cd = CD->find(1);
2053ab2a 953 # set notes -- LinerNotes object is created if it doesn't exist
954 $cd->notes('Notes go here');
988bf309 955
956=item accessor
957
958Specifies the type of accessor that should be created for the
75d07914 959relationship. Valid values are C<single> (for when there is only a single
960related object), C<multi> (when there can be many), and C<filter> (for
961when there is a single related object, but you also want the relationship
962accessor to double as a column accessor). For C<multi> accessors, an
963add_to_* method is also created, which calls C<create_related> for the
988bf309 964relationship.
965
8452e496 966=back
967
391ccf38 968Throws an exception if the condition is improperly supplied, or cannot
6d0ee587 969be resolved.
391ccf38 970
8452e496 971=cut
972
973sub add_relationship {
974 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
27f01d1f 975 $self->throw_exception("Can't create relationship without join condition")
976 unless $cond;
8452e496 977 $attrs ||= {};
87772e46 978
eba322a7 979 # Check foreign and self are right in cond
980 if ( (ref $cond ||'') eq 'HASH') {
981 for (keys %$cond) {
982 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
983 if /\./ && !/^foreign\./;
984 }
985 }
986
8452e496 987 my %rels = %{ $self->_relationships };
988 $rels{$rel} = { class => $f_source_name,
87772e46 989 source => $f_source_name,
8452e496 990 cond => $cond,
991 attrs => $attrs };
992 $self->_relationships(\%rels);
993
30126ac7 994 return $self;
87772e46 995
953a18ef 996 # XXX disabled. doesn't work properly currently. skip in tests.
997
8452e496 998 my $f_source = $self->schema->source($f_source_name);
999 unless ($f_source) {
c037c03a 1000 $self->ensure_class_loaded($f_source_name);
8452e496 1001 $f_source = $f_source_name->result_source;
87772e46 1002 #my $s_class = ref($self->schema);
1003 #$f_source_name =~ m/^${s_class}::(.*)$/;
1004 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1005 #$f_source = $self->schema->source($f_source_name);
8452e496 1006 }
1007 return unless $f_source; # Can't test rel without f_source
1008
88a66388 1009 eval { $self->_resolve_join($rel, 'me', {}, []) };
8452e496 1010
1011 if ($@) { # If the resolve failed, back out and re-throw the error
75d07914 1012 delete $rels{$rel}; #
8452e496 1013 $self->_relationships(\%rels);
701da8c4 1014 $self->throw_exception("Error creating relationship $rel: $@");
8452e496 1015 }
1016 1;
1017}
1018
87c4e602 1019=head2 relationships
8452e496 1020
391ccf38 1021=over 4
1022
1023=item Arguments: None
1024
1025=item Return value: List of relationship names
1026
1027=back
1028
1029 my @relnames = $source->relationships();
1030
2053ab2a 1031Returns all relationship names for this source.
8452e496 1032
1033=cut
1034
1035sub relationships {
1036 return keys %{shift->_relationships};
1037}
1038
87c4e602 1039=head2 relationship_info
1040
27f01d1f 1041=over 4
1042
ebc77b53 1043=item Arguments: $relname
27f01d1f 1044
391ccf38 1045=item Return value: Hashref of relation data,
1046
27f01d1f 1047=back
8452e496 1048
2053ab2a 1049Returns a hash of relationship information for the specified relationship
391ccf38 1050name. The keys/values are as specified for L</add_relationship>.
8452e496 1051
1052=cut
1053
1054sub relationship_info {
1055 my ($self, $rel) = @_;
1056 return $self->_relationships->{$rel};
75d07914 1057}
8452e496 1058
87c4e602 1059=head2 has_relationship
1060
27f01d1f 1061=over 4
1062
ebc77b53 1063=item Arguments: $rel
27f01d1f 1064
391ccf38 1065=item Return value: 1/0 (true/false)
1066
27f01d1f 1067=back
953a18ef 1068
2053ab2a 1069Returns true if the source has a relationship of this name, false otherwise.
988bf309 1070
1071=cut
953a18ef 1072
1073sub has_relationship {
1074 my ($self, $rel) = @_;
1075 return exists $self->_relationships->{$rel};
1076}
1077
de60a93d 1078=head2 reverse_relationship_info
1079
1080=over 4
1081
1082=item Arguments: $relname
1083
391ccf38 1084=item Return value: Hashref of relationship data
1085
de60a93d 1086=back
1087
391ccf38 1088Looks through all the relationships on the source this relationship
1089points to, looking for one whose condition is the reverse of the
1090condition on this relationship.
1091
1092A common use of this is to find the name of the C<belongs_to> relation
1093opposing a C<has_many> relation. For definition of these look in
1094L<DBIx::Class::Relationship>.
1095
1096The returned hashref is keyed by the name of the opposing
faaba25f 1097relationship, and contains its data in the same manner as
391ccf38 1098L</relationship_info>.
de60a93d 1099
1100=cut
1101
1102sub reverse_relationship_info {
1103 my ($self, $rel) = @_;
1104 my $rel_info = $self->relationship_info($rel);
1105 my $ret = {};
1106
1107 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1108
1109 my @cond = keys(%{$rel_info->{cond}});
1110 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
1111 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
bab77431 1112
de60a93d 1113 # Get the related result source for this relationship
1114 my $othertable = $self->related_source($rel);
1115
1116 # Get all the relationships for that source that related to this source
1117 # whose foreign column set are our self columns on $rel and whose self
bab77431 1118 # columns are our foreign columns on $rel.
de60a93d 1119 my @otherrels = $othertable->relationships();
1120 my $otherrelationship;
1121 foreach my $otherrel (@otherrels) {
1122 my $otherrel_info = $othertable->relationship_info($otherrel);
1123
1124 my $back = $othertable->related_source($otherrel);
f3fb2641 1125 next unless $back->source_name eq $self->source_name;
de60a93d 1126
1127 my @othertestconds;
1128
1129 if (ref $otherrel_info->{cond} eq 'HASH') {
1130 @othertestconds = ($otherrel_info->{cond});
1131 }
1132 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1133 @othertestconds = @{$otherrel_info->{cond}};
1134 }
1135 else {
1136 next;
1137 }
1138
1139 foreach my $othercond (@othertestconds) {
1140 my @other_cond = keys(%$othercond);
1141 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1142 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
6d0ee587 1143 next if (!$self->_compare_relationship_keys(\@refkeys, \@other_keys) ||
1144 !$self->_compare_relationship_keys(\@other_refkeys, \@keys));
de60a93d 1145 $ret->{$otherrel} = $otherrel_info;
1146 }
1147 }
1148 return $ret;
1149}
1150
de60a93d 1151sub compare_relationship_keys {
6d0ee587 1152 carp 'compare_relationship_keys is a private method, stop calling it';
1153 my $self = shift;
1154 $self->_compare_relationship_keys (@_);
1155}
1156
1157# Returns true if both sets of keynames are the same, false otherwise.
1158sub _compare_relationship_keys {
de60a93d 1159 my ($self, $keys1, $keys2) = @_;
1160
1161 # Make sure every keys1 is in keys2
1162 my $found;
1163 foreach my $key (@$keys1) {
1164 $found = 0;
1165 foreach my $prim (@$keys2) {
1166 if ($prim eq $key) {
1167 $found = 1;
1168 last;
1169 }
1170 }
1171 last unless $found;
1172 }
1173
1174 # Make sure every key2 is in key1
1175 if ($found) {
1176 foreach my $prim (@$keys2) {
1177 $found = 0;
1178 foreach my $key (@$keys1) {
1179 if ($prim eq $key) {
1180 $found = 1;
1181 last;
1182 }
1183 }
1184 last unless $found;
1185 }
1186 }
1187
1188 return $found;
1189}
1190
6d0ee587 1191# Returns the {from} structure used to express JOIN conditions
1192sub _resolve_join {
8a3fa4ae 1193 my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1979278e 1194
1195 # we need a supplied one, because we do in-place modifications, no returns
6d0ee587 1196 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
88a66388 1197 unless ref $seen eq 'HASH';
1979278e 1198
88a66388 1199 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1200 unless ref $jpath eq 'ARRAY';
1201
38f42d85 1202 $jpath = [@$jpath]; # copy
1979278e 1203
8a3fa4ae 1204 if (not defined $join) {
1205 return ();
1206 }
1207 elsif (ref $join eq 'ARRAY') {
caac1708 1208 return
1209 map {
8a3fa4ae 1210 $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
caac1708 1211 } @$join;
8a3fa4ae 1212 }
1213 elsif (ref $join eq 'HASH') {
1214
1215 my @ret;
1216 for my $rel (keys %$join) {
1217
1218 my $rel_info = $self->relationship_info($rel)
1219 or $self->throw_exception("No such relationship ${rel}");
1220
1221 my $force_left = $parent_force_left;
1222 $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1223
1224 # the actual seen value will be incremented by the recursion
6c0230de 1225 my $as = $self->storage->relname_to_table_alias(
1226 $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1227 );
1979278e 1228
8a3fa4ae 1229 push @ret, (
1230 $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1231 $self->related_source($rel)->_resolve_join(
38f42d85 1232 $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
8a3fa4ae 1233 )
1234 );
1235 }
1236 return @ret;
096395af 1237
8a3fa4ae 1238 }
1239 elsif (ref $join) {
1240 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1241 }
1242 else {
489709af 1243 my $count = ++$seen->{$join};
6c0230de 1244 my $as = $self->storage->relname_to_table_alias(
1245 $join, ($count > 1 && $count)
1246 );
1979278e 1247
8a3fa4ae 1248 my $rel_info = $self->relationship_info($join)
1249 or $self->throw_exception("No such relationship ${join}");
ba61fa2a 1250
1251 my $rel_src = $self->related_source($join);
1252 return [ { $as => $rel_src->from,
35ec0366 1253 -source_handle => $rel_src->handle,
8a3fa4ae 1254 -join_type => $parent_force_left
1255 ? 'left'
1256 : $rel_info->{attrs}{join_type}
1257 ,
38f42d85 1258 -join_path => [@$jpath, { $join => $as } ],
b82c8a28 1259 -is_single => (
1260 $rel_info->{attrs}{accessor}
1261 &&
1262 List::Util::first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
1263 ),
ba61fa2a 1264 -alias => $as,
1979278e 1265 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1266 },
6d0ee587 1267 $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
953a18ef 1268 }
1269}
1270
370f2ba2 1271sub pk_depends_on {
6d0ee587 1272 carp 'pk_depends_on is a private method, stop calling it';
1273 my $self = shift;
1274 $self->_pk_depends_on (@_);
1275}
1276
1277# Determines whether a relation is dependent on an object from this source
1278# having already been inserted. Takes the name of the relationship and a
1279# hashref of columns of the related object.
1280sub _pk_depends_on {
370f2ba2 1281 my ($self, $relname, $rel_data) = @_;
370f2ba2 1282
c39b48e5 1283 my $relinfo = $self->relationship_info($relname);
1284
1285 # don't assume things if the relationship direction is specified
1286 return $relinfo->{attrs}{is_foreign_key_constraint}
1287 if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1288
1289 my $cond = $relinfo->{cond};
370f2ba2 1290 return 0 unless ref($cond) eq 'HASH';
1291
1292 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
370f2ba2 1293 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1294
1295 # assume anything that references our PK probably is dependent on us
1296 # rather than vice versa, unless the far side is (a) defined or (b)
1297 # auto-increment
370f2ba2 1298 my $rel_source = $self->related_source($relname);
1299
1300 foreach my $p ($self->primary_columns) {
1301 if (exists $keyhash->{$p}) {
1302 unless (defined($rel_data->{$keyhash->{$p}})
1303 || $rel_source->column_info($keyhash->{$p})
1304 ->{is_auto_increment}) {
1305 return 0;
1306 }
1307 }
1308 }
1309
1310 return 1;
1311}
1312
6d0ee587 1313sub resolve_condition {
1314 carp 'resolve_condition is a private method, stop calling it';
1315 my $self = shift;
1316 $self->_resolve_condition (@_);
1317}
953a18ef 1318
6d0ee587 1319# Resolves the passed condition to a concrete query fragment. If given an alias,
1320# returns a join condition; if given an object, inverts that object to produce
1321# a related conditional from that object.
8c368cf3 1322our $UNRESOLVABLE_CONDITION = \'1 = 0';
1323
6d0ee587 1324sub _resolve_condition {
489709af 1325 my ($self, $cond, $as, $for) = @_;
953a18ef 1326 if (ref $cond eq 'HASH') {
1327 my %ret;
bd054cb4 1328 foreach my $k (keys %{$cond}) {
1329 my $v = $cond->{$k};
953a18ef 1330 # XXX should probably check these are valid columns
27f01d1f 1331 $k =~ s/^foreign\.// ||
75d07914 1332 $self->throw_exception("Invalid rel cond key ${k}");
27f01d1f 1333 $v =~ s/^self\.// ||
75d07914 1334 $self->throw_exception("Invalid rel cond val ${v}");
953a18ef 1335 if (ref $for) { # Object
3842b955 1336 #warn "$self $k $for $v";
370f2ba2 1337 unless ($for->has_column_loaded($v)) {
1338 if ($for->in_storage) {
8bbfe6b2 1339 $self->throw_exception(sprintf
5c89c897 1340 "Unable to resolve relationship '%s' from object %s: column '%s' not "
1341 . 'loaded from storage (or not passed to new() prior to insert()). You '
1342 . 'probably need to call ->discard_changes to get the server-side defaults '
1343 . 'from the database.',
8bbfe6b2 1344 $as,
971beb94 1345 $for,
5c89c897 1346 $v,
a4fcda00 1347 );
370f2ba2 1348 }
68f3b0dd 1349 return $UNRESOLVABLE_CONDITION;
370f2ba2 1350 }
1351 $ret{$k} = $for->get_column($v);
1352 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
3842b955 1353 #warn %ret;
2c037e6b 1354 } elsif (!defined $for) { # undef, i.e. "no object"
1355 $ret{$k} = undef;
2ec8e594 1356 } elsif (ref $as eq 'HASH') { # reverse hashref
1357 $ret{$v} = $as->{$k};
fde6e28e 1358 } elsif (ref $as) { # reverse object
1359 $ret{$v} = $as->get_column($k);
2c037e6b 1360 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1361 $ret{$v} = undef;
953a18ef 1362 } else {
489709af 1363 $ret{"${as}.${k}"} = "${for}.${v}";
953a18ef 1364 }
953a18ef 1365 }
1366 return \%ret;
5efe4c79 1367 } elsif (ref $cond eq 'ARRAY') {
6d0ee587 1368 return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
953a18ef 1369 } else {
35c77aa3 1370 die("Can't handle condition $cond yet :(");
87772e46 1371 }
1372}
1373
988bf309 1374
6d0ee587 1375# Accepts one or more relationships for the current source and returns an
1376# array of column names for each of those relationships. Column names are
1377# prefixed relative to the current source, in accordance with where they appear
38f42d85 1378# in the supplied relationships.
b3e8ac9b 1379
6d0ee587 1380sub _resolve_prefetch {
1979278e 1381 my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1382 $pref_path ||= [];
1383
8a3fa4ae 1384 if (not defined $pre) {
1385 return ();
1386 }
1387 elsif( ref $pre eq 'ARRAY' ) {
0f66a01b 1388 return
6d0ee587 1389 map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
0f66a01b 1390 @$pre;
b3e8ac9b 1391 }
1392 elsif( ref $pre eq 'HASH' ) {
1393 my @ret =
1394 map {
6d0ee587 1395 $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1396 $self->related_source($_)->_resolve_prefetch(
1979278e 1397 $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
0f66a01b 1398 } keys %$pre;
b3e8ac9b 1399 return @ret;
1400 }
1401 elsif( ref $pre ) {
a86b1efe 1402 $self->throw_exception(
1403 "don't know how to resolve prefetch reftype ".ref($pre));
b3e8ac9b 1404 }
1405 else {
1979278e 1406 my $p = $alias_map;
1407 $p = $p->{$_} for (@$pref_path, $pre);
1408
1409 $self->throw_exception (
5e8cb53c 1410 "Unable to resolve prefetch '$pre' - join alias map does not contain an entry for path: "
1979278e 1411 . join (' -> ', @$pref_path, $pre)
1412 ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
88a66388 1413
1979278e 1414 my $as = shift @{$p->{-join_aliases}};
1415
b3e8ac9b 1416 my $rel_info = $self->relationship_info( $pre );
a86b1efe 1417 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1418 unless $rel_info;
37f23589 1419 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
a86b1efe 1420 my $rel_source = $self->related_source($pre);
0f66a01b 1421
b82c8a28 1422 if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') {
0f66a01b 1423 $self->throw_exception(
1424 "Can't prefetch has_many ${pre} (join cond too complex)")
1425 unless ref($rel_info->{cond}) eq 'HASH';
cb136e67 1426 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1427 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1428 keys %{$collapse}) {
1429 my ($last) = ($fail =~ /([^\.]+)$/);
616b461d 1430 carp (
1431 "Prefetching multiple has_many rels ${last} and ${pre} "
1432 .(length($as_prefix)
1433 ? "at the same level (${as_prefix}) "
1434 : "at top level "
1435 )
2e251255 1436 . 'will explode the number of row objects retrievable via ->next or ->all. '
616b461d 1437 . 'Use at your own risk.'
1438 );
cb136e67 1439 }
b25e9fa0 1440 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1441 # values %{$rel_info->{cond}};
1442 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1443 # action at a distance. prepending the '.' allows simpler code
1444 # in ResultSet->_collapse_result
37f23589 1445 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
0f66a01b 1446 keys %{$rel_info->{cond}};
5a5bec6c 1447 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1448 ? @{$rel_info->{attrs}{order_by}}
b82c8a28 1449
1450 : (defined $rel_info->{attrs}{order_by}
5a5bec6c 1451 ? ($rel_info->{attrs}{order_by})
1452 : ()));
1453 push(@$order, map { "${as}.$_" } (@key, @ord));
0f66a01b 1454 }
1455
489709af 1456 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
a86b1efe 1457 $rel_source->columns;
b3e8ac9b 1458 }
1459}
953a18ef 1460
87c4e602 1461=head2 related_source
1462
27f01d1f 1463=over 4
1464
ebc77b53 1465=item Arguments: $relname
27f01d1f 1466
391ccf38 1467=item Return value: $source
1468
27f01d1f 1469=back
87772e46 1470
2053ab2a 1471Returns the result source object for the given relationship.
87772e46 1472
1473=cut
1474
1475sub related_source {
1476 my ($self, $rel) = @_;
aea52c85 1477 if( !$self->has_relationship( $rel ) ) {
701da8c4 1478 $self->throw_exception("No such relationship '$rel'");
aea52c85 1479 }
87772e46 1480 return $self->schema->source($self->relationship_info($rel)->{source});
8452e496 1481}
1482
77254782 1483=head2 related_class
1484
27f01d1f 1485=over 4
1486
ebc77b53 1487=item Arguments: $relname
27f01d1f 1488
391ccf38 1489=item Return value: $classname
1490
27f01d1f 1491=back
77254782 1492
2053ab2a 1493Returns the class name for objects in the given relationship.
77254782 1494
1495=cut
1496
1497sub related_class {
1498 my ($self, $rel) = @_;
1499 if( !$self->has_relationship( $rel ) ) {
1500 $self->throw_exception("No such relationship '$rel'");
1501 }
1502 return $self->schema->class($self->relationship_info($rel)->{source});
1503}
1504
aec3eff1 1505=head2 handle
1506
1507Obtain a new handle to this source. Returns an instance of a
1508L<DBIx::Class::ResultSourceHandle>.
1509
1510=cut
1511
1512sub handle {
24c349e8 1513 return DBIx::Class::ResultSourceHandle->new({
aec3eff1 1514 schema => $_[0]->schema,
3441fd57 1515 source_moniker => $_[0]->source_name
aec3eff1 1516 });
1517}
1518
701da8c4 1519=head2 throw_exception
1520
2053ab2a 1521See L<DBIx::Class::Schema/"throw_exception">.
701da8c4 1522
1523=cut
1524
1525sub throw_exception {
1526 my $self = shift;
1a58752c 1527
0b4926ce 1528 if (defined $self->schema) {
701da8c4 1529 $self->schema->throw_exception(@_);
1a58752c 1530 }
1531 else {
1532 DBIx::Class::Exception->throw(@_);
701da8c4 1533 }
1534}
1535
843f6bc1 1536=head2 source_info
d2f3e87b 1537
843f6bc1 1538Stores a hashref of per-source metadata. No specific key names
1539have yet been standardized, the examples below are purely hypothetical
1540and don't actually accomplish anything on their own:
391ccf38 1541
843f6bc1 1542 __PACKAGE__->source_info({
1543 "_tablespace" => 'fast_disk_array_3',
1544 "_engine" => 'InnoDB',
1545 });
391ccf38 1546
843f6bc1 1547=head2 new
391ccf38 1548
843f6bc1 1549 $class->new();
391ccf38 1550
843f6bc1 1551 $class->new({attribute_name => value});
d2f3e87b 1552
843f6bc1 1553Creates a new ResultSource object. Not normally called directly by end users.
391ccf38 1554
843f6bc1 1555=head2 column_info_from_storage
1556
1557=over
1558
1559=item Arguments: 1/0 (default: 0)
1560
1561=item Return value: 1/0
1562
1563=back
1564
880c075b 1565 __PACKAGE__->column_info_from_storage(1);
1566
843f6bc1 1567Enables the on-demand automatic loading of the above column
c1300297 1568metadata from storage as necessary. This is *deprecated*, and
843f6bc1 1569should not be used. It will be removed before 1.0.
1570
f89bb832 1571
9c992ba1 1572=head1 AUTHORS
1573
1574Matt S. Trout <mst@shadowcatsystems.co.uk>
1575
1576=head1 LICENSE
1577
1578You may distribute this code under the same terms as Perl itself.
1579
1580=cut
1581
b25e9fa0 15821;