1 package DBIx::Class::ResultSource;
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
8 use Carp::Clan qw/^DBIx::Class/;
11 use base qw/DBIx::Class/;
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 sqlt_deploy_callback/);
18 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
23 DBIx::Class::ResultSource - Result source object
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>)
39 my ($class, $attrs) = @_;
40 $class = ref $class if ref $class;
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 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
60 =item Arguments: @columns
62 =item Return value: The ResultSource object
66 $source->add_columns(qw/col1 col2 col3/);
68 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
70 Adds columns to the result source. If supplied key => hashref pairs, uses
71 the hashref as the column_info for that column. Repeated calls of this
72 method will add more columns, not replace them.
74 The column names given will be created as accessor methods on your
75 L<DBIx::Class::Row> objects, you can change the name of the accessor
76 by supplying an L</accessor> in the column_info hash.
78 The contents of the column_info are not set in stone. The following
79 keys are currently recognised/used by DBIx::Class:
85 Use this to set the name of the accessor method for this column. If unset,
86 the name of the column will be used.
90 This contains the column type. It is automatically filled by the
91 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
92 L<DBIx::Class::Schema::Loader> module. If you do not enter a
93 data_type, DBIx::Class will attempt to retrieve it from the
94 database for you, using L<DBI>'s column_info method. The values of this
95 key are typically upper-cased.
97 Currently there is no standard set of values for the data_type. Use
98 whatever your database supports.
102 The length of your column, if it is a column type that can have a size
103 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
107 Set this to a true value for a columns that is allowed to contain
108 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
110 =item is_auto_increment
112 Set this to a true value for a column whose value is somehow
113 automatically set. This is used to determine which columns to empty
114 when cloning objects using C<copy>. It is also used by
115 L<DBIx::Class::Schema/deploy>.
119 Set this to a true value for a column that contains a key from a
120 foreign table. This is currently only used by
121 L<DBIx::Class::Schema/deploy>.
125 Set this to the default value which will be inserted into a column
126 by the database. Can contain either a value or a function. This is
127 currently only used by L<DBIx::Class::Schema/deploy>.
131 Set this on a primary key column to the name of the sequence used to
132 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
133 will attempt to retrieve the name of the sequence from the database
138 Set this to a true value for a column whose value is retrieved
139 automatically from an oracle sequence. If you do not use an oracle
140 trigger to get the nextval, you have to set sequence as well.
144 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
145 to add extra non-generic data to the column. For example: C<< extra
146 => { unsigned => 1} >> is used by the MySQL producer to set an integer
147 column to unsigned. For more details, see
148 L<SQL::Translator::Producer::MySQL>.
156 =item Arguments: $colname, [ \%columninfo ]
158 =item Return value: 1/0 (true/false)
162 $source->add_column('col' => \%info?);
164 Add a single column and optional column info. Uses the same column
165 info keys as L</add_columns>.
170 my ($self, @cols) = @_;
171 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
174 my $columns = $self->_columns;
175 while (my $col = shift @cols) {
176 # If next entry is { ... } use that for the column info, if not
177 # use an empty hashref
178 my $column_info = ref $cols[0] ? shift(@cols) : {};
179 push(@added, $col) unless exists $columns->{$col};
180 $columns->{$col} = $column_info;
182 push @{ $self->_ordered_columns }, @added;
186 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
192 =item Arguments: $colname
194 =item Return value: 1/0 (true/false)
198 if ($source->has_column($colname)) { ... }
200 Returns true if the source has a column of this name, false otherwise.
205 my ($self, $column) = @_;
206 return exists $self->_columns->{$column};
213 =item Arguments: $colname
215 =item Return value: Hashref of info
219 my $info = $source->column_info($col);
221 Returns the column metadata hashref for a column, as originally passed
222 to L</add_columns>. See the description of L</add_columns> for information
223 on the contents of the hashref.
228 my ($self, $column) = @_;
229 $self->throw_exception("No such column $column")
230 unless exists $self->_columns->{$column};
231 #warn $self->{_columns_info_loaded}, "\n";
232 if ( ! $self->_columns->{$column}{data_type}
233 and $self->column_info_from_storage
234 and ! $self->{_columns_info_loaded}
235 and $self->schema and $self->storage )
237 $self->{_columns_info_loaded}++;
240 # eval for the case of storage without table
241 eval { $info = $self->storage->columns_info_for( $self->from ) };
243 for my $realcol ( keys %{$info} ) {
244 $lc_info->{lc $realcol} = $info->{$realcol};
246 foreach my $col ( keys %{$self->_columns} ) {
247 $self->_columns->{$col} = {
248 %{ $self->_columns->{$col} },
249 %{ $info->{$col} || $lc_info->{lc $col} || {} }
254 return $self->_columns->{$column};
261 =item Arguments: None
263 =item Return value: Ordered list of column names
267 my @column_names = $source->columns;
269 Returns all column names in the order they were declared to L</add_columns>.
275 $self->throw_exception(
276 "columns() is a read-only accessor, did you mean add_columns()?"
278 return @{$self->{_ordered_columns}||[]};
281 =head2 remove_columns
285 =item Arguments: @colnames
287 =item Return value: undefined
291 $source->remove_columns(qw/col1 col2 col3/);
293 Removes the given list of columns by name, from the result source.
295 B<Warning>: Removing a column that is also used in the sources primary
296 key, or in one of the sources unique constraints, B<will> result in a
297 broken result source.
303 =item Arguments: $colname
305 =item Return value: undefined
309 $source->remove_column('col');
311 Remove a single column by name from the result source, similar to
314 B<Warning>: Removing a column that is also used in the sources primary
315 key, or in one of the sources unique constraints, B<will> result in a
316 broken result source.
321 my ($self, @cols) = @_;
323 return unless $self->_ordered_columns;
325 my $columns = $self->_columns;
328 foreach my $col (@{$self->_ordered_columns}) {
329 push @remaining, $col unless grep(/$col/, @cols);
333 delete $columns->{$_};
336 $self->_ordered_columns(\@remaining);
339 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
341 =head2 set_primary_key
345 =item Arguments: @cols
347 =item Return value: undefined
351 Defines one or more columns as primary key for this source. Should be
352 called after L</add_columns>.
354 Additionally, defines a L<unique constraint|add_unique_constraint>
357 The primary key columns are used by L<DBIx::Class::PK::Auto> to
358 retrieve automatically created values from the database.
362 sub set_primary_key {
363 my ($self, @cols) = @_;
364 # check if primary key columns are valid columns
365 foreach my $col (@cols) {
366 $self->throw_exception("No such column $col on table " . $self->name)
367 unless $self->has_column($col);
369 $self->_primaries(\@cols);
371 $self->add_unique_constraint(primary => \@cols);
374 =head2 primary_columns
378 =item Arguments: None
380 =item Return value: Ordered list of primary column names
384 Read-only accessor which returns the list of primary keys, supplied by
389 sub primary_columns {
390 return @{shift->_primaries||[]};
393 =head2 add_unique_constraint
397 =item Arguments: [ $name ], \@colnames
399 =item Return value: undefined
403 Declare a unique constraint on this source. Call once for each unique
406 # For UNIQUE (column1, column2)
407 __PACKAGE__->add_unique_constraint(
408 constraint_name => [ qw/column1 column2/ ],
411 Alternatively, you can specify only the columns:
413 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
415 This will result in a unique constraint named C<table_column1_column2>, where
416 C<table> is replaced with the table name.
418 Unique constraints are used, for example, when you call
419 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
421 Throws an error if any of the given column names do not yet exist on
426 sub add_unique_constraint {
431 $name ||= $self->name_unique_constraint($cols);
433 foreach my $col (@$cols) {
434 $self->throw_exception("No such column $col on table " . $self->name)
435 unless $self->has_column($col);
438 my %unique_constraints = $self->unique_constraints;
439 $unique_constraints{$name} = $cols;
440 $self->_unique_constraints(\%unique_constraints);
443 =head2 name_unique_constraint
447 =item Arguments: @colnames
449 =item Return value: Constraint name
453 $source->table('mytable');
454 $source->name_unique_constraint('col1', 'col2');
458 Return a name for a unique constraint containing the specified
459 columns. The name is created by joining the table name and each column
460 name, using an underscore character.
462 For example, a constraint on a table named C<cd> containing the columns
463 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
465 This is used by L</add_unique_constraint> if you do not specify the
466 optional constraint name.
470 sub name_unique_constraint {
471 my ($self, $cols) = @_;
473 return join '_', $self->name, @$cols;
476 =head2 unique_constraints
480 =item Arguments: None
482 =item Return value: Hash of unique constraint data
486 $source->unique_constraints();
488 Read-only accessor which returns a hash of unique constraints on this source.
490 The hash is keyed by constraint name, and contains an arrayref of
491 column names as values.
495 sub unique_constraints {
496 return %{shift->_unique_constraints||{}};
499 =head2 unique_constraint_names
503 =item Arguments: None
505 =item Return value: Unique constraint names
509 $source->unique_constraint_names();
511 Returns the list of unique constraint names defined on this source.
515 sub unique_constraint_names {
518 my %unique_constraints = $self->unique_constraints;
520 return keys %unique_constraints;
523 =head2 unique_constraint_columns
527 =item Arguments: $constraintname
529 =item Return value: List of constraint columns
533 $source->unique_constraint_columns('myconstraint');
535 Returns the list of columns that make up the specified unique constraint.
539 sub unique_constraint_columns {
540 my ($self, $constraint_name) = @_;
542 my %unique_constraints = $self->unique_constraints;
544 $self->throw_exception(
545 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
546 ) unless exists $unique_constraints{$constraint_name};
548 return @{ $unique_constraints{$constraint_name} };
555 =item Arguments: None
557 =item Return value: $resultset
561 Returns a resultset for the given source. This will initially be created
564 $self->resultset_class->new($self, $self->resultset_attributes)
566 but is cached from then on unless resultset_class changes.
568 =head2 resultset_class
572 =item Arguments: $classname
574 =item Return value: $classname
578 package My::ResultSetClass;
579 use base 'DBIx::Class::ResultSet';
582 $source->resultset_class('My::ResultSet::Class');
584 Set the class of the resultset, this is useful if you want to create your
585 own resultset methods. Create your own class derived from
586 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
587 this method returns the name of the existing resultset class, if one
590 =head2 resultset_attributes
594 =item Arguments: \%attrs
596 =item Return value: \%attrs
600 $source->resultset_attributes({ order_by => [ 'id' ] });
602 Store a collection of resultset attributes, that will be set on every
603 L<DBIx::Class::ResultSet> produced from this result source. For a full
604 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
610 $self->throw_exception(
611 'resultset does not take any arguments. If you want another resultset, '.
612 'call it on the schema instead.'
615 return $self->resultset_class->new(
618 %{$self->{resultset_attributes}},
619 %{$self->schema->default_resultset_attributes}
628 =item Arguments: $source_name
630 =item Result value: $source_name
634 Set an alternate name for the result source when it is loaded into a schema.
635 This is useful if you want to refer to a result source by a name other than
638 package ArchivedBooks;
639 use base qw/DBIx::Class/;
640 __PACKAGE__->table('books_archive');
641 __PACKAGE__->source_name('Books');
643 # from your schema...
644 $schema->resultset('Books')->find(1);
650 =item Arguments: None
652 =item Return value: FROM clause
656 my $from_clause = $source->from();
658 Returns an expression of the source to be supplied to storage to specify
659 retrieval from this source. In the case of a database, the required FROM
666 =item Arguments: None
668 =item Return value: A schema object
672 my $schema = $source->schema();
674 Returns the L<DBIx::Class::Schema> object that this result source
681 =item Arguments: None
683 =item Return value: A Storage object
687 $source->storage->debug(1);
689 Returns the storage handle for the current schema.
691 See also: L<DBIx::Class::Storage>
695 sub storage { shift->schema->storage; }
697 =head2 add_relationship
701 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
703 =item Return value: 1/true if it succeeded
707 $source->add_relationship('relname', 'related_source', $cond, $attrs);
709 L<DBIx::Class::Relationship> describes a series of methods which
710 create pre-defined useful types of relationships. Look there first
711 before using this method directly.
713 The relationship name can be arbitrary, but must be unique for each
714 relationship attached to this result source. 'related_source' should
715 be the name with which the related result source was registered with
716 the current schema. For example:
718 $schema->source('Book')->add_relationship('reviews', 'Review', {
719 'foreign.book_id' => 'self.id',
722 The condition C<$cond> needs to be an L<SQL::Abstract>-style
723 representation of the join between the tables. For example, if you're
724 creating a relation from Author to Book,
726 { 'foreign.author_id' => 'self.id' }
728 will result in the JOIN clause
730 author me JOIN book foreign ON foreign.author_id = me.id
732 You can specify as many foreign => self mappings as necessary.
734 Valid attributes are as follows:
740 Explicitly specifies the type of join to use in the relationship. Any
741 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
742 the SQL command immediately before C<JOIN>.
746 An arrayref containing a list of accessors in the foreign class to proxy in
747 the main class. If, for example, you do the following:
749 CD->might_have(liner_notes => 'LinerNotes', undef, {
750 proxy => [ qw/notes/ ],
753 Then, assuming LinerNotes has an accessor named notes, you can do:
755 my $cd = CD->find(1);
756 # set notes -- LinerNotes object is created if it doesn't exist
757 $cd->notes('Notes go here');
761 Specifies the type of accessor that should be created for the
762 relationship. Valid values are C<single> (for when there is only a single
763 related object), C<multi> (when there can be many), and C<filter> (for
764 when there is a single related object, but you also want the relationship
765 accessor to double as a column accessor). For C<multi> accessors, an
766 add_to_* method is also created, which calls C<create_related> for the
771 Throws an exception if the condition is improperly supplied, or cannot
772 be resolved using L</resolve_join>.
776 sub add_relationship {
777 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
778 $self->throw_exception("Can't create relationship without join condition")
782 # Check foreign and self are right in cond
783 if ( (ref $cond ||'') eq 'HASH') {
785 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
786 if /\./ && !/^foreign\./;
790 my %rels = %{ $self->_relationships };
791 $rels{$rel} = { class => $f_source_name,
792 source => $f_source_name,
795 $self->_relationships(\%rels);
799 # XXX disabled. doesn't work properly currently. skip in tests.
801 my $f_source = $self->schema->source($f_source_name);
803 $self->ensure_class_loaded($f_source_name);
804 $f_source = $f_source_name->result_source;
805 #my $s_class = ref($self->schema);
806 #$f_source_name =~ m/^${s_class}::(.*)$/;
807 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
808 #$f_source = $self->schema->source($f_source_name);
810 return unless $f_source; # Can't test rel without f_source
812 eval { $self->resolve_join($rel, 'me') };
814 if ($@) { # If the resolve failed, back out and re-throw the error
815 delete $rels{$rel}; #
816 $self->_relationships(\%rels);
817 $self->throw_exception("Error creating relationship $rel: $@");
826 =item Arguments: None
828 =item Return value: List of relationship names
832 my @relnames = $source->relationships();
834 Returns all relationship names for this source.
839 return keys %{shift->_relationships};
842 =head2 relationship_info
846 =item Arguments: $relname
848 =item Return value: Hashref of relation data,
852 Returns a hash of relationship information for the specified relationship
853 name. The keys/values are as specified for L</add_relationship>.
857 sub relationship_info {
858 my ($self, $rel) = @_;
859 return $self->_relationships->{$rel};
862 =head2 has_relationship
866 =item Arguments: $rel
868 =item Return value: 1/0 (true/false)
872 Returns true if the source has a relationship of this name, false otherwise.
876 sub has_relationship {
877 my ($self, $rel) = @_;
878 return exists $self->_relationships->{$rel};
881 =head2 reverse_relationship_info
885 =item Arguments: $relname
887 =item Return value: Hashref of relationship data
891 Looks through all the relationships on the source this relationship
892 points to, looking for one whose condition is the reverse of the
893 condition on this relationship.
895 A common use of this is to find the name of the C<belongs_to> relation
896 opposing a C<has_many> relation. For definition of these look in
897 L<DBIx::Class::Relationship>.
899 The returned hashref is keyed by the name of the opposing
900 relationship, and contains it's data in the same manner as
901 L</relationship_info>.
905 sub reverse_relationship_info {
906 my ($self, $rel) = @_;
907 my $rel_info = $self->relationship_info($rel);
910 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
912 my @cond = keys(%{$rel_info->{cond}});
913 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
914 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
916 # Get the related result source for this relationship
917 my $othertable = $self->related_source($rel);
919 # Get all the relationships for that source that related to this source
920 # whose foreign column set are our self columns on $rel and whose self
921 # columns are our foreign columns on $rel.
922 my @otherrels = $othertable->relationships();
923 my $otherrelationship;
924 foreach my $otherrel (@otherrels) {
925 my $otherrel_info = $othertable->relationship_info($otherrel);
927 my $back = $othertable->related_source($otherrel);
928 next unless $back->source_name eq $self->source_name;
932 if (ref $otherrel_info->{cond} eq 'HASH') {
933 @othertestconds = ($otherrel_info->{cond});
935 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
936 @othertestconds = @{$otherrel_info->{cond}};
942 foreach my $othercond (@othertestconds) {
943 my @other_cond = keys(%$othercond);
944 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
945 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
946 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
947 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
948 $ret->{$otherrel} = $otherrel_info;
954 =head2 compare_relationship_keys
958 =item Arguments: \@keys1, \@keys2
960 =item Return value: 1/0 (true/false)
964 Returns true if both sets of keynames are the same, false otherwise.
968 sub compare_relationship_keys {
969 my ($self, $keys1, $keys2) = @_;
971 # Make sure every keys1 is in keys2
973 foreach my $key (@$keys1) {
975 foreach my $prim (@$keys2) {
984 # Make sure every key2 is in key1
986 foreach my $prim (@$keys2) {
988 foreach my $key (@$keys1) {
1001 =head2 sqlt_deploy_hook
1005 =item Arguments: $source, $sqlt_table
1007 =item Return value: undefined
1011 This is NOT a method of C<ResultSource>.
1013 An optional sub which you can declare in your own Result class that will get
1014 passed the L<SQL::Translator::Schema::Table> object when you deploy the schema
1015 via L</create_ddl_dir> or L</deploy>.
1017 This is useful to make L<SQL::Translator> create non-unique indexes,
1018 or set table options such as C<Engine=INNOFB>.
1020 For an example of what you can do with this, see
1021 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
1027 =item Arguments: $relation
1029 =item Return value: Join condition arrayref
1033 Returns the join structure required for the related result source.
1038 my ($self, $join, $alias, $seen, $force_left) = @_;
1040 $force_left ||= { force => 0 };
1041 if (ref $join eq 'ARRAY') {
1042 return map { $self->resolve_join($_, $alias, $seen) } @$join;
1043 } elsif (ref $join eq 'HASH') {
1046 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
1047 local $force_left->{force};
1049 $self->resolve_join($_, $alias, $seen, $force_left),
1050 $self->related_source($_)->resolve_join(
1051 $join->{$_}, $as, $seen, $force_left
1055 } elsif (ref $join) {
1056 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1058 my $count = ++$seen->{$join};
1059 #use Data::Dumper; warn Dumper($seen);
1060 my $as = ($count > 1 ? "${join}_${count}" : $join);
1061 my $rel_info = $self->relationship_info($join);
1062 $self->throw_exception("No such relationship ${join}") unless $rel_info;
1064 if ($force_left->{force}) {
1067 $type = $rel_info->{attrs}{join_type} || '';
1068 $force_left->{force} = 1 if lc($type) eq 'left';
1070 return [ { $as => $self->related_source($join)->from,
1071 -join_type => $type },
1072 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
1076 =head2 pk_depends_on
1080 =item Arguments: $relname, $rel_data
1082 =item Return value: 1/0 (true/false)
1086 Determines whether a relation is dependent on an object from this source
1087 having already been inserted. Takes the name of the relationship and a
1088 hashref of columns of the related object.
1093 my ($self, $relname, $rel_data) = @_;
1094 my $cond = $self->relationship_info($relname)->{cond};
1096 return 0 unless ref($cond) eq 'HASH';
1098 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1100 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1102 # assume anything that references our PK probably is dependent on us
1103 # rather than vice versa, unless the far side is (a) defined or (b)
1106 my $rel_source = $self->related_source($relname);
1108 foreach my $p ($self->primary_columns) {
1109 if (exists $keyhash->{$p}) {
1110 unless (defined($rel_data->{$keyhash->{$p}})
1111 || $rel_source->column_info($keyhash->{$p})
1112 ->{is_auto_increment}) {
1121 =head2 resolve_condition
1125 =item Arguments: $cond, $as, $alias|$object
1129 Resolves the passed condition to a concrete query fragment. If given an alias,
1130 returns a join condition; if given an object, inverts that object to produce
1131 a related conditional from that object.
1135 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1137 sub resolve_condition {
1138 my ($self, $cond, $as, $for) = @_;
1140 if (ref $cond eq 'HASH') {
1142 foreach my $k (keys %{$cond}) {
1143 my $v = $cond->{$k};
1144 # XXX should probably check these are valid columns
1145 $k =~ s/^foreign\.// ||
1146 $self->throw_exception("Invalid rel cond key ${k}");
1147 $v =~ s/^self\.// ||
1148 $self->throw_exception("Invalid rel cond val ${v}");
1149 if (ref $for) { # Object
1150 #warn "$self $k $for $v";
1151 unless ($for->has_column_loaded($v)) {
1152 if ($for->in_storage) {
1153 $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship");
1155 return $UNRESOLVABLE_CONDITION;
1157 $ret{$k} = $for->get_column($v);
1158 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1160 } elsif (!defined $for) { # undef, i.e. "no object"
1162 } elsif (ref $as eq 'HASH') { # reverse hashref
1163 $ret{$v} = $as->{$k};
1164 } elsif (ref $as) { # reverse object
1165 $ret{$v} = $as->get_column($k);
1166 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1169 $ret{"${as}.${k}"} = "${for}.${v}";
1173 } elsif (ref $cond eq 'ARRAY') {
1174 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
1176 die("Can't handle this yet :(");
1180 =head2 resolve_prefetch
1184 =item Arguments: hashref/arrayref/scalar
1188 Accepts one or more relationships for the current source and returns an
1189 array of column names for each of those relationships. Column names are
1190 prefixed relative to the current source, in accordance with where they appear
1191 in the supplied relationships. Examples:
1193 my $source = $schema->resultset('Tag')->source;
1194 @columns = $source->resolve_prefetch( { cd => 'artist' } );
1202 # 'cd.artist.artistid',
1206 @columns = $source->resolve_prefetch( qw[/ cd /] );
1216 $source = $schema->resultset('CD')->source;
1217 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
1221 # 'artist.artistid',
1223 # 'producer.producerid',
1229 sub resolve_prefetch {
1230 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1232 #$alias ||= $self->name;
1233 #warn $alias, Dumper $pre;
1234 if( ref $pre eq 'ARRAY' ) {
1236 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1239 elsif( ref $pre eq 'HASH' ) {
1242 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1243 $self->related_source($_)->resolve_prefetch(
1244 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1250 $self->throw_exception(
1251 "don't know how to resolve prefetch reftype ".ref($pre));
1254 my $count = ++$seen->{$pre};
1255 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1256 my $rel_info = $self->relationship_info( $pre );
1257 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1259 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1260 my $rel_source = $self->related_source($pre);
1262 if (exists $rel_info->{attrs}{accessor}
1263 && $rel_info->{attrs}{accessor} eq 'multi') {
1264 $self->throw_exception(
1265 "Can't prefetch has_many ${pre} (join cond too complex)")
1266 unless ref($rel_info->{cond}) eq 'HASH';
1267 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1268 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1269 keys %{$collapse}) {
1270 my ($last) = ($fail =~ /([^\.]+)$/);
1272 "Prefetching multiple has_many rels ${last} and ${pre} "
1273 .(length($as_prefix)
1274 ? "at the same level (${as_prefix}) "
1277 . 'will currently disrupt both the functionality of $rs->count(), '
1278 . 'and the amount of objects retrievable via $rs->next(). '
1279 . 'Use at your own risk.'
1282 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1283 # values %{$rel_info->{cond}};
1284 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1285 # action at a distance. prepending the '.' allows simpler code
1286 # in ResultSet->_collapse_result
1287 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1288 keys %{$rel_info->{cond}};
1289 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1290 ? @{$rel_info->{attrs}{order_by}}
1291 : (defined $rel_info->{attrs}{order_by}
1292 ? ($rel_info->{attrs}{order_by})
1294 push(@$order, map { "${as}.$_" } (@key, @ord));
1297 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1298 $rel_source->columns;
1299 #warn $alias, Dumper (\@ret);
1304 =head2 related_source
1308 =item Arguments: $relname
1310 =item Return value: $source
1314 Returns the result source object for the given relationship.
1318 sub related_source {
1319 my ($self, $rel) = @_;
1320 if( !$self->has_relationship( $rel ) ) {
1321 $self->throw_exception("No such relationship '$rel'");
1323 return $self->schema->source($self->relationship_info($rel)->{source});
1326 =head2 related_class
1330 =item Arguments: $relname
1332 =item Return value: $classname
1336 Returns the class name for objects in the given relationship.
1341 my ($self, $rel) = @_;
1342 if( !$self->has_relationship( $rel ) ) {
1343 $self->throw_exception("No such relationship '$rel'");
1345 return $self->schema->class($self->relationship_info($rel)->{source});
1350 Obtain a new handle to this source. Returns an instance of a
1351 L<DBIx::Class::ResultSourceHandle>.
1356 return new DBIx::Class::ResultSourceHandle({
1357 schema => $_[0]->schema,
1358 source_moniker => $_[0]->source_name
1362 =head2 throw_exception
1364 See L<DBIx::Class::Schema/"throw_exception">.
1368 sub throw_exception {
1370 if (defined $self->schema) {
1371 $self->schema->throw_exception(@_);
1379 Stores a hashref of per-source metadata. No specific key names
1380 have yet been standardized, the examples below are purely hypothetical
1381 and don't actually accomplish anything on their own:
1383 __PACKAGE__->source_info({
1384 "_tablespace" => 'fast_disk_array_3',
1385 "_engine" => 'InnoDB',
1392 $class->new({attribute_name => value});
1394 Creates a new ResultSource object. Not normally called directly by end users.
1398 =head2 column_info_from_storage
1402 =item Arguments: 1/0 (default: 0)
1404 =item Return value: 1/0
1408 Enables the on-demand automatic loading of the above column
1409 metadata from storage as neccesary. This is *deprecated*, and
1410 should not be used. It will be removed before 1.0.
1412 __PACKAGE__->column_info_from_storage(1);
1416 =head2 sqlt_deploy_hook($sqlt_table)
1418 Triggers C<sqlt_deploy_callback>.
1422 sub sqlt_deploy_hook {
1424 if ( my $hook = $self->sqlt_deploy_callback) {
1429 =head2 default_sqlt_deploy_hook($table)
1431 Delegates to a an optional C<sqlt_deploy_hook> method on the C<result_class>.
1433 This will get passed the L<SQL::Translator::Schema::Table> object when you
1434 deploy the schema via L</create_ddl_dir> or L</deploy>.
1436 For an example of what you can do with this, see
1437 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
1441 sub default_sqlt_deploy_hook {
1444 my $class = $self->result_class;
1446 if ($class and $class->can('sqlt_deploy_hook')) {
1447 $class->sqlt_deploy_hook(@_);
1451 =head2 sqlt_deploy_callback
1453 An attribute which contains the callback to trigger on C<sqlt_deploy_hook>.
1454 Defaults to C<default_sqlt_deploy_hook>. Can be a code reference or a method
1459 Matt S. Trout <mst@shadowcatsystems.co.uk>
1463 You may distribute this code under the same terms as Perl itself.