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