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>)
32 Basic view support also exists, see L<<DBIx::Class::ResultSource::View>.
41 my ($class, $attrs) = @_;
42 $class = ref $class if ref $class;
44 my $new = bless { %{$attrs || {}} }, $class;
45 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
46 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
47 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
48 $new->{_columns} = { %{$new->{_columns}||{}} };
49 $new->{_relationships} = { %{$new->{_relationships}||{}} };
50 $new->{name} ||= "!!NAME NOT SET!!";
51 $new->{_columns_info_loaded} ||= 0;
52 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
62 =item Arguments: @columns
64 =item Return value: The ResultSource object
68 $source->add_columns(qw/col1 col2 col3/);
70 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
72 Adds columns to the result source. If supplied key => hashref pairs, uses
73 the hashref as the column_info for that column. Repeated calls of this
74 method will add more columns, not replace them.
76 The column names given will be created as accessor methods on your
77 L<DBIx::Class::Row> objects. You can change the name of the accessor
78 by supplying an L</accessor> in the column_info hash.
80 The contents of the column_info are not set in stone. The following
81 keys are currently recognised/used by DBIx::Class:
87 Use this to set the name of the accessor method for this column. If unset,
88 the name of the column will be used.
92 This contains the column type. It is automatically filled by the
93 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
94 L<DBIx::Class::Schema::Loader> module. If you do not enter a
95 data_type, DBIx::Class will attempt to retrieve it from the
96 database for you, using L<DBI>'s column_info method. The values of this
97 key are typically upper-cased.
99 Currently there is no standard set of values for the data_type. Use
100 whatever your database supports.
104 The length of your column, if it is a column type that can have a size
105 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
109 Set this to a true value for a columns that is allowed to contain
110 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
112 =item is_auto_increment
114 Set this to a true value for a column whose value is somehow
115 automatically set. This is used to determine which columns to empty
116 when cloning objects using C<copy>. It is also used by
117 L<DBIx::Class::Schema/deploy>.
121 Set this to a true value for a column that contains a key from a
122 foreign table. This is currently only used by
123 L<DBIx::Class::Schema/deploy>.
127 Set this to the default value which will be inserted into a column
128 by the database. Can contain either a value or a function (use a
129 reference to a scalar e.g. C<\'now()'> if you want a function). This
130 is currently only used by L<DBIx::Class::Schema/deploy>.
132 See the note on L<DBIx::Class::Row/new> for more information about possible
133 issues related to db-side default values.
137 Set this on a primary key column to the name of the sequence used to
138 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
139 will attempt to retrieve the name of the sequence from the database
144 Set this to a true value for a column whose value is retrieved
145 automatically from an oracle sequence. If you do not use an Oracle
146 trigger to get the nextval, you have to set sequence as well.
150 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
151 to add extra non-generic data to the column. For example: C<< extra
152 => { unsigned => 1} >> is used by the MySQL producer to set an integer
153 column to unsigned. For more details, see
154 L<SQL::Translator::Producer::MySQL>.
162 =item Arguments: $colname, [ \%columninfo ]
164 =item Return value: 1/0 (true/false)
168 $source->add_column('col' => \%info?);
170 Add a single column and optional column info. Uses the same column
171 info keys as L</add_columns>.
176 my ($self, @cols) = @_;
177 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
180 my $columns = $self->_columns;
181 while (my $col = shift @cols) {
182 # If next entry is { ... } use that for the column info, if not
183 # use an empty hashref
184 my $column_info = ref $cols[0] ? shift(@cols) : {};
185 push(@added, $col) unless exists $columns->{$col};
186 $columns->{$col} = $column_info;
188 push @{ $self->_ordered_columns }, @added;
192 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
198 =item Arguments: $colname
200 =item Return value: 1/0 (true/false)
204 if ($source->has_column($colname)) { ... }
206 Returns true if the source has a column of this name, false otherwise.
211 my ($self, $column) = @_;
212 return exists $self->_columns->{$column};
219 =item Arguments: $colname
221 =item Return value: Hashref of info
225 my $info = $source->column_info($col);
227 Returns the column metadata hashref for a column, as originally passed
228 to L</add_columns>. See the description of L</add_columns> for information
229 on the contents of the hashref.
234 my ($self, $column) = @_;
235 $self->throw_exception("No such column $column")
236 unless exists $self->_columns->{$column};
237 #warn $self->{_columns_info_loaded}, "\n";
238 if ( ! $self->_columns->{$column}{data_type}
239 and $self->column_info_from_storage
240 and ! $self->{_columns_info_loaded}
241 and $self->schema and $self->storage )
243 $self->{_columns_info_loaded}++;
246 # eval for the case of storage without table
247 eval { $info = $self->storage->columns_info_for( $self->from ) };
249 for my $realcol ( keys %{$info} ) {
250 $lc_info->{lc $realcol} = $info->{$realcol};
252 foreach my $col ( keys %{$self->_columns} ) {
253 $self->_columns->{$col} = {
254 %{ $self->_columns->{$col} },
255 %{ $info->{$col} || $lc_info->{lc $col} || {} }
260 return $self->_columns->{$column};
267 =item Arguments: None
269 =item Return value: Ordered list of column names
273 my @column_names = $source->columns;
275 Returns all column names in the order they were declared to L</add_columns>.
281 $self->throw_exception(
282 "columns() is a read-only accessor, did you mean add_columns()?"
284 return @{$self->{_ordered_columns}||[]};
287 =head2 remove_columns
291 =item Arguments: @colnames
293 =item Return value: undefined
297 $source->remove_columns(qw/col1 col2 col3/);
299 Removes the given list of columns by name, from the result source.
301 B<Warning>: Removing a column that is also used in the sources primary
302 key, or in one of the sources unique constraints, B<will> result in a
303 broken result source.
309 =item Arguments: $colname
311 =item Return value: undefined
315 $source->remove_column('col');
317 Remove a single column by name from the result source, similar to
320 B<Warning>: Removing a column that is also used in the sources primary
321 key, or in one of the sources unique constraints, B<will> result in a
322 broken result source.
327 my ($self, @to_remove) = @_;
329 my $columns = $self->_columns
334 delete $columns->{$_};
338 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
341 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
343 =head2 set_primary_key
347 =item Arguments: @cols
349 =item Return value: undefined
353 Defines one or more columns as primary key for this source. Should be
354 called after L</add_columns>.
356 Additionally, defines a L<unique constraint|add_unique_constraint>
359 The primary key columns are used by L<DBIx::Class::PK::Auto> to
360 retrieve automatically created values from the database.
364 sub set_primary_key {
365 my ($self, @cols) = @_;
366 # check if primary key columns are valid columns
367 foreach my $col (@cols) {
368 $self->throw_exception("No such column $col on table " . $self->name)
369 unless $self->has_column($col);
371 $self->_primaries(\@cols);
373 $self->add_unique_constraint(primary => \@cols);
376 =head2 primary_columns
380 =item Arguments: None
382 =item Return value: Ordered list of primary column names
386 Read-only accessor which returns the list of primary keys, supplied by
391 sub primary_columns {
392 return @{shift->_primaries||[]};
395 =head2 add_unique_constraint
399 =item Arguments: [ $name ], \@colnames
401 =item Return value: undefined
405 Declare a unique constraint on this source. Call once for each unique
408 # For UNIQUE (column1, column2)
409 __PACKAGE__->add_unique_constraint(
410 constraint_name => [ qw/column1 column2/ ],
413 Alternatively, you can specify only the columns:
415 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
417 This will result in a unique constraint named C<table_column1_column2>, where
418 C<table> is replaced with the table name.
420 Unique constraints are used, for example, when you call
421 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
423 Throws an error if any of the given column names do not yet exist on
428 sub add_unique_constraint {
433 $name ||= $self->name_unique_constraint($cols);
435 foreach my $col (@$cols) {
436 $self->throw_exception("No such column $col on table " . $self->name)
437 unless $self->has_column($col);
440 my %unique_constraints = $self->unique_constraints;
441 $unique_constraints{$name} = $cols;
442 $self->_unique_constraints(\%unique_constraints);
445 =head2 name_unique_constraint
449 =item Arguments: @colnames
451 =item Return value: Constraint name
455 $source->table('mytable');
456 $source->name_unique_constraint('col1', 'col2');
460 Return a name for a unique constraint containing the specified
461 columns. The name is created by joining the table name and each column
462 name, using an underscore character.
464 For example, a constraint on a table named C<cd> containing the columns
465 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
467 This is used by L</add_unique_constraint> if you do not specify the
468 optional constraint name.
472 sub name_unique_constraint {
473 my ($self, $cols) = @_;
475 return join '_', $self->name, @$cols;
478 =head2 unique_constraints
482 =item Arguments: None
484 =item Return value: Hash of unique constraint data
488 $source->unique_constraints();
490 Read-only accessor which returns a hash of unique constraints on this source.
492 The hash is keyed by constraint name, and contains an arrayref of
493 column names as values.
497 sub unique_constraints {
498 return %{shift->_unique_constraints||{}};
501 =head2 unique_constraint_names
505 =item Arguments: None
507 =item Return value: Unique constraint names
511 $source->unique_constraint_names();
513 Returns the list of unique constraint names defined on this source.
517 sub unique_constraint_names {
520 my %unique_constraints = $self->unique_constraints;
522 return keys %unique_constraints;
525 =head2 unique_constraint_columns
529 =item Arguments: $constraintname
531 =item Return value: List of constraint columns
535 $source->unique_constraint_columns('myconstraint');
537 Returns the list of columns that make up the specified unique constraint.
541 sub unique_constraint_columns {
542 my ($self, $constraint_name) = @_;
544 my %unique_constraints = $self->unique_constraints;
546 $self->throw_exception(
547 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
548 ) unless exists $unique_constraints{$constraint_name};
550 return @{ $unique_constraints{$constraint_name} };
553 =head2 sqlt_deploy_callback
557 =item Arguments: $callback
561 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
563 An accessor to set a callback to be called during deployment of
564 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
565 L<DBIx::Class::Schema/deploy>.
567 The callback can be set as either a code reference or the name of a
568 method in the current result class.
570 If not set, the L</default_sqlt_deploy_hook> is called.
572 Your callback will be passed the $source object representing the
573 ResultSource instance being deployed, and the
574 L<SQL::Translator::Schema::Table> object being created from it. The
575 callback can be used to manipulate the table object or add your own
576 customised indexes. If you need to manipulate a non-table object, use
577 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
579 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
580 Your SQL> for examples.
582 This sqlt deployment callback can only be used to manipulate
583 SQL::Translator objects as they get turned into SQL. To execute
584 post-deploy statements which SQL::Translator does not currently
585 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
586 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
588 =head2 default_sqlt_deploy_hook
592 =item Arguments: $source, $sqlt_table
594 =item Return value: undefined
598 This is the sensible default for L</sqlt_deploy_callback>.
600 If a method named C<sqlt_deploy_hook> exists in your Result class, it
601 will be called and passed the current C<$source> and the
602 C<$sqlt_table> being deployed.
606 sub default_sqlt_deploy_hook {
609 my $class = $self->result_class;
611 if ($class and $class->can('sqlt_deploy_hook')) {
612 $class->sqlt_deploy_hook(@_);
616 sub _invoke_sqlt_deploy_hook {
618 if ( my $hook = $self->sqlt_deploy_callback) {
627 =item Arguments: None
629 =item Return value: $resultset
633 Returns a resultset for the given source. This will initially be created
636 $self->resultset_class->new($self, $self->resultset_attributes)
638 but is cached from then on unless resultset_class changes.
640 =head2 resultset_class
644 =item Arguments: $classname
646 =item Return value: $classname
650 package My::ResultSetClass;
651 use base 'DBIx::Class::ResultSet';
654 $source->resultset_class('My::ResultSet::Class');
656 Set the class of the resultset. This is useful if you want to create your
657 own resultset methods. Create your own class derived from
658 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
659 this method returns the name of the existing resultset class, if one
662 =head2 resultset_attributes
666 =item Arguments: \%attrs
668 =item Return value: \%attrs
672 $source->resultset_attributes({ order_by => [ 'id' ] });
674 Store a collection of resultset attributes, that will be set on every
675 L<DBIx::Class::ResultSet> produced from this result source. For a full
676 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
682 $self->throw_exception(
683 'resultset does not take any arguments. If you want another resultset, '.
684 'call it on the schema instead.'
687 return $self->resultset_class->new(
690 %{$self->{resultset_attributes}},
691 %{$self->schema->default_resultset_attributes}
700 =item Arguments: $source_name
702 =item Result value: $source_name
706 Set an alternate name for the result source when it is loaded into a schema.
707 This is useful if you want to refer to a result source by a name other than
710 package ArchivedBooks;
711 use base qw/DBIx::Class/;
712 __PACKAGE__->table('books_archive');
713 __PACKAGE__->source_name('Books');
715 # from your schema...
716 $schema->resultset('Books')->find(1);
722 =item Arguments: None
724 =item Return value: FROM clause
728 my $from_clause = $source->from();
730 Returns an expression of the source to be supplied to storage to specify
731 retrieval from this source. In the case of a database, the required FROM
738 =item Arguments: None
740 =item Return value: A schema object
744 my $schema = $source->schema();
746 Returns the L<DBIx::Class::Schema> object that this result source
753 =item Arguments: None
755 =item Return value: A Storage object
759 $source->storage->debug(1);
761 Returns the storage handle for the current schema.
763 See also: L<DBIx::Class::Storage>
767 sub storage { shift->schema->storage; }
769 =head2 add_relationship
773 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
775 =item Return value: 1/true if it succeeded
779 $source->add_relationship('relname', 'related_source', $cond, $attrs);
781 L<DBIx::Class::Relationship> describes a series of methods which
782 create pre-defined useful types of relationships. Look there first
783 before using this method directly.
785 The relationship name can be arbitrary, but must be unique for each
786 relationship attached to this result source. 'related_source' should
787 be the name with which the related result source was registered with
788 the current schema. For example:
790 $schema->source('Book')->add_relationship('reviews', 'Review', {
791 'foreign.book_id' => 'self.id',
794 The condition C<$cond> needs to be an L<SQL::Abstract>-style
795 representation of the join between the tables. For example, if you're
796 creating a relation from Author to Book,
798 { 'foreign.author_id' => 'self.id' }
800 will result in the JOIN clause
802 author me JOIN book foreign ON foreign.author_id = me.id
804 You can specify as many foreign => self mappings as necessary.
806 Valid attributes are as follows:
812 Explicitly specifies the type of join to use in the relationship. Any
813 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
814 the SQL command immediately before C<JOIN>.
818 An arrayref containing a list of accessors in the foreign class to proxy in
819 the main class. If, for example, you do the following:
821 CD->might_have(liner_notes => 'LinerNotes', undef, {
822 proxy => [ qw/notes/ ],
825 Then, assuming LinerNotes has an accessor named notes, you can do:
827 my $cd = CD->find(1);
828 # set notes -- LinerNotes object is created if it doesn't exist
829 $cd->notes('Notes go here');
833 Specifies the type of accessor that should be created for the
834 relationship. Valid values are C<single> (for when there is only a single
835 related object), C<multi> (when there can be many), and C<filter> (for
836 when there is a single related object, but you also want the relationship
837 accessor to double as a column accessor). For C<multi> accessors, an
838 add_to_* method is also created, which calls C<create_related> for the
843 Throws an exception if the condition is improperly supplied, or cannot
844 be resolved using L</resolve_join>.
848 sub add_relationship {
849 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
850 $self->throw_exception("Can't create relationship without join condition")
854 # Check foreign and self are right in cond
855 if ( (ref $cond ||'') eq 'HASH') {
857 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
858 if /\./ && !/^foreign\./;
862 my %rels = %{ $self->_relationships };
863 $rels{$rel} = { class => $f_source_name,
864 source => $f_source_name,
867 $self->_relationships(\%rels);
871 # XXX disabled. doesn't work properly currently. skip in tests.
873 my $f_source = $self->schema->source($f_source_name);
875 $self->ensure_class_loaded($f_source_name);
876 $f_source = $f_source_name->result_source;
877 #my $s_class = ref($self->schema);
878 #$f_source_name =~ m/^${s_class}::(.*)$/;
879 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
880 #$f_source = $self->schema->source($f_source_name);
882 return unless $f_source; # Can't test rel without f_source
884 eval { $self->resolve_join($rel, 'me') };
886 if ($@) { # If the resolve failed, back out and re-throw the error
887 delete $rels{$rel}; #
888 $self->_relationships(\%rels);
889 $self->throw_exception("Error creating relationship $rel: $@");
898 =item Arguments: None
900 =item Return value: List of relationship names
904 my @relnames = $source->relationships();
906 Returns all relationship names for this source.
911 return keys %{shift->_relationships};
914 =head2 relationship_info
918 =item Arguments: $relname
920 =item Return value: Hashref of relation data,
924 Returns a hash of relationship information for the specified relationship
925 name. The keys/values are as specified for L</add_relationship>.
929 sub relationship_info {
930 my ($self, $rel) = @_;
931 return $self->_relationships->{$rel};
934 =head2 has_relationship
938 =item Arguments: $rel
940 =item Return value: 1/0 (true/false)
944 Returns true if the source has a relationship of this name, false otherwise.
948 sub has_relationship {
949 my ($self, $rel) = @_;
950 return exists $self->_relationships->{$rel};
953 =head2 reverse_relationship_info
957 =item Arguments: $relname
959 =item Return value: Hashref of relationship data
963 Looks through all the relationships on the source this relationship
964 points to, looking for one whose condition is the reverse of the
965 condition on this relationship.
967 A common use of this is to find the name of the C<belongs_to> relation
968 opposing a C<has_many> relation. For definition of these look in
969 L<DBIx::Class::Relationship>.
971 The returned hashref is keyed by the name of the opposing
972 relationship, and contains it's data in the same manner as
973 L</relationship_info>.
977 sub reverse_relationship_info {
978 my ($self, $rel) = @_;
979 my $rel_info = $self->relationship_info($rel);
982 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
984 my @cond = keys(%{$rel_info->{cond}});
985 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
986 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
988 # Get the related result source for this relationship
989 my $othertable = $self->related_source($rel);
991 # Get all the relationships for that source that related to this source
992 # whose foreign column set are our self columns on $rel and whose self
993 # columns are our foreign columns on $rel.
994 my @otherrels = $othertable->relationships();
995 my $otherrelationship;
996 foreach my $otherrel (@otherrels) {
997 my $otherrel_info = $othertable->relationship_info($otherrel);
999 my $back = $othertable->related_source($otherrel);
1000 next unless $back->source_name eq $self->source_name;
1004 if (ref $otherrel_info->{cond} eq 'HASH') {
1005 @othertestconds = ($otherrel_info->{cond});
1007 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1008 @othertestconds = @{$otherrel_info->{cond}};
1014 foreach my $othercond (@othertestconds) {
1015 my @other_cond = keys(%$othercond);
1016 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1017 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1018 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
1019 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
1020 $ret->{$otherrel} = $otherrel_info;
1026 =head2 compare_relationship_keys
1030 =item Arguments: \@keys1, \@keys2
1032 =item Return value: 1/0 (true/false)
1036 Returns true if both sets of keynames are the same, false otherwise.
1040 sub compare_relationship_keys {
1041 my ($self, $keys1, $keys2) = @_;
1043 # Make sure every keys1 is in keys2
1045 foreach my $key (@$keys1) {
1047 foreach my $prim (@$keys2) {
1048 if ($prim eq $key) {
1056 # Make sure every key2 is in key1
1058 foreach my $prim (@$keys2) {
1060 foreach my $key (@$keys1) {
1061 if ($prim eq $key) {
1077 =item Arguments: $relation
1079 =item Return value: Join condition arrayref
1083 Returns the join structure required for the related result source.
1088 my ($self, $join, $alias, $seen, $force_left) = @_;
1090 $force_left ||= { force => 0 };
1091 if (ref $join eq 'ARRAY') {
1092 return map { $self->resolve_join($_, $alias, $seen) } @$join;
1093 } elsif (ref $join eq 'HASH') {
1096 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
1097 local $force_left->{force};
1099 $self->resolve_join($_, $alias, $seen, $force_left),
1100 $self->related_source($_)->resolve_join(
1101 $join->{$_}, $as, $seen, $force_left
1105 } elsif (ref $join) {
1106 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1108 my $count = ++$seen->{$join};
1109 #use Data::Dumper; warn Dumper($seen);
1110 my $as = ($count > 1 ? "${join}_${count}" : $join);
1111 my $rel_info = $self->relationship_info($join);
1112 $self->throw_exception("No such relationship ${join}") unless $rel_info;
1114 if ($force_left->{force}) {
1117 $type = $rel_info->{attrs}{join_type} || '';
1118 $force_left->{force} = 1 if lc($type) eq 'left';
1120 return [ { $as => $self->related_source($join)->from,
1121 -join_type => $type },
1122 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
1126 =head2 pk_depends_on
1130 =item Arguments: $relname, $rel_data
1132 =item Return value: 1/0 (true/false)
1136 Determines whether a relation is dependent on an object from this source
1137 having already been inserted. Takes the name of the relationship and a
1138 hashref of columns of the related object.
1143 my ($self, $relname, $rel_data) = @_;
1144 my $cond = $self->relationship_info($relname)->{cond};
1146 return 0 unless ref($cond) eq 'HASH';
1148 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1150 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1152 # assume anything that references our PK probably is dependent on us
1153 # rather than vice versa, unless the far side is (a) defined or (b)
1156 my $rel_source = $self->related_source($relname);
1158 foreach my $p ($self->primary_columns) {
1159 if (exists $keyhash->{$p}) {
1160 unless (defined($rel_data->{$keyhash->{$p}})
1161 || $rel_source->column_info($keyhash->{$p})
1162 ->{is_auto_increment}) {
1171 =head2 resolve_condition
1175 =item Arguments: $cond, $as, $alias|$object
1179 Resolves the passed condition to a concrete query fragment. If given an alias,
1180 returns a join condition; if given an object, inverts that object to produce
1181 a related conditional from that object.
1185 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1187 sub resolve_condition {
1188 my ($self, $cond, $as, $for) = @_;
1190 if (ref $cond eq 'HASH') {
1192 foreach my $k (keys %{$cond}) {
1193 my $v = $cond->{$k};
1194 # XXX should probably check these are valid columns
1195 $k =~ s/^foreign\.// ||
1196 $self->throw_exception("Invalid rel cond key ${k}");
1197 $v =~ s/^self\.// ||
1198 $self->throw_exception("Invalid rel cond val ${v}");
1199 if (ref $for) { # Object
1200 #warn "$self $k $for $v";
1201 unless ($for->has_column_loaded($v)) {
1202 if ($for->in_storage) {
1203 $self->throw_exception(
1204 "Column ${v} not loaded or not passed to new() prior to insert()"
1205 ." on ${for} trying to resolve relationship (maybe you forgot "
1206 ."to call ->reload_from_storage to get defaults from the db)"
1209 return $UNRESOLVABLE_CONDITION;
1211 $ret{$k} = $for->get_column($v);
1212 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1214 } elsif (!defined $for) { # undef, i.e. "no object"
1216 } elsif (ref $as eq 'HASH') { # reverse hashref
1217 $ret{$v} = $as->{$k};
1218 } elsif (ref $as) { # reverse object
1219 $ret{$v} = $as->get_column($k);
1220 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1223 $ret{"${as}.${k}"} = "${for}.${v}";
1227 } elsif (ref $cond eq 'ARRAY') {
1228 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
1230 die("Can't handle this yet :(");
1234 =head2 resolve_prefetch
1238 =item Arguments: hashref/arrayref/scalar
1242 Accepts one or more relationships for the current source and returns an
1243 array of column names for each of those relationships. Column names are
1244 prefixed relative to the current source, in accordance with where they appear
1245 in the supplied relationships. Examples:
1247 my $source = $schema->resultset('Tag')->source;
1248 @columns = $source->resolve_prefetch( { cd => 'artist' } );
1256 # 'cd.artist.artistid',
1260 @columns = $source->resolve_prefetch( qw[/ cd /] );
1270 $source = $schema->resultset('CD')->source;
1271 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
1275 # 'artist.artistid',
1277 # 'producer.producerid',
1283 sub resolve_prefetch {
1284 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1286 #$alias ||= $self->name;
1287 #warn $alias, Dumper $pre;
1288 if( ref $pre eq 'ARRAY' ) {
1290 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1293 elsif( ref $pre eq 'HASH' ) {
1296 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1297 $self->related_source($_)->resolve_prefetch(
1298 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1304 $self->throw_exception(
1305 "don't know how to resolve prefetch reftype ".ref($pre));
1308 my $count = ++$seen->{$pre};
1309 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1310 my $rel_info = $self->relationship_info( $pre );
1311 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1313 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1314 my $rel_source = $self->related_source($pre);
1316 if (exists $rel_info->{attrs}{accessor}
1317 && $rel_info->{attrs}{accessor} eq 'multi') {
1318 $self->throw_exception(
1319 "Can't prefetch has_many ${pre} (join cond too complex)")
1320 unless ref($rel_info->{cond}) eq 'HASH';
1321 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1322 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1323 keys %{$collapse}) {
1324 my ($last) = ($fail =~ /([^\.]+)$/);
1326 "Prefetching multiple has_many rels ${last} and ${pre} "
1327 .(length($as_prefix)
1328 ? "at the same level (${as_prefix}) "
1331 . 'will currently disrupt both the functionality of $rs->count(), '
1332 . 'and the amount of objects retrievable via $rs->next(). '
1333 . 'Use at your own risk.'
1336 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1337 # values %{$rel_info->{cond}};
1338 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1339 # action at a distance. prepending the '.' allows simpler code
1340 # in ResultSet->_collapse_result
1341 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1342 keys %{$rel_info->{cond}};
1343 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1344 ? @{$rel_info->{attrs}{order_by}}
1345 : (defined $rel_info->{attrs}{order_by}
1346 ? ($rel_info->{attrs}{order_by})
1348 push(@$order, map { "${as}.$_" } (@key, @ord));
1351 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1352 $rel_source->columns;
1353 #warn $alias, Dumper (\@ret);
1358 =head2 related_source
1362 =item Arguments: $relname
1364 =item Return value: $source
1368 Returns the result source object for the given relationship.
1372 sub related_source {
1373 my ($self, $rel) = @_;
1374 if( !$self->has_relationship( $rel ) ) {
1375 $self->throw_exception("No such relationship '$rel'");
1377 return $self->schema->source($self->relationship_info($rel)->{source});
1380 =head2 related_class
1384 =item Arguments: $relname
1386 =item Return value: $classname
1390 Returns the class name for objects in the given relationship.
1395 my ($self, $rel) = @_;
1396 if( !$self->has_relationship( $rel ) ) {
1397 $self->throw_exception("No such relationship '$rel'");
1399 return $self->schema->class($self->relationship_info($rel)->{source});
1404 Obtain a new handle to this source. Returns an instance of a
1405 L<DBIx::Class::ResultSourceHandle>.
1410 return new DBIx::Class::ResultSourceHandle({
1411 schema => $_[0]->schema,
1412 source_moniker => $_[0]->source_name
1416 =head2 throw_exception
1418 See L<DBIx::Class::Schema/"throw_exception">.
1422 sub throw_exception {
1424 if (defined $self->schema) {
1425 $self->schema->throw_exception(@_);
1433 Stores a hashref of per-source metadata. No specific key names
1434 have yet been standardized, the examples below are purely hypothetical
1435 and don't actually accomplish anything on their own:
1437 __PACKAGE__->source_info({
1438 "_tablespace" => 'fast_disk_array_3',
1439 "_engine" => 'InnoDB',
1446 $class->new({attribute_name => value});
1448 Creates a new ResultSource object. Not normally called directly by end users.
1450 =head2 column_info_from_storage
1454 =item Arguments: 1/0 (default: 0)
1456 =item Return value: 1/0
1460 __PACKAGE__->column_info_from_storage(1);
1462 Enables the on-demand automatic loading of the above column
1463 metadata from storage as neccesary. This is *deprecated*, and
1464 should not be used. It will be removed before 1.0.
1469 Matt S. Trout <mst@shadowcatsystems.co.uk>
1473 You may distribute this code under the same terms as Perl itself.