Change my email
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
1 package DBIx::Class::ResultSource;
2
3 use strict;
4 use warnings;
5
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
8 use Carp::Clan qw/^DBIx::Class/;
9 use Storable;
10
11 use base qw/DBIx::Class/;
12
13 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
14   _columns _primaries _unique_constraints name resultset_attributes
15   schema from _relationships column_info_from_storage source_info
16   source_name/);
17
18 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
19   result_class/);
20
21 =head1 NAME
22
23 DBIx::Class::ResultSource - Result source object
24
25 =head1 SYNOPSIS
26
27 =head1 DESCRIPTION
28
29 A ResultSource is a component of a schema from which results can be directly
30 retrieved, most usually a table (see L<DBIx::Class::ResultSource::Table>)
31
32 =head1 METHODS
33
34 =pod
35
36 =cut
37
38 sub new {
39   my ($class, $attrs) = @_;
40   $class = ref $class if ref $class;
41
42   my $new = bless { %{$attrs || {}} }, $class;
43   $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
44   $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
45   $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
46   $new->{_columns} = { %{$new->{_columns}||{}} };
47   $new->{_relationships} = { %{$new->{_relationships}||{}} };
48   $new->{name} ||= "!!NAME NOT SET!!";
49   $new->{_columns_info_loaded} ||= 0;
50   return $new;
51 }
52
53 =pod
54
55 =head2 add_columns
56
57 =over
58
59 =item Arguments: @columns
60
61 =item Return value: The ResultSource object
62
63 =back
64
65   $source->add_columns(qw/col1 col2 col3/);
66
67   $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
68
69 Adds columns to the result source. If supplied key => hashref pairs, uses
70 the hashref as the column_info for that column. Repeated calls of this
71 method will add more columns, not replace them.
72
73 The column names given will be created as accessor methods on your
74 L<DBIx::Class::Row> objects, you can change the name of the accessor
75 by supplying an L</accessor> in the column_info hash.
76
77 The contents of the column_info are not set in stone. The following
78 keys are currently recognised/used by DBIx::Class:
79
80 =over 4
81
82 =item accessor
83
84 Use this to set the name of the accessor method for this column. If unset,
85 the name of the column will be used.
86
87 =item data_type
88
89 This contains the column type. It is automatically filled by the
90 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
91 L<DBIx::Class::Schema::Loader> module. If you do not enter a
92 data_type, DBIx::Class will attempt to retrieve it from the
93 database for you, using L<DBI>'s column_info method. The values of this
94 key are typically upper-cased.
95
96 Currently there is no standard set of values for the data_type. Use
97 whatever your database supports.
98
99 =item size
100
101 The length of your column, if it is a column type that can have a size
102 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
103
104 =item is_nullable
105
106 Set this to a true value for a columns that is allowed to contain
107 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
108
109 =item is_auto_increment
110
111 Set this to a true value for a column whose value is somehow
112 automatically set. This is used to determine which columns to empty
113 when cloning objects using C<copy>. It is also used by
114 L<DBIx::Class::Schema/deploy>.
115
116 =item is_foreign_key
117
118 Set this to a true value for a column that contains a key from a
119 foreign table. This is currently only used by
120 L<DBIx::Class::Schema/deploy>.
121
122 =item default_value
123
124 Set this to the default value which will be inserted into a column
125 by the database. Can contain either a value or a function. This is
126 currently only used by L<DBIx::Class::Schema/deploy>.
127
128 =item sequence
129
130 Set this on a primary key column to the name of the sequence used to
131 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
132 will attempt to retrieve the name of the sequence from the database
133 automatically.
134
135 =item auto_nextval
136
137 Set this to a true value for a column whose value is retrieved
138 automatically from an oracle sequence. If you do not use an oracle
139 trigger to get the nextval, you have to set sequence as well.
140
141 =item extra
142
143 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
144 to add extra non-generic data to the column. For example: C<< extra
145 => { unsigned => 1} >> is used by the MySQL producer to set an integer
146 column to unsigned. For more details, see
147 L<SQL::Translator::Producer::MySQL>.
148
149 =back
150
151 =head2 add_column
152
153 =over
154
155 =item Arguments: $colname, [ \%columninfo ]
156
157 =item Return value: 1/0 (true/false)
158
159 =back
160
161   $source->add_column('col' => \%info?);
162
163 Add a single column and optional column info. Uses the same column
164 info keys as L</add_columns>.
165
166 =cut
167
168 sub add_columns {
169   my ($self, @cols) = @_;
170   $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
171
172   my @added;
173   my $columns = $self->_columns;
174   while (my $col = shift @cols) {
175     # If next entry is { ... } use that for the column info, if not
176     # use an empty hashref
177     my $column_info = ref $cols[0] ? shift(@cols) : {};
178     push(@added, $col) unless exists $columns->{$col};
179     $columns->{$col} = $column_info;
180   }
181   push @{ $self->_ordered_columns }, @added;
182   return $self;
183 }
184
185 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
186
187 =head2 has_column
188
189 =over
190
191 =item Arguments: $colname
192
193 =item Return value: 1/0 (true/false)
194
195 =back
196
197   if ($source->has_column($colname)) { ... }
198
199 Returns true if the source has a column of this name, false otherwise.
200
201 =cut
202
203 sub has_column {
204   my ($self, $column) = @_;
205   return exists $self->_columns->{$column};
206 }
207
208 =head2 column_info
209
210 =over
211
212 =item Arguments: $colname
213
214 =item Return value: Hashref of info
215
216 =back
217
218   my $info = $source->column_info($col);
219
220 Returns the column metadata hashref for a column, as originally passed
221 to L</add_columns>. See the description of L</add_columns> for information
222 on the contents of the hashref.
223
224 =cut
225
226 sub column_info {
227   my ($self, $column) = @_;
228   $self->throw_exception("No such column $column")
229     unless exists $self->_columns->{$column};
230   #warn $self->{_columns_info_loaded}, "\n";
231   if ( ! $self->_columns->{$column}{data_type}
232        and $self->column_info_from_storage
233        and ! $self->{_columns_info_loaded}
234        and $self->schema and $self->storage )
235   {
236     $self->{_columns_info_loaded}++;
237     my $info = {};
238     my $lc_info = {};
239     # eval for the case of storage without table
240     eval { $info = $self->storage->columns_info_for( $self->from ) };
241     unless ($@) {
242       for my $realcol ( keys %{$info} ) {
243         $lc_info->{lc $realcol} = $info->{$realcol};
244       }
245       foreach my $col ( keys %{$self->_columns} ) {
246         $self->_columns->{$col} = {
247           %{ $self->_columns->{$col} },
248           %{ $info->{$col} || $lc_info->{lc $col} || {} }
249         };
250       }
251     }
252   }
253   return $self->_columns->{$column};
254 }
255
256 =head2 columns
257
258 =over
259
260 =item Arguments: None
261
262 =item Return value: Ordered list of column names
263
264 =back
265
266   my @column_names = $source->columns;
267
268 Returns all column names in the order they were declared to L</add_columns>.
269
270 =cut
271
272 sub columns {
273   my $self = shift;
274   $self->throw_exception(
275     "columns() is a read-only accessor, did you mean add_columns()?"
276   ) if (@_ > 1);
277   return @{$self->{_ordered_columns}||[]};
278 }
279
280 =head2 remove_columns
281
282 =over
283
284 =item Arguments: @colnames
285
286 =item Return value: undefined
287
288 =back
289
290   $source->remove_columns(qw/col1 col2 col3/);
291
292 Removes the given list of columns by name, from the result source.
293
294 B<Warning>: Removing a column that is also used in the sources primary
295 key, or in one of the sources unique constraints, B<will> result in a
296 broken result source.
297
298 =head2 remove_column
299
300 =over
301
302 =item Arguments: $colname
303
304 =item Return value: undefined
305
306 =back
307
308   $source->remove_column('col');
309
310 Remove a single column by name from the result source, similar to
311 L</remove_columns>.
312
313 B<Warning>: Removing a column that is also used in the sources primary
314 key, or in one of the sources unique constraints, B<will> result in a
315 broken result source.
316
317 =cut
318
319 sub remove_columns {
320   my ($self, @cols) = @_;
321
322   return unless $self->_ordered_columns;
323
324   my $columns = $self->_columns;
325   my @remaining;
326
327   foreach my $col (@{$self->_ordered_columns}) {
328     push @remaining, $col unless grep(/$col/, @cols);
329   }
330
331   foreach (@cols) {
332     delete $columns->{$_};
333   };
334
335   $self->_ordered_columns(\@remaining);
336 }
337
338 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
339
340 =head2 set_primary_key
341
342 =over 4
343
344 =item Arguments: @cols
345
346 =item Return value: undefined
347
348 =back
349
350 Defines one or more columns as primary key for this source. Should be
351 called after L</add_columns>.
352
353 Additionally, defines a L<unique constraint|add_unique_constraint>
354 named C<primary>.
355
356 The primary key columns are used by L<DBIx::Class::PK::Auto> to
357 retrieve automatically created values from the database.
358
359 =cut
360
361 sub set_primary_key {
362   my ($self, @cols) = @_;
363   # check if primary key columns are valid columns
364   foreach my $col (@cols) {
365     $self->throw_exception("No such column $col on table " . $self->name)
366       unless $self->has_column($col);
367   }
368   $self->_primaries(\@cols);
369
370   $self->add_unique_constraint(primary => \@cols);
371 }
372
373 =head2 primary_columns
374
375 =over 4
376
377 =item Arguments: None
378
379 =item Return value: Ordered list of primary column names
380
381 =back
382
383 Read-only accessor which returns the list of primary keys, supplied by
384 L</set_primary_key>.
385
386 =cut
387
388 sub primary_columns {
389   return @{shift->_primaries||[]};
390 }
391
392 =head2 add_unique_constraint
393
394 =over 4
395
396 =item Arguments: [ $name ], \@colnames
397
398 =item Return value: undefined
399
400 =back
401
402 Declare a unique constraint on this source. Call once for each unique
403 constraint.
404
405   # For UNIQUE (column1, column2)
406   __PACKAGE__->add_unique_constraint(
407     constraint_name => [ qw/column1 column2/ ],
408   );
409
410 Alternatively, you can specify only the columns:
411
412   __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
413
414 This will result in a unique constraint named C<table_column1_column2>, where
415 C<table> is replaced with the table name.
416
417 Unique constraints are used, for example, when you call
418 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
419
420 Throws an error if any of the given column names do not yet exist on
421 the result source.
422
423 =cut
424
425 sub add_unique_constraint {
426   my $self = shift;
427   my $cols = pop @_;
428   my $name = shift;
429
430   $name ||= $self->name_unique_constraint($cols);
431
432   foreach my $col (@$cols) {
433     $self->throw_exception("No such column $col on table " . $self->name)
434       unless $self->has_column($col);
435   }
436
437   my %unique_constraints = $self->unique_constraints;
438   $unique_constraints{$name} = $cols;
439   $self->_unique_constraints(\%unique_constraints);
440 }
441
442 =head2 name_unique_constraint
443
444 =over 4
445
446 =item Arguments: @colnames
447
448 =item Return value: Constraint name
449
450 =back
451
452   $source->table('mytable');
453   $source->name_unique_constraint('col1', 'col2');
454   # returns
455   'mytable_col1_col2'
456
457 Return a name for a unique constraint containing the specified
458 columns. The name is created by joining the table name and each column
459 name, using an underscore character.
460
461 For example, a constraint on a table named C<cd> containing the columns
462 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
463
464 This is used by L</add_unique_constraint> if you do not specify the
465 optional constraint name.
466
467 =cut
468
469 sub name_unique_constraint {
470   my ($self, $cols) = @_;
471
472   return join '_', $self->name, @$cols;
473 }
474
475 =head2 unique_constraints
476
477 =over 4
478
479 =item Arguments: None
480
481 =item Return value: Hash of unique constraint data
482
483 =back
484
485   $source->unique_constraints();
486
487 Read-only accessor which returns a hash of unique constraints on this source.
488
489 The hash is keyed by constraint name, and contains an arrayref of
490 column names as values.
491
492 =cut
493
494 sub unique_constraints {
495   return %{shift->_unique_constraints||{}};
496 }
497
498 =head2 unique_constraint_names
499
500 =over 4
501
502 =item Arguments: None
503
504 =item Return value: Unique constraint names
505
506 =back
507
508   $source->unique_constraint_names();
509
510 Returns the list of unique constraint names defined on this source.
511
512 =cut
513
514 sub unique_constraint_names {
515   my ($self) = @_;
516
517   my %unique_constraints = $self->unique_constraints;
518
519   return keys %unique_constraints;
520 }
521
522 =head2 unique_constraint_columns
523
524 =over 4
525
526 =item Arguments: $constraintname
527
528 =item Return value: List of constraint columns
529
530 =back
531
532   $source->unique_constraint_columns('myconstraint');
533
534 Returns the list of columns that make up the specified unique constraint.
535
536 =cut
537
538 sub unique_constraint_columns {
539   my ($self, $constraint_name) = @_;
540
541   my %unique_constraints = $self->unique_constraints;
542
543   $self->throw_exception(
544     "Unknown unique constraint $constraint_name on '" . $self->name . "'"
545   ) unless exists $unique_constraints{$constraint_name};
546
547   return @{ $unique_constraints{$constraint_name} };
548 }
549
550 =head2 resultset
551
552 =over 4
553
554 =item Arguments: None
555
556 =item Return value: $resultset
557
558 =back
559
560 Returns a resultset for the given source. This will initially be created
561 on demand by calling
562
563   $self->resultset_class->new($self, $self->resultset_attributes)
564
565 but is cached from then on unless resultset_class changes.
566
567 =head2 resultset_class
568
569 =over 4
570
571 =item Arguments: $classname
572
573 =item Return value: $classname
574
575 =back
576
577   package My::ResultSetClass;
578   use base 'DBIx::Class::ResultSet';
579   ...
580
581   $source->resultset_class('My::ResultSet::Class');
582
583 Set the class of the resultset, this is useful if you want to create your
584 own resultset methods. Create your own class derived from
585 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
586 this method returns the name of the existing resultset class, if one
587 exists.
588
589 =head2 resultset_attributes
590
591 =over 4
592
593 =item Arguments: \%attrs
594
595 =item Return value: \%attrs
596
597 =back
598
599   $source->resultset_attributes({ order_by => [ 'id' ] });
600
601 Store a collection of resultset attributes, that will be set on every
602 L<DBIx::Class::ResultSet> produced from this result source. For a full
603 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
604
605 =cut
606
607 sub resultset {
608   my $self = shift;
609   $self->throw_exception(
610     'resultset does not take any arguments. If you want another resultset, '.
611     'call it on the schema instead.'
612   ) if scalar @_;
613
614   return $self->resultset_class->new(
615     $self,
616     {
617       %{$self->{resultset_attributes}},
618       %{$self->schema->default_resultset_attributes}
619     },
620   );
621 }
622
623 =head2 source_name
624
625 =over 4
626
627 =item Arguments: $source_name
628
629 =item Result value: $source_name
630
631 =back
632
633 Set an alternate name for the result source when it is loaded into a schema.
634 This is useful if you want to refer to a result source by a name other than
635 its class name.
636
637   package ArchivedBooks;
638   use base qw/DBIx::Class/;
639   __PACKAGE__->table('books_archive');
640   __PACKAGE__->source_name('Books');
641
642   # from your schema...
643   $schema->resultset('Books')->find(1);
644
645 =head2 from
646
647 =over 4
648
649 =item Arguments: None
650
651 =item Return value: FROM clause
652
653 =back
654
655   my $from_clause = $source->from();
656
657 Returns an expression of the source to be supplied to storage to specify
658 retrieval from this source. In the case of a database, the required FROM
659 clause contents.
660
661 =head2 schema
662
663 =over 4
664
665 =item Arguments: None
666
667 =item Return value: A schema object
668
669 =back
670
671   my $schema = $source->schema();
672
673 Returns the L<DBIx::Class::Schema> object that this result source 
674 belongs to.
675
676 =head2 storage
677
678 =over 4
679
680 =item Arguments: None
681
682 =item Return value: A Storage object
683
684 =back
685
686   $source->storage->debug(1);
687
688 Returns the storage handle for the current schema.
689
690 See also: L<DBIx::Class::Storage>
691
692 =cut
693
694 sub storage { shift->schema->storage; }
695
696 =head2 add_relationship
697
698 =over 4
699
700 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
701
702 =item Return value: 1/true if it succeeded
703
704 =back
705
706   $source->add_relationship('relname', 'related_source', $cond, $attrs);
707
708 L<DBIx::Class::Relationship> describes a series of methods which
709 create pre-defined useful types of relationships. Look there first
710 before using this method directly.
711
712 The relationship name can be arbitrary, but must be unique for each
713 relationship attached to this result source. 'related_source' should
714 be the name with which the related result source was registered with
715 the current schema. For example:
716
717   $schema->source('Book')->add_relationship('reviews', 'Review', {
718     'foreign.book_id' => 'self.id',
719   });
720
721 The condition C<$cond> needs to be an L<SQL::Abstract>-style
722 representation of the join between the tables. For example, if you're
723 creating a relation from Author to Book,
724
725   { 'foreign.author_id' => 'self.id' }
726
727 will result in the JOIN clause
728
729   author me JOIN book foreign ON foreign.author_id = me.id
730
731 You can specify as many foreign => self mappings as necessary.
732
733 Valid attributes are as follows:
734
735 =over 4
736
737 =item join_type
738
739 Explicitly specifies the type of join to use in the relationship. Any
740 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
741 the SQL command immediately before C<JOIN>.
742
743 =item proxy
744
745 An arrayref containing a list of accessors in the foreign class to proxy in
746 the main class. If, for example, you do the following:
747
748   CD->might_have(liner_notes => 'LinerNotes', undef, {
749     proxy => [ qw/notes/ ],
750   });
751
752 Then, assuming LinerNotes has an accessor named notes, you can do:
753
754   my $cd = CD->find(1);
755   # set notes -- LinerNotes object is created if it doesn't exist
756   $cd->notes('Notes go here');
757
758 =item accessor
759
760 Specifies the type of accessor that should be created for the
761 relationship. Valid values are C<single> (for when there is only a single
762 related object), C<multi> (when there can be many), and C<filter> (for
763 when there is a single related object, but you also want the relationship
764 accessor to double as a column accessor). For C<multi> accessors, an
765 add_to_* method is also created, which calls C<create_related> for the
766 relationship.
767
768 =back
769
770 Throws an exception if the condition is improperly supplied, or cannot
771 be resolved using L</resolve_join>.
772
773 =cut
774
775 sub add_relationship {
776   my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
777   $self->throw_exception("Can't create relationship without join condition")
778     unless $cond;
779   $attrs ||= {};
780
781   # Check foreign and self are right in cond
782   if ( (ref $cond ||'') eq 'HASH') {
783     for (keys %$cond) {
784       $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
785         if /\./ && !/^foreign\./;
786     }
787   }
788
789   my %rels = %{ $self->_relationships };
790   $rels{$rel} = { class => $f_source_name,
791                   source => $f_source_name,
792                   cond  => $cond,
793                   attrs => $attrs };
794   $self->_relationships(\%rels);
795
796   return $self;
797
798   # XXX disabled. doesn't work properly currently. skip in tests.
799
800   my $f_source = $self->schema->source($f_source_name);
801   unless ($f_source) {
802     $self->ensure_class_loaded($f_source_name);
803     $f_source = $f_source_name->result_source;
804     #my $s_class = ref($self->schema);
805     #$f_source_name =~ m/^${s_class}::(.*)$/;
806     #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
807     #$f_source = $self->schema->source($f_source_name);
808   }
809   return unless $f_source; # Can't test rel without f_source
810
811   eval { $self->resolve_join($rel, 'me') };
812
813   if ($@) { # If the resolve failed, back out and re-throw the error
814     delete $rels{$rel}; #
815     $self->_relationships(\%rels);
816     $self->throw_exception("Error creating relationship $rel: $@");
817   }
818   1;
819 }
820
821 =head2 relationships
822
823 =over 4
824
825 =item Arguments: None
826
827 =item Return value: List of relationship names
828
829 =back
830
831   my @relnames = $source->relationships();
832
833 Returns all relationship names for this source.
834
835 =cut
836
837 sub relationships {
838   return keys %{shift->_relationships};
839 }
840
841 =head2 relationship_info
842
843 =over 4
844
845 =item Arguments: $relname
846
847 =item Return value: Hashref of relation data,
848
849 =back
850
851 Returns a hash of relationship information for the specified relationship
852 name. The keys/values are as specified for L</add_relationship>.
853
854 =cut
855
856 sub relationship_info {
857   my ($self, $rel) = @_;
858   return $self->_relationships->{$rel};
859 }
860
861 =head2 has_relationship
862
863 =over 4
864
865 =item Arguments: $rel
866
867 =item Return value: 1/0 (true/false)
868
869 =back
870
871 Returns true if the source has a relationship of this name, false otherwise.
872
873 =cut
874
875 sub has_relationship {
876   my ($self, $rel) = @_;
877   return exists $self->_relationships->{$rel};
878 }
879
880 =head2 reverse_relationship_info
881
882 =over 4
883
884 =item Arguments: $relname
885
886 =item Return value: Hashref of relationship data
887
888 =back
889
890 Looks through all the relationships on the source this relationship
891 points to, looking for one whose condition is the reverse of the
892 condition on this relationship.
893
894 A common use of this is to find the name of the C<belongs_to> relation
895 opposing a C<has_many> relation. For definition of these look in
896 L<DBIx::Class::Relationship>.
897
898 The returned hashref is keyed by the name of the opposing
899 relationship, and contains it's data in the same manner as
900 L</relationship_info>.
901
902 =cut
903
904 sub reverse_relationship_info {
905   my ($self, $rel) = @_;
906   my $rel_info = $self->relationship_info($rel);
907   my $ret = {};
908
909   return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
910
911   my @cond = keys(%{$rel_info->{cond}});
912   my @refkeys = map {/^\w+\.(\w+)$/} @cond;
913   my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
914
915   # Get the related result source for this relationship
916   my $othertable = $self->related_source($rel);
917
918   # Get all the relationships for that source that related to this source
919   # whose foreign column set are our self columns on $rel and whose self
920   # columns are our foreign columns on $rel.
921   my @otherrels = $othertable->relationships();
922   my $otherrelationship;
923   foreach my $otherrel (@otherrels) {
924     my $otherrel_info = $othertable->relationship_info($otherrel);
925
926     my $back = $othertable->related_source($otherrel);
927     next unless $back->source_name eq $self->source_name;
928
929     my @othertestconds;
930
931     if (ref $otherrel_info->{cond} eq 'HASH') {
932       @othertestconds = ($otherrel_info->{cond});
933     }
934     elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
935       @othertestconds = @{$otherrel_info->{cond}};
936     }
937     else {
938       next;
939     }
940
941     foreach my $othercond (@othertestconds) {
942       my @other_cond = keys(%$othercond);
943       my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
944       my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
945       next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
946                !$self->compare_relationship_keys(\@other_refkeys, \@keys));
947       $ret->{$otherrel} =  $otherrel_info;
948     }
949   }
950   return $ret;
951 }
952
953 =head2 compare_relationship_keys
954
955 =over 4
956
957 =item Arguments: \@keys1, \@keys2
958
959 =item Return value: 1/0 (true/false)
960
961 =back
962
963 Returns true if both sets of keynames are the same, false otherwise.
964
965 =cut
966
967 sub compare_relationship_keys {
968   my ($self, $keys1, $keys2) = @_;
969
970   # Make sure every keys1 is in keys2
971   my $found;
972   foreach my $key (@$keys1) {
973     $found = 0;
974     foreach my $prim (@$keys2) {
975       if ($prim eq $key) {
976         $found = 1;
977         last;
978       }
979     }
980     last unless $found;
981   }
982
983   # Make sure every key2 is in key1
984   if ($found) {
985     foreach my $prim (@$keys2) {
986       $found = 0;
987       foreach my $key (@$keys1) {
988         if ($prim eq $key) {
989           $found = 1;
990           last;
991         }
992       }
993       last unless $found;
994     }
995   }
996
997   return $found;
998 }
999
1000 =head2 sqlt_deploy_hook
1001
1002 =over 4
1003
1004 =item Arguments: $source, $sqlt_table
1005
1006 =item Return value: undefined
1007
1008 =back
1009
1010 This is NOT a method of C<ResultSource>.
1011
1012 An optional sub which you can declare in your own Result class that will get 
1013 passed the L<SQL::Translator::Schema::Table> object when you deploy the schema
1014 via L</create_ddl_dir> or L</deploy>.
1015
1016 This is useful to make L<SQL::Translator> create non-unique indexes,
1017 or set table options such as C<Engine=INNOFB>.
1018
1019 For an example of what you can do with this, see 
1020 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
1021
1022 =head2 resolve_join
1023
1024 =over 4
1025
1026 =item Arguments: $relation
1027
1028 =item Return value: Join condition arrayref
1029
1030 =back
1031
1032 Returns the join structure required for the related result source.
1033
1034 =cut
1035
1036 sub resolve_join {
1037   my ($self, $join, $alias, $seen, $force_left) = @_;
1038   $seen ||= {};
1039   $force_left ||= { force => 0 };
1040   if (ref $join eq 'ARRAY') {
1041     return map { $self->resolve_join($_, $alias, $seen) } @$join;
1042   } elsif (ref $join eq 'HASH') {
1043     return
1044       map {
1045         my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
1046         local $force_left->{force};
1047         (
1048           $self->resolve_join($_, $alias, $seen, $force_left),
1049           $self->related_source($_)->resolve_join(
1050             $join->{$_}, $as, $seen, $force_left
1051           )
1052         );
1053       } keys %$join;
1054   } elsif (ref $join) {
1055     $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1056   } else {
1057     my $count = ++$seen->{$join};
1058     #use Data::Dumper; warn Dumper($seen);
1059     my $as = ($count > 1 ? "${join}_${count}" : $join);
1060     my $rel_info = $self->relationship_info($join);
1061     $self->throw_exception("No such relationship ${join}") unless $rel_info;
1062     my $type;
1063     if ($force_left->{force}) {
1064       $type = 'left';
1065     } else {
1066       $type = $rel_info->{attrs}{join_type} || '';
1067       $force_left->{force} = 1 if lc($type) eq 'left';
1068     }
1069     return [ { $as => $self->related_source($join)->from,
1070                -join_type => $type },
1071              $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
1072   }
1073 }
1074
1075 =head2 pk_depends_on
1076
1077 =over 4
1078
1079 =item Arguments: $relname, $rel_data
1080
1081 =item Return value: 1/0 (true/false)
1082
1083 =back
1084
1085 Determines whether a relation is dependent on an object from this source
1086 having already been inserted. Takes the name of the relationship and a
1087 hashref of columns of the related object.
1088
1089 =cut
1090
1091 sub pk_depends_on {
1092   my ($self, $relname, $rel_data) = @_;
1093   my $cond = $self->relationship_info($relname)->{cond};
1094
1095   return 0 unless ref($cond) eq 'HASH';
1096
1097   # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1098
1099   my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1100
1101   # assume anything that references our PK probably is dependent on us
1102   # rather than vice versa, unless the far side is (a) defined or (b)
1103   # auto-increment
1104
1105   my $rel_source = $self->related_source($relname);
1106
1107   foreach my $p ($self->primary_columns) {
1108     if (exists $keyhash->{$p}) {
1109       unless (defined($rel_data->{$keyhash->{$p}})
1110               || $rel_source->column_info($keyhash->{$p})
1111                             ->{is_auto_increment}) {
1112         return 0;
1113       }
1114     }
1115   }
1116
1117   return 1;
1118 }
1119
1120 =head2 resolve_condition
1121
1122 =over 4
1123
1124 =item Arguments: $cond, $as, $alias|$object
1125
1126 =back
1127
1128 Resolves the passed condition to a concrete query fragment. If given an alias,
1129 returns a join condition; if given an object, inverts that object to produce
1130 a related conditional from that object.
1131
1132 =cut
1133
1134 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1135
1136 sub resolve_condition {
1137   my ($self, $cond, $as, $for) = @_;
1138   #warn %$cond;
1139   if (ref $cond eq 'HASH') {
1140     my %ret;
1141     foreach my $k (keys %{$cond}) {
1142       my $v = $cond->{$k};
1143       # XXX should probably check these are valid columns
1144       $k =~ s/^foreign\.// ||
1145         $self->throw_exception("Invalid rel cond key ${k}");
1146       $v =~ s/^self\.// ||
1147         $self->throw_exception("Invalid rel cond val ${v}");
1148       if (ref $for) { # Object
1149         #warn "$self $k $for $v";
1150         unless ($for->has_column_loaded($v)) {
1151           if ($for->in_storage) {
1152             $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship");
1153           }
1154           return $UNRESOLVABLE_CONDITION;
1155         }
1156         $ret{$k} = $for->get_column($v);
1157         #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1158         #warn %ret;
1159       } elsif (!defined $for) { # undef, i.e. "no object"
1160         $ret{$k} = undef;
1161       } elsif (ref $as eq 'HASH') { # reverse hashref
1162         $ret{$v} = $as->{$k};
1163       } elsif (ref $as) { # reverse object
1164         $ret{$v} = $as->get_column($k);
1165       } elsif (!defined $as) { # undef, i.e. "no reverse object"
1166         $ret{$v} = undef;
1167       } else {
1168         $ret{"${as}.${k}"} = "${for}.${v}";
1169       }
1170     }
1171     return \%ret;
1172   } elsif (ref $cond eq 'ARRAY') {
1173     return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
1174   } else {
1175    die("Can't handle this yet :(");
1176   }
1177 }
1178
1179 =head2 resolve_prefetch
1180
1181 =over 4
1182
1183 =item Arguments: hashref/arrayref/scalar
1184
1185 =back
1186
1187 Accepts one or more relationships for the current source and returns an
1188 array of column names for each of those relationships. Column names are
1189 prefixed relative to the current source, in accordance with where they appear
1190 in the supplied relationships. Examples:
1191
1192   my $source = $schema->resultset('Tag')->source;
1193   @columns = $source->resolve_prefetch( { cd => 'artist' } );
1194
1195   # @columns =
1196   #(
1197   #  'cd.cdid',
1198   #  'cd.artist',
1199   #  'cd.title',
1200   #  'cd.year',
1201   #  'cd.artist.artistid',
1202   #  'cd.artist.name'
1203   #)
1204
1205   @columns = $source->resolve_prefetch( qw[/ cd /] );
1206
1207   # @columns =
1208   #(
1209   #   'cd.cdid',
1210   #   'cd.artist',
1211   #   'cd.title',
1212   #   'cd.year'
1213   #)
1214
1215   $source = $schema->resultset('CD')->source;
1216   @columns = $source->resolve_prefetch( qw[/ artist producer /] );
1217
1218   # @columns =
1219   #(
1220   #  'artist.artistid',
1221   #  'artist.name',
1222   #  'producer.producerid',
1223   #  'producer.name'
1224   #)
1225
1226 =cut
1227
1228 sub resolve_prefetch {
1229   my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1230   $seen ||= {};
1231   #$alias ||= $self->name;
1232   #warn $alias, Dumper $pre;
1233   if( ref $pre eq 'ARRAY' ) {
1234     return
1235       map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1236         @$pre;
1237   }
1238   elsif( ref $pre eq 'HASH' ) {
1239     my @ret =
1240     map {
1241       $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1242       $self->related_source($_)->resolve_prefetch(
1243                $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1244     } keys %$pre;
1245     #die Dumper \@ret;
1246     return @ret;
1247   }
1248   elsif( ref $pre ) {
1249     $self->throw_exception(
1250       "don't know how to resolve prefetch reftype ".ref($pre));
1251   }
1252   else {
1253     my $count = ++$seen->{$pre};
1254     my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1255     my $rel_info = $self->relationship_info( $pre );
1256     $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1257       unless $rel_info;
1258     my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1259     my $rel_source = $self->related_source($pre);
1260
1261     if (exists $rel_info->{attrs}{accessor}
1262          && $rel_info->{attrs}{accessor} eq 'multi') {
1263       $self->throw_exception(
1264         "Can't prefetch has_many ${pre} (join cond too complex)")
1265         unless ref($rel_info->{cond}) eq 'HASH';
1266       my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1267       if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1268                          keys %{$collapse}) {
1269         my ($last) = ($fail =~ /([^\.]+)$/);
1270         carp (
1271           "Prefetching multiple has_many rels ${last} and ${pre} "
1272           .(length($as_prefix)
1273             ? "at the same level (${as_prefix}) "
1274             : "at top level "
1275           )
1276           . 'will currently disrupt both the functionality of $rs->count(), '
1277           . 'and the amount of objects retrievable via $rs->next(). '
1278           . 'Use at your own risk.'
1279         );
1280       }
1281       #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1282       #              values %{$rel_info->{cond}};
1283       $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1284         # action at a distance. prepending the '.' allows simpler code
1285         # in ResultSet->_collapse_result
1286       my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1287                     keys %{$rel_info->{cond}};
1288       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1289                    ? @{$rel_info->{attrs}{order_by}}
1290                    : (defined $rel_info->{attrs}{order_by}
1291                        ? ($rel_info->{attrs}{order_by})
1292                        : ()));
1293       push(@$order, map { "${as}.$_" } (@key, @ord));
1294     }
1295
1296     return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1297       $rel_source->columns;
1298     #warn $alias, Dumper (\@ret);
1299     #return @ret;
1300   }
1301 }
1302
1303 =head2 related_source
1304
1305 =over 4
1306
1307 =item Arguments: $relname
1308
1309 =item Return value: $source
1310
1311 =back
1312
1313 Returns the result source object for the given relationship.
1314
1315 =cut
1316
1317 sub related_source {
1318   my ($self, $rel) = @_;
1319   if( !$self->has_relationship( $rel ) ) {
1320     $self->throw_exception("No such relationship '$rel'");
1321   }
1322   return $self->schema->source($self->relationship_info($rel)->{source});
1323 }
1324
1325 =head2 related_class
1326
1327 =over 4
1328
1329 =item Arguments: $relname
1330
1331 =item Return value: $classname
1332
1333 =back
1334
1335 Returns the class name for objects in the given relationship.
1336
1337 =cut
1338
1339 sub related_class {
1340   my ($self, $rel) = @_;
1341   if( !$self->has_relationship( $rel ) ) {
1342     $self->throw_exception("No such relationship '$rel'");
1343   }
1344   return $self->schema->class($self->relationship_info($rel)->{source});
1345 }
1346
1347 =head2 handle
1348
1349 Obtain a new handle to this source. Returns an instance of a 
1350 L<DBIx::Class::ResultSourceHandle>.
1351
1352 =cut
1353
1354 sub handle {
1355     return new DBIx::Class::ResultSourceHandle({
1356         schema         => $_[0]->schema,
1357         source_moniker => $_[0]->source_name
1358     });
1359 }
1360
1361 =head2 throw_exception
1362
1363 See L<DBIx::Class::Schema/"throw_exception">.
1364
1365 =cut
1366
1367 sub throw_exception {
1368   my $self = shift;
1369   if (defined $self->schema) {
1370     $self->schema->throw_exception(@_);
1371   } else {
1372     croak(@_);
1373   }
1374 }
1375
1376 =head2 source_info
1377
1378 Stores a hashref of per-source metadata.  No specific key names
1379 have yet been standardized, the examples below are purely hypothetical
1380 and don't actually accomplish anything on their own:
1381
1382   __PACKAGE__->source_info({
1383     "_tablespace" => 'fast_disk_array_3',
1384     "_engine" => 'InnoDB',
1385   });
1386
1387 =head2 new
1388
1389   $class->new();
1390
1391   $class->new({attribute_name => value});
1392
1393 Creates a new ResultSource object.  Not normally called directly by end users.
1394
1395 =cut
1396
1397 =head2 column_info_from_storage
1398
1399 =over
1400
1401 =item Arguments: 1/0 (default: 0)
1402
1403 =item Return value: 1/0
1404
1405 =back
1406
1407 Enables the on-demand automatic loading of the above column
1408 metadata from storage as neccesary.  This is *deprecated*, and
1409 should not be used.  It will be removed before 1.0.
1410
1411   __PACKAGE__->column_info_from_storage(1);
1412
1413 =head1 AUTHORS
1414
1415 Matt S. Trout <mst@shadowcatsystems.co.uk>
1416
1417 =head1 LICENSE
1418
1419 You may distribute this code under the same terms as Perl itself.
1420
1421 =cut
1422
1423 1;