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
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>)
40 $class->new({attribute_name => value});
42 Creates a new ResultSource object. Not normally called directly by end users.
47 my ($class, $attrs) = @_;
48 $class = ref $class if ref $class;
50 my $new = bless { %{$attrs || {}} }, $class;
51 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
52 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
53 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
54 $new->{_columns} = { %{$new->{_columns}||{}} };
55 $new->{_relationships} = { %{$new->{_relationships}||{}} };
56 $new->{name} ||= "!!NAME NOT SET!!";
57 $new->{_columns_info_loaded} ||= 0;
65 Stores a hashref of per-source metadata. No specific key names
66 have yet been standardized, the examples below are purely hypothetical
67 and don't actually accomplish anything on their own:
69 __PACKAGE__->source_info({
70 "_tablespace" => 'fast_disk_array_3',
71 "_engine" => 'InnoDB',
78 =item Arguments: @columns
80 =item Return value: The ResultSource object
84 $table->add_columns(qw/col1 col2 col3/);
86 $table->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
88 Adds columns to the result source. If supplied key => hashref pairs, uses
89 the hashref as the column_info for that column. Repeated calls of this
90 method will add more columns, not replace them.
92 The column names given will be created as accessor methods on your
93 L<DBIx::Class::Row> objects, you can change the name of the accessor
94 by supplying an L</accessor> in the column_info hash.
96 The contents of the column_info are not set in stone. The following
97 keys are currently recognised/used by DBIx::Class:
103 Use this to set the name of the accessor method for this column. If unset,
104 the name of the column will be used.
108 This contains the column type. It is automatically filled by the
109 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
110 L<DBIx::Class::Schema::Loader> module. If you do not enter a
111 data_type, DBIx::Class will attempt to retrieve it from the
112 database for you, using L<DBI>'s column_info method. The values of this
113 key are typically upper-cased.
115 Currently there is no standard set of values for the data_type. Use
116 whatever your database supports.
120 The length of your column, if it is a column type that can have a size
121 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
125 Set this to a true value for a columns that is allowed to contain
126 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
128 =item is_auto_increment
130 Set this to a true value for a column whose value is somehow
131 automatically set. This is used to determine which columns to empty
132 when cloning objects using C<copy>. It is also used by
133 L<DBIx::Class::Schema/deploy>.
137 Set this to a true value for a column that contains a key from a
138 foreign table. This is currently only used by
139 L<DBIx::Class::Schema/deploy>.
143 Set this to the default value which will be inserted into a column
144 by the database. Can contain either a value or a function. This is
145 currently only used by L<DBIx::Class::Schema/deploy>.
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 $table->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 ($obj->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 = $obj->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};
275 =head2 column_info_from_storage
279 =item Arguments: 1/0 (default: 0)
281 =item Return value: 1/0
285 Enables the on-demand automatic loading of the above column
286 metadata from storage as neccesary. This is *deprecated*, and
287 should not be used. It will be removed before 1.0.
289 __PACKAGE__->column_info_from_storage(1);
295 =item Arguments: None
297 =item Return value: Ordered list of column names
301 my @column_names = $source->columns;
303 Returns all column names in the order they were declared to L</add_columns>.
309 $self->throw_exception(
310 "columns() is a read-only accessor, did you mean add_columns()?"
312 return @{$self->{_ordered_columns}||[]};
315 =head2 remove_columns
319 =item Arguments: @colnames
321 =item Return value: undefined
325 $source->remove_columns(qw/col1 col2 col3/);
327 Removes the given list of columns by name, from the result source.
329 B<Warning>: Removing a column that is also used in the sources primary
330 key, or in one of the sources unique constraints, B<will> result in a
331 broken result source.
337 =item Arguments: $colname
339 =item Return value: undefined
343 $source->remove_column('col');
345 Remove a single column by name from the result source, similar to
348 B<Warning>: Removing a column that is also used in the sources primary
349 key, or in one of the sources unique constraints, B<will> result in a
350 broken result source.
355 my ($self, @cols) = @_;
357 return unless $self->_ordered_columns;
359 my $columns = $self->_columns;
362 foreach my $col (@{$self->_ordered_columns}) {
363 push @remaining, $col unless grep(/$col/, @cols);
367 delete $columns->{$_};
370 $self->_ordered_columns(\@remaining);
373 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
375 =head2 set_primary_key
379 =item Arguments: @cols
381 =item Return value: undefined
385 Defines one or more columns as primary key for this source. Should be
386 called after L</add_columns>.
388 Additionally, defines a L<unique constraint|add_unique_constraint>
391 The primary key columns are used by L<DBIx::Class::PK::Auto> to
392 retrieve automatically created values from the database.
396 sub set_primary_key {
397 my ($self, @cols) = @_;
398 # check if primary key columns are valid columns
399 foreach my $col (@cols) {
400 $self->throw_exception("No such column $col on table " . $self->name)
401 unless $self->has_column($col);
403 $self->_primaries(\@cols);
405 $self->add_unique_constraint(primary => \@cols);
408 =head2 primary_columns
412 =item Arguments: None
414 =item Return value: Ordered list of primary column names
418 Read-only accessor which returns the list of primary keys, supplied by
423 sub primary_columns {
424 return @{shift->_primaries||[]};
427 =head2 add_unique_constraint
431 =item Arguments: [ $name ], \@colnames
433 =item Return value: undefined
437 Declare a unique constraint on this source. Call once for each unique
440 # For UNIQUE (column1, column2)
441 __PACKAGE__->add_unique_constraint(
442 constraint_name => [ qw/column1 column2/ ],
445 Alternatively, you can specify only the columns:
447 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
449 This will result in a unique constraint named C<table_column1_column2>, where
450 C<table> is replaced with the table name.
452 Unique constraints are used, for example, when you call
453 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
455 Throws an error if any of the given column names do not yet exist on
460 sub add_unique_constraint {
465 $name ||= $self->name_unique_constraint($cols);
467 foreach my $col (@$cols) {
468 $self->throw_exception("No such column $col on table " . $self->name)
469 unless $self->has_column($col);
472 my %unique_constraints = $self->unique_constraints;
473 $unique_constraints{$name} = $cols;
474 $self->_unique_constraints(\%unique_constraints);
477 =head2 name_unique_constraint
481 =item Arguments: @colnames
483 =item Return value: Constraint name
487 $source->table('mytable');
488 $source->name_unique_constraint('col1', 'col2');
492 Return a name for a unique constraint containing the specified
493 columns. The name is created by joining the table name and each column
494 name, using an underscore character.
496 For example, a constraint on a table named C<cd> containing the columns
497 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
499 This is used by L</add_unique_constraint> if you do not specify the
500 optional constraint name.
504 sub name_unique_constraint {
505 my ($self, $cols) = @_;
507 return join '_', $self->name, @$cols;
510 =head2 unique_constraints
514 =item Arguments: None
516 =item Return value: Hash of unique constraint data
520 $source->unique_constraints();
522 Read-only accessor which returns a hash of unique constraints on this source.
524 The hash is keyed by constraint name, and contains an arrayref of
525 column names as values.
529 sub unique_constraints {
530 return %{shift->_unique_constraints||{}};
533 =head2 unique_constraint_names
537 =item Arguments: None
539 =item Return value: Unique constraint names
543 $source->unique_constraint_names();
545 Returns the list of unique constraint names defined on this source.
549 sub unique_constraint_names {
552 my %unique_constraints = $self->unique_constraints;
554 return keys %unique_constraints;
557 =head2 unique_constraint_columns
561 =item Arguments: $constraintname
563 =item Return value: List of constraint columns
567 $source->unique_constraint_columns('myconstraint');
569 Returns the list of columns that make up the specified unique constraint.
573 sub unique_constraint_columns {
574 my ($self, $constraint_name) = @_;
576 my %unique_constraints = $self->unique_constraints;
578 $self->throw_exception(
579 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
580 ) unless exists $unique_constraints{$constraint_name};
582 return @{ $unique_constraints{$constraint_name} };
589 =item Arguments: None
591 =item Return value: FROM clause
595 my $from_clause = $source->from();
597 Returns an expression of the source to be supplied to storage to specify
598 retrieval from this source. In the case of a database, the required FROM
605 =item Arguments: None
607 =item Return value: A schema object
611 my $schema = $source->schema();
613 Returns the L<DBIx::Class::Schema> object that this result source
620 =item Arguments: None
622 =item Return value: A Storage object
626 $source->storage->debug(1);
628 Returns the storage handle for the current schema.
630 See also: L<DBIx::Class::Storage>
634 sub storage { shift->schema->storage; }
636 =head2 add_relationship
640 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
642 =item Return value: 1/true if it succeeded
646 $source->add_relationship('relname', 'related_source', $cond, $attrs);
648 L<DBIx::Class::Relationship> describes a series of methods which
649 create pre-defined useful types of relationships. Look there first
650 before using this method directly.
652 The relationship name can be arbitrary, but must be unique for each
653 relationship attached to this result source. 'related_source' should
654 be the name with which the related result source was registered with
655 the current schema. For example:
657 $schema->source('Book')->add_relationship('reviews', 'Review', {
658 'foreign.book_id' => 'self.id',
661 The condition C<$cond> needs to be an L<SQL::Abstract>-style
662 representation of the join between the tables. For example, if you're
663 creating a relation from Author to Book,
665 { 'foreign.author_id' => 'self.id' }
667 will result in the JOIN clause
669 author me JOIN book foreign ON foreign.author_id = me.id
671 You can specify as many foreign => self mappings as necessary.
673 Valid attributes are as follows:
679 Explicitly specifies the type of join to use in the relationship. Any
680 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
681 the SQL command immediately before C<JOIN>.
685 An arrayref containing a list of accessors in the foreign class to proxy in
686 the main class. If, for example, you do the following:
688 CD->might_have(liner_notes => 'LinerNotes', undef, {
689 proxy => [ qw/notes/ ],
692 Then, assuming LinerNotes has an accessor named notes, you can do:
694 my $cd = CD->find(1);
695 # set notes -- LinerNotes object is created if it doesn't exist
696 $cd->notes('Notes go here');
700 Specifies the type of accessor that should be created for the
701 relationship. Valid values are C<single> (for when there is only a single
702 related object), C<multi> (when there can be many), and C<filter> (for
703 when there is a single related object, but you also want the relationship
704 accessor to double as a column accessor). For C<multi> accessors, an
705 add_to_* method is also created, which calls C<create_related> for the
710 Throws an exception if the condition is improperly supplied, or cannot
711 be resolved using L</resolve_join>.
715 sub add_relationship {
716 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
717 $self->throw_exception("Can't create relationship without join condition")
721 # Check foreign and self are right in cond
722 if ( (ref $cond ||'') eq 'HASH') {
724 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
725 if /\./ && !/^foreign\./;
729 my %rels = %{ $self->_relationships };
730 $rels{$rel} = { class => $f_source_name,
731 source => $f_source_name,
734 $self->_relationships(\%rels);
738 # XXX disabled. doesn't work properly currently. skip in tests.
740 my $f_source = $self->schema->source($f_source_name);
742 $self->ensure_class_loaded($f_source_name);
743 $f_source = $f_source_name->result_source;
744 #my $s_class = ref($self->schema);
745 #$f_source_name =~ m/^${s_class}::(.*)$/;
746 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
747 #$f_source = $self->schema->source($f_source_name);
749 return unless $f_source; # Can't test rel without f_source
751 eval { $self->resolve_join($rel, 'me') };
753 if ($@) { # If the resolve failed, back out and re-throw the error
754 delete $rels{$rel}; #
755 $self->_relationships(\%rels);
756 $self->throw_exception("Error creating relationship $rel: $@");
765 =item Arguments: None
767 =item Return value: List of relationship names
771 my @relnames = $source->relationships();
773 Returns all relationship names for this source.
778 return keys %{shift->_relationships};
781 =head2 relationship_info
785 =item Arguments: $relname
787 =item Return value: Hashref of relation data,
791 Returns a hash of relationship information for the specified relationship
792 name. The keys/values are as specified for L</add_relationship>.
796 sub relationship_info {
797 my ($self, $rel) = @_;
798 return $self->_relationships->{$rel};
801 =head2 has_relationship
805 =item Arguments: $rel
807 =item Return value: 1/0 (true/false)
811 Returns true if the source has a relationship of this name, false otherwise.
815 sub has_relationship {
816 my ($self, $rel) = @_;
817 return exists $self->_relationships->{$rel};
820 =head2 reverse_relationship_info
824 =item Arguments: $relname
826 =item Return value: Hashref of relationship data
830 Looks through all the relationships on the source this relationship
831 points to, looking for one whose condition is the reverse of the
832 condition on this relationship.
834 A common use of this is to find the name of the C<belongs_to> relation
835 opposing a C<has_many> relation. For definition of these look in
836 L<DBIx::Class::Relationship>.
838 The returned hashref is keyed by the name of the opposing
839 relationship, and contains it's data in the same manner as
840 L</relationship_info>.
844 sub reverse_relationship_info {
845 my ($self, $rel) = @_;
846 my $rel_info = $self->relationship_info($rel);
849 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
851 my @cond = keys(%{$rel_info->{cond}});
852 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
853 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
855 # Get the related result source for this relationship
856 my $othertable = $self->related_source($rel);
858 # Get all the relationships for that source that related to this source
859 # whose foreign column set are our self columns on $rel and whose self
860 # columns are our foreign columns on $rel.
861 my @otherrels = $othertable->relationships();
862 my $otherrelationship;
863 foreach my $otherrel (@otherrels) {
864 my $otherrel_info = $othertable->relationship_info($otherrel);
866 my $back = $othertable->related_source($otherrel);
867 next unless $back->source_name eq $self->source_name;
871 if (ref $otherrel_info->{cond} eq 'HASH') {
872 @othertestconds = ($otherrel_info->{cond});
874 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
875 @othertestconds = @{$otherrel_info->{cond}};
881 foreach my $othercond (@othertestconds) {
882 my @other_cond = keys(%$othercond);
883 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
884 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
885 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
886 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
887 $ret->{$otherrel} = $otherrel_info;
893 =head2 compare_relationship_keys
897 =item Arguments: \@keys1, \@keys2
899 =item Return value: 1/0 (true/false)
903 Returns true if both sets of keynames are the same, false otherwise.
907 sub compare_relationship_keys {
908 my ($self, $keys1, $keys2) = @_;
910 # Make sure every keys1 is in keys2
912 foreach my $key (@$keys1) {
914 foreach my $prim (@$keys2) {
923 # Make sure every key2 is in key1
925 foreach my $prim (@$keys2) {
927 foreach my $key (@$keys1) {
944 =item Arguments: $relation
946 =item Return value: Join condition arrayref
950 Returns the join structure required for the related result source.
955 my ($self, $join, $alias, $seen, $force_left) = @_;
957 $force_left ||= { force => 0 };
958 if (ref $join eq 'ARRAY') {
959 return map { $self->resolve_join($_, $alias, $seen) } @$join;
960 } elsif (ref $join eq 'HASH') {
963 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
964 local $force_left->{force};
966 $self->resolve_join($_, $alias, $seen, $force_left),
967 $self->related_source($_)->resolve_join(
968 $join->{$_}, $as, $seen, $force_left
972 } elsif (ref $join) {
973 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
975 my $count = ++$seen->{$join};
976 #use Data::Dumper; warn Dumper($seen);
977 my $as = ($count > 1 ? "${join}_${count}" : $join);
978 my $rel_info = $self->relationship_info($join);
979 $self->throw_exception("No such relationship ${join}") unless $rel_info;
981 if ($force_left->{force}) {
984 $type = $rel_info->{attrs}{join_type} || '';
985 $force_left->{force} = 1 if lc($type) eq 'left';
987 return [ { $as => $self->related_source($join)->from,
988 -join_type => $type },
989 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
997 =item Arguments: $relname, $rel_data
999 =item Return value: 1/0 (true/false)
1003 Determines whether a relation is dependent on an object from this source
1004 having already been inserted. Takes the name of the relationship and a
1005 hashref of columns of the related object.
1010 my ($self, $relname, $rel_data) = @_;
1011 my $cond = $self->relationship_info($relname)->{cond};
1013 return 0 unless ref($cond) eq 'HASH';
1015 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1017 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1019 # assume anything that references our PK probably is dependent on us
1020 # rather than vice versa, unless the far side is (a) defined or (b)
1023 my $rel_source = $self->related_source($relname);
1025 foreach my $p ($self->primary_columns) {
1026 if (exists $keyhash->{$p}) {
1027 unless (defined($rel_data->{$keyhash->{$p}})
1028 || $rel_source->column_info($keyhash->{$p})
1029 ->{is_auto_increment}) {
1038 =head2 resolve_condition
1042 =item Arguments: $cond, $as, $alias|$object
1046 Resolves the passed condition to a concrete query fragment. If given an alias,
1047 returns a join condition; if given an object, inverts that object to produce
1048 a related conditional from that object.
1052 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1054 sub resolve_condition {
1055 my ($self, $cond, $as, $for) = @_;
1057 if (ref $cond eq 'HASH') {
1059 foreach my $k (keys %{$cond}) {
1060 my $v = $cond->{$k};
1061 # XXX should probably check these are valid columns
1062 $k =~ s/^foreign\.// ||
1063 $self->throw_exception("Invalid rel cond key ${k}");
1064 $v =~ s/^self\.// ||
1065 $self->throw_exception("Invalid rel cond val ${v}");
1066 if (ref $for) { # Object
1067 #warn "$self $k $for $v";
1068 unless ($for->has_column_loaded($v)) {
1069 if ($for->in_storage) {
1070 $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship");
1072 return $UNRESOLVABLE_CONDITION;
1074 $ret{$k} = $for->get_column($v);
1075 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1077 } elsif (!defined $for) { # undef, i.e. "no object"
1079 } elsif (ref $as eq 'HASH') { # reverse hashref
1080 $ret{$v} = $as->{$k};
1081 } elsif (ref $as) { # reverse object
1082 $ret{$v} = $as->get_column($k);
1083 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1086 $ret{"${as}.${k}"} = "${for}.${v}";
1090 } elsif (ref $cond eq 'ARRAY') {
1091 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
1093 die("Can't handle this yet :(");
1097 =head2 resolve_prefetch
1101 =item Arguments: hashref/arrayref/scalar
1105 Accepts one or more relationships for the current source and returns an
1106 array of column names for each of those relationships. Column names are
1107 prefixed relative to the current source, in accordance with where they appear
1108 in the supplied relationships. Examples:
1110 my $source = $schema->resultset('Tag')->source;
1111 @columns = $source->resolve_prefetch( { cd => 'artist' } );
1119 # 'cd.artist.artistid',
1123 @columns = $source->resolve_prefetch( qw[/ cd /] );
1133 $source = $schema->resultset('CD')->source;
1134 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
1138 # 'artist.artistid',
1140 # 'producer.producerid',
1146 sub resolve_prefetch {
1147 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
1149 #$alias ||= $self->name;
1150 #warn $alias, Dumper $pre;
1151 if( ref $pre eq 'ARRAY' ) {
1153 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
1156 elsif( ref $pre eq 'HASH' ) {
1159 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
1160 $self->related_source($_)->resolve_prefetch(
1161 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
1167 $self->throw_exception(
1168 "don't know how to resolve prefetch reftype ".ref($pre));
1171 my $count = ++$seen->{$pre};
1172 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
1173 my $rel_info = $self->relationship_info( $pre );
1174 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
1176 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1177 my $rel_source = $self->related_source($pre);
1179 if (exists $rel_info->{attrs}{accessor}
1180 && $rel_info->{attrs}{accessor} eq 'multi') {
1181 $self->throw_exception(
1182 "Can't prefetch has_many ${pre} (join cond too complex)")
1183 unless ref($rel_info->{cond}) eq 'HASH';
1184 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1185 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1186 keys %{$collapse}) {
1187 my ($last) = ($fail =~ /([^\.]+)$/);
1189 "Prefetching multiple has_many rels ${last} and ${pre} "
1190 .(length($as_prefix)
1191 ? "at the same level (${as_prefix}) "
1194 . 'will currently disrupt both the functionality of $rs->count(), '
1195 . 'and the amount of objects retrievable via $rs->next(). '
1196 . 'Use at your own risk.'
1199 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1200 # values %{$rel_info->{cond}};
1201 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
1202 # action at a distance. prepending the '.' allows simpler code
1203 # in ResultSet->_collapse_result
1204 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1205 keys %{$rel_info->{cond}};
1206 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1207 ? @{$rel_info->{attrs}{order_by}}
1208 : (defined $rel_info->{attrs}{order_by}
1209 ? ($rel_info->{attrs}{order_by})
1211 push(@$order, map { "${as}.$_" } (@key, @ord));
1214 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1215 $rel_source->columns;
1216 #warn $alias, Dumper (\@ret);
1221 =head2 related_source
1225 =item Arguments: $relname
1227 =item Return value: $source
1231 Returns the result source object for the given relationship.
1235 sub related_source {
1236 my ($self, $rel) = @_;
1237 if( !$self->has_relationship( $rel ) ) {
1238 $self->throw_exception("No such relationship '$rel'");
1240 return $self->schema->source($self->relationship_info($rel)->{source});
1243 =head2 related_class
1247 =item Arguments: $relname
1249 =item Return value: $classname
1253 Returns the class name for objects in the given relationship.
1258 my ($self, $rel) = @_;
1259 if( !$self->has_relationship( $rel ) ) {
1260 $self->throw_exception("No such relationship '$rel'");
1262 return $self->schema->class($self->relationship_info($rel)->{source});
1269 =item Arguments: None
1271 =item Return value: $resultset
1275 Returns a resultset for the given source. This will initially be created
1276 on demand by calling
1278 $self->resultset_class->new($self, $self->resultset_attributes)
1280 but is cached from then on unless resultset_class changes.
1282 =head2 resultset_class
1286 =item Arguments: $classname
1288 =item Return value: $classname
1292 package My::ResultSetClass;
1293 use base 'DBIx::Class::ResultSet';
1296 $source->resultset_class('My::ResultSet::Class');
1298 Set the class of the resultset, this is useful if you want to create your
1299 own resultset methods. Create your own class derived from
1300 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
1301 this method returns the name of the existing resultset class, if one
1304 =head2 resultset_attributes
1308 =item Arguments: \%attrs
1310 =item Return value: \%attrs
1314 $source->resultset_attributes({ order_by => [ 'id' ] });
1316 Store a collection of resultset attributes, that will be set on every
1317 L<DBIx::Class::ResultSet> produced from this result source. For a full
1318 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
1324 $self->throw_exception(
1325 'resultset does not take any arguments. If you want another resultset, '.
1326 'call it on the schema instead.'
1329 return $self->resultset_class->new(
1332 %{$self->{resultset_attributes}},
1333 %{$self->schema->default_resultset_attributes}
1342 =item Arguments: $source_name
1344 =item Result value: $source_name
1348 Set an alternate name for the result source when it is loaded into a schema.
1349 This is useful if you want to refer to a result source by a name other than
1352 package ArchivedBooks;
1353 use base qw/DBIx::Class/;
1354 __PACKAGE__->table('books_archive');
1355 __PACKAGE__->source_name('Books');
1357 # from your schema...
1358 $schema->resultset('Books')->find(1);
1362 Obtain a new handle to this source. Returns an instance of a
1363 L<DBIx::Class::ResultSourceHandle>.
1368 return new DBIx::Class::ResultSourceHandle({
1369 schema => $_[0]->schema,
1370 source_moniker => $_[0]->source_name
1374 =head2 throw_exception
1376 See L<DBIx::Class::Schema/"throw_exception">.
1380 sub throw_exception {
1382 if (defined $self->schema) {
1383 $self->schema->throw_exception(@_);
1389 =head2 sqlt_deploy_hook($sqlt_table)
1393 =item Arguments: $source, $sqlt_table
1395 =item Return value: undefined
1399 An optional sub which you can declare in your own Result class that will get
1400 passed the L<SQL::Translator::Schema::Table> object when you deploy the schema
1401 via L</create_ddl_dir> or L</deploy>.
1403 This is useful to make L<SQL::Translator> create non-unique indexes,
1404 or set table options such as C<Engine=INNOFB>.
1406 For an example of what you can do with this, see
1407 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
1411 Matt S. Trout <mst@shadowcatsystems.co.uk>
1415 You may distribute this code under the same terms as Perl itself.