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('inherited' => 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 = { %{$attrs || {}}, _resultset => undef };
54 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
55 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
56 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
57 $new->{_columns} = { %{$new->{_columns}||{}} };
58 $new->{_relationships} = { %{$new->{_relationships}||{}} };
59 $new->{name} ||= "!!NAME NOT SET!!";
60 $new->{_columns_info_loaded} ||= 0;
68 Stores a hashref of per-source metadata. No specific key names
69 have yet been standardized, the examples below are purely hypothetical
70 and don't actually accomplish anything on their own:
72 __PACKAGE__->source_info({
73 "_tablespace" => 'fast_disk_array_3',
74 "_engine" => 'InnoDB',
79 $table->add_columns(qw/col1 col2 col3/);
81 $table->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
83 Adds columns to the result source. If supplied key => hashref pairs, uses
84 the hashref as the column_info for that column. Repeated calls of this
85 method will add more columns, not replace them.
87 The contents of the column_info are not set in stone. The following
88 keys are currently recognised/used by DBIx::Class:
94 Use this to set the name of the accessor for this column. If unset,
95 the name of the column will be used.
99 This contains the column type. It is automatically filled by the
100 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
101 L<DBIx::Class::Schema::Loader> module. If you do not enter a
102 data_type, DBIx::Class will attempt to retrieve it from the
103 database for you, using L<DBI>'s column_info method. The values of this
104 key are typically upper-cased.
106 Currently there is no standard set of values for the data_type. Use
107 whatever your database supports.
111 The length of your column, if it is a column type that can have a size
112 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
116 Set this to a true value for a columns that is allowed to contain
117 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
119 =item is_auto_increment
121 Set this to a true value for a column whose value is somehow
122 automatically set. This is used to determine which columns to empty
123 when cloning objects using C<copy>. It is also used by
124 L<DBIx::Class::Schema/deploy>.
128 Set this to a true value for a column that contains a key from a
129 foreign table. This is currently only used by
130 L<DBIx::Class::Schema/deploy>.
134 Set this to the default value which will be inserted into a column
135 by the database. Can contain either a value or a function. This is
136 currently only used by L<DBIx::Class::Schema/deploy>.
140 Set this on a primary key column to the name of the sequence used to
141 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
142 will attempt to retrieve the name of the sequence from the database
147 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
148 to add extra non-generic data to the column. For example: C<< extras
149 => { unsigned => 1} >> is used by the MySQL producer to set an integer
150 column to unsigned. For more details, see
151 L<SQL::Translator::Producer::MySQL>.
157 $table->add_column('col' => \%info?);
159 Convenience alias to add_columns.
164 my ($self, @cols) = @_;
165 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
168 my $columns = $self->_columns;
169 while (my $col = shift @cols) {
170 # If next entry is { ... } use that for the column info, if not
171 # use an empty hashref
172 my $column_info = ref $cols[0] ? shift(@cols) : {};
173 push(@added, $col) unless exists $columns->{$col};
174 $columns->{$col} = $column_info;
176 push @{ $self->_ordered_columns }, @added;
180 *add_column = \&add_columns;
184 if ($obj->has_column($col)) { ... }
186 Returns true if the source has a column of this name, false otherwise.
191 my ($self, $column) = @_;
192 return exists $self->_columns->{$column};
197 my $info = $obj->column_info($col);
199 Returns the column metadata hashref for a column. See the description
200 of add_column for information on the contents of the hashref.
205 my ($self, $column) = @_;
206 $self->throw_exception("No such column $column")
207 unless exists $self->_columns->{$column};
208 #warn $self->{_columns_info_loaded}, "\n";
209 if ( ! $self->_columns->{$column}{data_type}
210 and $self->column_info_from_storage
211 and ! $self->{_columns_info_loaded}
212 and $self->schema and $self->storage )
214 $self->{_columns_info_loaded}++;
217 # eval for the case of storage without table
218 eval { $info = $self->storage->columns_info_for( $self->from ) };
220 for my $realcol ( keys %{$info} ) {
221 $lc_info->{lc $realcol} = $info->{$realcol};
223 foreach my $col ( keys %{$self->_columns} ) {
224 $self->_columns->{$col} = {
225 %{ $self->_columns->{$col} },
226 %{ $info->{$col} || $lc_info->{lc $col} || {} }
231 return $self->_columns->{$column};
234 =head2 column_info_from_storage
236 Enables the on-demand automatic loading of the above column
237 metadata from storage as neccesary. This is *deprecated*, and
238 should not be used. It will be removed before 1.0.
240 __PACKAGE__->column_info_from_storage(1);
244 my @column_names = $obj->columns;
246 Returns all column names in the order they were declared to add_columns.
252 $self->throw_exception(
253 "columns() is a read-only accessor, did you mean add_columns()?"
255 return @{$self->{_ordered_columns}||[]};
258 =head2 remove_columns
260 $table->remove_columns(qw/col1 col2 col3/);
262 Removes columns from the result source.
266 $table->remove_column('col');
268 Convenience alias to remove_columns.
273 my ($self, @cols) = @_;
275 return unless $self->_ordered_columns;
277 my $columns = $self->_columns;
280 foreach my $col (@{$self->_ordered_columns}) {
281 push @remaining, $col unless grep(/$col/, @cols);
285 delete $columns->{$_};
288 $self->_ordered_columns(\@remaining);
291 *remove_column = \&remove_columns;
293 =head2 set_primary_key
297 =item Arguments: @cols
301 Defines one or more columns as primary key for this source. Should be
302 called after C<add_columns>.
304 Additionally, defines a unique constraint named C<primary>.
306 The primary key columns are used by L<DBIx::Class::PK::Auto> to
307 retrieve automatically created values from the database.
311 sub set_primary_key {
312 my ($self, @cols) = @_;
313 # check if primary key columns are valid columns
314 foreach my $col (@cols) {
315 $self->throw_exception("No such column $col on table " . $self->name)
316 unless $self->has_column($col);
318 $self->_primaries(\@cols);
320 $self->add_unique_constraint(primary => \@cols);
323 =head2 primary_columns
325 Read-only accessor which returns the list of primary keys.
329 sub primary_columns {
330 return @{shift->_primaries||[]};
333 =head2 add_unique_constraint
335 Declare a unique constraint on this source. Call once for each unique
338 # For UNIQUE (column1, column2)
339 __PACKAGE__->add_unique_constraint(
340 constraint_name => [ qw/column1 column2/ ],
343 Alternatively, you can specify only the columns:
345 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
347 This will result in a unique constraint named C<table_column1_column2>, where
348 C<table> is replaced with the table name.
350 Unique constraints are used, for example, when you call
351 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
355 sub add_unique_constraint {
360 $name ||= $self->name_unique_constraint($cols);
362 foreach my $col (@$cols) {
363 $self->throw_exception("No such column $col on table " . $self->name)
364 unless $self->has_column($col);
367 my %unique_constraints = $self->unique_constraints;
368 $unique_constraints{$name} = $cols;
369 $self->_unique_constraints(\%unique_constraints);
372 =head2 name_unique_constraint
374 Return a name for a unique constraint containing the specified columns. These
375 names consist of the table name and each column name, separated by underscores.
377 For example, a constraint on a table named C<cd> containing the columns
378 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
382 sub name_unique_constraint {
383 my ($self, $cols) = @_;
385 return join '_', $self->name, @$cols;
388 =head2 unique_constraints
390 Read-only accessor which returns the list of unique constraints on this source.
394 sub unique_constraints {
395 return %{shift->_unique_constraints||{}};
398 =head2 unique_constraint_names
400 Returns the list of unique constraint names defined on this source.
404 sub unique_constraint_names {
407 my %unique_constraints = $self->unique_constraints;
409 return keys %unique_constraints;
412 =head2 unique_constraint_columns
414 Returns the list of columns that make up the specified unique constraint.
418 sub unique_constraint_columns {
419 my ($self, $constraint_name) = @_;
421 my %unique_constraints = $self->unique_constraints;
423 $self->throw_exception(
424 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
425 ) unless exists $unique_constraints{$constraint_name};
427 return @{ $unique_constraints{$constraint_name} };
432 Returns an expression of the source to be supplied to storage to specify
433 retrieval from this source. In the case of a database, the required FROM
438 Returns the L<DBIx::Class::Schema> object that this result source
443 Returns the storage handle for the current schema.
445 See also: L<DBIx::Class::Storage>
449 sub storage { shift->schema->storage; }
451 =head2 add_relationship
453 $source->add_relationship('relname', 'related_source', $cond, $attrs);
455 The relationship name can be arbitrary, but must be unique for each
456 relationship attached to this result source. 'related_source' should
457 be the name with which the related result source was registered with
458 the current schema. For example:
460 $schema->source('Book')->add_relationship('reviews', 'Review', {
461 'foreign.book_id' => 'self.id',
464 The condition C<$cond> needs to be an L<SQL::Abstract>-style
465 representation of the join between the tables. For example, if you're
466 creating a rel from Author to Book,
468 { 'foreign.author_id' => 'self.id' }
470 will result in the JOIN clause
472 author me JOIN book foreign ON foreign.author_id = me.id
474 You can specify as many foreign => self mappings as necessary.
476 Valid attributes are as follows:
482 Explicitly specifies the type of join to use in the relationship. Any
483 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
484 the SQL command immediately before C<JOIN>.
488 An arrayref containing a list of accessors in the foreign class to proxy in
489 the main class. If, for example, you do the following:
491 CD->might_have(liner_notes => 'LinerNotes', undef, {
492 proxy => [ qw/notes/ ],
495 Then, assuming LinerNotes has an accessor named notes, you can do:
497 my $cd = CD->find(1);
498 # set notes -- LinerNotes object is created if it doesn't exist
499 $cd->notes('Notes go here');
503 Specifies the type of accessor that should be created for the
504 relationship. Valid values are C<single> (for when there is only a single
505 related object), C<multi> (when there can be many), and C<filter> (for
506 when there is a single related object, but you also want the relationship
507 accessor to double as a column accessor). For C<multi> accessors, an
508 add_to_* method is also created, which calls C<create_related> for the
515 sub add_relationship {
516 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
517 $self->throw_exception("Can't create relationship without join condition")
521 my %rels = %{ $self->_relationships };
522 $rels{$rel} = { class => $f_source_name,
523 source => $f_source_name,
526 $self->_relationships(\%rels);
530 # XXX disabled. doesn't work properly currently. skip in tests.
532 my $f_source = $self->schema->source($f_source_name);
534 $self->ensure_class_loaded($f_source_name);
535 $f_source = $f_source_name->result_source;
536 #my $s_class = ref($self->schema);
537 #$f_source_name =~ m/^${s_class}::(.*)$/;
538 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
539 #$f_source = $self->schema->source($f_source_name);
541 return unless $f_source; # Can't test rel without f_source
543 eval { $self->resolve_join($rel, 'me') };
545 if ($@) { # If the resolve failed, back out and re-throw the error
546 delete $rels{$rel}; #
547 $self->_relationships(\%rels);
548 $self->throw_exception("Error creating relationship $rel: $@");
555 Returns all relationship names for this source.
560 return keys %{shift->_relationships};
563 =head2 relationship_info
567 =item Arguments: $relname
571 Returns a hash of relationship information for the specified relationship
576 sub relationship_info {
577 my ($self, $rel) = @_;
578 return $self->_relationships->{$rel};
581 =head2 has_relationship
585 =item Arguments: $rel
589 Returns true if the source has a relationship of this name, false otherwise.
593 sub has_relationship {
594 my ($self, $rel) = @_;
595 return exists $self->_relationships->{$rel};
598 =head2 reverse_relationship_info
602 =item Arguments: $relname
606 Returns an array of hash references of relationship information for
607 the other side of the specified relationship name.
611 sub reverse_relationship_info {
612 my ($self, $rel) = @_;
613 my $rel_info = $self->relationship_info($rel);
616 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
618 my @cond = keys(%{$rel_info->{cond}});
619 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
620 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
622 # Get the related result source for this relationship
623 my $othertable = $self->related_source($rel);
625 # Get all the relationships for that source that related to this source
626 # whose foreign column set are our self columns on $rel and whose self
627 # columns are our foreign columns on $rel.
628 my @otherrels = $othertable->relationships();
629 my $otherrelationship;
630 foreach my $otherrel (@otherrels) {
631 my $otherrel_info = $othertable->relationship_info($otherrel);
633 my $back = $othertable->related_source($otherrel);
634 next unless $back->name eq $self->name;
638 if (ref $otherrel_info->{cond} eq 'HASH') {
639 @othertestconds = ($otherrel_info->{cond});
641 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
642 @othertestconds = @{$otherrel_info->{cond}};
648 foreach my $othercond (@othertestconds) {
649 my @other_cond = keys(%$othercond);
650 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
651 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
652 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
653 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
654 $ret->{$otherrel} = $otherrel_info;
660 =head2 compare_relationship_keys
664 =item Arguments: $keys1, $keys2
668 Returns true if both sets of keynames are the same, false otherwise.
672 sub compare_relationship_keys {
673 my ($self, $keys1, $keys2) = @_;
675 # Make sure every keys1 is in keys2
677 foreach my $key (@$keys1) {
679 foreach my $prim (@$keys2) {
688 # Make sure every key2 is in key1
690 foreach my $prim (@$keys2) {
692 foreach my $key (@$keys1) {
709 =item Arguments: $relation
713 Returns the join structure required for the related result source.
718 my ($self, $join, $alias, $seen) = @_;
720 if (ref $join eq 'ARRAY') {
721 return map { $self->resolve_join($_, $alias, $seen) } @$join;
722 } elsif (ref $join eq 'HASH') {
725 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
726 ($self->resolve_join($_, $alias, $seen),
727 $self->related_source($_)->resolve_join($join->{$_}, $as, $seen));
729 } elsif (ref $join) {
730 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
732 my $count = ++$seen->{$join};
733 #use Data::Dumper; warn Dumper($seen);
734 my $as = ($count > 1 ? "${join}_${count}" : $join);
735 my $rel_info = $self->relationship_info($join);
736 $self->throw_exception("No such relationship ${join}") unless $rel_info;
737 my $type = $rel_info->{attrs}{join_type} || '';
738 return [ { $as => $self->related_source($join)->from,
739 -join_type => $type },
740 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
744 =head2 resolve_condition
748 =item Arguments: $cond, $as, $alias|$object
752 Resolves the passed condition to a concrete query fragment. If given an alias,
753 returns a join condition; if given an object, inverts that object to produce
754 a related conditional from that object.
758 sub resolve_condition {
759 my ($self, $cond, $as, $for) = @_;
761 if (ref $cond eq 'HASH') {
763 foreach my $k (keys %{$cond}) {
765 # XXX should probably check these are valid columns
766 $k =~ s/^foreign\.// ||
767 $self->throw_exception("Invalid rel cond key ${k}");
769 $self->throw_exception("Invalid rel cond val ${v}");
770 if (ref $for) { # Object
771 #warn "$self $k $for $v";
772 $ret{$k} = $for->get_column($v);
774 } elsif (!defined $for) { # undef, i.e. "no object"
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 @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
880 keys %{$rel_info->{cond}};
881 $collapse->{"${as_prefix}${pre}"} = \@key;
882 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
883 ? @{$rel_info->{attrs}{order_by}}
884 : (defined $rel_info->{attrs}{order_by}
885 ? ($rel_info->{attrs}{order_by})
887 push(@$order, map { "${as}.$_" } (@key, @ord));
890 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
891 $rel_source->columns;
892 #warn $alias, Dumper (\@ret);
897 =head2 related_source
901 =item Arguments: $relname
905 Returns the result source object for the given relationship.
910 my ($self, $rel) = @_;
911 if( !$self->has_relationship( $rel ) ) {
912 $self->throw_exception("No such relationship '$rel'");
914 return $self->schema->source($self->relationship_info($rel)->{source});
921 =item Arguments: $relname
925 Returns the class name for objects in the given relationship.
930 my ($self, $rel) = @_;
931 if( !$self->has_relationship( $rel ) ) {
932 $self->throw_exception("No such relationship '$rel'");
934 return $self->schema->class($self->relationship_info($rel)->{source});
939 Returns a resultset for the given source. This will initially be created
942 $self->resultset_class->new($self, $self->resultset_attributes)
944 but is cached from then on unless resultset_class changes.
946 =head2 resultset_class
948 ` package My::ResultSetClass;
949 use base 'DBIx::Class::ResultSet';
952 $source->resultset_class('My::ResultSet::Class');
954 Set the class of the resultset, this is useful if you want to create your
955 own resultset methods. Create your own class derived from
956 L<DBIx::Class::ResultSet>, and set it here.
958 =head2 resultset_attributes
960 $source->resultset_attributes({ order_by => [ 'id' ] });
962 Specify here any attributes you wish to pass to your specialised resultset.
968 $self->throw_exception(
969 'resultset does not take any arguments. If you want another resultset, '.
970 'call it on the schema instead.'
973 # disabled until we can figure out a way to do it without consistency issues
975 #return $self->{_resultset}
976 # if ref $self->{_resultset} eq $self->resultset_class;
977 #return $self->{_resultset} =
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.