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