1 package DBIx::Class::ResultSource;
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
8 use Carp::Clan qw/^DBIx::Class/;
11 use base qw/DBIx::Class/;
13 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
14 _columns _primaries _unique_constraints name resultset_attributes
15 schema from _relationships column_info_from_storage source_info
16 source_name _indices/);
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;
58 $new->_indices([]) unless $new->_indices;
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 column names given will be created as accessor methods on your
86 L<DBIx::Class::Row> objects, you can change the name of the accessor
87 by supplying an L</accessor> in the column_info hash.
89 The contents of the column_info are not set in stone. The following
90 keys are currently recognised/used by DBIx::Class:
96 Use this to set the name of the accessor method for this column. If unset,
97 the name of the column will be used.
101 This contains the column type. It is automatically filled by the
102 L<SQL::Translator::Producer::DBIx::Class::File> producer, and the
103 L<DBIx::Class::Schema::Loader> module. If you do not enter a
104 data_type, DBIx::Class will attempt to retrieve it from the
105 database for you, using L<DBI>'s column_info method. The values of this
106 key are typically upper-cased.
108 Currently there is no standard set of values for the data_type. Use
109 whatever your database supports.
113 The length of your column, if it is a column type that can have a size
114 restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
118 Set this to a true value for a columns that is allowed to contain
119 NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
121 =item is_auto_increment
123 Set this to a true value for a column whose value is somehow
124 automatically set. This is used to determine which columns to empty
125 when cloning objects using C<copy>. It is also used by
126 L<DBIx::Class::Schema/deploy>.
130 Set this to a true value for a column that contains a key from a
131 foreign table. This is currently only used by
132 L<DBIx::Class::Schema/deploy>.
136 Set this to the default value which will be inserted into a column
137 by the database. Can contain either a value or a function. This is
138 currently only used by L<DBIx::Class::Schema/deploy>.
142 Set this on a primary key column to the name of the sequence used to
143 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
144 will attempt to retrieve the name of the sequence from the database
149 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
150 to add extra non-generic data to the column. For example: C<< extra
151 => { unsigned => 1} >> is used by the MySQL producer to set an integer
152 column to unsigned. For more details, see
153 L<SQL::Translator::Producer::MySQL>.
159 $table->add_column('col' => \%info?);
161 Convenience alias to add_columns.
166 my ($self, @cols) = @_;
167 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
170 my $columns = $self->_columns;
171 while (my $col = shift @cols) {
172 # If next entry is { ... } use that for the column info, if not
173 # use an empty hashref
174 my $column_info = ref $cols[0] ? shift(@cols) : {};
175 push(@added, $col) unless exists $columns->{$col};
176 $columns->{$col} = $column_info;
178 push @{ $self->_ordered_columns }, @added;
182 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
186 if ($obj->has_column($col)) { ... }
188 Returns true if the source has a column of this name, false otherwise.
193 my ($self, $column) = @_;
194 return exists $self->_columns->{$column};
199 my $info = $obj->column_info($col);
201 Returns the column metadata hashref for a column. See the description
202 of add_column for information on the contents of the hashref.
207 my ($self, $column) = @_;
208 $self->throw_exception("No such column $column")
209 unless exists $self->_columns->{$column};
210 #warn $self->{_columns_info_loaded}, "\n";
211 if ( ! $self->_columns->{$column}{data_type}
212 and $self->column_info_from_storage
213 and ! $self->{_columns_info_loaded}
214 and $self->schema and $self->storage )
216 $self->{_columns_info_loaded}++;
219 # eval for the case of storage without table
220 eval { $info = $self->storage->columns_info_for( $self->from ) };
222 for my $realcol ( keys %{$info} ) {
223 $lc_info->{lc $realcol} = $info->{$realcol};
225 foreach my $col ( keys %{$self->_columns} ) {
226 $self->_columns->{$col} = {
227 %{ $self->_columns->{$col} },
228 %{ $info->{$col} || $lc_info->{lc $col} || {} }
233 return $self->_columns->{$column};
236 =head2 column_info_from_storage
238 Enables the on-demand automatic loading of the above column
239 metadata from storage as neccesary. This is *deprecated*, and
240 should not be used. It will be removed before 1.0.
242 __PACKAGE__->column_info_from_storage(1);
246 my @column_names = $obj->columns;
248 Returns all column names in the order they were declared to add_columns.
254 $self->throw_exception(
255 "columns() is a read-only accessor, did you mean add_columns()?"
257 return @{$self->{_ordered_columns}||[]};
260 =head2 remove_columns
262 $table->remove_columns(qw/col1 col2 col3/);
264 Removes columns from the result source.
268 $table->remove_column('col');
270 Convenience alias to remove_columns.
275 my ($self, @cols) = @_;
277 return unless $self->_ordered_columns;
279 my $columns = $self->_columns;
282 foreach my $col (@{$self->_ordered_columns}) {
283 push @remaining, $col unless grep(/$col/, @cols);
287 delete $columns->{$_};
290 $self->_ordered_columns(\@remaining);
293 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
295 =head2 set_primary_key
299 =item Arguments: @cols
303 Defines one or more columns as primary key for this source. Should be
304 called after C<add_columns>.
306 Additionally, defines a unique constraint named C<primary>.
308 The primary key columns are used by L<DBIx::Class::PK::Auto> to
309 retrieve automatically created values from the database.
313 sub set_primary_key {
314 my ($self, @cols) = @_;
315 # check if primary key columns are valid columns
316 foreach my $col (@cols) {
317 $self->throw_exception("No such column $col on table " . $self->name)
318 unless $self->has_column($col);
320 $self->_primaries(\@cols);
322 $self->add_unique_constraint(primary => \@cols);
325 =head2 primary_columns
327 Read-only accessor which returns the list of primary keys.
331 sub primary_columns {
332 return @{shift->_primaries||[]};
335 =head2 add_unique_constraint
337 Declare a unique constraint on this source. Call once for each unique
340 # For UNIQUE (column1, column2)
341 __PACKAGE__->add_unique_constraint(
342 constraint_name => [ qw/column1 column2/ ],
345 Alternatively, you can specify only the columns:
347 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
349 This will result in a unique constraint named C<table_column1_column2>, where
350 C<table> is replaced with the table name.
352 Unique constraints are used, for example, when you call
353 L<DBIx::Class::ResultSet/find>. Only columns in the constraint are searched.
357 sub add_unique_constraint {
362 $name ||= $self->name_unique_constraint($cols);
364 foreach my $col (@$cols) {
365 $self->throw_exception("No such column $col on table " . $self->name)
366 unless $self->has_column($col);
369 my %unique_constraints = $self->unique_constraints;
370 $unique_constraints{$name} = $cols;
371 $self->_unique_constraints(\%unique_constraints);
374 =head2 name_unique_constraint
376 Return a name for a unique constraint containing the specified columns. These
377 names consist of the table name and each column name, separated by underscores.
379 For example, a constraint on a table named C<cd> containing the columns
380 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
384 sub name_unique_constraint {
385 my ($self, $cols) = @_;
387 return join '_', $self->name, @$cols;
390 =head2 unique_constraints
392 Read-only accessor which returns the list of unique constraints on this source.
396 sub unique_constraints {
397 return %{shift->_unique_constraints||{}};
400 =head2 unique_constraint_names
402 Returns the list of unique constraint names defined on this source.
406 sub unique_constraint_names {
409 my %unique_constraints = $self->unique_constraints;
411 return keys %unique_constraints;
414 =head2 unique_constraint_columns
416 Returns the list of columns that make up the specified unique constraint.
420 sub unique_constraint_columns {
421 my ($self, $constraint_name) = @_;
423 my %unique_constraints = $self->unique_constraints;
425 $self->throw_exception(
426 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
427 ) unless exists $unique_constraints{$constraint_name};
429 return @{ $unique_constraints{$constraint_name} };
434 Returns an expression of the source to be supplied to storage to specify
435 retrieval from this source. In the case of a database, the required FROM
440 Returns the L<DBIx::Class::Schema> object that this result source
445 Returns the storage handle for the current schema.
447 See also: L<DBIx::Class::Storage>
451 sub storage { shift->schema->storage; }
455 Add an index to the result source. This has no effect for DBIx::Class - it is
456 just used for creating SQL with L<SQL::Translator>. Takes the same arguments
457 as L<SQL::Translator::Schema::Table::add_index>.
462 my ($self, $idx) = @_;
464 push @{ $self->_indices }, $idx;
469 Returns list of secondary (i.e. non unique) indicies created on this table.
474 return @{ shift->_indices };
477 =head2 add_relationship
479 $source->add_relationship('relname', 'related_source', $cond, $attrs);
481 The relationship name can be arbitrary, but must be unique for each
482 relationship attached to this result source. 'related_source' should
483 be the name with which the related result source was registered with
484 the current schema. For example:
486 $schema->source('Book')->add_relationship('reviews', 'Review', {
487 'foreign.book_id' => 'self.id',
490 The condition C<$cond> needs to be an L<SQL::Abstract>-style
491 representation of the join between the tables. For example, if you're
492 creating a rel from Author to Book,
494 { 'foreign.author_id' => 'self.id' }
496 will result in the JOIN clause
498 author me JOIN book foreign ON foreign.author_id = me.id
500 You can specify as many foreign => self mappings as necessary.
502 Valid attributes are as follows:
508 Explicitly specifies the type of join to use in the relationship. Any
509 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
510 the SQL command immediately before C<JOIN>.
514 An arrayref containing a list of accessors in the foreign class to proxy in
515 the main class. If, for example, you do the following:
517 CD->might_have(liner_notes => 'LinerNotes', undef, {
518 proxy => [ qw/notes/ ],
521 Then, assuming LinerNotes has an accessor named notes, you can do:
523 my $cd = CD->find(1);
524 # set notes -- LinerNotes object is created if it doesn't exist
525 $cd->notes('Notes go here');
529 Specifies the type of accessor that should be created for the
530 relationship. Valid values are C<single> (for when there is only a single
531 related object), C<multi> (when there can be many), and C<filter> (for
532 when there is a single related object, but you also want the relationship
533 accessor to double as a column accessor). For C<multi> accessors, an
534 add_to_* method is also created, which calls C<create_related> for the
541 sub add_relationship {
542 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
543 $self->throw_exception("Can't create relationship without join condition")
547 # Check foreign and self are right in cond
548 if ( (ref $cond ||'') eq 'HASH') {
550 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
551 if /\./ && !/^foreign\./;
555 my %rels = %{ $self->_relationships };
556 $rels{$rel} = { class => $f_source_name,
557 source => $f_source_name,
560 $self->_relationships(\%rels);
564 # XXX disabled. doesn't work properly currently. skip in tests.
566 my $f_source = $self->schema->source($f_source_name);
568 $self->ensure_class_loaded($f_source_name);
569 $f_source = $f_source_name->result_source;
570 #my $s_class = ref($self->schema);
571 #$f_source_name =~ m/^${s_class}::(.*)$/;
572 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
573 #$f_source = $self->schema->source($f_source_name);
575 return unless $f_source; # Can't test rel without f_source
577 eval { $self->resolve_join($rel, 'me') };
579 if ($@) { # If the resolve failed, back out and re-throw the error
580 delete $rels{$rel}; #
581 $self->_relationships(\%rels);
582 $self->throw_exception("Error creating relationship $rel: $@");
589 Returns all relationship names for this source.
594 return keys %{shift->_relationships};
597 =head2 relationship_info
601 =item Arguments: $relname
605 Returns a hash of relationship information for the specified relationship
610 sub relationship_info {
611 my ($self, $rel) = @_;
612 return $self->_relationships->{$rel};
615 =head2 has_relationship
619 =item Arguments: $rel
623 Returns true if the source has a relationship of this name, false otherwise.
627 sub has_relationship {
628 my ($self, $rel) = @_;
629 return exists $self->_relationships->{$rel};
632 =head2 reverse_relationship_info
636 =item Arguments: $relname
640 Returns an array of hash references of relationship information for
641 the other side of the specified relationship name.
645 sub reverse_relationship_info {
646 my ($self, $rel) = @_;
647 my $rel_info = $self->relationship_info($rel);
650 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
652 my @cond = keys(%{$rel_info->{cond}});
653 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
654 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
656 # Get the related result source for this relationship
657 my $othertable = $self->related_source($rel);
659 # Get all the relationships for that source that related to this source
660 # whose foreign column set are our self columns on $rel and whose self
661 # columns are our foreign columns on $rel.
662 my @otherrels = $othertable->relationships();
663 my $otherrelationship;
664 foreach my $otherrel (@otherrels) {
665 my $otherrel_info = $othertable->relationship_info($otherrel);
667 my $back = $othertable->related_source($otherrel);
668 next unless $back->name eq $self->name;
672 if (ref $otherrel_info->{cond} eq 'HASH') {
673 @othertestconds = ($otherrel_info->{cond});
675 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
676 @othertestconds = @{$otherrel_info->{cond}};
682 foreach my $othercond (@othertestconds) {
683 my @other_cond = keys(%$othercond);
684 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
685 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
686 next if (!$self->compare_relationship_keys(\@refkeys, \@other_keys) ||
687 !$self->compare_relationship_keys(\@other_refkeys, \@keys));
688 $ret->{$otherrel} = $otherrel_info;
694 =head2 compare_relationship_keys
698 =item Arguments: $keys1, $keys2
702 Returns true if both sets of keynames are the same, false otherwise.
706 sub compare_relationship_keys {
707 my ($self, $keys1, $keys2) = @_;
709 # Make sure every keys1 is in keys2
711 foreach my $key (@$keys1) {
713 foreach my $prim (@$keys2) {
722 # Make sure every key2 is in key1
724 foreach my $prim (@$keys2) {
726 foreach my $key (@$keys1) {
743 =item Arguments: $relation
747 Returns the join structure required for the related result source.
752 my ($self, $join, $alias, $seen, $force_left) = @_;
754 $force_left ||= { force => 0 };
755 if (ref $join eq 'ARRAY') {
756 return map { $self->resolve_join($_, $alias, $seen) } @$join;
757 } elsif (ref $join eq 'HASH') {
760 my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
761 local $force_left->{force};
763 $self->resolve_join($_, $alias, $seen, $force_left),
764 $self->related_source($_)->resolve_join(
765 $join->{$_}, $as, $seen, $force_left
769 } elsif (ref $join) {
770 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
772 my $count = ++$seen->{$join};
773 #use Data::Dumper; warn Dumper($seen);
774 my $as = ($count > 1 ? "${join}_${count}" : $join);
775 my $rel_info = $self->relationship_info($join);
776 $self->throw_exception("No such relationship ${join}") unless $rel_info;
778 if ($force_left->{force}) {
781 $type = $rel_info->{attrs}{join_type} || '';
782 $force_left->{force} = 1 if lc($type) eq 'left';
784 return [ { $as => $self->related_source($join)->from,
785 -join_type => $type },
786 $self->resolve_condition($rel_info->{cond}, $as, $alias) ];
790 =head2 resolve_condition
794 =item Arguments: $cond, $as, $alias|$object
798 Resolves the passed condition to a concrete query fragment. If given an alias,
799 returns a join condition; if given an object, inverts that object to produce
800 a related conditional from that object.
804 sub resolve_condition {
805 my ($self, $cond, $as, $for) = @_;
807 if (ref $cond eq 'HASH') {
809 foreach my $k (keys %{$cond}) {
811 # XXX should probably check these are valid columns
812 $k =~ s/^foreign\.// ||
813 $self->throw_exception("Invalid rel cond key ${k}");
815 $self->throw_exception("Invalid rel cond val ${v}");
816 if (ref $for) { # Object
817 #warn "$self $k $for $v";
818 $ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
820 } elsif (!defined $for) { # undef, i.e. "no object"
822 } elsif (ref $as eq 'HASH') { # reverse hashref
823 $ret{$v} = $as->{$k};
824 } elsif (ref $as) { # reverse object
825 $ret{$v} = $as->get_column($k);
826 } elsif (!defined $as) { # undef, i.e. "no reverse object"
829 $ret{"${as}.${k}"} = "${for}.${v}";
833 } elsif (ref $cond eq 'ARRAY') {
834 return [ map { $self->resolve_condition($_, $as, $for) } @$cond ];
836 die("Can't handle this yet :(");
840 =head2 resolve_prefetch
844 =item Arguments: hashref/arrayref/scalar
848 Accepts one or more relationships for the current source and returns an
849 array of column names for each of those relationships. Column names are
850 prefixed relative to the current source, in accordance with where they appear
851 in the supplied relationships. Examples:
853 my $source = $schema->resultset('Tag')->source;
854 @columns = $source->resolve_prefetch( { cd => 'artist' } );
862 # 'cd.artist.artistid',
866 @columns = $source->resolve_prefetch( qw[/ cd /] );
876 $source = $schema->resultset('CD')->source;
877 @columns = $source->resolve_prefetch( qw[/ artist producer /] );
883 # 'producer.producerid',
889 sub resolve_prefetch {
890 my ($self, $pre, $alias, $seen, $order, $collapse) = @_;
892 #$alias ||= $self->name;
893 #warn $alias, Dumper $pre;
894 if( ref $pre eq 'ARRAY' ) {
896 map { $self->resolve_prefetch( $_, $alias, $seen, $order, $collapse ) }
899 elsif( ref $pre eq 'HASH' ) {
902 $self->resolve_prefetch($_, $alias, $seen, $order, $collapse),
903 $self->related_source($_)->resolve_prefetch(
904 $pre->{$_}, "${alias}.$_", $seen, $order, $collapse)
910 $self->throw_exception(
911 "don't know how to resolve prefetch reftype ".ref($pre));
914 my $count = ++$seen->{$pre};
915 my $as = ($count > 1 ? "${pre}_${count}" : $pre);
916 my $rel_info = $self->relationship_info( $pre );
917 $self->throw_exception( $self->name . " has no such relationship '$pre'" )
919 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
920 my $rel_source = $self->related_source($pre);
922 if (exists $rel_info->{attrs}{accessor}
923 && $rel_info->{attrs}{accessor} eq 'multi') {
924 $self->throw_exception(
925 "Can't prefetch has_many ${pre} (join cond too complex)")
926 unless ref($rel_info->{cond}) eq 'HASH';
927 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
928 # values %{$rel_info->{cond}};
929 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
930 # action at a distance. prepending the '.' allows simpler code
931 # in ResultSet->_collapse_result
932 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
933 keys %{$rel_info->{cond}};
934 my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
935 ? @{$rel_info->{attrs}{order_by}}
936 : (defined $rel_info->{attrs}{order_by}
937 ? ($rel_info->{attrs}{order_by})
939 push(@$order, map { "${as}.$_" } (@key, @ord));
942 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
943 $rel_source->columns;
944 #warn $alias, Dumper (\@ret);
949 =head2 related_source
953 =item Arguments: $relname
957 Returns the result source object for the given relationship.
962 my ($self, $rel) = @_;
963 if( !$self->has_relationship( $rel ) ) {
964 $self->throw_exception("No such relationship '$rel'");
966 return $self->schema->source($self->relationship_info($rel)->{source});
973 =item Arguments: $relname
977 Returns the class name for objects in the given relationship.
982 my ($self, $rel) = @_;
983 if( !$self->has_relationship( $rel ) ) {
984 $self->throw_exception("No such relationship '$rel'");
986 return $self->schema->class($self->relationship_info($rel)->{source});
991 Returns a resultset for the given source. This will initially be created
994 $self->resultset_class->new($self, $self->resultset_attributes)
996 but is cached from then on unless resultset_class changes.
998 =head2 resultset_class
1000 ` package My::ResultSetClass;
1001 use base 'DBIx::Class::ResultSet';
1004 $source->resultset_class('My::ResultSet::Class');
1006 Set the class of the resultset, this is useful if you want to create your
1007 own resultset methods. Create your own class derived from
1008 L<DBIx::Class::ResultSet>, and set it here.
1010 =head2 resultset_attributes
1012 $source->resultset_attributes({ order_by => [ 'id' ] });
1014 Specify here any attributes you wish to pass to your specialised
1015 resultset. For a full list of these, please see
1016 L<DBIx::Class::ResultSet/ATTRIBUTES>.
1022 $self->throw_exception(
1023 'resultset does not take any arguments. If you want another resultset, '.
1024 'call it on the schema instead.'
1027 return $self->resultset_class->new(
1030 %{$self->{resultset_attributes}},
1031 %{$self->schema->default_resultset_attributes}
1040 =item Arguments: $source_name
1044 Set the name of the result source when it is loaded into a schema.
1045 This is usefull if you want to refer to a result source by a name other than
1048 package ArchivedBooks;
1049 use base qw/DBIx::Class/;
1050 __PACKAGE__->table('books_archive');
1051 __PACKAGE__->source_name('Books');
1053 # from your schema...
1054 $schema->resultset('Books')->find(1);
1058 Obtain a new handle to this source. Returns an instance of a
1059 L<DBIx::Class::ResultSourceHandle>.
1064 return new DBIx::Class::ResultSourceHandle({
1065 schema => $_[0]->schema,
1066 source_moniker => $_[0]->source_name
1070 =head2 throw_exception
1072 See L<DBIx::Class::Schema/"throw_exception">.
1076 sub throw_exception {
1078 if (defined $self->schema) {
1079 $self->schema->throw_exception(@_);
1087 Matt S. Trout <mst@shadowcatsystems.co.uk>
1091 You may distribute this code under the same terms as Perl itself.