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