1 package DBIx::Class::ResultSource;
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
9 use DBIx::Class::Exception;
10 use Carp::Clan qw/^DBIx::Class/;
12 use base qw/DBIx::Class/;
14 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
15 _columns _primaries _unique_constraints name resultset_attributes
16 schema from _relationships column_info_from_storage source_info
17 source_name sqlt_deploy_callback/);
19 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
24 DBIx::Class::ResultSource - Result source object
28 # Create a table based result source, in a result class.
30 package MyDB::Schema::Result::Artist;
31 use base qw/DBIx::Class::Core/;
33 __PACKAGE__->table('artist');
34 __PACKAGE__->add_columns(qw/ artistid name /);
35 __PACKAGE__->set_primary_key('artistid');
36 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
40 # Create a query (view) based result source, in a result class
41 package MyDB::Schema::Result::Year2000CDs;
42 use base qw/DBIx::Class::Core/;
44 __PACKAGE__->load_components('InflateColumn::DateTime');
45 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
47 __PACKAGE__->table('year2000cds');
48 __PACKAGE__->result_source_instance->is_virtual(1);
49 __PACKAGE__->result_source_instance->view_definition(
50 "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
56 A ResultSource is an object that represents a source of data for querying.
58 This class is a base class for various specialised types of result
59 sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
60 default result source type, so one is created for you when defining a
61 result class as described in the synopsis above.
63 More specifically, the L<DBIx::Class::Core> base class pulls in the
64 L<DBIx::Class::ResultSourceProxy::Table> component, which defines
65 the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
66 When called, C<table> creates and stores an instance of
67 L<DBIx::Class::ResultSoure::Table>. Luckily, to use tables as result
68 sources, you don't need to remember any of this.
70 Result sources representing select queries, or views, can also be
71 created, see L<DBIx::Class::ResultSource::View> for full details.
73 =head2 Finding result source objects
75 As mentioned above, a result source instance is created and stored for
76 you when you define a L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
78 You can retrieve the result source at runtime in the following ways:
82 =item From a Schema object:
84 $schema->source($source_name);
86 =item From a Row object:
90 =item From a ResultSet object:
103 my ($class, $attrs) = @_;
104 $class = ref $class if ref $class;
106 my $new = bless { %{$attrs || {}} }, $class;
107 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
108 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
109 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
110 $new->{_columns} = { %{$new->{_columns}||{}} };
111 $new->{_relationships} = { %{$new->{_relationships}||{}} };
112 $new->{name} ||= "!!NAME NOT SET!!";
113 $new->{_columns_info_loaded} ||= 0;
114 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
124 =item Arguments: @columns
126 =item Return value: The ResultSource object
130 $source->add_columns(qw/col1 col2 col3/);
132 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
134 Adds columns to the result source. If supplied colname => hashref
135 pairs, uses the hashref as the L</column_info> for that column. Repeated
136 calls of this method will add more columns, not replace them.
138 The column names given will be created as accessor methods on your
139 L<DBIx::Class::Row> objects. You can change the name of the accessor
140 by supplying an L</accessor> in the column_info hash.
142 The contents of the column_info are not set in stone. The following
143 keys are currently recognised/used by DBIx::Class:
149 { accessor => '_name' }
151 # example use, replace standard accessor with one of your own:
153 my ($self, $value) = @_;
155 die "Name cannot contain digits!" if($value =~ /\d/);
156 $self->_name($value);
158 return $self->_name();
161 Use this to set the name of the accessor method for this column. If unset,
162 the name of the column will be used.
166 { data_type => 'integer' }
168 This contains the column type. It is automatically filled if you use the
169 L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
170 L<DBIx::Class::Schema::Loader> module.
172 Currently there is no standard set of values for the data_type. Use
173 whatever your database supports.
179 The length of your column, if it is a column type that can have a size
180 restriction. This is currently only used to create tables from your
181 schema, see L<DBIx::Class::Schema/deploy>.
187 Set this to a true value for a columns that is allowed to contain NULL
188 values, default is false. This is currently only used to create tables
189 from your schema, see L<DBIx::Class::Schema/deploy>.
191 =item is_auto_increment
193 { is_auto_increment => 1 }
195 Set this to a true value for a column whose value is somehow
196 automatically set, defaults to false. This is used to determine which
197 columns to empty when cloning objects using
198 L<DBIx::Class::Row/copy>. It is also used by
199 L<DBIx::Class::Schema/deploy>.
205 Set this to a true or false value (not C<undef>) to explicitly specify
206 if this column contains numeric data. This controls how set_column
207 decides whether to consider a column dirty after an update: if
208 C<is_numeric> is true a numeric comparison C<< != >> will take place
209 instead of the usual C<eq>
211 If not specified the storage class will attempt to figure this out on
212 first access to the column, based on the column C<data_type>. The
213 result will be cached in this attribute.
217 { is_foreign_key => 1 }
219 Set this to a true value for a column that contains a key from a
220 foreign table, defaults to false. This is currently only used to
221 create tables from your schema, see L<DBIx::Class::Schema/deploy>.
225 { default_value => \'now()' }
227 Set this to the default value which will be inserted into a column by
228 the database. Can contain either a value or a function (use a
229 reference to a scalar e.g. C<\'now()'> if you want a function). This
230 is currently only used to create tables from your schema, see
231 L<DBIx::Class::Schema/deploy>.
233 See the note on L<DBIx::Class::Row/new> for more information about possible
234 issues related to db-side default values.
238 { sequence => 'my_table_seq' }
240 Set this on a primary key column to the name of the sequence used to
241 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
242 will attempt to retrieve the name of the sequence from the database
247 Set this to a true value for a column whose value is retrieved automatically
248 from a sequence or function (if supported by your Storage driver.) For a
249 sequence, if you do not use a trigger to get the nextval, you have to set the
250 L</sequence> value as well.
252 Also set this for MSSQL columns with the 'uniqueidentifier'
253 L<DBIx::Class::ResultSource/data_type> whose values you want to automatically
254 generate using C<NEWID()>, unless they are a primary key in which case this will
259 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
260 to add extra non-generic data to the column. For example: C<< extra
261 => { unsigned => 1} >> is used by the MySQL producer to set an integer
262 column to unsigned. For more details, see
263 L<SQL::Translator::Producer::MySQL>.
271 =item Arguments: $colname, \%columninfo?
273 =item Return value: 1/0 (true/false)
277 $source->add_column('col' => \%info);
279 Add a single column and optional column info. Uses the same column
280 info keys as L</add_columns>.
285 my ($self, @cols) = @_;
286 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
289 my $columns = $self->_columns;
290 while (my $col = shift @cols) {
291 # If next entry is { ... } use that for the column info, if not
292 # use an empty hashref
293 my $column_info = ref $cols[0] ? shift(@cols) : {};
294 push(@added, $col) unless exists $columns->{$col};
295 $columns->{$col} = $column_info;
297 push @{ $self->_ordered_columns }, @added;
301 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
307 =item Arguments: $colname
309 =item Return value: 1/0 (true/false)
313 if ($source->has_column($colname)) { ... }
315 Returns true if the source has a column of this name, false otherwise.
320 my ($self, $column) = @_;
321 return exists $self->_columns->{$column};
328 =item Arguments: $colname
330 =item Return value: Hashref of info
334 my $info = $source->column_info($col);
336 Returns the column metadata hashref for a column, as originally passed
337 to L</add_columns>. See L</add_columns> above for information on the
338 contents of the hashref.
343 my ($self, $column) = @_;
344 $self->throw_exception("No such column $column")
345 unless exists $self->_columns->{$column};
346 #warn $self->{_columns_info_loaded}, "\n";
347 if ( ! $self->_columns->{$column}{data_type}
348 and $self->column_info_from_storage
349 and ! $self->{_columns_info_loaded}
350 and $self->schema and $self->storage )
352 $self->{_columns_info_loaded}++;
355 # eval for the case of storage without table
356 eval { $info = $self->storage->columns_info_for( $self->from ) };
358 for my $realcol ( keys %{$info} ) {
359 $lc_info->{lc $realcol} = $info->{$realcol};
361 foreach my $col ( keys %{$self->_columns} ) {
362 $self->_columns->{$col} = {
363 %{ $self->_columns->{$col} },
364 %{ $info->{$col} || $lc_info->{lc $col} || {} }
369 return $self->_columns->{$column};
376 =item Arguments: None
378 =item Return value: Ordered list of column names
382 my @column_names = $source->columns;
384 Returns all column names in the order they were declared to L</add_columns>.
390 $self->throw_exception(
391 "columns() is a read-only accessor, did you mean add_columns()?"
393 return @{$self->{_ordered_columns}||[]};
396 =head2 remove_columns
400 =item Arguments: @colnames
402 =item Return value: undefined
406 $source->remove_columns(qw/col1 col2 col3/);
408 Removes the given list of columns by name, from the result source.
410 B<Warning>: Removing a column that is also used in the sources primary
411 key, or in one of the sources unique constraints, B<will> result in a
412 broken result source.
418 =item Arguments: $colname
420 =item Return value: undefined
424 $source->remove_column('col');
426 Remove a single column by name from the result source, similar to
429 B<Warning>: Removing a column that is also used in the sources primary
430 key, or in one of the sources unique constraints, B<will> result in a
431 broken result source.
436 my ($self, @to_remove) = @_;
438 my $columns = $self->_columns
443 delete $columns->{$_};
447 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
450 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
452 =head2 set_primary_key
456 =item Arguments: @cols
458 =item Return value: undefined
462 Defines one or more columns as primary key for this source. Must be
463 called after L</add_columns>.
465 Additionally, defines a L<unique constraint|add_unique_constraint>
468 The primary key columns are used by L<DBIx::Class::PK::Auto> to
469 retrieve automatically created values from the database. They are also
470 used as default joining columns when specifying relationships, see
471 L<DBIx::Class::Relationship>.
475 sub set_primary_key {
476 my ($self, @cols) = @_;
477 # check if primary key columns are valid columns
478 foreach my $col (@cols) {
479 $self->throw_exception("No such column $col on table " . $self->name)
480 unless $self->has_column($col);
482 $self->_primaries(\@cols);
484 $self->add_unique_constraint(primary => \@cols);
487 =head2 primary_columns
491 =item Arguments: None
493 =item Return value: Ordered list of primary column names
497 Read-only accessor which returns the list of primary keys, supplied by
502 sub primary_columns {
503 return @{shift->_primaries||[]};
506 =head2 add_unique_constraint
510 =item Arguments: $name?, \@colnames
512 =item Return value: undefined
516 Declare a unique constraint on this source. Call once for each unique
519 # For UNIQUE (column1, column2)
520 __PACKAGE__->add_unique_constraint(
521 constraint_name => [ qw/column1 column2/ ],
524 Alternatively, you can specify only the columns:
526 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
528 This will result in a unique constraint named
529 C<table_column1_column2>, where C<table> is replaced with the table
532 Unique constraints are used, for example, when you pass the constraint
533 name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
534 only columns in the constraint are searched.
536 Throws an error if any of the given column names do not yet exist on
541 sub add_unique_constraint {
546 $name ||= $self->name_unique_constraint($cols);
548 foreach my $col (@$cols) {
549 $self->throw_exception("No such column $col on table " . $self->name)
550 unless $self->has_column($col);
553 my %unique_constraints = $self->unique_constraints;
554 $unique_constraints{$name} = $cols;
555 $self->_unique_constraints(\%unique_constraints);
558 =head2 name_unique_constraint
562 =item Arguments: @colnames
564 =item Return value: Constraint name
568 $source->table('mytable');
569 $source->name_unique_constraint('col1', 'col2');
573 Return a name for a unique constraint containing the specified
574 columns. The name is created by joining the table name and each column
575 name, using an underscore character.
577 For example, a constraint on a table named C<cd> containing the columns
578 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
580 This is used by L</add_unique_constraint> if you do not specify the
581 optional constraint name.
585 sub name_unique_constraint {
586 my ($self, $cols) = @_;
588 my $name = $self->name;
589 $name = $$name if (ref $name eq 'SCALAR');
591 return join '_', $name, @$cols;
594 =head2 unique_constraints
598 =item Arguments: None
600 =item Return value: Hash of unique constraint data
604 $source->unique_constraints();
606 Read-only accessor which returns a hash of unique constraints on this
609 The hash is keyed by constraint name, and contains an arrayref of
610 column names as values.
614 sub unique_constraints {
615 return %{shift->_unique_constraints||{}};
618 =head2 unique_constraint_names
622 =item Arguments: None
624 =item Return value: Unique constraint names
628 $source->unique_constraint_names();
630 Returns the list of unique constraint names defined on this source.
634 sub unique_constraint_names {
637 my %unique_constraints = $self->unique_constraints;
639 return keys %unique_constraints;
642 =head2 unique_constraint_columns
646 =item Arguments: $constraintname
648 =item Return value: List of constraint columns
652 $source->unique_constraint_columns('myconstraint');
654 Returns the list of columns that make up the specified unique constraint.
658 sub unique_constraint_columns {
659 my ($self, $constraint_name) = @_;
661 my %unique_constraints = $self->unique_constraints;
663 $self->throw_exception(
664 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
665 ) unless exists $unique_constraints{$constraint_name};
667 return @{ $unique_constraints{$constraint_name} };
670 =head2 sqlt_deploy_callback
674 =item Arguments: $callback
678 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
680 An accessor to set a callback to be called during deployment of
681 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
682 L<DBIx::Class::Schema/deploy>.
684 The callback can be set as either a code reference or the name of a
685 method in the current result class.
687 If not set, the L</default_sqlt_deploy_hook> is called.
689 Your callback will be passed the $source object representing the
690 ResultSource instance being deployed, and the
691 L<SQL::Translator::Schema::Table> object being created from it. The
692 callback can be used to manipulate the table object or add your own
693 customised indexes. If you need to manipulate a non-table object, use
694 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
696 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
697 Your SQL> for examples.
699 This sqlt deployment callback can only be used to manipulate
700 SQL::Translator objects as they get turned into SQL. To execute
701 post-deploy statements which SQL::Translator does not currently
702 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
703 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
705 =head2 default_sqlt_deploy_hook
709 =item Arguments: $source, $sqlt_table
711 =item Return value: undefined
715 This is the sensible default for L</sqlt_deploy_callback>.
717 If a method named C<sqlt_deploy_hook> exists in your Result class, it
718 will be called and passed the current C<$source> and the
719 C<$sqlt_table> being deployed.
723 sub default_sqlt_deploy_hook {
726 my $class = $self->result_class;
728 if ($class and $class->can('sqlt_deploy_hook')) {
729 $class->sqlt_deploy_hook(@_);
733 sub _invoke_sqlt_deploy_hook {
735 if ( my $hook = $self->sqlt_deploy_callback) {
744 =item Arguments: None
746 =item Return value: $resultset
750 Returns a resultset for the given source. This will initially be created
753 $self->resultset_class->new($self, $self->resultset_attributes)
755 but is cached from then on unless resultset_class changes.
757 =head2 resultset_class
761 =item Arguments: $classname
763 =item Return value: $classname
767 package My::Schema::ResultSet::Artist;
768 use base 'DBIx::Class::ResultSet';
771 # In the result class
772 __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
775 $source->resultset_class('My::Schema::ResultSet::Artist');
777 Set the class of the resultset. This is useful if you want to create your
778 own resultset methods. Create your own class derived from
779 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
780 this method returns the name of the existing resultset class, if one
783 =head2 resultset_attributes
787 =item Arguments: \%attrs
789 =item Return value: \%attrs
793 # In the result class
794 __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
797 $source->resultset_attributes({ order_by => [ 'id' ] });
799 Store a collection of resultset attributes, that will be set on every
800 L<DBIx::Class::ResultSet> produced from this result source. For a full
801 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
807 $self->throw_exception(
808 'resultset does not take any arguments. If you want another resultset, '.
809 'call it on the schema instead.'
812 return $self->resultset_class->new(
815 %{$self->{resultset_attributes}},
816 %{$self->schema->default_resultset_attributes}
825 =item Arguments: $source_name
827 =item Result value: $source_name
831 Set an alternate name for the result source when it is loaded into a schema.
832 This is useful if you want to refer to a result source by a name other than
835 package ArchivedBooks;
836 use base qw/DBIx::Class/;
837 __PACKAGE__->table('books_archive');
838 __PACKAGE__->source_name('Books');
840 # from your schema...
841 $schema->resultset('Books')->find(1);
847 =item Arguments: None
849 =item Return value: FROM clause
853 my $from_clause = $source->from();
855 Returns an expression of the source to be supplied to storage to specify
856 retrieval from this source. In the case of a database, the required FROM
863 =item Arguments: None
865 =item Return value: A schema object
869 my $schema = $source->schema();
871 Returns the L<DBIx::Class::Schema> object that this result source
878 =item Arguments: None
880 =item Return value: A Storage object
884 $source->storage->debug(1);
886 Returns the storage handle for the current schema.
888 See also: L<DBIx::Class::Storage>
892 sub storage { shift->schema->storage; }
894 =head2 add_relationship
898 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
900 =item Return value: 1/true if it succeeded
904 $source->add_relationship('relname', 'related_source', $cond, $attrs);
906 L<DBIx::Class::Relationship> describes a series of methods which
907 create pre-defined useful types of relationships. Look there first
908 before using this method directly.
910 The relationship name can be arbitrary, but must be unique for each
911 relationship attached to this result source. 'related_source' should
912 be the name with which the related result source was registered with
913 the current schema. For example:
915 $schema->source('Book')->add_relationship('reviews', 'Review', {
916 'foreign.book_id' => 'self.id',
919 The condition C<$cond> needs to be an L<SQL::Abstract>-style
920 representation of the join between the tables. For example, if you're
921 creating a relation from Author to Book,
923 { 'foreign.author_id' => 'self.id' }
925 will result in the JOIN clause
927 author me JOIN book foreign ON foreign.author_id = me.id
929 You can specify as many foreign => self mappings as necessary.
931 Valid attributes are as follows:
937 Explicitly specifies the type of join to use in the relationship. Any
938 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
939 the SQL command immediately before C<JOIN>.
943 An arrayref containing a list of accessors in the foreign class to proxy in
944 the main class. If, for example, you do the following:
946 CD->might_have(liner_notes => 'LinerNotes', undef, {
947 proxy => [ qw/notes/ ],
950 Then, assuming LinerNotes has an accessor named notes, you can do:
952 my $cd = CD->find(1);
953 # set notes -- LinerNotes object is created if it doesn't exist
954 $cd->notes('Notes go here');
958 Specifies the type of accessor that should be created for the
959 relationship. Valid values are C<single> (for when there is only a single
960 related object), C<multi> (when there can be many), and C<filter> (for
961 when there is a single related object, but you also want the relationship
962 accessor to double as a column accessor). For C<multi> accessors, an
963 add_to_* method is also created, which calls C<create_related> for the
968 Throws an exception if the condition is improperly supplied, or cannot
973 sub add_relationship {
974 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
975 $self->throw_exception("Can't create relationship without join condition")
979 # Check foreign and self are right in cond
980 if ( (ref $cond ||'') eq 'HASH') {
982 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
983 if /\./ && !/^foreign\./;
987 my %rels = %{ $self->_relationships };
988 $rels{$rel} = { class => $f_source_name,
989 source => $f_source_name,
992 $self->_relationships(\%rels);
996 # XXX disabled. doesn't work properly currently. skip in tests.
998 my $f_source = $self->schema->source($f_source_name);
1000 $self->ensure_class_loaded($f_source_name);
1001 $f_source = $f_source_name->result_source;
1002 #my $s_class = ref($self->schema);
1003 #$f_source_name =~ m/^${s_class}::(.*)$/;
1004 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1005 #$f_source = $self->schema->source($f_source_name);
1007 return unless $f_source; # Can't test rel without f_source
1009 eval { $self->_resolve_join($rel, 'me', {}, []) };
1011 if ($@) { # If the resolve failed, back out and re-throw the error
1012 delete $rels{$rel}; #
1013 $self->_relationships(\%rels);
1014 $self->throw_exception("Error creating relationship $rel: $@");
1019 =head2 relationships
1023 =item Arguments: None
1025 =item Return value: List of relationship names
1029 my @relnames = $source->relationships();
1031 Returns all relationship names for this source.
1036 return keys %{shift->_relationships};
1039 =head2 relationship_info
1043 =item Arguments: $relname
1045 =item Return value: Hashref of relation data,
1049 Returns a hash of relationship information for the specified relationship
1050 name. The keys/values are as specified for L</add_relationship>.
1054 sub relationship_info {
1055 my ($self, $rel) = @_;
1056 return $self->_relationships->{$rel};
1059 =head2 has_relationship
1063 =item Arguments: $rel
1065 =item Return value: 1/0 (true/false)
1069 Returns true if the source has a relationship of this name, false otherwise.
1073 sub has_relationship {
1074 my ($self, $rel) = @_;
1075 return exists $self->_relationships->{$rel};
1078 =head2 reverse_relationship_info
1082 =item Arguments: $relname
1084 =item Return value: Hashref of relationship data
1088 Looks through all the relationships on the source this relationship
1089 points to, looking for one whose condition is the reverse of the
1090 condition on this relationship.
1092 A common use of this is to find the name of the C<belongs_to> relation
1093 opposing a C<has_many> relation. For definition of these look in
1094 L<DBIx::Class::Relationship>.
1096 The returned hashref is keyed by the name of the opposing
1097 relationship, and contains its data in the same manner as
1098 L</relationship_info>.
1102 sub reverse_relationship_info {
1103 my ($self, $rel) = @_;
1104 my $rel_info = $self->relationship_info($rel);
1107 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1109 my @cond = keys(%{$rel_info->{cond}});
1110 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
1111 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
1113 # Get the related result source for this relationship
1114 my $othertable = $self->related_source($rel);
1116 # Get all the relationships for that source that related to this source
1117 # whose foreign column set are our self columns on $rel and whose self
1118 # columns are our foreign columns on $rel.
1119 my @otherrels = $othertable->relationships();
1120 my $otherrelationship;
1121 foreach my $otherrel (@otherrels) {
1122 my $otherrel_info = $othertable->relationship_info($otherrel);
1124 my $back = $othertable->related_source($otherrel);
1125 next unless $back->source_name eq $self->source_name;
1129 if (ref $otherrel_info->{cond} eq 'HASH') {
1130 @othertestconds = ($otherrel_info->{cond});
1132 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1133 @othertestconds = @{$otherrel_info->{cond}};
1139 foreach my $othercond (@othertestconds) {
1140 my @other_cond = keys(%$othercond);
1141 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1142 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1143 next if (!$self->_compare_relationship_keys(\@refkeys, \@other_keys) ||
1144 !$self->_compare_relationship_keys(\@other_refkeys, \@keys));
1145 $ret->{$otherrel} = $otherrel_info;
1151 sub compare_relationship_keys {
1152 carp 'compare_relationship_keys is a private method, stop calling it';
1154 $self->_compare_relationship_keys (@_);
1157 # Returns true if both sets of keynames are the same, false otherwise.
1158 sub _compare_relationship_keys {
1159 my ($self, $keys1, $keys2) = @_;
1161 # Make sure every keys1 is in keys2
1163 foreach my $key (@$keys1) {
1165 foreach my $prim (@$keys2) {
1166 if ($prim eq $key) {
1174 # Make sure every key2 is in key1
1176 foreach my $prim (@$keys2) {
1178 foreach my $key (@$keys1) {
1179 if ($prim eq $key) {
1192 carp 'resolve_join is a private method, stop calling it';
1194 $self->_resolve_join (@_);
1197 # Returns the {from} structure used to express JOIN conditions
1199 my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1201 # we need a supplied one, because we do in-place modifications, no returns
1202 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1203 unless ref $seen eq 'HASH';
1205 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1206 unless ref $jpath eq 'ARRAY';
1210 if (not defined $join) {
1213 elsif (ref $join eq 'ARRAY') {
1216 $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
1219 elsif (ref $join eq 'HASH') {
1222 for my $rel (keys %$join) {
1224 my $rel_info = $self->relationship_info($rel)
1225 or $self->throw_exception("No such relationship ${rel}");
1227 my $force_left = $parent_force_left;
1228 $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1230 # the actual seen value will be incremented by the recursion
1231 my $as = ($seen->{$rel} ? join ('_', $rel, $seen->{$rel} + 1) : $rel);
1234 $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1235 $self->related_source($rel)->_resolve_join(
1236 $join->{$rel}, $as, $seen, [@$jpath, $rel], $force_left
1244 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1247 my $count = ++$seen->{$join};
1248 my $as = ($count > 1 ? "${join}_${count}" : $join);
1250 my $rel_info = $self->relationship_info($join)
1251 or $self->throw_exception("No such relationship ${join}");
1253 my $rel_src = $self->related_source($join);
1254 return [ { $as => $rel_src->from,
1255 -source_handle => $rel_src->handle,
1256 -join_type => $parent_force_left
1258 : $rel_info->{attrs}{join_type}
1260 -join_path => [@$jpath, $join],
1262 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1264 $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
1269 carp 'pk_depends_on is a private method, stop calling it';
1271 $self->_pk_depends_on (@_);
1274 # Determines whether a relation is dependent on an object from this source
1275 # having already been inserted. Takes the name of the relationship and a
1276 # hashref of columns of the related object.
1277 sub _pk_depends_on {
1278 my ($self, $relname, $rel_data) = @_;
1280 my $relinfo = $self->relationship_info($relname);
1282 # don't assume things if the relationship direction is specified
1283 return $relinfo->{attrs}{is_foreign_key_constraint}
1284 if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1286 my $cond = $relinfo->{cond};
1287 return 0 unless ref($cond) eq 'HASH';
1289 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1290 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1292 # assume anything that references our PK probably is dependent on us
1293 # rather than vice versa, unless the far side is (a) defined or (b)
1295 my $rel_source = $self->related_source($relname);
1297 foreach my $p ($self->primary_columns) {
1298 if (exists $keyhash->{$p}) {
1299 unless (defined($rel_data->{$keyhash->{$p}})
1300 || $rel_source->column_info($keyhash->{$p})
1301 ->{is_auto_increment}) {
1310 sub resolve_condition {
1311 carp 'resolve_condition is a private method, stop calling it';
1313 $self->_resolve_condition (@_);
1316 # Resolves the passed condition to a concrete query fragment. If given an alias,
1317 # returns a join condition; if given an object, inverts that object to produce
1318 # a related conditional from that object.
1319 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1321 sub _resolve_condition {
1322 my ($self, $cond, $as, $for) = @_;
1323 if (ref $cond eq 'HASH') {
1325 foreach my $k (keys %{$cond}) {
1326 my $v = $cond->{$k};
1327 # XXX should probably check these are valid columns
1328 $k =~ s/^foreign\.// ||
1329 $self->throw_exception("Invalid rel cond key ${k}");
1330 $v =~ s/^self\.// ||
1331 $self->throw_exception("Invalid rel cond val ${v}");
1332 if (ref $for) { # Object
1333 #warn "$self $k $for $v";
1334 unless ($for->has_column_loaded($v)) {
1335 if ($for->in_storage) {
1336 $self->throw_exception(sprintf
1337 "Unable to resolve relationship '%s' from object %s: column '%s' not "
1338 . 'loaded from storage (or not passed to new() prior to insert()). You '
1339 . 'probably need to call ->discard_changes to get the server-side defaults '
1340 . 'from the database.',
1346 return $UNRESOLVABLE_CONDITION;
1348 $ret{$k} = $for->get_column($v);
1349 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1351 } elsif (!defined $for) { # undef, i.e. "no object"
1353 } elsif (ref $as eq 'HASH') { # reverse hashref
1354 $ret{$v} = $as->{$k};
1355 } elsif (ref $as) { # reverse object
1356 $ret{$v} = $as->get_column($k);
1357 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1360 $ret{"${as}.${k}"} = "${for}.${v}";
1364 } elsif (ref $cond eq 'ARRAY') {
1365 return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
1367 die("Can't handle condition $cond yet :(");
1371 # Legacy code, needs to go entirely away (fully replaced by _resolve_prefetch)
1372 sub resolve_prefetch {
1373 carp 'resolve_prefetch is a private method, stop calling it';
1375 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1377 if( ref $pre eq 'ARRAY' ) {
1379 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1382 elsif( ref $pre eq 'HASH' ) {
1385 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1386 $self->related_source($_)->resolve_prefetch(
1387 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1392 $self->throw_exception(
1393 "don't know how to resolve prefetch reftype ".ref($pre));
1396 my $count = ++$seen->{$pre};
1397 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1398 my $rel_info = $self->relationship_info( $pre );
1399 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1401 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1402 my $rel_source = $self->related_source($pre);
1404 if (exists $rel_info->{attrs}{accessor}
1405 && $rel_info->{attrs}{accessor} eq 'multi') {
1406 $self->throw_exception(
1407 "Can't prefetch has_many ${pre} (join cond too complex)")
1408 unless ref($rel_info->{cond}) eq 'HASH';
1409 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1410 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1411 keys %{$collapse}) {
1412 my ($last) = ($fail =~ /([^\.]+)$/);
1414 "Prefetching multiple has_many rels ${last} and ${pre} "
1415 .(length($as_prefix)
1416 ? "at the same level (${as_prefix}) "
1419 . 'will explode the number of row objects retrievable via ->next or ->all. '
1420 . 'Use at your own risk.'
1423 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1424 # values %{$rel_info->{cond}};
1425 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1426 # action at a distance. prepending the '.' allows simpler code
1427 # in ResultSet->_collapse_result
1428 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1429 keys %{$rel_info->{cond}};
1430 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1431 ? @{$rel_info->{attrs}{order_by}}
1432 : (defined $rel_info->{attrs}{order_by}
1433 ? ($rel_info->{attrs}{order_by})
1435 push(@$order, map { "${as}.$_" } (@key, @ord));
1438 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1439 $rel_source->columns;
1443 # Accepts one or more relationships for the current source and returns an
1444 # array of column names for each of those relationships. Column names are
1445 # prefixed relative to the current source, in accordance with where they appear
1446 # in the supplied relationships. Needs an alias_map generated by
1447 # $rs->_joinpath_aliases
1449 sub _resolve_prefetch {
1450 my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1453 if (not defined $pre) {
1456 elsif( ref $pre eq 'ARRAY' ) {
1458 map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
1461 elsif( ref $pre eq 'HASH' ) {
1464 $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1465 $self->related_source($_)->_resolve_prefetch(
1466 $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
1471 $self->throw_exception(
1472 "don't know how to resolve prefetch reftype ".ref($pre));
1476 $p = $p->{$_} for (@$pref_path, $pre);
1478 $self->throw_exception (
1479 "Unable to resolve prefetch '$pre' - join alias map does not contain an entry for path: "
1480 . join (' -> ', @$pref_path, $pre)
1481 ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
1483 my $as = shift @{$p->{-join_aliases}};
1485 my $rel_info = $self->relationship_info( $pre );
1486 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1488 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1489 my $rel_source = $self->related_source($pre);
1491 if (exists $rel_info->{attrs}{accessor}
1492 && $rel_info->{attrs}{accessor} eq 'multi') {
1493 $self->throw_exception(
1494 "Can't prefetch has_many ${pre} (join cond too complex)")
1495 unless ref($rel_info->{cond}) eq 'HASH';
1496 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1497 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1498 keys %{$collapse}) {
1499 my ($last) = ($fail =~ /([^\.]+)$/);
1501 "Prefetching multiple has_many rels ${last} and ${pre} "
1502 .(length($as_prefix)
1503 ? "at the same level (${as_prefix}) "
1506 . 'will explode the number of row objects retrievable via ->next or ->all. '
1507 . 'Use at your own risk.'
1510 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1511 # values %{$rel_info->{cond}};
1512 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1513 # action at a distance. prepending the '.' allows simpler code
1514 # in ResultSet->_collapse_result
1515 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1516 keys %{$rel_info->{cond}};
1517 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1518 ? @{$rel_info->{attrs}{order_by}}
1519 : (defined $rel_info->{attrs}{order_by}
1520 ? ($rel_info->{attrs}{order_by})
1522 push(@$order, map { "${as}.$_" } (@key, @ord));
1525 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1526 $rel_source->columns;
1530 =head2 related_source
1534 =item Arguments: $relname
1536 =item Return value: $source
1540 Returns the result source object for the given relationship.
1544 sub related_source {
1545 my ($self, $rel) = @_;
1546 if( !$self->has_relationship( $rel ) ) {
1547 $self->throw_exception("No such relationship '$rel'");
1549 return $self->schema->source($self->relationship_info($rel)->{source});
1552 =head2 related_class
1556 =item Arguments: $relname
1558 =item Return value: $classname
1562 Returns the class name for objects in the given relationship.
1567 my ($self, $rel) = @_;
1568 if( !$self->has_relationship( $rel ) ) {
1569 $self->throw_exception("No such relationship '$rel'");
1571 return $self->schema->class($self->relationship_info($rel)->{source});
1576 Obtain a new handle to this source. Returns an instance of a
1577 L<DBIx::Class::ResultSourceHandle>.
1582 return new DBIx::Class::ResultSourceHandle({
1583 schema => $_[0]->schema,
1584 source_moniker => $_[0]->source_name
1588 =head2 throw_exception
1590 See L<DBIx::Class::Schema/"throw_exception">.
1594 sub throw_exception {
1597 if (defined $self->schema) {
1598 $self->schema->throw_exception(@_);
1601 DBIx::Class::Exception->throw(@_);
1607 Stores a hashref of per-source metadata. No specific key names
1608 have yet been standardized, the examples below are purely hypothetical
1609 and don't actually accomplish anything on their own:
1611 __PACKAGE__->source_info({
1612 "_tablespace" => 'fast_disk_array_3',
1613 "_engine" => 'InnoDB',
1620 $class->new({attribute_name => value});
1622 Creates a new ResultSource object. Not normally called directly by end users.
1624 =head2 column_info_from_storage
1628 =item Arguments: 1/0 (default: 0)
1630 =item Return value: 1/0
1634 __PACKAGE__->column_info_from_storage(1);
1636 Enables the on-demand automatic loading of the above column
1637 metadata from storage as neccesary. This is *deprecated*, and
1638 should not be used. It will be removed before 1.0.
1643 Matt S. Trout <mst@shadowcatsystems.co.uk>
1647 You may distribute this code under the same terms as Perl itself.