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