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, @to_remove) = @_;
323 my $columns = $self->_columns
328 delete $columns->{$_};
332 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
335 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
337 =head2 set_primary_key
341 =item Arguments: @cols
343 =item Return value: undefined
347 Defines one or more columns as primary key for this source. Should be
348 called after L</add_columns>.
350 Additionally, defines a L<unique constraint|add_unique_constraint>
353 The primary key columns are used by L<DBIx::Class::PK::Auto> to
354 retrieve automatically created values from the database.
358 sub set_primary_key {
359 my ($self, @cols) = @_;
360 # check if primary key columns are valid columns
361 foreach my $col (@cols) {
362 $self->throw_exception("No such column $col on table " . $self->name)
363 unless $self->has_column($col);
365 $self->_primaries(\@cols);
367 $self->add_unique_constraint(primary => \@cols);
370 =head2 primary_columns
374 =item Arguments: None
376 =item Return value: Ordered list of primary column names
380 Read-only accessor which returns the list of primary keys, supplied by
385 sub primary_columns {
386 return @{shift->_primaries||[]};
389 =head2 add_unique_constraint
393 =item Arguments: [ $name ], \@colnames
395 =item Return value: undefined
399 Declare a unique constraint on this source. Call once for each unique
402 # For UNIQUE (column1, column2)
403 __PACKAGE__->add_unique_constraint(
404 constraint_name => [ qw/column1 column2/ ],
407 Alternatively, you can specify only the columns:
409 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
411 This will result in a unique constraint named C<table_column1_column2>, where
412 C<table> is replaced with the table name.
414 Unique constraints are used, for example, when you call
415 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
417 Throws an error if any of the given column names do not yet exist on
422 sub add_unique_constraint {
427 $name ||= $self->name_unique_constraint($cols);
429 foreach my $col (@$cols) {
430 $self->throw_exception("No such column $col on table " . $self->name)
431 unless $self->has_column($col);
434 my %unique_constraints = $self->unique_constraints;
435 $unique_constraints{$name} = $cols;
436 $self->_unique_constraints(\%unique_constraints);
439 =head2 name_unique_constraint
443 =item Arguments: @colnames
445 =item Return value: Constraint name
449 $source->table('mytable');
450 $source->name_unique_constraint('col1', 'col2');
454 Return a name for a unique constraint containing the specified
455 columns. The name is created by joining the table name and each column
456 name, using an underscore character.
458 For example, a constraint on a table named C<cd> containing the columns
459 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
461 This is used by L</add_unique_constraint> if you do not specify the
462 optional constraint name.
466 sub name_unique_constraint {
467 my ($self, $cols) = @_;
469 return join '_', $self->name, @$cols;
472 =head2 unique_constraints
476 =item Arguments: None
478 =item Return value: Hash of unique constraint data
482 $source->unique_constraints();
484 Read-only accessor which returns a hash of unique constraints on this source.
486 The hash is keyed by constraint name, and contains an arrayref of
487 column names as values.
491 sub unique_constraints {
492 return %{shift->_unique_constraints||{}};
495 =head2 unique_constraint_names
499 =item Arguments: None
501 =item Return value: Unique constraint names
505 $source->unique_constraint_names();
507 Returns the list of unique constraint names defined on this source.
511 sub unique_constraint_names {
514 my %unique_constraints = $self->unique_constraints;
516 return keys %unique_constraints;
519 =head2 unique_constraint_columns
523 =item Arguments: $constraintname
525 =item Return value: List of constraint columns
529 $source->unique_constraint_columns('myconstraint');
531 Returns the list of columns that make up the specified unique constraint.
535 sub unique_constraint_columns {
536 my ($self, $constraint_name) = @_;
538 my %unique_constraints = $self->unique_constraints;
540 $self->throw_exception(
541 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
542 ) unless exists $unique_constraints{$constraint_name};
544 return @{ $unique_constraints{$constraint_name} };
547 =head2 sqlt_deploy_callback
551 =item Arguments: $callback
555 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
557 An accessor to set a callback to be called during deployment of
558 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
559 L<DBIx::Class::Schema/deploy>.
561 The callback can be set as either a code reference or the name of a
562 method in the current result class.
564 If not set, the L</default_sqlt_deploy_hook> is called.
566 Your callback will be passed the $source object representing the
567 ResultSource instance being deployed, and the
568 L<SQL::Translator::Schema::Table> object being created from it. The
569 callback can be used to manipulate the table object or add your own
570 customised indexes. If you need to manipulate a non-table object, use
571 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
573 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
574 Your SQL> for examples.
576 This sqlt deployment callback can only be used to manipulate
577 SQL::Translator objects as they get turned into SQL. To execute
578 post-deploy statements which SQL::Translator does not currently
579 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
580 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
582 =head2 default_sqlt_deploy_hook
586 =item Arguments: $source, $sqlt_table
588 =item Return value: undefined
592 This is the sensible default for L</sqlt_deploy_callback>.
594 If a method named C<sqlt_deploy_hook> exists in your Result class, it
595 will be called and passed the current C<$source> and the
596 C<$sqlt_table> being deployed.
600 sub default_sqlt_deploy_hook {
603 my $class = $self->result_class;
605 if ($class and $class->can('sqlt_deploy_hook')) {
606 $class->sqlt_deploy_hook(@_);
610 sub _invoke_sqlt_deploy_hook {
612 if ( my $hook = $self->sqlt_deploy_callback) {
621 =item Arguments: None
623 =item Return value: $resultset
627 Returns a resultset for the given source. This will initially be created
630 $self->resultset_class->new($self, $self->resultset_attributes)
632 but is cached from then on unless resultset_class changes.
634 =head2 resultset_class
638 =item Arguments: $classname
640 =item Return value: $classname
644 package My::ResultSetClass;
645 use base 'DBIx::Class::ResultSet';
648 $source->resultset_class('My::ResultSet::Class');
650 Set the class of the resultset. This is useful if you want to create your
651 own resultset methods. Create your own class derived from
652 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
653 this method returns the name of the existing resultset class, if one
656 =head2 resultset_attributes
660 =item Arguments: \%attrs
662 =item Return value: \%attrs
666 $source->resultset_attributes({ order_by => [ 'id' ] });
668 Store a collection of resultset attributes, that will be set on every
669 L<DBIx::Class::ResultSet> produced from this result source. For a full
670 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
676 $self->throw_exception(
677 'resultset does not take any arguments. If you want another resultset, '.
678 'call it on the schema instead.'
681 return $self->resultset_class->new(
684 %{$self->{resultset_attributes}},
685 %{$self->schema->default_resultset_attributes}
694 =item Arguments: $source_name
696 =item Result value: $source_name
700 Set an alternate name for the result source when it is loaded into a schema.
701 This is useful if you want to refer to a result source by a name other than
704 package ArchivedBooks;
705 use base qw/DBIx::Class/;
706 __PACKAGE__->table('books_archive');
707 __PACKAGE__->source_name('Books');
709 # from your schema...
710 $schema->resultset('Books')->find(1);
716 =item Arguments: None
718 =item Return value: FROM clause
722 my $from_clause = $source->from();
724 Returns an expression of the source to be supplied to storage to specify
725 retrieval from this source. In the case of a database, the required FROM
732 =item Arguments: None
734 =item Return value: A schema object
738 my $schema = $source->schema();
740 Returns the L<DBIx::Class::Schema> object that this result source
747 =item Arguments: None
749 =item Return value: A Storage object
753 $source->storage->debug(1);
755 Returns the storage handle for the current schema.
757 See also: L<DBIx::Class::Storage>
761 sub storage { shift->schema->storage; }
763 =head2 add_relationship
767 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
769 =item Return value: 1/true if it succeeded
773 $source->add_relationship('relname', 'related_source', $cond, $attrs);
775 L<DBIx::Class::Relationship> describes a series of methods which
776 create pre-defined useful types of relationships. Look there first
777 before using this method directly.
779 The relationship name can be arbitrary, but must be unique for each
780 relationship attached to this result source. 'related_source' should
781 be the name with which the related result source was registered with
782 the current schema. For example:
784 $schema->source('Book')->add_relationship('reviews', 'Review', {
785 'foreign.book_id' => 'self.id',
788 The condition C<$cond> needs to be an L<SQL::Abstract>-style
789 representation of the join between the tables. For example, if you're
790 creating a relation from Author to Book,
792 { 'foreign.author_id' => 'self.id' }
794 will result in the JOIN clause
796 author me JOIN book foreign ON foreign.author_id = me.id
798 You can specify as many foreign => self mappings as necessary.
800 Valid attributes are as follows:
806 Explicitly specifies the type of join to use in the relationship. Any
807 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
808 the SQL command immediately before C<JOIN>.
812 An arrayref containing a list of accessors in the foreign class to proxy in
813 the main class. If, for example, you do the following:
815 CD->might_have(liner_notes => 'LinerNotes', undef, {
816 proxy => [ qw/notes/ ],
819 Then, assuming LinerNotes has an accessor named notes, you can do:
821 my $cd = CD->find(1);
822 # set notes -- LinerNotes object is created if it doesn't exist
823 $cd->notes('Notes go here');
827 Specifies the type of accessor that should be created for the
828 relationship. Valid values are C<single> (for when there is only a single
829 related object), C<multi> (when there can be many), and C<filter> (for
830 when there is a single related object, but you also want the relationship
831 accessor to double as a column accessor). For C<multi> accessors, an
832 add_to_* method is also created, which calls C<create_related> for the
837 Throws an exception if the condition is improperly supplied, or cannot
838 be resolved using L</resolve_join>.
842 sub add_relationship {
843 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
844 $self->throw_exception("Can't create relationship without join condition")
848 # Check foreign and self are right in cond
849 if ( (ref $cond ||'') eq 'HASH') {
851 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
852 if /\./ && !/^foreign\./;
856 my %rels = %{ $self->_relationships };
857 $rels{$rel} = { class => $f_source_name,
858 source => $f_source_name,
861 $self->_relationships(\%rels);
865 # XXX disabled. doesn't work properly currently. skip in tests.
867 my $f_source = $self->schema->source($f_source_name);
869 $self->ensure_class_loaded($f_source_name);
870 $f_source = $f_source_name->result_source;
871 #my $s_class = ref($self->schema);
872 #$f_source_name =~ m/^${s_class}::(.*)$/;
873 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
874 #$f_source = $self->schema->source($f_source_name);
876 return unless $f_source; # Can't test rel without f_source
878 eval { $self->resolve_join($rel, 'me') };
880 if ($@) { # If the resolve failed, back out and re-throw the error
881 delete $rels{$rel}; #
882 $self->_relationships(\%rels);
883 $self->throw_exception("Error creating relationship $rel: $@");
892 =item Arguments: None
894 =item Return value: List of relationship names
898 my @relnames = $source->relationships();
900 Returns all relationship names for this source.
905 return keys %{shift->_relationships};
908 =head2 relationship_info
912 =item Arguments: $relname
914 =item Return value: Hashref of relation data,
918 Returns a hash of relationship information for the specified relationship
919 name. The keys/values are as specified for L</add_relationship>.
923 sub relationship_info {
924 my ($self, $rel) = @_;
925 return $self->_relationships->{$rel};
928 =head2 has_relationship
932 =item Arguments: $rel
934 =item Return value: 1/0 (true/false)
938 Returns true if the source has a relationship of this name, false otherwise.
942 sub has_relationship {
943 my ($self, $rel) = @_;
944 return exists $self->_relationships->{$rel};
947 =head2 reverse_relationship_info
951 =item Arguments: $relname
953 =item Return value: Hashref of relationship data
957 Looks through all the relationships on the source this relationship
958 points to, looking for one whose condition is the reverse of the
959 condition on this relationship.
961 A common use of this is to find the name of the C<belongs_to> relation
962 opposing a C<has_many> relation. For definition of these look in
963 L<DBIx::Class::Relationship>.
965 The returned hashref is keyed by the name of the opposing
966 relationship, and contains it's data in the same manner as
967 L</relationship_info>.
971 sub reverse_relationship_info {
972 my ($self, $rel) = @_;
973 my $rel_info = $self->relationship_info($rel);
976 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
978 my @cond = keys(%{$rel_info->{cond}});
979 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
980 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
982 # Get the related result source for this relationship
983 my $othertable = $self->related_source($rel);
985 # Get all the relationships for that source that related to this source
986 # whose foreign column set are our self columns on $rel and whose self
987 # columns are our foreign columns on $rel.
988 my @otherrels = $othertable->relationships();
989 my $otherrelationship;
990 foreach my $otherrel (@otherrels) {
991 my $otherrel_info = $othertable->relationship_info($otherrel);
993 my $back = $othertable->related_source($otherrel);
994 next unless $back->source_name eq $self->source_name;
998 if (ref $otherrel_info->{cond} eq 'HASH') {
999 @othertestconds = ($otherrel_info->{cond});
1001 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1002 @othertestconds = @{$otherrel_info->{cond}};
1008 foreach my $othercond (@othertestconds) {
1009 my @other_cond = keys(%$othercond);
1010 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1011 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1012 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
1013 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
1014 $ret->{$otherrel} = $otherrel_info;
1020 =head2 compare_relationship_keys
1024 =item Arguments: \@keys1, \@keys2
1026 =item Return value: 1/0 (true/false)
1030 Returns true if both sets of keynames are the same, false otherwise.
1034 sub compare_relationship_keys {
1035 my ($self, $keys1, $keys2) = @_;
1037 # Make sure every keys1 is in keys2
1039 foreach my $key (@$keys1) {
1041 foreach my $prim (@$keys2) {
1042 if ($prim eq $key) {
1050 # Make sure every key2 is in key1
1052 foreach my $prim (@$keys2) {
1054 foreach my $key (@$keys1) {
1055 if ($prim eq $key) {
1071 =item Arguments: $relation
1073 =item Return value: Join condition arrayref
1077 Returns the join structure required for the related result source.
1082 my ($self, $join, $alias, $seen, $force_left) = @_;
1084 $force_left ||= { force => 0 };
1085 if (ref $join eq 'ARRAY') {
1086 return map { $self->resolve_join($_, $alias, $seen) } @$join;
1087 } elsif (ref $join eq 'HASH') {
1090 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
1091 local $force_left->{force};
1093 $self->resolve_join($_, $alias, $seen, $force_left),
1094 $self->related_source($_)->resolve_join(
1095 $join->{$_}, $as, $seen, $force_left
1099 } elsif (ref $join) {
1100 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1102 my $count = ++$seen->{$join};
1103 #use Data::Dumper; warn Dumper($seen);
1104 my $as = ($count > 1 ? "${join}_${count}" : $join);
1105 my $rel_info = $self->relationship_info($join);
1106 $self->throw_exception("No such relationship ${join}") unless $rel_info;
1108 if ($force_left->{force}) {
1111 $type = $rel_info->{attrs}{join_type} || '';
1112 $force_left->{force} = 1 if lc($type) eq 'left';
1114 return [ { $as => $self->related_source($join)->from,
1115 -join_type => $type },
1116 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
1120 =head2 pk_depends_on
1124 =item Arguments: $relname, $rel_data
1126 =item Return value: 1/0 (true/false)
1130 Determines whether a relation is dependent on an object from this source
1131 having already been inserted. Takes the name of the relationship and a
1132 hashref of columns of the related object.
1137 my ($self, $relname, $rel_data) = @_;
1138 my $cond = $self->relationship_info($relname)->{cond};
1140 return 0 unless ref($cond) eq 'HASH';
1142 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1144 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1146 # assume anything that references our PK probably is dependent on us
1147 # rather than vice versa, unless the far side is (a) defined or (b)
1150 my $rel_source = $self->related_source($relname);
1152 foreach my $p ($self->primary_columns) {
1153 if (exists $keyhash->{$p}) {
1154 unless (defined($rel_data->{$keyhash->{$p}})
1155 || $rel_source->column_info($keyhash->{$p})
1156 ->{is_auto_increment}) {
1165 =head2 resolve_condition
1169 =item Arguments: $cond, $as, $alias|$object
1173 Resolves the passed condition to a concrete query fragment. If given an alias,
1174 returns a join condition; if given an object, inverts that object to produce
1175 a related conditional from that object.
1179 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1181 sub resolve_condition {
1182 my ($self, $cond, $as, $for) = @_;
1184 if (ref $cond eq 'HASH') {
1186 foreach my $k (keys %{$cond}) {
1187 my $v = $cond->{$k};
1188 # XXX should probably check these are valid columns
1189 $k =~ s/^foreign\.// ||
1190 $self->throw_exception("Invalid rel cond key ${k}");
1191 $v =~ s/^self\.// ||
1192 $self->throw_exception("Invalid rel cond val ${v}");
1193 if (ref $for) { # Object
1194 #warn "$self $k $for $v";
1195 unless ($for->has_column_loaded($v)) {
1196 if ($for->in_storage) {
1197 $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship");
1199 return $UNRESOLVABLE_CONDITION;
1201 $ret{$k} = $for->get_column($v);
1202 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1204 } elsif (!defined $for) { # undef, i.e. "no object"
1206 } elsif (ref $as eq 'HASH') { # reverse hashref
1207 $ret{$v} = $as->{$k};
1208 } elsif (ref $as) { # reverse object
1209 $ret{$v} = $as->get_column($k);
1210 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1213 $ret{"${as}.${k}"} = "${for}.${v}";
1217 } elsif (ref $cond eq 'ARRAY') {
1218 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
1220 die("Can't handle this yet :(");
1224 =head2 resolve_prefetch
1228 =item Arguments: hashref/arrayref/scalar
1232 Accepts one or more relationships for the current source and returns an
1233 array of column names for each of those relationships. Column names are
1234 prefixed relative to the current source, in accordance with where they appear
1235 in the supplied relationships. Examples:
1237 my $source = $schema->resultset('Tag')->source;
1238 @columns = $source->resolve_prefetch( { cd => 'artist' } );
1246 # 'cd.artist.artistid',
1250 @columns = $source->resolve_prefetch( qw[/ cd /] );
1260 $source = $schema->resultset('CD')->source;
1261 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
1265 # 'artist.artistid',
1267 # 'producer.producerid',
1273 sub resolve_prefetch {
1274 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1276 #$alias ||= $self->name;
1277 #warn $alias, Dumper $pre;
1278 if( ref $pre eq 'ARRAY' ) {
1280 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1283 elsif( ref $pre eq 'HASH' ) {
1286 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1287 $self->related_source($_)->resolve_prefetch(
1288 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1294 $self->throw_exception(
1295 "don't know how to resolve prefetch reftype ".ref($pre));
1298 my $count = ++$seen->{$pre};
1299 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1300 my $rel_info = $self->relationship_info( $pre );
1301 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1303 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1304 my $rel_source = $self->related_source($pre);
1306 if (exists $rel_info->{attrs}{accessor}
1307 && $rel_info->{attrs}{accessor} eq 'multi') {
1308 $self->throw_exception(
1309 "Can't prefetch has_many ${pre} (join cond too complex)")
1310 unless ref($rel_info->{cond}) eq 'HASH';
1311 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1312 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1313 keys %{$collapse}) {
1314 my ($last) = ($fail =~ /([^\.]+)$/);
1316 "Prefetching multiple has_many rels ${last} and ${pre} "
1317 .(length($as_prefix)
1318 ? "at the same level (${as_prefix}) "
1321 . 'will currently disrupt both the functionality of $rs->count(), '
1322 . 'and the amount of objects retrievable via $rs->next(). '
1323 . 'Use at your own risk.'
1326 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1327 # values %{$rel_info->{cond}};
1328 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1329 # action at a distance. prepending the '.' allows simpler code
1330 # in ResultSet->_collapse_result
1331 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1332 keys %{$rel_info->{cond}};
1333 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1334 ? @{$rel_info->{attrs}{order_by}}
1335 : (defined $rel_info->{attrs}{order_by}
1336 ? ($rel_info->{attrs}{order_by})
1338 push(@$order, map { "${as}.$_" } (@key, @ord));
1341 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1342 $rel_source->columns;
1343 #warn $alias, Dumper (\@ret);
1348 =head2 related_source
1352 =item Arguments: $relname
1354 =item Return value: $source
1358 Returns the result source object for the given relationship.
1362 sub related_source {
1363 my ($self, $rel) = @_;
1364 if( !$self->has_relationship( $rel ) ) {
1365 $self->throw_exception("No such relationship '$rel'");
1367 return $self->schema->source($self->relationship_info($rel)->{source});
1370 =head2 related_class
1374 =item Arguments: $relname
1376 =item Return value: $classname
1380 Returns the class name for objects in the given relationship.
1385 my ($self, $rel) = @_;
1386 if( !$self->has_relationship( $rel ) ) {
1387 $self->throw_exception("No such relationship '$rel'");
1389 return $self->schema->class($self->relationship_info($rel)->{source});
1394 Obtain a new handle to this source. Returns an instance of a
1395 L<DBIx::Class::ResultSourceHandle>.
1400 return new DBIx::Class::ResultSourceHandle({
1401 schema => $_[0]->schema,
1402 source_moniker => $_[0]->source_name
1406 =head2 throw_exception
1408 See L<DBIx::Class::Schema/"throw_exception">.
1412 sub throw_exception {
1414 if (defined $self->schema) {
1415 $self->schema->throw_exception(@_);
1423 Stores a hashref of per-source metadata. No specific key names
1424 have yet been standardized, the examples below are purely hypothetical
1425 and don't actually accomplish anything on their own:
1427 __PACKAGE__->source_info({
1428 "_tablespace" => 'fast_disk_array_3',
1429 "_engine" => 'InnoDB',
1436 $class->new({attribute_name => value});
1438 Creates a new ResultSource object. Not normally called directly by end users.
1440 =head2 column_info_from_storage
1444 =item Arguments: 1/0 (default: 0)
1446 =item Return value: 1/0
1450 __PACKAGE__->column_info_from_storage(1);
1452 Enables the on-demand automatic loading of the above column
1453 metadata from storage as neccesary. This is *deprecated*, and
1454 should not be used. It will be removed before 1.0.
1459 Matt S. Trout <mst@shadowcatsystems.co.uk>
1463 You may distribute this code under the same terms as Perl itself.