First step to add some sanity to _resolve_condition
[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::Carp;
12 use DBIx::Class::_Util 'is_literal_value';
13 use Devel::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 Result object:
99
100    $result->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: L<$result_source|/new>
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<Result|DBIx::Class::Manual::ResultClass> 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 column 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 || $self->name || 'Unknown source...?',
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: not defined
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: not defined
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: not defined
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
593   my $colinfo = $self->columns_info(\@cols);
594   for my $col (@cols) {
595     carp_unique(sprintf (
596       "Primary key of source '%s' includes the column '%s' which has its "
597     . "'is_nullable' attribute set to true. This is a mistake and will cause "
598     . 'various Result-object operations to fail',
599       $self->source_name || $self->name || 'Unknown source...?',
600       $col,
601     )) if $colinfo->{$col}{is_nullable};
602   }
603
604   $self->_primaries(\@cols);
605
606   $self->add_unique_constraint(primary => \@cols);
607 }
608
609 =head2 primary_columns
610
611 =over 4
612
613 =item Arguments: none
614
615 =item Return Value: Ordered list of primary column names
616
617 =back
618
619 Read-only accessor which returns the list of primary keys, supplied by
620 L</set_primary_key>.
621
622 =cut
623
624 sub primary_columns {
625   return @{shift->_primaries||[]};
626 }
627
628 # a helper method that will automatically die with a descriptive message if
629 # no pk is defined on the source in question. For internal use to save
630 # on if @pks... boilerplate
631 sub _pri_cols_or_die {
632   my $self = shift;
633   my @pcols = $self->primary_columns
634     or $self->throw_exception (sprintf(
635       "Operation requires a primary key to be declared on '%s' via set_primary_key",
636       # source_name is set only after schema-registration
637       $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
638     ));
639   return @pcols;
640 }
641
642 # same as above but mandating single-column PK (used by relationship condition
643 # inference)
644 sub _single_pri_col_or_die {
645   my $self = shift;
646   my ($pri, @too_many) = $self->_pri_cols_or_die;
647
648   $self->throw_exception( sprintf(
649     "Operation requires a single-column primary key declared on '%s'",
650     $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
651   )) if @too_many;
652   return $pri;
653 }
654
655
656 =head2 sequence
657
658 Manually define the correct sequence for your table, to avoid the overhead
659 associated with looking up the sequence automatically. The supplied sequence
660 will be applied to the L</column_info> of each L<primary_key|/set_primary_key>
661
662 =over 4
663
664 =item Arguments: $sequence_name
665
666 =item Return Value: not defined
667
668 =back
669
670 =cut
671
672 sub sequence {
673   my ($self,$seq) = @_;
674
675   my @pks = $self->primary_columns
676     or return;
677
678   $_->{sequence} = $seq
679     for values %{ $self->columns_info (\@pks) };
680 }
681
682
683 =head2 add_unique_constraint
684
685 =over 4
686
687 =item Arguments: $name?, \@colnames
688
689 =item Return Value: not defined
690
691 =back
692
693 Declare a unique constraint on this source. Call once for each unique
694 constraint.
695
696   # For UNIQUE (column1, column2)
697   __PACKAGE__->add_unique_constraint(
698     constraint_name => [ qw/column1 column2/ ],
699   );
700
701 Alternatively, you can specify only the columns:
702
703   __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
704
705 This will result in a unique constraint named
706 C<table_column1_column2>, where C<table> is replaced with the table
707 name.
708
709 Unique constraints are used, for example, when you pass the constraint
710 name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
711 only columns in the constraint are searched.
712
713 Throws an error if any of the given column names do not yet exist on
714 the result source.
715
716 =cut
717
718 sub add_unique_constraint {
719   my $self = shift;
720
721   if (@_ > 2) {
722     $self->throw_exception(
723         'add_unique_constraint() does not accept multiple constraints, use '
724       . 'add_unique_constraints() instead'
725     );
726   }
727
728   my $cols = pop @_;
729   if (ref $cols ne 'ARRAY') {
730     $self->throw_exception (
731       'Expecting an arrayref of constraint columns, got ' . ($cols||'NOTHING')
732     );
733   }
734
735   my $name = shift @_;
736
737   $name ||= $self->name_unique_constraint($cols);
738
739   foreach my $col (@$cols) {
740     $self->throw_exception("No such column $col on table " . $self->name)
741       unless $self->has_column($col);
742   }
743
744   my %unique_constraints = $self->unique_constraints;
745   $unique_constraints{$name} = $cols;
746   $self->_unique_constraints(\%unique_constraints);
747 }
748
749 =head2 add_unique_constraints
750
751 =over 4
752
753 =item Arguments: @constraints
754
755 =item Return Value: not defined
756
757 =back
758
759 Declare multiple unique constraints on this source.
760
761   __PACKAGE__->add_unique_constraints(
762     constraint_name1 => [ qw/column1 column2/ ],
763     constraint_name2 => [ qw/column2 column3/ ],
764   );
765
766 Alternatively, you can specify only the columns:
767
768   __PACKAGE__->add_unique_constraints(
769     [ qw/column1 column2/ ],
770     [ qw/column3 column4/ ]
771   );
772
773 This will result in unique constraints named C<table_column1_column2> and
774 C<table_column3_column4>, where C<table> is replaced with the table name.
775
776 Throws an error if any of the given column names do not yet exist on
777 the result source.
778
779 See also L</add_unique_constraint>.
780
781 =cut
782
783 sub add_unique_constraints {
784   my $self = shift;
785   my @constraints = @_;
786
787   if ( !(@constraints % 2) && first { ref $_ ne 'ARRAY' } @constraints ) {
788     # with constraint name
789     while (my ($name, $constraint) = splice @constraints, 0, 2) {
790       $self->add_unique_constraint($name => $constraint);
791     }
792   }
793   else {
794     # no constraint name
795     foreach my $constraint (@constraints) {
796       $self->add_unique_constraint($constraint);
797     }
798   }
799 }
800
801 =head2 name_unique_constraint
802
803 =over 4
804
805 =item Arguments: \@colnames
806
807 =item Return Value: Constraint name
808
809 =back
810
811   $source->table('mytable');
812   $source->name_unique_constraint(['col1', 'col2']);
813   # returns
814   'mytable_col1_col2'
815
816 Return a name for a unique constraint containing the specified
817 columns. The name is created by joining the table name and each column
818 name, using an underscore character.
819
820 For example, a constraint on a table named C<cd> containing the columns
821 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
822
823 This is used by L</add_unique_constraint> if you do not specify the
824 optional constraint name.
825
826 =cut
827
828 sub name_unique_constraint {
829   my ($self, $cols) = @_;
830
831   my $name = $self->name;
832   $name = $$name if (ref $name eq 'SCALAR');
833
834   return join '_', $name, @$cols;
835 }
836
837 =head2 unique_constraints
838
839 =over 4
840
841 =item Arguments: none
842
843 =item Return Value: Hash of unique constraint data
844
845 =back
846
847   $source->unique_constraints();
848
849 Read-only accessor which returns a hash of unique constraints on this
850 source.
851
852 The hash is keyed by constraint name, and contains an arrayref of
853 column names as values.
854
855 =cut
856
857 sub unique_constraints {
858   return %{shift->_unique_constraints||{}};
859 }
860
861 =head2 unique_constraint_names
862
863 =over 4
864
865 =item Arguments: none
866
867 =item Return Value: Unique constraint names
868
869 =back
870
871   $source->unique_constraint_names();
872
873 Returns the list of unique constraint names defined on this source.
874
875 =cut
876
877 sub unique_constraint_names {
878   my ($self) = @_;
879
880   my %unique_constraints = $self->unique_constraints;
881
882   return keys %unique_constraints;
883 }
884
885 =head2 unique_constraint_columns
886
887 =over 4
888
889 =item Arguments: $constraintname
890
891 =item Return Value: List of constraint columns
892
893 =back
894
895   $source->unique_constraint_columns('myconstraint');
896
897 Returns the list of columns that make up the specified unique constraint.
898
899 =cut
900
901 sub unique_constraint_columns {
902   my ($self, $constraint_name) = @_;
903
904   my %unique_constraints = $self->unique_constraints;
905
906   $self->throw_exception(
907     "Unknown unique constraint $constraint_name on '" . $self->name . "'"
908   ) unless exists $unique_constraints{$constraint_name};
909
910   return @{ $unique_constraints{$constraint_name} };
911 }
912
913 =head2 sqlt_deploy_callback
914
915 =over
916
917 =item Arguments: $callback_name | \&callback_code
918
919 =item Return Value: $callback_name | \&callback_code
920
921 =back
922
923   __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
924
925    or
926
927   __PACKAGE__->sqlt_deploy_callback(sub {
928     my ($source_instance, $sqlt_table) = @_;
929     ...
930   } );
931
932 An accessor to set a callback to be called during deployment of
933 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
934 L<DBIx::Class::Schema/deploy>.
935
936 The callback can be set as either a code reference or the name of a
937 method in the current result class.
938
939 Defaults to L</default_sqlt_deploy_hook>.
940
941 Your callback will be passed the $source object representing the
942 ResultSource instance being deployed, and the
943 L<SQL::Translator::Schema::Table> object being created from it. The
944 callback can be used to manipulate the table object or add your own
945 customised indexes. If you need to manipulate a non-table object, use
946 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
947
948 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
949 Your SQL> for examples.
950
951 This sqlt deployment callback can only be used to manipulate
952 SQL::Translator objects as they get turned into SQL. To execute
953 post-deploy statements which SQL::Translator does not currently
954 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
955 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
956
957 =head2 default_sqlt_deploy_hook
958
959 This is the default deploy hook implementation which checks if your
960 current Result class has a C<sqlt_deploy_hook> method, and if present
961 invokes it B<on the Result class directly>. This is to preserve the
962 semantics of C<sqlt_deploy_hook> which was originally designed to expect
963 the Result class name and the
964 L<$sqlt_table instance|SQL::Translator::Schema::Table> of the table being
965 deployed.
966
967 =cut
968
969 sub default_sqlt_deploy_hook {
970   my $self = shift;
971
972   my $class = $self->result_class;
973
974   if ($class and $class->can('sqlt_deploy_hook')) {
975     $class->sqlt_deploy_hook(@_);
976   }
977 }
978
979 sub _invoke_sqlt_deploy_hook {
980   my $self = shift;
981   if ( my $hook = $self->sqlt_deploy_callback) {
982     $self->$hook(@_);
983   }
984 }
985
986 =head2 result_class
987
988 =over 4
989
990 =item Arguments: $classname
991
992 =item Return Value: $classname
993
994 =back
995
996  use My::Schema::ResultClass::Inflator;
997  ...
998
999  use My::Schema::Artist;
1000  ...
1001  __PACKAGE__->result_class('My::Schema::ResultClass::Inflator');
1002
1003 Set the default result class for this source. You can use this to create
1004 and use your own result inflator. See L<DBIx::Class::ResultSet/result_class>
1005 for more details.
1006
1007 Please note that setting this to something like
1008 L<DBIx::Class::ResultClass::HashRefInflator> will make every result unblessed
1009 and make life more difficult.  Inflators like those are better suited to
1010 temporary usage via L<DBIx::Class::ResultSet/result_class>.
1011
1012 =head2 resultset
1013
1014 =over 4
1015
1016 =item Arguments: none
1017
1018 =item Return Value: L<$resultset|DBIx::Class::ResultSet>
1019
1020 =back
1021
1022 Returns a resultset for the given source. This will initially be created
1023 on demand by calling
1024
1025   $self->resultset_class->new($self, $self->resultset_attributes)
1026
1027 but is cached from then on unless resultset_class changes.
1028
1029 =head2 resultset_class
1030
1031 =over 4
1032
1033 =item Arguments: $classname
1034
1035 =item Return Value: $classname
1036
1037 =back
1038
1039   package My::Schema::ResultSet::Artist;
1040   use base 'DBIx::Class::ResultSet';
1041   ...
1042
1043   # In the result class
1044   __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
1045
1046   # Or in code
1047   $source->resultset_class('My::Schema::ResultSet::Artist');
1048
1049 Set the class of the resultset. This is useful if you want to create your
1050 own resultset methods. Create your own class derived from
1051 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
1052 this method returns the name of the existing resultset class, if one
1053 exists.
1054
1055 =head2 resultset_attributes
1056
1057 =over 4
1058
1059 =item Arguments: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
1060
1061 =item Return Value: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
1062
1063 =back
1064
1065   # In the result class
1066   __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
1067
1068   # Or in code
1069   $source->resultset_attributes({ order_by => [ 'id' ] });
1070
1071 Store a collection of resultset attributes, that will be set on every
1072 L<DBIx::Class::ResultSet> produced from this result source.
1073
1074 B<CAVEAT>: C<resultset_attributes> comes with its own set of issues and
1075 bugs! While C<resultset_attributes> isn't deprecated per se, its usage is
1076 not recommended!
1077
1078 Since relationships use attributes to link tables together, the "default"
1079 attributes you set may cause unpredictable and undesired behavior.  Furthermore,
1080 the defaults cannot be turned off, so you are stuck with them.
1081
1082 In most cases, what you should actually be using are project-specific methods:
1083
1084   package My::Schema::ResultSet::Artist;
1085   use base 'DBIx::Class::ResultSet';
1086   ...
1087
1088   # BAD IDEA!
1089   #__PACKAGE__->resultset_attributes({ prefetch => 'tracks' });
1090
1091   # GOOD IDEA!
1092   sub with_tracks { shift->search({}, { prefetch => 'tracks' }) }
1093
1094   # in your code
1095   $schema->resultset('Artist')->with_tracks->...
1096
1097 This gives you the flexibility of not using it when you don't need it.
1098
1099 For more complex situations, another solution would be to use a virtual view
1100 via L<DBIx::Class::ResultSource::View>.
1101
1102 =cut
1103
1104 sub resultset {
1105   my $self = shift;
1106   $self->throw_exception(
1107     'resultset does not take any arguments. If you want another resultset, '.
1108     'call it on the schema instead.'
1109   ) if scalar @_;
1110
1111   $self->resultset_class->new(
1112     $self,
1113     {
1114       try { %{$self->schema->default_resultset_attributes} },
1115       %{$self->{resultset_attributes}},
1116     },
1117   );
1118 }
1119
1120 =head2 name
1121
1122 =over 4
1123
1124 =item Arguments: none
1125
1126 =item Result value: $name
1127
1128 =back
1129
1130 Returns the name of the result source, which will typically be the table
1131 name. This may be a scalar reference if the result source has a non-standard
1132 name.
1133
1134 =head2 source_name
1135
1136 =over 4
1137
1138 =item Arguments: $source_name
1139
1140 =item Result value: $source_name
1141
1142 =back
1143
1144 Set an alternate name for the result source when it is loaded into a schema.
1145 This is useful if you want to refer to a result source by a name other than
1146 its class name.
1147
1148   package ArchivedBooks;
1149   use base qw/DBIx::Class/;
1150   __PACKAGE__->table('books_archive');
1151   __PACKAGE__->source_name('Books');
1152
1153   # from your schema...
1154   $schema->resultset('Books')->find(1);
1155
1156 =head2 from
1157
1158 =over 4
1159
1160 =item Arguments: none
1161
1162 =item Return Value: FROM clause
1163
1164 =back
1165
1166   my $from_clause = $source->from();
1167
1168 Returns an expression of the source to be supplied to storage to specify
1169 retrieval from this source. In the case of a database, the required FROM
1170 clause contents.
1171
1172 =cut
1173
1174 sub from { die 'Virtual method!' }
1175
1176 =head2 schema
1177
1178 =over 4
1179
1180 =item Arguments: L<$schema?|DBIx::Class::Schema>
1181
1182 =item Return Value: L<$schema|DBIx::Class::Schema>
1183
1184 =back
1185
1186   my $schema = $source->schema();
1187
1188 Sets and/or returns the L<DBIx::Class::Schema> object to which this
1189 result source instance has been attached to.
1190
1191 =cut
1192
1193 sub schema {
1194   if (@_ > 1) {
1195     $_[0]->{schema} = $_[1];
1196   }
1197   else {
1198     $_[0]->{schema} || do {
1199       my $name = $_[0]->{source_name} || '_unnamed_';
1200       my $err = 'Unable to perform storage-dependent operations with a detached result source '
1201               . "(source '$name' is not associated with a schema).";
1202
1203       $err .= ' You need to use $schema->thaw() or manually set'
1204             . ' $DBIx::Class::ResultSourceHandle::thaw_schema while thawing.'
1205         if $_[0]->{_detached_thaw};
1206
1207       DBIx::Class::Exception->throw($err);
1208     };
1209   }
1210 }
1211
1212 =head2 storage
1213
1214 =over 4
1215
1216 =item Arguments: none
1217
1218 =item Return Value: L<$storage|DBIx::Class::Storage>
1219
1220 =back
1221
1222   $source->storage->debug(1);
1223
1224 Returns the L<storage handle|DBIx::Class::Storage> for the current schema.
1225
1226 =cut
1227
1228 sub storage { shift->schema->storage; }
1229
1230 =head2 add_relationship
1231
1232 =over 4
1233
1234 =item Arguments: $rel_name, $related_source_name, \%cond, \%attrs?
1235
1236 =item Return Value: 1/true if it succeeded
1237
1238 =back
1239
1240   $source->add_relationship('rel_name', 'related_source', $cond, $attrs);
1241
1242 L<DBIx::Class::Relationship> describes a series of methods which
1243 create pre-defined useful types of relationships. Look there first
1244 before using this method directly.
1245
1246 The relationship name can be arbitrary, but must be unique for each
1247 relationship attached to this result source. 'related_source' should
1248 be the name with which the related result source was registered with
1249 the current schema. For example:
1250
1251   $schema->source('Book')->add_relationship('reviews', 'Review', {
1252     'foreign.book_id' => 'self.id',
1253   });
1254
1255 The condition C<$cond> needs to be an L<SQL::Abstract>-style
1256 representation of the join between the tables. For example, if you're
1257 creating a relation from Author to Book,
1258
1259   { 'foreign.author_id' => 'self.id' }
1260
1261 will result in the JOIN clause
1262
1263   author me JOIN book foreign ON foreign.author_id = me.id
1264
1265 You can specify as many foreign => self mappings as necessary.
1266
1267 Valid attributes are as follows:
1268
1269 =over 4
1270
1271 =item join_type
1272
1273 Explicitly specifies the type of join to use in the relationship. Any
1274 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
1275 the SQL command immediately before C<JOIN>.
1276
1277 =item proxy
1278
1279 An arrayref containing a list of accessors in the foreign class to proxy in
1280 the main class. If, for example, you do the following:
1281
1282   CD->might_have(liner_notes => 'LinerNotes', undef, {
1283     proxy => [ qw/notes/ ],
1284   });
1285
1286 Then, assuming LinerNotes has an accessor named notes, you can do:
1287
1288   my $cd = CD->find(1);
1289   # set notes -- LinerNotes object is created if it doesn't exist
1290   $cd->notes('Notes go here');
1291
1292 =item accessor
1293
1294 Specifies the type of accessor that should be created for the
1295 relationship. Valid values are C<single> (for when there is only a single
1296 related object), C<multi> (when there can be many), and C<filter> (for
1297 when there is a single related object, but you also want the relationship
1298 accessor to double as a column accessor). For C<multi> accessors, an
1299 add_to_* method is also created, which calls C<create_related> for the
1300 relationship.
1301
1302 =back
1303
1304 Throws an exception if the condition is improperly supplied, or cannot
1305 be resolved.
1306
1307 =cut
1308
1309 sub add_relationship {
1310   my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
1311   $self->throw_exception("Can't create relationship without join condition")
1312     unless $cond;
1313   $attrs ||= {};
1314
1315   # Check foreign and self are right in cond
1316   if ( (ref $cond ||'') eq 'HASH') {
1317     for (keys %$cond) {
1318       $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
1319         if /\./ && !/^foreign\./;
1320     }
1321   }
1322
1323   my %rels = %{ $self->_relationships };
1324   $rels{$rel} = { class => $f_source_name,
1325                   source => $f_source_name,
1326                   cond  => $cond,
1327                   attrs => $attrs };
1328   $self->_relationships(\%rels);
1329
1330   return $self;
1331
1332 # XXX disabled. doesn't work properly currently. skip in tests.
1333
1334   my $f_source = $self->schema->source($f_source_name);
1335   unless ($f_source) {
1336     $self->ensure_class_loaded($f_source_name);
1337     $f_source = $f_source_name->result_source;
1338     #my $s_class = ref($self->schema);
1339     #$f_source_name =~ m/^${s_class}::(.*)$/;
1340     #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1341     #$f_source = $self->schema->source($f_source_name);
1342   }
1343   return unless $f_source; # Can't test rel without f_source
1344
1345   try { $self->_resolve_join($rel, 'me', {}, []) }
1346   catch {
1347     # If the resolve failed, back out and re-throw the error
1348     delete $rels{$rel};
1349     $self->_relationships(\%rels);
1350     $self->throw_exception("Error creating relationship $rel: $_");
1351   };
1352
1353   1;
1354 }
1355
1356 =head2 relationships
1357
1358 =over 4
1359
1360 =item Arguments: none
1361
1362 =item Return Value: L<@rel_names|DBIx::Class::Relationship>
1363
1364 =back
1365
1366   my @relnames = $source->relationships();
1367
1368 Returns all relationship names for this source.
1369
1370 =cut
1371
1372 sub relationships {
1373   return keys %{shift->_relationships};
1374 }
1375
1376 =head2 relationship_info
1377
1378 =over 4
1379
1380 =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1381
1382 =item Return Value: L<\%rel_data|DBIx::Class::Relationship::Base/add_relationship>
1383
1384 =back
1385
1386 Returns a hash of relationship information for the specified relationship
1387 name. The keys/values are as specified for L<DBIx::Class::Relationship::Base/add_relationship>.
1388
1389 =cut
1390
1391 sub relationship_info {
1392   #my ($self, $rel) = @_;
1393   return shift->_relationships->{+shift};
1394 }
1395
1396 =head2 has_relationship
1397
1398 =over 4
1399
1400 =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1401
1402 =item Return Value: 1/0 (true/false)
1403
1404 =back
1405
1406 Returns true if the source has a relationship of this name, false otherwise.
1407
1408 =cut
1409
1410 sub has_relationship {
1411   #my ($self, $rel) = @_;
1412   return exists shift->_relationships->{+shift};
1413 }
1414
1415 =head2 reverse_relationship_info
1416
1417 =over 4
1418
1419 =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1420
1421 =item Return Value: L<\%rel_data|DBIx::Class::Relationship::Base/add_relationship>
1422
1423 =back
1424
1425 Looks through all the relationships on the source this relationship
1426 points to, looking for one whose condition is the reverse of the
1427 condition on this relationship.
1428
1429 A common use of this is to find the name of the C<belongs_to> relation
1430 opposing a C<has_many> relation. For definition of these look in
1431 L<DBIx::Class::Relationship>.
1432
1433 The returned hashref is keyed by the name of the opposing
1434 relationship, and contains its data in the same manner as
1435 L</relationship_info>.
1436
1437 =cut
1438
1439 sub reverse_relationship_info {
1440   my ($self, $rel) = @_;
1441
1442   my $rel_info = $self->relationship_info($rel)
1443     or $self->throw_exception("No such relationship '$rel'");
1444
1445   my $ret = {};
1446
1447   return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1448
1449   my $stripped_cond = $self->__strip_relcond ($rel_info->{cond});
1450
1451   my $registered_source_name = $self->source_name;
1452
1453   # this may be a partial schema or something else equally esoteric
1454   my $other_rsrc = $self->related_source($rel);
1455
1456   # Get all the relationships for that source that related to this source
1457   # whose foreign column set are our self columns on $rel and whose self
1458   # columns are our foreign columns on $rel
1459   foreach my $other_rel ($other_rsrc->relationships) {
1460
1461     # only consider stuff that points back to us
1462     # "us" here is tricky - if we are in a schema registration, we want
1463     # to use the source_names, otherwise we will use the actual classes
1464
1465     # the schema may be partial
1466     my $roundtrip_rsrc = try { $other_rsrc->related_source($other_rel) }
1467       or next;
1468
1469     if ($registered_source_name) {
1470       next if $registered_source_name ne ($roundtrip_rsrc->source_name || '')
1471     }
1472     else {
1473       next if $self->result_class ne $roundtrip_rsrc->result_class;
1474     }
1475
1476     my $other_rel_info = $other_rsrc->relationship_info($other_rel);
1477
1478     # this can happen when we have a self-referential class
1479     next if $other_rel_info eq $rel_info;
1480
1481     next unless ref $other_rel_info->{cond} eq 'HASH';
1482     my $other_stripped_cond = $self->__strip_relcond($other_rel_info->{cond});
1483
1484     $ret->{$other_rel} = $other_rel_info if (
1485       $self->_compare_relationship_keys (
1486         [ keys %$stripped_cond ], [ values %$other_stripped_cond ]
1487       )
1488         and
1489       $self->_compare_relationship_keys (
1490         [ values %$stripped_cond ], [ keys %$other_stripped_cond ]
1491       )
1492     );
1493   }
1494
1495   return $ret;
1496 }
1497
1498 # all this does is removes the foreign/self prefix from a condition
1499 sub __strip_relcond {
1500   +{
1501     map
1502       { map { /^ (?:foreign|self) \. (\w+) $/x } ($_, $_[1]{$_}) }
1503       keys %{$_[1]}
1504   }
1505 }
1506
1507 sub compare_relationship_keys {
1508   carp 'compare_relationship_keys is a private method, stop calling it';
1509   my $self = shift;
1510   $self->_compare_relationship_keys (@_);
1511 }
1512
1513 # Returns true if both sets of keynames are the same, false otherwise.
1514 sub _compare_relationship_keys {
1515 #  my ($self, $keys1, $keys2) = @_;
1516   return
1517     join ("\x00", sort @{$_[1]})
1518       eq
1519     join ("\x00", sort @{$_[2]})
1520   ;
1521 }
1522
1523 # optionally takes either an arrayref of column names, or a hashref of already
1524 # retrieved colinfos
1525 # returns an arrayref of column names of the shortest unique constraint
1526 # (matching some of the input if any), giving preference to the PK
1527 sub _identifying_column_set {
1528   my ($self, $cols) = @_;
1529
1530   my %unique = $self->unique_constraints;
1531   my $colinfos = ref $cols eq 'HASH' ? $cols : $self->columns_info($cols||());
1532
1533   # always prefer the PK first, and then shortest constraints first
1534   USET:
1535   for my $set (delete $unique{primary}, sort { @$a <=> @$b } (values %unique) ) {
1536     next unless $set && @$set;
1537
1538     for (@$set) {
1539       next USET unless ($colinfos->{$_} && !$colinfos->{$_}{is_nullable} );
1540     }
1541
1542     # copy so we can mangle it at will
1543     return [ @$set ];
1544   }
1545
1546   return undef;
1547 }
1548
1549 # Returns the {from} structure used to express JOIN conditions
1550 sub _resolve_join {
1551   my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1552
1553   # we need a supplied one, because we do in-place modifications, no returns
1554   $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1555     unless ref $seen eq 'HASH';
1556
1557   $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1558     unless ref $jpath eq 'ARRAY';
1559
1560   $jpath = [@$jpath]; # copy
1561
1562   if (not defined $join or not length $join) {
1563     return ();
1564   }
1565   elsif (ref $join eq 'ARRAY') {
1566     return
1567       map {
1568         $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
1569       } @$join;
1570   }
1571   elsif (ref $join eq 'HASH') {
1572
1573     my @ret;
1574     for my $rel (keys %$join) {
1575
1576       my $rel_info = $self->relationship_info($rel)
1577         or $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1578
1579       my $force_left = $parent_force_left;
1580       $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1581
1582       # the actual seen value will be incremented by the recursion
1583       my $as = $self->storage->relname_to_table_alias(
1584         $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1585       );
1586
1587       push @ret, (
1588         $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1589         $self->related_source($rel)->_resolve_join(
1590           $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
1591         )
1592       );
1593     }
1594     return @ret;
1595
1596   }
1597   elsif (ref $join) {
1598     $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1599   }
1600   else {
1601     my $count = ++$seen->{$join};
1602     my $as = $self->storage->relname_to_table_alias(
1603       $join, ($count > 1 && $count)
1604     );
1605
1606     my $rel_info = $self->relationship_info($join)
1607       or $self->throw_exception("No such relationship $join on " . $self->source_name);
1608
1609     my $rel_src = $self->related_source($join);
1610     return [ { $as => $rel_src->from,
1611                -rsrc => $rel_src,
1612                -join_type => $parent_force_left
1613                   ? 'left'
1614                   : $rel_info->{attrs}{join_type}
1615                 ,
1616                -join_path => [@$jpath, { $join => $as } ],
1617                -is_single => (
1618                   (! $rel_info->{attrs}{accessor})
1619                     or
1620                   first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
1621                 ),
1622                -alias => $as,
1623                -relation_chain_depth => ( $seen->{-relation_chain_depth} || 0 ) + 1,
1624              },
1625              scalar $self->_resolve_condition($rel_info->{cond}, $as, $alias, $join)
1626           ];
1627   }
1628 }
1629
1630 sub pk_depends_on {
1631   carp 'pk_depends_on is a private method, stop calling it';
1632   my $self = shift;
1633   $self->_pk_depends_on (@_);
1634 }
1635
1636 # Determines whether a relation is dependent on an object from this source
1637 # having already been inserted. Takes the name of the relationship and a
1638 # hashref of columns of the related object.
1639 sub _pk_depends_on {
1640   my ($self, $rel_name, $rel_data) = @_;
1641
1642   my $relinfo = $self->relationship_info($rel_name);
1643
1644   # don't assume things if the relationship direction is specified
1645   return $relinfo->{attrs}{is_foreign_key_constraint}
1646     if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1647
1648   my $cond = $relinfo->{cond};
1649   return 0 unless ref($cond) eq 'HASH';
1650
1651   # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1652   my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1653
1654   # assume anything that references our PK probably is dependent on us
1655   # rather than vice versa, unless the far side is (a) defined or (b)
1656   # auto-increment
1657   my $rel_source = $self->related_source($rel_name);
1658
1659   foreach my $p ($self->primary_columns) {
1660     if (exists $keyhash->{$p}) {
1661       unless (defined($rel_data->{$keyhash->{$p}})
1662               || $rel_source->column_info($keyhash->{$p})
1663                             ->{is_auto_increment}) {
1664         return 0;
1665       }
1666     }
1667   }
1668
1669   return 1;
1670 }
1671
1672 sub _resolve_condition {
1673 #  carp_unique sprintf
1674 #    '_resolve_condition is a private method, and moreover is about to go '
1675 #  . 'away. Please contact the development team at %s if you believe you '
1676 #  . 'have a genuine use for this method, in order to discuss alternatives.',
1677 #    DBIx::Class::_ENV_::HELP_URL,
1678 #  ;
1679
1680 #######################
1681 ### API Design? What's that...? (a backwards compatible shim, kill me now)
1682
1683   my ($self, $cond, @res_args, $rel_name);
1684
1685   # we *SIMPLY DON'T KNOW YET* which arg is which, yay
1686   ($self, $cond, $res_args[0], $res_args[1], $rel_name) = @_;
1687
1688   # assume that an undef is an object-like unset (set_from_related(undef))
1689   my @is_objlike = map { ! defined $_ or length ref $_ } (@res_args);
1690
1691   # turn objlike into proper objects for saner code further down
1692   for (0,1) {
1693     next unless $is_objlike[$_];
1694
1695     if ( defined blessed $res_args[$_] ) {
1696
1697       # but wait - there is more!!! WHAT THE FUCK?!?!?!?!
1698       if ($res_args[$_]->isa('DBIx::Class::ResultSet')) {
1699         carp('Passing a resultset for relationship resolution makes no sense - invoking __gremlins__');
1700         $is_objlike[$_] = 0;
1701         $res_args[$_] = '__gremlins__';
1702       }
1703     }
1704     else {
1705       $res_args[$_] ||= {};
1706
1707       $self->throw_exception("Unsupported object-like structure encountered: $res_args[$_]")
1708         unless ref $res_args[$_] eq 'HASH';
1709
1710       # hate everywhere
1711       $res_args[$_] = $self->relationship_info($rel_name)->{source}->result_class->new($res_args[$_]);
1712     }
1713   }
1714
1715   $self->throw_exception('No practical way to resolve a relationship between two structures')
1716     if $is_objlike[0] and $is_objlike[1];
1717
1718   my $args = {
1719     condition => $cond,
1720     rel_name => $rel_name,
1721     $is_objlike[1] ? ( self_alias => $res_args[0], foreign_alias => 'me',         self_resultobj    => $res_args[1] )
1722   : $is_objlike[0] ? ( self_alias => 'me',         foreign_alias => $res_args[1], foreign_resultobj => $res_args[0] )
1723   :                  ( self_alias => $res_args[1], foreign_alias => $res_args[0] )
1724   };
1725 #######################
1726
1727   # now it's fucking easy isn't it?!
1728   my @res = $self->_resolve_relationship_condition( $args );
1729
1730   # FIXME - this is also insane, but just be consistent for now
1731   # _resolve_relationship_condition always returns qualified cols
1732   # even in the case of objects, but nothing downstream expects this
1733   if (ref $res[0] eq 'HASH' and ($is_objlike[0] or $is_objlike[1]) ) {
1734     $res[0] = { map
1735       { ($_ =~ /\.(.+)/) => $res[0]{$_} }
1736       keys %{$res[0]}
1737     };
1738   }
1739
1740   # more legacy
1741   return wantarray ? @res : $res[0];
1742 }
1743
1744 our $UNRESOLVABLE_CONDITION = \ '1 = 0';
1745
1746 # Resolves the passed condition to a concrete query fragment and a flag
1747 # indicating whether this is a cross-table condition. Also an optional
1748 # list of non-trivial values (normally conditions) returned as a part
1749 # of a joinfree condition hash
1750 sub _resolve_relationship_condition {
1751   my $self = shift;
1752
1753   # self-explanatory API, modeled on the custom cond coderef:
1754   # condition
1755   # rel_name
1756   # foreign_alias
1757   # foreign_resultobj
1758   # self_alias
1759   # self_resultobj
1760   my $args = { ref $_[0] eq 'HASH' ? %{ $_[0] } : @_ };
1761
1762   for ( qw( rel_name self_alias foreign_alias ) ) {
1763     $self->throw_exception("Mandatory attribute '$_' is not a plain string")
1764       if !defined $args->{$_} or length ref $args->{$_};
1765   }
1766
1767   $self->throw_exception('No practical way to resolve a relationship between two objects')
1768     if defined $args->{self_resultobj} and defined $args->{foreign_resultobj};
1769
1770   $args->{condition} ||= $self->relationship_info($args->{rel_name})->{cond};
1771
1772   if (ref $args->{condition} eq 'CODE') {
1773
1774     my ($crosstable_cond, $joinfree_cond) = $args->{condition}->({
1775       self_alias => $args->{self_alias},
1776       foreign_alias => $args->{foreign_alias},
1777       self_resultsource => $self,
1778       foreign_relname => $args->{rel_name},
1779       self_rowobj => defined $args->{self_resultobj} ? $args->{self_resultobj} : undef,
1780     });
1781
1782     my @nonvalue_cols;
1783     if ($joinfree_cond) {
1784
1785       # FIXME sanity check until things stabilize, remove at some point
1786       $self->throw_exception (
1787         "A join-free condition returned for relationship '$args->{rel_name}' without a row-object to chain from"
1788       ) unless defined $args->{self_resultobj};
1789
1790       my $foreign_src_fq_col_list = { map { ( "$args->{foreign_alias}.$_" => 1 ) } $self->related_source($args->{rel_name})->columns };
1791
1792       # FIXME another sanity check
1793       if (
1794         ref $joinfree_cond ne 'HASH'
1795           or
1796         grep { ! $foreign_src_fq_col_list->{$_} } keys %$joinfree_cond
1797       ) {
1798         $self->throw_exception (
1799           "The join-free condition returned for relationship '$args->{rel_name}' must be a hash "
1800          .'reference with all keys being fully qualified column names of the foreign source'
1801         );
1802       }
1803
1804       # see which parts of the joinfree cond are *NOT* foreign-source-column equalities
1805       my $joinfree_cond_equality_columns = { map
1806         {( $_ => 1 )}
1807         @{ $self->schema->storage->_extract_fixed_condition_columns($joinfree_cond) }
1808       };
1809       @nonvalue_cols = map
1810         { $_ =~ /^\Q$args->{foreign_alias}.\E(.+)/ }
1811         grep
1812           { ! $joinfree_cond_equality_columns->{$_} }
1813           keys %$joinfree_cond;
1814
1815       return ($joinfree_cond, 0, (@nonvalue_cols ? \@nonvalue_cols : undef));
1816     }
1817     else {
1818       return ($crosstable_cond, 1);
1819     }
1820   }
1821   elsif (ref $args->{condition} eq 'HASH') {
1822
1823     # the condition is static - use parallel arrays
1824     # for a "pivot" depending on which side of the
1825     # rel did we get as an object
1826     my (@f_cols, @l_cols);
1827     for my $fc (keys %{$args->{condition}}) {
1828       my $lc = $args->{condition}{$fc};
1829
1830       # FIXME STRICTMODE should probably check these are valid columns
1831       $fc =~ s/^foreign\.// ||
1832         $self->throw_exception("Invalid rel cond key '$fc'");
1833
1834       $lc =~ s/^self\.// ||
1835         $self->throw_exception("Invalid rel cond val '$lc'");
1836
1837       push @f_cols, $fc;
1838       push @l_cols, $lc;
1839     }
1840
1841     # plain values
1842     if (! defined $args->{self_resultobj} and ! defined $args->{foreign_resultobj}) {
1843       return ( { map
1844         {( "$args->{foreign_alias}.$f_cols[$_]" => { -ident => "$args->{self_alias}.$l_cols[$_]" } )}
1845         (0..$#f_cols)
1846       }, 1 ); # is crosstable
1847     }
1848     else {
1849
1850       my $cond;
1851
1852       my ($obj, $obj_alias, $plain_alias, $obj_cols, $plain_cols) = defined $args->{self_resultobj}
1853         ? ( @{$args}{qw( self_resultobj self_alias foreign_alias )}, \@l_cols, \@f_cols )
1854         : ( @{$args}{qw( foreign_resultobj foreign_alias self_alias )}, \@f_cols, \@l_cols )
1855       ;
1856
1857       for my $i (0..$#$obj_cols) {
1858         if (defined $args->{self_resultobj} and ! $obj->has_column_loaded($obj_cols->[$i])) {
1859
1860           $self->throw_exception(sprintf
1861             "Unable to resolve relationship '%s' from object '%s': column '%s' not "
1862           . 'loaded from storage (or not passed to new() prior to insert()). You '
1863           . 'probably need to call ->discard_changes to get the server-side defaults '
1864           . 'from the database.',
1865             $args->{rel_name},
1866             $obj,
1867             $obj_cols->[$i],
1868           ) if $obj->in_storage;
1869
1870           return $UNRESOLVABLE_CONDITION;
1871         }
1872         else {
1873           $cond->{"$plain_alias.$plain_cols->[$i]"} = $obj->get_column($obj_cols->[$i]);
1874         }
1875       }
1876
1877       return ($cond, 0); # joinfree
1878     }
1879   }
1880   elsif (ref $args->{condition} eq 'ARRAY') {
1881     if (@{$args->{condition}} == 0) {
1882       return $UNRESOLVABLE_CONDITION;
1883     }
1884     elsif (@{$args->{condition}} == 1) {
1885       return $self->_resolve_relationship_condition({
1886         %$args,
1887         condition => $args->{condition}[0],
1888       });
1889     }
1890     else {
1891       # FIXME - we are discarding nonvalues here... likely incorrect...
1892       # then again - the entire thing is an OR, so we *can't* use
1893       # the values anyway
1894       # Return a hard crosstable => 1 to ensure nothing tries to use
1895       # the result in such manner
1896       my @ret;
1897       for (@{$args->{condition}}) {
1898         my ($cond) = $self->_resolve_relationship_condition({
1899           %$args,
1900           condition => $_,
1901         });
1902         push @ret, $cond;
1903       }
1904       return (\@ret, 1); # forced cross-tab
1905     }
1906   }
1907   else {
1908     $self->throw_exception ("Can't handle condition $args->{condition} for relationship '$args->{rel_name}' yet :(");
1909   }
1910
1911   die "not supposed to get here - missing return()";
1912 }
1913
1914 =head2 related_source
1915
1916 =over 4
1917
1918 =item Arguments: $rel_name
1919
1920 =item Return Value: $source
1921
1922 =back
1923
1924 Returns the result source object for the given relationship.
1925
1926 =cut
1927
1928 sub related_source {
1929   my ($self, $rel) = @_;
1930   if( !$self->has_relationship( $rel ) ) {
1931     $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1932   }
1933
1934   # if we are not registered with a schema - just use the prototype
1935   # however if we do have a schema - ask for the source by name (and
1936   # throw in the process if all fails)
1937   if (my $schema = try { $self->schema }) {
1938     $schema->source($self->relationship_info($rel)->{source});
1939   }
1940   else {
1941     my $class = $self->relationship_info($rel)->{class};
1942     $self->ensure_class_loaded($class);
1943     $class->result_source_instance;
1944   }
1945 }
1946
1947 =head2 related_class
1948
1949 =over 4
1950
1951 =item Arguments: $rel_name
1952
1953 =item Return Value: $classname
1954
1955 =back
1956
1957 Returns the class name for objects in the given relationship.
1958
1959 =cut
1960
1961 sub related_class {
1962   my ($self, $rel) = @_;
1963   if( !$self->has_relationship( $rel ) ) {
1964     $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1965   }
1966   return $self->schema->class($self->relationship_info($rel)->{source});
1967 }
1968
1969 =head2 handle
1970
1971 =over 4
1972
1973 =item Arguments: none
1974
1975 =item Return Value: L<$source_handle|DBIx::Class::ResultSourceHandle>
1976
1977 =back
1978
1979 Obtain a new L<result source handle instance|DBIx::Class::ResultSourceHandle>
1980 for this source. Used as a serializable pointer to this resultsource, as it is not
1981 easy (nor advisable) to serialize CODErefs which may very well be present in e.g.
1982 relationship definitions.
1983
1984 =cut
1985
1986 sub handle {
1987   return DBIx::Class::ResultSourceHandle->new({
1988     source_moniker => $_[0]->source_name,
1989
1990     # so that a detached thaw can be re-frozen
1991     $_[0]->{_detached_thaw}
1992       ? ( _detached_source  => $_[0]          )
1993       : ( schema            => $_[0]->schema  )
1994     ,
1995   });
1996 }
1997
1998 my $global_phase_destroy;
1999 sub DESTROY {
2000   return if $global_phase_destroy ||= in_global_destruction;
2001
2002 ######
2003 # !!! ACHTUNG !!!!
2004 ######
2005 #
2006 # Under no circumstances shall $_[0] be stored anywhere else (like copied to
2007 # a lexical variable, or shifted, or anything else). Doing so will mess up
2008 # the refcount of this particular result source, and will allow the $schema
2009 # we are trying to save to reattach back to the source we are destroying.
2010 # The relevant code checking refcounts is in ::Schema::DESTROY()
2011
2012   # if we are not a schema instance holder - we don't matter
2013   return if(
2014     ! ref $_[0]->{schema}
2015       or
2016     isweak $_[0]->{schema}
2017   );
2018
2019   # weaken our schema hold forcing the schema to find somewhere else to live
2020   # during global destruction (if we have not yet bailed out) this will throw
2021   # which will serve as a signal to not try doing anything else
2022   # however beware - on older perls the exception seems randomly untrappable
2023   # due to some weird race condition during thread joining :(((
2024   local $@;
2025   eval {
2026     weaken $_[0]->{schema};
2027
2028     # if schema is still there reintroduce ourselves with strong refs back to us
2029     if ($_[0]->{schema}) {
2030       my $srcregs = $_[0]->{schema}->source_registrations;
2031       for (keys %$srcregs) {
2032         next unless $srcregs->{$_};
2033         $srcregs->{$_} = $_[0] if $srcregs->{$_} == $_[0];
2034       }
2035     }
2036
2037     1;
2038   } or do {
2039     $global_phase_destroy = 1;
2040   };
2041
2042   return;
2043 }
2044
2045 sub STORABLE_freeze { Storable::nfreeze($_[0]->handle) }
2046
2047 sub STORABLE_thaw {
2048   my ($self, $cloning, $ice) = @_;
2049   %$self = %{ (Storable::thaw($ice))->resolve };
2050 }
2051
2052 =head2 throw_exception
2053
2054 See L<DBIx::Class::Schema/"throw_exception">.
2055
2056 =cut
2057
2058 sub throw_exception {
2059   my $self = shift;
2060
2061   $self->{schema}
2062     ? $self->{schema}->throw_exception(@_)
2063     : DBIx::Class::Exception->throw(@_)
2064   ;
2065 }
2066
2067 =head2 source_info
2068
2069 Stores a hashref of per-source metadata.  No specific key names
2070 have yet been standardized, the examples below are purely hypothetical
2071 and don't actually accomplish anything on their own:
2072
2073   __PACKAGE__->source_info({
2074     "_tablespace" => 'fast_disk_array_3',
2075     "_engine" => 'InnoDB',
2076   });
2077
2078 =head2 new
2079
2080   $class->new();
2081
2082   $class->new({attribute_name => value});
2083
2084 Creates a new ResultSource object.  Not normally called directly by end users.
2085
2086 =head2 column_info_from_storage
2087
2088 =over
2089
2090 =item Arguments: 1/0 (default: 0)
2091
2092 =item Return Value: 1/0
2093
2094 =back
2095
2096   __PACKAGE__->column_info_from_storage(1);
2097
2098 Enables the on-demand automatic loading of the above column
2099 metadata from storage as necessary.  This is *deprecated*, and
2100 should not be used.  It will be removed before 1.0.
2101
2102
2103 =head1 AUTHOR AND CONTRIBUTORS
2104
2105 See L<AUTHOR|DBIx::Class/AUTHOR> and L<CONTRIBUTORS|DBIx::Class/CONTRIBUTORS> in DBIx::Class
2106
2107 =head1 LICENSE
2108
2109 You may distribute this code under the same terms as Perl itself.
2110
2111 =cut
2112
2113 1;