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