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 L<DBIx::Class::Row/copy>. It is also used by
117 L<DBIx::Class::Schema/deploy>.
121 Set this to a true or false value (not C<undef>) to explicitly specify
122 if this column contains numeric data. This controls how set_column
123 decides whether to consider a column dirty after an update: if
124 C<is_numeric> is true a numeric comparison C<< != >> will take place
125 instead of the usual C<eq>
127 If not specified the storage class will attempt to figure this out on
128 first access to the column, based on the column C<data_type>. The
129 result will be cached in this attribute.
133 Set this to a true value for a column that contains a key from a
134 foreign table. This is currently only used by
135 L<DBIx::Class::Schema/deploy>.
139 Set this to the default value which will be inserted into a column
140 by the database. Can contain either a value or a function (use a
141 reference to a scalar e.g. C<\'now()'> if you want a function). This
142 is currently only used by L<DBIx::Class::Schema/deploy>.
144 See the note on L<DBIx::Class::Row/new> for more information about possible
145 issues related to db-side default values.
149 Set this on a primary key column to the name of the sequence used to
150 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
151 will attempt to retrieve the name of the sequence from the database
156 Set this to a true value for a column whose value is retrieved
157 automatically from an oracle sequence. If you do not use an Oracle
158 trigger to get the nextval, you have to set sequence as well.
162 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
163 to add extra non-generic data to the column. For example: C<< extra
164 => { unsigned => 1} >> is used by the MySQL producer to set an integer
165 column to unsigned. For more details, see
166 L<SQL::Translator::Producer::MySQL>.
174 =item Arguments: $colname, [ \%columninfo ]
176 =item Return value: 1/0 (true/false)
180 $source->add_column('col' => \%info?);
182 Add a single column and optional column info. Uses the same column
183 info keys as L</add_columns>.
188 my ($self, @cols) = @_;
189 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
192 my $columns = $self->_columns;
193 while (my $col = shift @cols) {
194 # If next entry is { ... } use that for the column info, if not
195 # use an empty hashref
196 my $column_info = ref $cols[0] ? shift(@cols) : {};
197 push(@added, $col) unless exists $columns->{$col};
198 $columns->{$col} = $column_info;
200 push @{ $self->_ordered_columns }, @added;
204 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
210 =item Arguments: $colname
212 =item Return value: 1/0 (true/false)
216 if ($source->has_column($colname)) { ... }
218 Returns true if the source has a column of this name, false otherwise.
223 my ($self, $column) = @_;
224 return exists $self->_columns->{$column};
231 =item Arguments: $colname
233 =item Return value: Hashref of info
237 my $info = $source->column_info($col);
239 Returns the column metadata hashref for a column, as originally passed
240 to L</add_columns>. See the description of L</add_columns> for information
241 on the contents of the hashref.
246 my ($self, $column) = @_;
247 $self->throw_exception("No such column $column")
248 unless exists $self->_columns->{$column};
249 #warn $self->{_columns_info_loaded}, "\n";
250 if ( ! $self->_columns->{$column}{data_type}
251 and $self->column_info_from_storage
252 and ! $self->{_columns_info_loaded}
253 and $self->schema and $self->storage )
255 $self->{_columns_info_loaded}++;
258 # eval for the case of storage without table
259 eval { $info = $self->storage->columns_info_for( $self->from ) };
261 for my $realcol ( keys %{$info} ) {
262 $lc_info->{lc $realcol} = $info->{$realcol};
264 foreach my $col ( keys %{$self->_columns} ) {
265 $self->_columns->{$col} = {
266 %{ $self->_columns->{$col} },
267 %{ $info->{$col} || $lc_info->{lc $col} || {} }
272 return $self->_columns->{$column};
279 =item Arguments: None
281 =item Return value: Ordered list of column names
285 my @column_names = $source->columns;
287 Returns all column names in the order they were declared to L</add_columns>.
293 $self->throw_exception(
294 "columns() is a read-only accessor, did you mean add_columns()?"
296 return @{$self->{_ordered_columns}||[]};
299 =head2 remove_columns
303 =item Arguments: @colnames
305 =item Return value: undefined
309 $source->remove_columns(qw/col1 col2 col3/);
311 Removes the given list of columns by name, from the result source.
313 B<Warning>: Removing a column that is also used in the sources primary
314 key, or in one of the sources unique constraints, B<will> result in a
315 broken result source.
321 =item Arguments: $colname
323 =item Return value: undefined
327 $source->remove_column('col');
329 Remove a single column by name from the result source, similar to
332 B<Warning>: Removing a column that is also used in the sources primary
333 key, or in one of the sources unique constraints, B<will> result in a
334 broken result source.
339 my ($self, @to_remove) = @_;
341 my $columns = $self->_columns
346 delete $columns->{$_};
350 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
353 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
355 =head2 set_primary_key
359 =item Arguments: @cols
361 =item Return value: undefined
365 Defines one or more columns as primary key for this source. Should be
366 called after L</add_columns>.
368 Additionally, defines a L<unique constraint|add_unique_constraint>
371 The primary key columns are used by L<DBIx::Class::PK::Auto> to
372 retrieve automatically created values from the database.
376 sub set_primary_key {
377 my ($self, @cols) = @_;
378 # check if primary key columns are valid columns
379 foreach my $col (@cols) {
380 $self->throw_exception("No such column $col on table " . $self->name)
381 unless $self->has_column($col);
383 $self->_primaries(\@cols);
385 $self->add_unique_constraint(primary => \@cols);
388 =head2 primary_columns
392 =item Arguments: None
394 =item Return value: Ordered list of primary column names
398 Read-only accessor which returns the list of primary keys, supplied by
403 sub primary_columns {
404 return @{shift->_primaries||[]};
407 =head2 add_unique_constraint
411 =item Arguments: [ $name ], \@colnames
413 =item Return value: undefined
417 Declare a unique constraint on this source. Call once for each unique
420 # For UNIQUE (column1, column2)
421 __PACKAGE__->add_unique_constraint(
422 constraint_name => [ qw/column1 column2/ ],
425 Alternatively, you can specify only the columns:
427 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
429 This will result in a unique constraint named C<table_column1_column2>, where
430 C<table> is replaced with the table name.
432 Unique constraints are used, for example, when you call
433 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
435 Throws an error if any of the given column names do not yet exist on
440 sub add_unique_constraint {
445 $name ||= $self->name_unique_constraint($cols);
447 foreach my $col (@$cols) {
448 $self->throw_exception("No such column $col on table " . $self->name)
449 unless $self->has_column($col);
452 my %unique_constraints = $self->unique_constraints;
453 $unique_constraints{$name} = $cols;
454 $self->_unique_constraints(\%unique_constraints);
457 =head2 name_unique_constraint
461 =item Arguments: @colnames
463 =item Return value: Constraint name
467 $source->table('mytable');
468 $source->name_unique_constraint('col1', 'col2');
472 Return a name for a unique constraint containing the specified
473 columns. The name is created by joining the table name and each column
474 name, using an underscore character.
476 For example, a constraint on a table named C<cd> containing the columns
477 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
479 This is used by L</add_unique_constraint> if you do not specify the
480 optional constraint name.
484 sub name_unique_constraint {
485 my ($self, $cols) = @_;
487 return join '_', $self->name, @$cols;
490 =head2 unique_constraints
494 =item Arguments: None
496 =item Return value: Hash of unique constraint data
500 $source->unique_constraints();
502 Read-only accessor which returns a hash of unique constraints on this source.
504 The hash is keyed by constraint name, and contains an arrayref of
505 column names as values.
509 sub unique_constraints {
510 return %{shift->_unique_constraints||{}};
513 =head2 unique_constraint_names
517 =item Arguments: None
519 =item Return value: Unique constraint names
523 $source->unique_constraint_names();
525 Returns the list of unique constraint names defined on this source.
529 sub unique_constraint_names {
532 my %unique_constraints = $self->unique_constraints;
534 return keys %unique_constraints;
537 =head2 unique_constraint_columns
541 =item Arguments: $constraintname
543 =item Return value: List of constraint columns
547 $source->unique_constraint_columns('myconstraint');
549 Returns the list of columns that make up the specified unique constraint.
553 sub unique_constraint_columns {
554 my ($self, $constraint_name) = @_;
556 my %unique_constraints = $self->unique_constraints;
558 $self->throw_exception(
559 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
560 ) unless exists $unique_constraints{$constraint_name};
562 return @{ $unique_constraints{$constraint_name} };
565 =head2 sqlt_deploy_callback
569 =item Arguments: $callback
573 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
575 An accessor to set a callback to be called during deployment of
576 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
577 L<DBIx::Class::Schema/deploy>.
579 The callback can be set as either a code reference or the name of a
580 method in the current result class.
582 If not set, the L</default_sqlt_deploy_hook> is called.
584 Your callback will be passed the $source object representing the
585 ResultSource instance being deployed, and the
586 L<SQL::Translator::Schema::Table> object being created from it. The
587 callback can be used to manipulate the table object or add your own
588 customised indexes. If you need to manipulate a non-table object, use
589 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
591 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
592 Your SQL> for examples.
594 This sqlt deployment callback can only be used to manipulate
595 SQL::Translator objects as they get turned into SQL. To execute
596 post-deploy statements which SQL::Translator does not currently
597 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
598 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
600 =head2 default_sqlt_deploy_hook
604 =item Arguments: $source, $sqlt_table
606 =item Return value: undefined
610 This is the sensible default for L</sqlt_deploy_callback>.
612 If a method named C<sqlt_deploy_hook> exists in your Result class, it
613 will be called and passed the current C<$source> and the
614 C<$sqlt_table> being deployed.
618 sub default_sqlt_deploy_hook {
621 my $class = $self->result_class;
623 if ($class and $class->can('sqlt_deploy_hook')) {
624 $class->sqlt_deploy_hook(@_);
628 sub _invoke_sqlt_deploy_hook {
630 if ( my $hook = $self->sqlt_deploy_callback) {
639 =item Arguments: None
641 =item Return value: $resultset
645 Returns a resultset for the given source. This will initially be created
648 $self->resultset_class->new($self, $self->resultset_attributes)
650 but is cached from then on unless resultset_class changes.
652 =head2 resultset_class
656 =item Arguments: $classname
658 =item Return value: $classname
662 package My::ResultSetClass;
663 use base 'DBIx::Class::ResultSet';
666 $source->resultset_class('My::ResultSet::Class');
668 Set the class of the resultset. This is useful if you want to create your
669 own resultset methods. Create your own class derived from
670 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
671 this method returns the name of the existing resultset class, if one
674 =head2 resultset_attributes
678 =item Arguments: \%attrs
680 =item Return value: \%attrs
684 $source->resultset_attributes({ order_by => [ 'id' ] });
686 Store a collection of resultset attributes, that will be set on every
687 L<DBIx::Class::ResultSet> produced from this result source. For a full
688 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
694 $self->throw_exception(
695 'resultset does not take any arguments. If you want another resultset, '.
696 'call it on the schema instead.'
699 return $self->resultset_class->new(
702 %{$self->{resultset_attributes}},
703 %{$self->schema->default_resultset_attributes}
712 =item Arguments: $source_name
714 =item Result value: $source_name
718 Set an alternate name for the result source when it is loaded into a schema.
719 This is useful if you want to refer to a result source by a name other than
722 package ArchivedBooks;
723 use base qw/DBIx::Class/;
724 __PACKAGE__->table('books_archive');
725 __PACKAGE__->source_name('Books');
727 # from your schema...
728 $schema->resultset('Books')->find(1);
734 =item Arguments: None
736 =item Return value: FROM clause
740 my $from_clause = $source->from();
742 Returns an expression of the source to be supplied to storage to specify
743 retrieval from this source. In the case of a database, the required FROM
750 =item Arguments: None
752 =item Return value: A schema object
756 my $schema = $source->schema();
758 Returns the L<DBIx::Class::Schema> object that this result source
765 =item Arguments: None
767 =item Return value: A Storage object
771 $source->storage->debug(1);
773 Returns the storage handle for the current schema.
775 See also: L<DBIx::Class::Storage>
779 sub storage { shift->schema->storage; }
781 =head2 add_relationship
785 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
787 =item Return value: 1/true if it succeeded
791 $source->add_relationship('relname', 'related_source', $cond, $attrs);
793 L<DBIx::Class::Relationship> describes a series of methods which
794 create pre-defined useful types of relationships. Look there first
795 before using this method directly.
797 The relationship name can be arbitrary, but must be unique for each
798 relationship attached to this result source. 'related_source' should
799 be the name with which the related result source was registered with
800 the current schema. For example:
802 $schema->source('Book')->add_relationship('reviews', 'Review', {
803 'foreign.book_id' => 'self.id',
806 The condition C<$cond> needs to be an L<SQL::Abstract>-style
807 representation of the join between the tables. For example, if you're
808 creating a relation from Author to Book,
810 { 'foreign.author_id' => 'self.id' }
812 will result in the JOIN clause
814 author me JOIN book foreign ON foreign.author_id = me.id
816 You can specify as many foreign => self mappings as necessary.
818 Valid attributes are as follows:
824 Explicitly specifies the type of join to use in the relationship. Any
825 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
826 the SQL command immediately before C<JOIN>.
830 An arrayref containing a list of accessors in the foreign class to proxy in
831 the main class. If, for example, you do the following:
833 CD->might_have(liner_notes => 'LinerNotes', undef, {
834 proxy => [ qw/notes/ ],
837 Then, assuming LinerNotes has an accessor named notes, you can do:
839 my $cd = CD->find(1);
840 # set notes -- LinerNotes object is created if it doesn't exist
841 $cd->notes('Notes go here');
845 Specifies the type of accessor that should be created for the
846 relationship. Valid values are C<single> (for when there is only a single
847 related object), C<multi> (when there can be many), and C<filter> (for
848 when there is a single related object, but you also want the relationship
849 accessor to double as a column accessor). For C<multi> accessors, an
850 add_to_* method is also created, which calls C<create_related> for the
855 Throws an exception if the condition is improperly supplied, or cannot
860 sub add_relationship {
861 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
862 $self->throw_exception("Can't create relationship without join condition")
866 # Check foreign and self are right in cond
867 if ( (ref $cond ||'') eq 'HASH') {
869 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
870 if /\./ && !/^foreign\./;
874 my %rels = %{ $self->_relationships };
875 $rels{$rel} = { class => $f_source_name,
876 source => $f_source_name,
879 $self->_relationships(\%rels);
883 # XXX disabled. doesn't work properly currently. skip in tests.
885 my $f_source = $self->schema->source($f_source_name);
887 $self->ensure_class_loaded($f_source_name);
888 $f_source = $f_source_name->result_source;
889 #my $s_class = ref($self->schema);
890 #$f_source_name =~ m/^${s_class}::(.*)$/;
891 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
892 #$f_source = $self->schema->source($f_source_name);
894 return unless $f_source; # Can't test rel without f_source
896 eval { $self->_resolve_join($rel, 'me', {}, []) };
898 if ($@) { # If the resolve failed, back out and re-throw the error
899 delete $rels{$rel}; #
900 $self->_relationships(\%rels);
901 $self->throw_exception("Error creating relationship $rel: $@");
910 =item Arguments: None
912 =item Return value: List of relationship names
916 my @relnames = $source->relationships();
918 Returns all relationship names for this source.
923 return keys %{shift->_relationships};
926 =head2 relationship_info
930 =item Arguments: $relname
932 =item Return value: Hashref of relation data,
936 Returns a hash of relationship information for the specified relationship
937 name. The keys/values are as specified for L</add_relationship>.
941 sub relationship_info {
942 my ($self, $rel) = @_;
943 return $self->_relationships->{$rel};
946 =head2 has_relationship
950 =item Arguments: $rel
952 =item Return value: 1/0 (true/false)
956 Returns true if the source has a relationship of this name, false otherwise.
960 sub has_relationship {
961 my ($self, $rel) = @_;
962 return exists $self->_relationships->{$rel};
965 =head2 reverse_relationship_info
969 =item Arguments: $relname
971 =item Return value: Hashref of relationship data
975 Looks through all the relationships on the source this relationship
976 points to, looking for one whose condition is the reverse of the
977 condition on this relationship.
979 A common use of this is to find the name of the C<belongs_to> relation
980 opposing a C<has_many> relation. For definition of these look in
981 L<DBIx::Class::Relationship>.
983 The returned hashref is keyed by the name of the opposing
984 relationship, and contains it's data in the same manner as
985 L</relationship_info>.
989 sub reverse_relationship_info {
990 my ($self, $rel) = @_;
991 my $rel_info = $self->relationship_info($rel);
994 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
996 my @cond = keys(%{$rel_info->{cond}});
997 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
998 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
1000 # Get the related result source for this relationship
1001 my $othertable = $self->related_source($rel);
1003 # Get all the relationships for that source that related to this source
1004 # whose foreign column set are our self columns on $rel and whose self
1005 # columns are our foreign columns on $rel.
1006 my @otherrels = $othertable->relationships();
1007 my $otherrelationship;
1008 foreach my $otherrel (@otherrels) {
1009 my $otherrel_info = $othertable->relationship_info($otherrel);
1011 my $back = $othertable->related_source($otherrel);
1012 next unless $back->source_name eq $self->source_name;
1016 if (ref $otherrel_info->{cond} eq 'HASH') {
1017 @othertestconds = ($otherrel_info->{cond});
1019 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1020 @othertestconds = @{$otherrel_info->{cond}};
1026 foreach my $othercond (@othertestconds) {
1027 my @other_cond = keys(%$othercond);
1028 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1029 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1030 next if (!$self->_compare_relationship_keys(\@refkeys, \@other_keys) ||
1031 !$self->_compare_relationship_keys(\@other_refkeys, \@keys));
1032 $ret->{$otherrel} = $otherrel_info;
1038 sub compare_relationship_keys {
1039 carp 'compare_relationship_keys is a private method, stop calling it';
1041 $self->_compare_relationship_keys (@_);
1044 # Returns true if both sets of keynames are the same, false otherwise.
1045 sub _compare_relationship_keys {
1046 my ($self, $keys1, $keys2) = @_;
1048 # Make sure every keys1 is in keys2
1050 foreach my $key (@$keys1) {
1052 foreach my $prim (@$keys2) {
1053 if ($prim eq $key) {
1061 # Make sure every key2 is in key1
1063 foreach my $prim (@$keys2) {
1065 foreach my $key (@$keys1) {
1066 if ($prim eq $key) {
1079 carp 'resolve_join is a private method, stop calling it';
1081 $self->_resolve_join (@_);
1084 # Returns the {from} structure used to express JOIN conditions
1086 my ($self, $join, $alias, $seen, $jpath, $force_left) = @_;
1088 # we need a supplied one, because we do in-place modifications, no returns
1089 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1090 unless ref $seen eq 'HASH';
1092 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1093 unless ref $jpath eq 'ARRAY';
1097 if (ref $join eq 'ARRAY') {
1100 $self->_resolve_join($_, $alias, $seen, $jpath, $force_left);
1102 } elsif (ref $join eq 'HASH') {
1105 my $as = ($seen->{$_} ? join ('_', $_, $seen->{$_} + 1) : $_); # the actual seen value will be incremented below
1106 local $force_left->{force} = $force_left->{force};
1108 $self->_resolve_join($_, $alias, $seen, [@$jpath], $force_left),
1109 $self->related_source($_)->_resolve_join(
1110 $join->{$_}, $as, $seen, [@$jpath, $_], $force_left
1114 } elsif (ref $join) {
1115 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1118 return() unless defined $join;
1120 my $count = ++$seen->{$join};
1121 my $as = ($count > 1 ? "${join}_${count}" : $join);
1123 my $rel_info = $self->relationship_info($join);
1124 $self->throw_exception("No such relationship ${join}") unless $rel_info;
1129 $type = $rel_info->{attrs}{join_type} || '';
1130 $force_left = 1 if lc($type) eq 'left';
1133 my $rel_src = $self->related_source($join);
1134 return [ { $as => $rel_src->from,
1135 -source_handle => $rel_src->handle,
1136 -join_type => $type,
1137 -join_path => [@$jpath, $join],
1139 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1141 $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
1146 carp 'pk_depends_on is a private method, stop calling it';
1148 $self->_pk_depends_on (@_);
1151 # Determines whether a relation is dependent on an object from this source
1152 # having already been inserted. Takes the name of the relationship and a
1153 # hashref of columns of the related object.
1154 sub _pk_depends_on {
1155 my ($self, $relname, $rel_data) = @_;
1156 my $cond = $self->relationship_info($relname)->{cond};
1158 return 0 unless ref($cond) eq 'HASH';
1160 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1162 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1164 # assume anything that references our PK probably is dependent on us
1165 # rather than vice versa, unless the far side is (a) defined or (b)
1168 my $rel_source = $self->related_source($relname);
1170 foreach my $p ($self->primary_columns) {
1171 if (exists $keyhash->{$p}) {
1172 unless (defined($rel_data->{$keyhash->{$p}})
1173 || $rel_source->column_info($keyhash->{$p})
1174 ->{is_auto_increment}) {
1183 sub resolve_condition {
1184 carp 'resolve_condition is a private method, stop calling it';
1186 $self->_resolve_condition (@_);
1189 # Resolves the passed condition to a concrete query fragment. If given an alias,
1190 # returns a join condition; if given an object, inverts that object to produce
1191 # a related conditional from that object.
1192 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1194 sub _resolve_condition {
1195 my ($self, $cond, $as, $for) = @_;
1196 if (ref $cond eq 'HASH') {
1198 foreach my $k (keys %{$cond}) {
1199 my $v = $cond->{$k};
1200 # XXX should probably check these are valid columns
1201 $k =~ s/^foreign\.// ||
1202 $self->throw_exception("Invalid rel cond key ${k}");
1203 $v =~ s/^self\.// ||
1204 $self->throw_exception("Invalid rel cond val ${v}");
1205 if (ref $for) { # Object
1206 #warn "$self $k $for $v";
1207 unless ($for->has_column_loaded($v)) {
1208 if ($for->in_storage) {
1209 $self->throw_exception(
1210 "Column ${v} not loaded or not passed to new() prior to insert()"
1211 ." on ${for} trying to resolve relationship (maybe you forgot "
1212 ."to call ->discard_changes to get defaults from the db)"
1215 return $UNRESOLVABLE_CONDITION;
1217 $ret{$k} = $for->get_column($v);
1218 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1220 } elsif (!defined $for) { # undef, i.e. "no object"
1222 } elsif (ref $as eq 'HASH') { # reverse hashref
1223 $ret{$v} = $as->{$k};
1224 } elsif (ref $as) { # reverse object
1225 $ret{$v} = $as->get_column($k);
1226 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1229 $ret{"${as}.${k}"} = "${for}.${v}";
1233 } elsif (ref $cond eq 'ARRAY') {
1234 return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
1236 die("Can't handle condition $cond yet :(");
1240 # Legacy code, needs to go entirely away (fully replaced by _resolve_prefetch)
1241 sub resolve_prefetch {
1242 carp 'resolve_prefetch is a private method, stop calling it';
1244 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1246 if( ref $pre eq 'ARRAY' ) {
1248 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1251 elsif( ref $pre eq 'HASH' ) {
1254 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1255 $self->related_source($_)->resolve_prefetch(
1256 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1261 $self->throw_exception(
1262 "don't know how to resolve prefetch reftype ".ref($pre));
1265 my $count = ++$seen->{$pre};
1266 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1267 my $rel_info = $self->relationship_info( $pre );
1268 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1270 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1271 my $rel_source = $self->related_source($pre);
1273 if (exists $rel_info->{attrs}{accessor}
1274 && $rel_info->{attrs}{accessor} eq 'multi') {
1275 $self->throw_exception(
1276 "Can't prefetch has_many ${pre} (join cond too complex)")
1277 unless ref($rel_info->{cond}) eq 'HASH';
1278 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1279 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1280 keys %{$collapse}) {
1281 my ($last) = ($fail =~ /([^\.]+)$/);
1283 "Prefetching multiple has_many rels ${last} and ${pre} "
1284 .(length($as_prefix)
1285 ? "at the same level (${as_prefix}) "
1288 . 'will explode the number of row objects retrievable via ->next or ->all. '
1289 . 'Use at your own risk.'
1292 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1293 # values %{$rel_info->{cond}};
1294 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1295 # action at a distance. prepending the '.' allows simpler code
1296 # in ResultSet->_collapse_result
1297 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1298 keys %{$rel_info->{cond}};
1299 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1300 ? @{$rel_info->{attrs}{order_by}}
1301 : (defined $rel_info->{attrs}{order_by}
1302 ? ($rel_info->{attrs}{order_by})
1304 push(@$order, map { "${as}.$_" } (@key, @ord));
1307 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1308 $rel_source->columns;
1312 # Accepts one or more relationships for the current source and returns an
1313 # array of column names for each of those relationships. Column names are
1314 # prefixed relative to the current source, in accordance with where they appear
1315 # in the supplied relationships. Needs an alias_map generated by
1316 # $rs->_joinpath_aliases
1318 sub _resolve_prefetch {
1319 my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1322 if( ref $pre eq 'ARRAY' ) {
1324 map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
1327 elsif( ref $pre eq 'HASH' ) {
1330 $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1331 $self->related_source($_)->_resolve_prefetch(
1332 $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
1337 $self->throw_exception(
1338 "don't know how to resolve prefetch reftype ".ref($pre));
1342 $p = $p->{$_} for (@$pref_path, $pre);
1344 $self->throw_exception (
1345 "Unable to resolve prefetch $pre - join alias map does not contain an entry for path: "
1346 . join (' -> ', @$pref_path, $pre)
1347 ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
1349 my $as = shift @{$p->{-join_aliases}};
1351 my $rel_info = $self->relationship_info( $pre );
1352 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1354 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1355 my $rel_source = $self->related_source($pre);
1357 if (exists $rel_info->{attrs}{accessor}
1358 && $rel_info->{attrs}{accessor} eq 'multi') {
1359 $self->throw_exception(
1360 "Can't prefetch has_many ${pre} (join cond too complex)")
1361 unless ref($rel_info->{cond}) eq 'HASH';
1362 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1363 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1364 keys %{$collapse}) {
1365 my ($last) = ($fail =~ /([^\.]+)$/);
1367 "Prefetching multiple has_many rels ${last} and ${pre} "
1368 .(length($as_prefix)
1369 ? "at the same level (${as_prefix}) "
1372 . 'will explode the number of row objects retrievable via ->next or ->all. '
1373 . 'Use at your own risk.'
1376 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1377 # values %{$rel_info->{cond}};
1378 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1379 # action at a distance. prepending the '.' allows simpler code
1380 # in ResultSet->_collapse_result
1381 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1382 keys %{$rel_info->{cond}};
1383 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1384 ? @{$rel_info->{attrs}{order_by}}
1385 : (defined $rel_info->{attrs}{order_by}
1386 ? ($rel_info->{attrs}{order_by})
1388 push(@$order, map { "${as}.$_" } (@key, @ord));
1391 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1392 $rel_source->columns;
1396 =head2 related_source
1400 =item Arguments: $relname
1402 =item Return value: $source
1406 Returns the result source object for the given relationship.
1410 sub related_source {
1411 my ($self, $rel) = @_;
1412 if( !$self->has_relationship( $rel ) ) {
1413 $self->throw_exception("No such relationship '$rel'");
1415 return $self->schema->source($self->relationship_info($rel)->{source});
1418 =head2 related_class
1422 =item Arguments: $relname
1424 =item Return value: $classname
1428 Returns the class name for objects in the given relationship.
1433 my ($self, $rel) = @_;
1434 if( !$self->has_relationship( $rel ) ) {
1435 $self->throw_exception("No such relationship '$rel'");
1437 return $self->schema->class($self->relationship_info($rel)->{source});
1442 Obtain a new handle to this source. Returns an instance of a
1443 L<DBIx::Class::ResultSourceHandle>.
1448 return new DBIx::Class::ResultSourceHandle({
1449 schema => $_[0]->schema,
1450 source_moniker => $_[0]->source_name
1454 =head2 throw_exception
1456 See L<DBIx::Class::Schema/"throw_exception">.
1460 sub throw_exception {
1462 if (defined $self->schema) {
1463 $self->schema->throw_exception(@_);
1471 Stores a hashref of per-source metadata. No specific key names
1472 have yet been standardized, the examples below are purely hypothetical
1473 and don't actually accomplish anything on their own:
1475 __PACKAGE__->source_info({
1476 "_tablespace" => 'fast_disk_array_3',
1477 "_engine" => 'InnoDB',
1484 $class->new({attribute_name => value});
1486 Creates a new ResultSource object. Not normally called directly by end users.
1488 =head2 column_info_from_storage
1492 =item Arguments: 1/0 (default: 0)
1494 =item Return value: 1/0
1498 __PACKAGE__->column_info_from_storage(1);
1500 Enables the on-demand automatic loading of the above column
1501 metadata from storage as neccesary. This is *deprecated*, and
1502 should not be used. It will be removed before 1.0.
1507 Matt S. Trout <mst@shadowcatsystems.co.uk>
1511 You may distribute this code under the same terms as Perl itself.