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