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/);
17 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
20 __PACKAGE__->mk_group_ro_accessors('simple' => qw/source_name/);
24 DBIx::Class::ResultSource - Result source object
30 A ResultSource is a component of a schema from which results can be directly
31 retrieved, most usually a table (see L<DBIx::Class::ResultSource::Table>)
41 $class->new({attribute_name => value});
43 Creates a new ResultSource object. Not normally called directly by end users.
48 my ($class, $attrs) = @_;
49 $class = ref $class if ref $class;
51 my $new = bless { %{$attrs || {}} }, $class;
52 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
53 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
54 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
55 $new->{_columns} = { %{$new->{_columns}||{}} };
56 $new->{_relationships} = { %{$new->{_relationships}||{}} };
57 $new->{name} ||= "!!NAME NOT SET!!";
58 $new->{_columns_info_loaded} ||= 0;
66 Stores a hashref of per-source metadata. No specific key names
67 have yet been standardized, the examples below are purely hypothetical
68 and don't actually accomplish anything on their own:
70 __PACKAGE__->source_info({
71 "_tablespace" => 'fast_disk_array_3',
72 "_engine" => 'InnoDB',
77 $table->add_columns(qw/col1 col2 col3/);
79 $table->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
81 Adds columns to the result source. If supplied key => hashref pairs, uses
82 the hashref as the column_info for that column. Repeated calls of this
83 method will add more columns, not replace them.
85 The contents of the column_info are not set in stone. The following
86 keys are currently recognised/used by DBIx::Class:
92 Use this to set the name of the accessor for this column. If unset,
93 the name of the column will be used.
97 This contains the column type. It is automatically filled by the
98 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
99 L<DBIx::Class::Schema::Loader> module. If you do not enter a
100 data_type, DBIx::Class will attempt to retrieve it from the
101 database for you, using L<DBI>'s column_info method. The values of this
102 key are typically upper-cased.
104 Currently there is no standard set of values for the data_type. Use
105 whatever your database supports.
109 The length of your column, if it is a column type that can have a size
110 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
114 Set this to a true value for a columns that is allowed to contain
115 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
117 =item is_auto_increment
119 Set this to a true value for a column whose value is somehow
120 automatically set. This is used to determine which columns to empty
121 when cloning objects using C<copy>. It is also used by
122 L<DBIx::Class::Schema/deploy>.
126 Set this to a true value for a column that contains a key from a
127 foreign table. This is currently only used by
128 L<DBIx::Class::Schema/deploy>.
132 Set this to the default value which will be inserted into a column
133 by the database. Can contain either a value or a function. This is
134 currently only used by L<DBIx::Class::Schema/deploy>.
138 Set this on a primary key column to the name of the sequence used to
139 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
140 will attempt to retrieve the name of the sequence from the database
145 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
146 to add extra non-generic data to the column. For example: C<< extras
147 => { unsigned => 1} >> is used by the MySQL producer to set an integer
148 column to unsigned. For more details, see
149 L<SQL::Translator::Producer::MySQL>.
155 $table->add_column('col' => \%info?);
157 Convenience alias to add_columns.
162 my ($self, @cols) = @_;
163 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
166 my $columns = $self->_columns;
167 while (my $col = shift @cols) {
168 # If next entry is { ... } use that for the column info, if not
169 # use an empty hashref
170 my $column_info = ref $cols[0] ? shift(@cols) : {};
171 push(@added, $col) unless exists $columns->{$col};
172 $columns->{$col} = $column_info;
174 push @{ $self->_ordered_columns }, @added;
178 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
182 if ($obj->has_column($col)) { ... }
184 Returns true if the source has a column of this name, false otherwise.
189 my ($self, $column) = @_;
190 return exists $self->_columns->{$column};
195 my $info = $obj->column_info($col);
197 Returns the column metadata hashref for a column. See the description
198 of add_column for information on the contents of the hashref.
203 my ($self, $column) = @_;
204 $self->throw_exception("No such column $column")
205 unless exists $self->_columns->{$column};
206 #warn $self->{_columns_info_loaded}, "\n";
207 if ( ! $self->_columns->{$column}{data_type}
208 and $self->column_info_from_storage
209 and ! $self->{_columns_info_loaded}
210 and $self->schema and $self->storage )
212 $self->{_columns_info_loaded}++;
215 # eval for the case of storage without table
216 eval { $info = $self->storage->columns_info_for( $self->from ) };
218 for my $realcol ( keys %{$info} ) {
219 $lc_info->{lc $realcol} = $info->{$realcol};
221 foreach my $col ( keys %{$self->_columns} ) {
222 $self->_columns->{$col} = {
223 %{ $self->_columns->{$col} },
224 %{ $info->{$col} || $lc_info->{lc $col} || {} }
229 return $self->_columns->{$column};
232 =head2 column_info_from_storage
234 Enables the on-demand automatic loading of the above column
235 metadata from storage as neccesary. This is *deprecated*, and
236 should not be used. It will be removed before 1.0.
238 __PACKAGE__->column_info_from_storage(1);
242 my @column_names = $obj->columns;
244 Returns all column names in the order they were declared to add_columns.
250 $self->throw_exception(
251 "columns() is a read-only accessor, did you mean add_columns()?"
253 return @{$self->{_ordered_columns}||[]};
256 =head2 remove_columns
258 $table->remove_columns(qw/col1 col2 col3/);
260 Removes columns from the result source.
264 $table->remove_column('col');
266 Convenience alias to remove_columns.
271 my ($self, @cols) = @_;
273 return unless $self->_ordered_columns;
275 my $columns = $self->_columns;
278 foreach my $col (@{$self->_ordered_columns}) {
279 push @remaining, $col unless grep(/$col/, @cols);
283 delete $columns->{$_};
286 $self->_ordered_columns(\@remaining);
289 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
291 =head2 set_primary_key
295 =item Arguments: @cols
299 Defines one or more columns as primary key for this source. Should be
300 called after C<add_columns>.
302 Additionally, defines a unique constraint named C<primary>.
304 The primary key columns are used by L<DBIx::Class::PK::Auto> to
305 retrieve automatically created values from the database.
309 sub set_primary_key {
310 my ($self, @cols) = @_;
311 # check if primary key columns are valid columns
312 foreach my $col (@cols) {
313 $self->throw_exception("No such column $col on table " . $self->name)
314 unless $self->has_column($col);
316 $self->_primaries(\@cols);
318 $self->add_unique_constraint(primary => \@cols);
321 =head2 primary_columns
323 Read-only accessor which returns the list of primary keys.
327 sub primary_columns {
328 return @{shift->_primaries||[]};
331 =head2 add_unique_constraint
333 Declare a unique constraint on this source. Call once for each unique
336 # For UNIQUE (column1, column2)
337 __PACKAGE__->add_unique_constraint(
338 constraint_name => [ qw/column1 column2/ ],
341 Alternatively, you can specify only the columns:
343 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
345 This will result in a unique constraint named C<table_column1_column2>, where
346 C<table> is replaced with the table name.
348 Unique constraints are used, for example, when you call
349 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
353 sub add_unique_constraint {
358 $name ||= $self->name_unique_constraint($cols);
360 foreach my $col (@$cols) {
361 $self->throw_exception("No such column $col on table " . $self->name)
362 unless $self->has_column($col);
365 my %unique_constraints = $self->unique_constraints;
366 $unique_constraints{$name} = $cols;
367 $self->_unique_constraints(\%unique_constraints);
370 =head2 name_unique_constraint
372 Return a name for a unique constraint containing the specified columns. These
373 names consist of the table name and each column name, separated by underscores.
375 For example, a constraint on a table named C<cd> containing the columns
376 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
380 sub name_unique_constraint {
381 my ($self, $cols) = @_;
383 return join '_', $self->name, @$cols;
386 =head2 unique_constraints
388 Read-only accessor which returns the list of unique constraints on this source.
392 sub unique_constraints {
393 return %{shift->_unique_constraints||{}};
396 =head2 unique_constraint_names
398 Returns the list of unique constraint names defined on this source.
402 sub unique_constraint_names {
405 my %unique_constraints = $self->unique_constraints;
407 return keys %unique_constraints;
410 =head2 unique_constraint_columns
412 Returns the list of columns that make up the specified unique constraint.
416 sub unique_constraint_columns {
417 my ($self, $constraint_name) = @_;
419 my %unique_constraints = $self->unique_constraints;
421 $self->throw_exception(
422 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
423 ) unless exists $unique_constraints{$constraint_name};
425 return @{ $unique_constraints{$constraint_name} };
430 Returns an expression of the source to be supplied to storage to specify
431 retrieval from this source. In the case of a database, the required FROM
436 Returns the L<DBIx::Class::Schema> object that this result source
441 Returns the storage handle for the current schema.
443 See also: L<DBIx::Class::Storage>
447 sub storage { shift->schema->storage; }
449 =head2 add_relationship
451 $source->add_relationship('relname', 'related_source', $cond, $attrs);
453 The relationship name can be arbitrary, but must be unique for each
454 relationship attached to this result source. 'related_source' should
455 be the name with which the related result source was registered with
456 the current schema. For example:
458 $schema->source('Book')->add_relationship('reviews', 'Review', {
459 'foreign.book_id' => 'self.id',
462 The condition C<$cond> needs to be an L<SQL::Abstract>-style
463 representation of the join between the tables. For example, if you're
464 creating a rel from Author to Book,
466 { 'foreign.author_id' => 'self.id' }
468 will result in the JOIN clause
470 author me JOIN book foreign ON foreign.author_id = me.id
472 You can specify as many foreign => self mappings as necessary.
474 Valid attributes are as follows:
480 Explicitly specifies the type of join to use in the relationship. Any
481 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
482 the SQL command immediately before C<JOIN>.
486 An arrayref containing a list of accessors in the foreign class to proxy in
487 the main class. If, for example, you do the following:
489 CD->might_have(liner_notes => 'LinerNotes', undef, {
490 proxy => [ qw/notes/ ],
493 Then, assuming LinerNotes has an accessor named notes, you can do:
495 my $cd = CD->find(1);
496 # set notes -- LinerNotes object is created if it doesn't exist
497 $cd->notes('Notes go here');
501 Specifies the type of accessor that should be created for the
502 relationship. Valid values are C<single> (for when there is only a single
503 related object), C<multi> (when there can be many), and C<filter> (for
504 when there is a single related object, but you also want the relationship
505 accessor to double as a column accessor). For C<multi> accessors, an
506 add_to_* method is also created, which calls C<create_related> for the
513 sub add_relationship {
514 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
515 $self->throw_exception("Can't create relationship without join condition")
519 my %rels = %{ $self->_relationships };
520 $rels{$rel} = { class => $f_source_name,
521 source => $f_source_name,
524 $self->_relationships(\%rels);
528 # XXX disabled. doesn't work properly currently. skip in tests.
530 my $f_source = $self->schema->source($f_source_name);
532 $self->ensure_class_loaded($f_source_name);
533 $f_source = $f_source_name->result_source;
534 #my $s_class = ref($self->schema);
535 #$f_source_name =~ m/^${s_class}::(.*)$/;
536 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
537 #$f_source = $self->schema->source($f_source_name);
539 return unless $f_source; # Can't test rel without f_source
541 eval { $self->resolve_join($rel, 'me') };
543 if ($@) { # If the resolve failed, back out and re-throw the error
544 delete $rels{$rel}; #
545 $self->_relationships(\%rels);
546 $self->throw_exception("Error creating relationship $rel: $@");
553 Returns all relationship names for this source.
558 return keys %{shift->_relationships};
561 =head2 relationship_info
565 =item Arguments: $relname
569 Returns a hash of relationship information for the specified relationship
574 sub relationship_info {
575 my ($self, $rel) = @_;
576 return $self->_relationships->{$rel};
579 =head2 has_relationship
583 =item Arguments: $rel
587 Returns true if the source has a relationship of this name, false otherwise.
591 sub has_relationship {
592 my ($self, $rel) = @_;
593 return exists $self->_relationships->{$rel};
596 =head2 reverse_relationship_info
600 =item Arguments: $relname
604 Returns an array of hash references of relationship information for
605 the other side of the specified relationship name.
609 sub reverse_relationship_info {
610 my ($self, $rel) = @_;
611 my $rel_info = $self->relationship_info($rel);
614 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
616 my @cond = keys(%{$rel_info->{cond}});
617 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
618 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
620 # Get the related result source for this relationship
621 my $othertable = $self->related_source($rel);
623 # Get all the relationships for that source that related to this source
624 # whose foreign column set are our self columns on $rel and whose self
625 # columns are our foreign columns on $rel.
626 my @otherrels = $othertable->relationships();
627 my $otherrelationship;
628 foreach my $otherrel (@otherrels) {
629 my $otherrel_info = $othertable->relationship_info($otherrel);
631 my $back = $othertable->related_source($otherrel);
632 next unless $back->name eq $self->name;
636 if (ref $otherrel_info->{cond} eq 'HASH') {
637 @othertestconds = ($otherrel_info->{cond});
639 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
640 @othertestconds = @{$otherrel_info->{cond}};
646 foreach my $othercond (@othertestconds) {
647 my @other_cond = keys(%$othercond);
648 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
649 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
650 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
651 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
652 $ret->{$otherrel} = $otherrel_info;
658 =head2 compare_relationship_keys
662 =item Arguments: $keys1, $keys2
666 Returns true if both sets of keynames are the same, false otherwise.
670 sub compare_relationship_keys {
671 my ($self, $keys1, $keys2) = @_;
673 # Make sure every keys1 is in keys2
675 foreach my $key (@$keys1) {
677 foreach my $prim (@$keys2) {
686 # Make sure every key2 is in key1
688 foreach my $prim (@$keys2) {
690 foreach my $key (@$keys1) {
707 =item Arguments: $relation
711 Returns the join structure required for the related result source.
716 my ($self, $join, $alias, $seen) = @_;
718 if (ref $join eq 'ARRAY') {
719 return map { $self->resolve_join($_, $alias, $seen) } @$join;
720 } elsif (ref $join eq 'HASH') {
723 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
724 ($self->resolve_join($_, $alias, $seen),
725 $self->related_source($_)->resolve_join($join->{$_}, $as, $seen));
727 } elsif (ref $join) {
728 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
730 my $count = ++$seen->{$join};
731 #use Data::Dumper; warn Dumper($seen);
732 my $as = ($count > 1 ? "${join}_${count}" : $join);
733 my $rel_info = $self->relationship_info($join);
734 $self->throw_exception("No such relationship ${join}") unless $rel_info;
735 my $type = $rel_info->{attrs}{join_type} || '';
736 return [ { $as => $self->related_source($join)->from,
737 -join_type => $type },
738 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
742 =head2 resolve_condition
746 =item Arguments: $cond, $as, $alias|$object
750 Resolves the passed condition to a concrete query fragment. If given an alias,
751 returns a join condition; if given an object, inverts that object to produce
752 a related conditional from that object.
756 sub resolve_condition {
757 my ($self, $cond, $as, $for) = @_;
759 if (ref $cond eq 'HASH') {
761 foreach my $k (keys %{$cond}) {
763 # XXX should probably check these are valid columns
764 $k =~ s/^foreign\.// ||
765 $self->throw_exception("Invalid rel cond key ${k}");
767 $self->throw_exception("Invalid rel cond val ${v}");
768 if (ref $for) { # Object
769 #warn "$self $k $for $v";
770 $ret{$k} = $for->get_column($v);
772 } elsif (!defined $for) { # undef, i.e. "no object"
774 } elsif (ref $as eq 'HASH') { # reverse hashref
775 $ret{$v} = $as->{$k};
776 } elsif (ref $as) { # reverse object
777 $ret{$v} = $as->get_column($k);
778 } elsif (!defined $as) { # undef, i.e. "no reverse object"
781 $ret{"${as}.${k}"} = "${for}.${v}";
785 } elsif (ref $cond eq 'ARRAY') {
786 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
788 die("Can't handle this yet :(");
792 =head2 resolve_prefetch
796 =item Arguments: hashref/arrayref/scalar
800 Accepts one or more relationships for the current source and returns an
801 array of column names for each of those relationships. Column names are
802 prefixed relative to the current source, in accordance with where they appear
803 in the supplied relationships. Examples:
805 my $source = $schema->resultset('Tag')->source;
806 @columns = $source->resolve_prefetch( { cd => 'artist' } );
814 # 'cd.artist.artistid',
818 @columns = $source->resolve_prefetch( qw[/ cd /] );
828 $source = $schema->resultset('CD')->source;
829 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
835 # 'producer.producerid',
841 sub resolve_prefetch {
842 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
844 #$alias ||= $self->name;
845 #warn $alias, Dumper $pre;
846 if( ref $pre eq 'ARRAY' ) {
848 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
851 elsif( ref $pre eq 'HASH' ) {
854 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
855 $self->related_source($_)->resolve_prefetch(
856 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
862 $self->throw_exception(
863 "don't know how to resolve prefetch reftype ".ref($pre));
866 my $count = ++$seen->{$pre};
867 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
868 my $rel_info = $self->relationship_info( $pre );
869 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
871 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
872 my $rel_source = $self->related_source($pre);
874 if (exists $rel_info->{attrs}{accessor}
875 && $rel_info->{attrs}{accessor} eq 'multi') {
876 $self->throw_exception(
877 "Can't prefetch has_many ${pre} (join cond too complex)")
878 unless ref($rel_info->{cond}) eq 'HASH';
879 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
880 # values %{$rel_info->{cond}};
881 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
882 # action at a distance. prepending the '.' allows simpler code
883 # in ResultSet->_collapse_result
884 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
885 keys %{$rel_info->{cond}};
886 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
887 ? @{$rel_info->{attrs}{order_by}}
888 : (defined $rel_info->{attrs}{order_by}
889 ? ($rel_info->{attrs}{order_by})
891 push(@$order, map { "${as}.$_" } (@key, @ord));
894 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
895 $rel_source->columns;
896 #warn $alias, Dumper (\@ret);
901 =head2 related_source
905 =item Arguments: $relname
909 Returns the result source object for the given relationship.
914 my ($self, $rel) = @_;
915 if( !$self->has_relationship( $rel ) ) {
916 $self->throw_exception("No such relationship '$rel'");
918 return $self->schema->source($self->relationship_info($rel)->{source});
925 =item Arguments: $relname
929 Returns the class name for objects in the given relationship.
934 my ($self, $rel) = @_;
935 if( !$self->has_relationship( $rel ) ) {
936 $self->throw_exception("No such relationship '$rel'");
938 return $self->schema->class($self->relationship_info($rel)->{source});
943 Returns a resultset for the given source. This will initially be created
946 $self->resultset_class->new($self, $self->resultset_attributes)
948 but is cached from then on unless resultset_class changes.
950 =head2 resultset_class
952 ` package My::ResultSetClass;
953 use base 'DBIx::Class::ResultSet';
956 $source->resultset_class('My::ResultSet::Class');
958 Set the class of the resultset, this is useful if you want to create your
959 own resultset methods. Create your own class derived from
960 L<DBIx::Class::ResultSet>, and set it here.
962 =head2 resultset_attributes
964 $source->resultset_attributes({ order_by => [ 'id' ] });
966 Specify here any attributes you wish to pass to your specialised
967 resultset. For a full list of these, please see
968 L<DBIx::Class::ResultSet/ATTRIBUTES>.
974 $self->throw_exception(
975 'resultset does not take any arguments. If you want another resultset, '.
976 'call it on the schema instead.'
979 return $self->resultset_class->new(
980 $self, $self->{resultset_attributes}
988 =item Arguments: $source_name
992 Set the name of the result source when it is loaded into a schema.
993 This is usefull if you want to refer to a result source by a name other than
996 package ArchivedBooks;
997 use base qw/DBIx::Class/;
998 __PACKAGE__->table('books_archive');
999 __PACKAGE__->source_name('Books');
1001 # from your schema...
1002 $schema->resultset('Books')->find(1);
1006 Obtain a new handle to this source. Returns an instance of a
1007 L<DBIx::Class::ResultSourceHandle>.
1012 return new DBIx::Class::ResultSourceHandle({
1013 schema => $_[0]->schema,
1014 source_moniker => $_[0]->source_name
1018 =head2 throw_exception
1020 See L<DBIx::Class::Schema/"throw_exception">.
1024 sub throw_exception {
1026 if (defined $self->schema) {
1027 $self->schema->throw_exception(@_);
1035 Matt S. Trout <mst@shadowcatsystems.co.uk>
1039 You may distribute this code under the same terms as Perl itself.