1 package DBIx::Class::ResultSource;
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
9 use DBIx::Class::Exception;
10 use Carp::Clan qw/^DBIx::Class/;
12 use List::Util 'first';
13 use Scalar::Util qw/weaken isweak/;
14 use Storable qw/nfreeze thaw/;
17 use base qw/DBIx::Class/;
19 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
20 _columns _primaries _unique_constraints name resultset_attributes
21 from _relationships column_info_from_storage source_info
22 source_name sqlt_deploy_callback/);
24 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
29 DBIx::Class::ResultSource - Result source object
33 # Create a table based result source, in a result class.
35 package MyDB::Schema::Result::Artist;
36 use base qw/DBIx::Class::Core/;
38 __PACKAGE__->table('artist');
39 __PACKAGE__->add_columns(qw/ artistid name /);
40 __PACKAGE__->set_primary_key('artistid');
41 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
45 # Create a query (view) based result source, in a result class
46 package MyDB::Schema::Result::Year2000CDs;
47 use base qw/DBIx::Class::Core/;
49 __PACKAGE__->load_components('InflateColumn::DateTime');
50 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
52 __PACKAGE__->table('year2000cds');
53 __PACKAGE__->result_source_instance->is_virtual(1);
54 __PACKAGE__->result_source_instance->view_definition(
55 "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
61 A ResultSource is an object that represents a source of data for querying.
63 This class is a base class for various specialised types of result
64 sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
65 default result source type, so one is created for you when defining a
66 result class as described in the synopsis above.
68 More specifically, the L<DBIx::Class::Core> base class pulls in the
69 L<DBIx::Class::ResultSourceProxy::Table> component, which defines
70 the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
71 When called, C<table> creates and stores an instance of
72 L<DBIx::Class::ResultSoure::Table>. Luckily, to use tables as result
73 sources, you don't need to remember any of this.
75 Result sources representing select queries, or views, can also be
76 created, see L<DBIx::Class::ResultSource::View> for full details.
78 =head2 Finding result source objects
80 As mentioned above, a result source instance is created and stored for
81 you when you define a L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
83 You can retrieve the result source at runtime in the following ways:
87 =item From a Schema object:
89 $schema->source($source_name);
91 =item From a Row object:
95 =item From a ResultSet object:
108 my ($class, $attrs) = @_;
109 $class = ref $class if ref $class;
111 my $new = bless { %{$attrs || {}} }, $class;
112 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
113 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
114 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
115 $new->{_columns} = { %{$new->{_columns}||{}} };
116 $new->{_relationships} = { %{$new->{_relationships}||{}} };
117 $new->{name} ||= "!!NAME NOT SET!!";
118 $new->{_columns_info_loaded} ||= 0;
119 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
129 =item Arguments: @columns
131 =item Return value: The ResultSource object
135 $source->add_columns(qw/col1 col2 col3/);
137 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
139 Adds columns to the result source. If supplied colname => hashref
140 pairs, uses the hashref as the L</column_info> for that column. Repeated
141 calls of this method will add more columns, not replace them.
143 The column names given will be created as accessor methods on your
144 L<DBIx::Class::Row> objects. You can change the name of the accessor
145 by supplying an L</accessor> in the column_info hash.
147 If a column name beginning with a plus sign ('+col1') is provided, the
148 attributes provided will be merged with any existing attributes for the
149 column, with the new attributes taking precedence in the case that an
150 attribute already exists. Using this without a hashref
151 (C<< $source->add_columns(qw/+col1 +col2/) >>) is legal, but useless --
152 it does the same thing it would do without the plus.
154 The contents of the column_info are not set in stone. The following
155 keys are currently recognised/used by DBIx::Class:
161 { accessor => '_name' }
163 # example use, replace standard accessor with one of your own:
165 my ($self, $value) = @_;
167 die "Name cannot contain digits!" if($value =~ /\d/);
168 $self->_name($value);
170 return $self->_name();
173 Use this to set the name of the accessor method for this column. If unset,
174 the name of the column will be used.
178 { data_type => 'integer' }
180 This contains the column type. It is automatically filled if you use the
181 L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
182 L<DBIx::Class::Schema::Loader> module.
184 Currently there is no standard set of values for the data_type. Use
185 whatever your database supports.
191 The length of your column, if it is a column type that can have a size
192 restriction. This is currently only used to create tables from your
193 schema, see L<DBIx::Class::Schema/deploy>.
199 Set this to a true value for a columns that is allowed to contain NULL
200 values, default is false. This is currently only used to create tables
201 from your schema, see L<DBIx::Class::Schema/deploy>.
203 =item is_auto_increment
205 { is_auto_increment => 1 }
207 Set this to a true value for a column whose value is somehow
208 automatically set, defaults to false. This is used to determine which
209 columns to empty when cloning objects using
210 L<DBIx::Class::Row/copy>. It is also used by
211 L<DBIx::Class::Schema/deploy>.
217 Set this to a true or false value (not C<undef>) to explicitly specify
218 if this column contains numeric data. This controls how set_column
219 decides whether to consider a column dirty after an update: if
220 C<is_numeric> is true a numeric comparison C<< != >> will take place
221 instead of the usual C<eq>
223 If not specified the storage class will attempt to figure this out on
224 first access to the column, based on the column C<data_type>. The
225 result will be cached in this attribute.
229 { is_foreign_key => 1 }
231 Set this to a true value for a column that contains a key from a
232 foreign table, defaults to false. This is currently only used to
233 create tables from your schema, see L<DBIx::Class::Schema/deploy>.
237 { default_value => \'now()' }
239 Set this to the default value which will be inserted into a column by
240 the database. Can contain either a value or a function (use a
241 reference to a scalar e.g. C<\'now()'> if you want a function). This
242 is currently only used to create tables from your schema, see
243 L<DBIx::Class::Schema/deploy>.
245 See the note on L<DBIx::Class::Row/new> for more information about possible
246 issues related to db-side default values.
250 { sequence => 'my_table_seq' }
252 Set this on a primary key column to the name of the sequence used to
253 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
254 will attempt to retrieve the name of the sequence from the database
259 Set this to a true value for a column whose value is retrieved automatically
260 from a sequence or function (if supported by your Storage driver.) For a
261 sequence, if you do not use a trigger to get the nextval, you have to set the
262 L</sequence> value as well.
264 Also set this for MSSQL columns with the 'uniqueidentifier'
265 L<data_type|DBIx::Class::ResultSource/data_type> whose values you want to
266 automatically generate using C<NEWID()>, unless they are a primary key in which
267 case this will be done anyway.
271 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
272 to add extra non-generic data to the column. For example: C<< extra
273 => { unsigned => 1} >> is used by the MySQL producer to set an integer
274 column to unsigned. For more details, see
275 L<SQL::Translator::Producer::MySQL>.
283 =item Arguments: $colname, \%columninfo?
285 =item Return value: 1/0 (true/false)
289 $source->add_column('col' => \%info);
291 Add a single column and optional column info. Uses the same column
292 info keys as L</add_columns>.
297 my ($self, @cols) = @_;
298 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
301 my $columns = $self->_columns;
302 while (my $col = shift @cols) {
303 my $column_info = {};
304 if ($col =~ s/^\+//) {
305 $column_info = $self->column_info($col);
308 # If next entry is { ... } use that for the column info, if not
309 # use an empty hashref
311 my $new_info = shift(@cols);
312 %$column_info = (%$column_info, %$new_info);
314 push(@added, $col) unless exists $columns->{$col};
315 $columns->{$col} = $column_info;
317 push @{ $self->_ordered_columns }, @added;
321 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
327 =item Arguments: $colname
329 =item Return value: 1/0 (true/false)
333 if ($source->has_column($colname)) { ... }
335 Returns true if the source has a column of this name, false otherwise.
340 my ($self, $column) = @_;
341 return exists $self->_columns->{$column};
348 =item Arguments: $colname
350 =item Return value: Hashref of info
354 my $info = $source->column_info($col);
356 Returns the column metadata hashref for a column, as originally passed
357 to L</add_columns>. See L</add_columns> above for information on the
358 contents of the hashref.
363 my ($self, $column) = @_;
364 $self->throw_exception("No such column $column")
365 unless exists $self->_columns->{$column};
367 if ( ! $self->_columns->{$column}{data_type}
368 and ! $self->{_columns_info_loaded}
369 and $self->column_info_from_storage
370 and my $stor = try { $self->storage } )
372 $self->{_columns_info_loaded}++;
374 # try for the case of storage without table
376 my $info = $stor->columns_info_for( $self->from );
378 { (lc $_) => $info->{$_} }
382 foreach my $col ( keys %{$self->_columns} ) {
383 $self->_columns->{$col} = {
384 %{ $self->_columns->{$col} },
385 %{ $info->{$col} || $lc_info->{lc $col} || {} }
391 return $self->_columns->{$column};
398 =item Arguments: None
400 =item Return value: Ordered list of column names
404 my @column_names = $source->columns;
406 Returns all column names in the order they were declared to L</add_columns>.
412 $self->throw_exception(
413 "columns() is a read-only accessor, did you mean add_columns()?"
415 return @{$self->{_ordered_columns}||[]};
422 =item Arguments: \@colnames ?
424 =item Return value: Hashref of column name/info pairs
428 my $columns_info = $source->columns_info;
430 Like L</column_info> but returns information for the requested columns. If
431 the optional column-list arrayref is ommitted it returns info on all columns
432 currently defined on the ResultSource via L</add_columns>.
437 my ($self, $columns) = @_;
439 my $colinfo = $self->_columns;
442 first { ! $_->{data_type} } values %$colinfo
444 ! $self->{_columns_info_loaded}
446 $self->column_info_from_storage
448 my $stor = try { $self->storage }
450 $self->{_columns_info_loaded}++;
452 # try for the case of storage without table
454 my $info = $stor->columns_info_for( $self->from );
456 { (lc $_) => $info->{$_} }
460 foreach my $col ( keys %$colinfo ) {
462 %{ $colinfo->{$col} },
463 %{ $info->{$col} || $lc_info->{lc $col} || {} }
473 if (my $inf = $colinfo->{$_}) {
477 $self->throw_exception( sprintf (
478 "No such column '%s' on source %s",
492 =head2 remove_columns
496 =item Arguments: @colnames
498 =item Return value: undefined
502 $source->remove_columns(qw/col1 col2 col3/);
504 Removes the given list of columns by name, from the result source.
506 B<Warning>: Removing a column that is also used in the sources primary
507 key, or in one of the sources unique constraints, B<will> result in a
508 broken result source.
514 =item Arguments: $colname
516 =item Return value: undefined
520 $source->remove_column('col');
522 Remove a single column by name from the result source, similar to
525 B<Warning>: Removing a column that is also used in the sources primary
526 key, or in one of the sources unique constraints, B<will> result in a
527 broken result source.
532 my ($self, @to_remove) = @_;
534 my $columns = $self->_columns
539 delete $columns->{$_};
543 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
546 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
548 =head2 set_primary_key
552 =item Arguments: @cols
554 =item Return value: undefined
558 Defines one or more columns as primary key for this source. Must be
559 called after L</add_columns>.
561 Additionally, defines a L<unique constraint|add_unique_constraint>
564 Note: you normally do want to define a primary key on your sources
565 B<even if the underlying database table does not have a primary key>.
567 L<DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
572 sub set_primary_key {
573 my ($self, @cols) = @_;
574 # check if primary key columns are valid columns
575 foreach my $col (@cols) {
576 $self->throw_exception("No such column $col on table " . $self->name)
577 unless $self->has_column($col);
579 $self->_primaries(\@cols);
581 $self->add_unique_constraint(primary => \@cols);
584 =head2 primary_columns
588 =item Arguments: None
590 =item Return value: Ordered list of primary column names
594 Read-only accessor which returns the list of primary keys, supplied by
599 sub primary_columns {
600 return @{shift->_primaries||[]};
603 # a helper method that will automatically die with a descriptive message if
604 # no pk is defined on the source in question. For internal use to save
605 # on if @pks... boilerplate
608 my @pcols = $self->primary_columns
609 or $self->throw_exception (sprintf(
610 "Operation requires a primary key to be declared on '%s' via set_primary_key",
611 # source_name is set only after schema-registration
612 $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
619 Manually define the correct sequence for your table, to avoid the overhead
620 associated with looking up the sequence automatically. The supplied sequence
621 will be applied to the L</column_info> of each L<primary_key|/set_primary_key>
625 =item Arguments: $sequence_name
627 =item Return value: undefined
634 my ($self,$seq) = @_;
636 my $rsrc = $self->result_source;
637 my @pks = $rsrc->primary_columns
640 $_->{sequence} = $seq
641 for values %{ $rsrc->columns_info (\@pks) };
645 =head2 add_unique_constraint
649 =item Arguments: $name?, \@colnames
651 =item Return value: undefined
655 Declare a unique constraint on this source. Call once for each unique
658 # For UNIQUE (column1, column2)
659 __PACKAGE__->add_unique_constraint(
660 constraint_name => [ qw/column1 column2/ ],
663 Alternatively, you can specify only the columns:
665 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
667 This will result in a unique constraint named
668 C<table_column1_column2>, where C<table> is replaced with the table
671 Unique constraints are used, for example, when you pass the constraint
672 name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
673 only columns in the constraint are searched.
675 Throws an error if any of the given column names do not yet exist on
680 sub add_unique_constraint {
684 $self->throw_exception(
685 'add_unique_constraint() does not accept multiple constraints, use '
686 . 'add_unique_constraints() instead'
691 if (ref $cols ne 'ARRAY') {
692 $self->throw_exception (
693 'Expecting an arrayref of constraint columns, got ' . ($cols||'NOTHING')
699 $name ||= $self->name_unique_constraint($cols);
701 foreach my $col (@$cols) {
702 $self->throw_exception("No such column $col on table " . $self->name)
703 unless $self->has_column($col);
706 my %unique_constraints = $self->unique_constraints;
707 $unique_constraints{$name} = $cols;
708 $self->_unique_constraints(\%unique_constraints);
711 =head2 add_unique_constraints
715 =item Arguments: @constraints
717 =item Return value: undefined
721 Declare multiple unique constraints on this source.
723 __PACKAGE__->add_unique_constraints(
724 constraint_name1 => [ qw/column1 column2/ ],
725 constraint_name2 => [ qw/column2 column3/ ],
728 Alternatively, you can specify only the columns:
730 __PACKAGE__->add_unique_constraints(
731 [ qw/column1 column2/ ],
732 [ qw/column3 column4/ ]
735 This will result in unique constraints named C<table_column1_column2> and
736 C<table_column3_column4>, where C<table> is replaced with the table name.
738 Throws an error if any of the given column names do not yet exist on
741 See also L</add_unique_constraint>.
745 sub add_unique_constraints {
747 my @constraints = @_;
749 if ( !(@constraints % 2) && first { ref $_ ne 'ARRAY' } @constraints ) {
750 # with constraint name
751 while (my ($name, $constraint) = splice @constraints, 0, 2) {
752 $self->add_unique_constraint($name => $constraint);
757 foreach my $constraint (@constraints) {
758 $self->add_unique_constraint($constraint);
763 =head2 name_unique_constraint
767 =item Arguments: \@colnames
769 =item Return value: Constraint name
773 $source->table('mytable');
774 $source->name_unique_constraint(['col1', 'col2']);
778 Return a name for a unique constraint containing the specified
779 columns. The name is created by joining the table name and each column
780 name, using an underscore character.
782 For example, a constraint on a table named C<cd> containing the columns
783 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
785 This is used by L</add_unique_constraint> if you do not specify the
786 optional constraint name.
790 sub name_unique_constraint {
791 my ($self, $cols) = @_;
793 my $name = $self->name;
794 $name = $$name if (ref $name eq 'SCALAR');
796 return join '_', $name, @$cols;
799 =head2 unique_constraints
803 =item Arguments: None
805 =item Return value: Hash of unique constraint data
809 $source->unique_constraints();
811 Read-only accessor which returns a hash of unique constraints on this
814 The hash is keyed by constraint name, and contains an arrayref of
815 column names as values.
819 sub unique_constraints {
820 return %{shift->_unique_constraints||{}};
823 =head2 unique_constraint_names
827 =item Arguments: None
829 =item Return value: Unique constraint names
833 $source->unique_constraint_names();
835 Returns the list of unique constraint names defined on this source.
839 sub unique_constraint_names {
842 my %unique_constraints = $self->unique_constraints;
844 return keys %unique_constraints;
847 =head2 unique_constraint_columns
851 =item Arguments: $constraintname
853 =item Return value: List of constraint columns
857 $source->unique_constraint_columns('myconstraint');
859 Returns the list of columns that make up the specified unique constraint.
863 sub unique_constraint_columns {
864 my ($self, $constraint_name) = @_;
866 my %unique_constraints = $self->unique_constraints;
868 $self->throw_exception(
869 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
870 ) unless exists $unique_constraints{$constraint_name};
872 return @{ $unique_constraints{$constraint_name} };
875 =head2 sqlt_deploy_callback
879 =item Arguments: $callback
883 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
885 An accessor to set a callback to be called during deployment of
886 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
887 L<DBIx::Class::Schema/deploy>.
889 The callback can be set as either a code reference or the name of a
890 method in the current result class.
892 If not set, the L</default_sqlt_deploy_hook> is called.
894 Your callback will be passed the $source object representing the
895 ResultSource instance being deployed, and the
896 L<SQL::Translator::Schema::Table> object being created from it. The
897 callback can be used to manipulate the table object or add your own
898 customised indexes. If you need to manipulate a non-table object, use
899 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
901 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
902 Your SQL> for examples.
904 This sqlt deployment callback can only be used to manipulate
905 SQL::Translator objects as they get turned into SQL. To execute
906 post-deploy statements which SQL::Translator does not currently
907 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
908 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
910 =head2 default_sqlt_deploy_hook
914 =item Arguments: $source, $sqlt_table
916 =item Return value: undefined
920 This is the sensible default for L</sqlt_deploy_callback>.
922 If a method named C<sqlt_deploy_hook> exists in your Result class, it
923 will be called and passed the current C<$source> and the
924 C<$sqlt_table> being deployed.
928 sub default_sqlt_deploy_hook {
931 my $class = $self->result_class;
933 if ($class and $class->can('sqlt_deploy_hook')) {
934 $class->sqlt_deploy_hook(@_);
938 sub _invoke_sqlt_deploy_hook {
940 if ( my $hook = $self->sqlt_deploy_callback) {
949 =item Arguments: None
951 =item Return value: $resultset
955 Returns a resultset for the given source. This will initially be created
958 $self->resultset_class->new($self, $self->resultset_attributes)
960 but is cached from then on unless resultset_class changes.
962 =head2 resultset_class
966 =item Arguments: $classname
968 =item Return value: $classname
972 package My::Schema::ResultSet::Artist;
973 use base 'DBIx::Class::ResultSet';
976 # In the result class
977 __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
980 $source->resultset_class('My::Schema::ResultSet::Artist');
982 Set the class of the resultset. This is useful if you want to create your
983 own resultset methods. Create your own class derived from
984 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
985 this method returns the name of the existing resultset class, if one
988 =head2 resultset_attributes
992 =item Arguments: \%attrs
994 =item Return value: \%attrs
998 # In the result class
999 __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
1002 $source->resultset_attributes({ order_by => [ 'id' ] });
1004 Store a collection of resultset attributes, that will be set on every
1005 L<DBIx::Class::ResultSet> produced from this result source. For a full
1006 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
1012 $self->throw_exception(
1013 'resultset does not take any arguments. If you want another resultset, '.
1014 'call it on the schema instead.'
1017 $self->resultset_class->new(
1020 try { %{$self->schema->default_resultset_attributes} },
1021 %{$self->{resultset_attributes}},
1030 =item Arguments: $source_name
1032 =item Result value: $source_name
1036 Set an alternate name for the result source when it is loaded into a schema.
1037 This is useful if you want to refer to a result source by a name other than
1040 package ArchivedBooks;
1041 use base qw/DBIx::Class/;
1042 __PACKAGE__->table('books_archive');
1043 __PACKAGE__->source_name('Books');
1045 # from your schema...
1046 $schema->resultset('Books')->find(1);
1052 =item Arguments: None
1054 =item Return value: FROM clause
1058 my $from_clause = $source->from();
1060 Returns an expression of the source to be supplied to storage to specify
1061 retrieval from this source. In the case of a database, the required FROM
1068 =item Arguments: $schema
1070 =item Return value: A schema object
1074 my $schema = $source->schema();
1076 Sets and/or returns the L<DBIx::Class::Schema> object to which this
1077 result source instance has been attached to.
1083 $_[0]->{schema} = $_[1];
1086 $_[0]->{schema} || do {
1087 my $name = $_[0]->{source_name} || '_unnamed_';
1088 my $err = 'Unable to perform storage-dependent operations with a detached result source '
1089 . "(source '$name' is not associated with a schema).";
1091 $err .= ' You need to use $schema->thaw() or manually set'
1092 . ' $DBIx::Class::ResultSourceHandle::thaw_schema while thawing.'
1093 if $_[0]->{_detached_thaw};
1095 DBIx::Class::Exception->throw($err);
1104 =item Arguments: None
1106 =item Return value: A Storage object
1110 $source->storage->debug(1);
1112 Returns the storage handle for the current schema.
1114 See also: L<DBIx::Class::Storage>
1118 sub storage { shift->schema->storage; }
1120 =head2 add_relationship
1124 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
1126 =item Return value: 1/true if it succeeded
1130 $source->add_relationship('relname', 'related_source', $cond, $attrs);
1132 L<DBIx::Class::Relationship> describes a series of methods which
1133 create pre-defined useful types of relationships. Look there first
1134 before using this method directly.
1136 The relationship name can be arbitrary, but must be unique for each
1137 relationship attached to this result source. 'related_source' should
1138 be the name with which the related result source was registered with
1139 the current schema. For example:
1141 $schema->source('Book')->add_relationship('reviews', 'Review', {
1142 'foreign.book_id' => 'self.id',
1145 The condition C<$cond> needs to be an L<SQL::Abstract>-style
1146 representation of the join between the tables. For example, if you're
1147 creating a relation from Author to Book,
1149 { 'foreign.author_id' => 'self.id' }
1151 will result in the JOIN clause
1153 author me JOIN book foreign ON foreign.author_id = me.id
1155 You can specify as many foreign => self mappings as necessary.
1157 Valid attributes are as follows:
1163 Explicitly specifies the type of join to use in the relationship. Any
1164 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
1165 the SQL command immediately before C<JOIN>.
1169 An arrayref containing a list of accessors in the foreign class to proxy in
1170 the main class. If, for example, you do the following:
1172 CD->might_have(liner_notes => 'LinerNotes', undef, {
1173 proxy => [ qw/notes/ ],
1176 Then, assuming LinerNotes has an accessor named notes, you can do:
1178 my $cd = CD->find(1);
1179 # set notes -- LinerNotes object is created if it doesn't exist
1180 $cd->notes('Notes go here');
1184 Specifies the type of accessor that should be created for the
1185 relationship. Valid values are C<single> (for when there is only a single
1186 related object), C<multi> (when there can be many), and C<filter> (for
1187 when there is a single related object, but you also want the relationship
1188 accessor to double as a column accessor). For C<multi> accessors, an
1189 add_to_* method is also created, which calls C<create_related> for the
1194 Throws an exception if the condition is improperly supplied, or cannot
1199 sub add_relationship {
1200 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
1201 $self->throw_exception("Can't create relationship without join condition")
1205 # Check foreign and self are right in cond
1206 if ( (ref $cond ||'') eq 'HASH') {
1208 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
1209 if /\./ && !/^foreign\./;
1213 my %rels = %{ $self->_relationships };
1214 $rels{$rel} = { class => $f_source_name,
1215 source => $f_source_name,
1218 $self->_relationships(\%rels);
1222 # XXX disabled. doesn't work properly currently. skip in tests.
1224 my $f_source = $self->schema->source($f_source_name);
1225 unless ($f_source) {
1226 $self->ensure_class_loaded($f_source_name);
1227 $f_source = $f_source_name->result_source;
1228 #my $s_class = ref($self->schema);
1229 #$f_source_name =~ m/^${s_class}::(.*)$/;
1230 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1231 #$f_source = $self->schema->source($f_source_name);
1233 return unless $f_source; # Can't test rel without f_source
1235 try { $self->_resolve_join($rel, 'me', {}, []) }
1237 # If the resolve failed, back out and re-throw the error
1239 $self->_relationships(\%rels);
1240 $self->throw_exception("Error creating relationship $rel: $_");
1246 =head2 relationships
1250 =item Arguments: None
1252 =item Return value: List of relationship names
1256 my @relnames = $source->relationships();
1258 Returns all relationship names for this source.
1263 return keys %{shift->_relationships};
1266 =head2 relationship_info
1270 =item Arguments: $relname
1272 =item Return value: Hashref of relation data,
1276 Returns a hash of relationship information for the specified relationship
1277 name. The keys/values are as specified for L</add_relationship>.
1281 sub relationship_info {
1282 my ($self, $rel) = @_;
1283 return $self->_relationships->{$rel};
1286 =head2 has_relationship
1290 =item Arguments: $rel
1292 =item Return value: 1/0 (true/false)
1296 Returns true if the source has a relationship of this name, false otherwise.
1300 sub has_relationship {
1301 my ($self, $rel) = @_;
1302 return exists $self->_relationships->{$rel};
1305 =head2 reverse_relationship_info
1309 =item Arguments: $relname
1311 =item Return value: Hashref of relationship data
1315 Looks through all the relationships on the source this relationship
1316 points to, looking for one whose condition is the reverse of the
1317 condition on this relationship.
1319 A common use of this is to find the name of the C<belongs_to> relation
1320 opposing a C<has_many> relation. For definition of these look in
1321 L<DBIx::Class::Relationship>.
1323 The returned hashref is keyed by the name of the opposing
1324 relationship, and contains its data in the same manner as
1325 L</relationship_info>.
1329 sub reverse_relationship_info {
1330 my ($self, $rel) = @_;
1331 my $rel_info = $self->relationship_info($rel);
1334 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1336 my @cond = keys(%{$rel_info->{cond}});
1337 my @refkeys = map {/^\w+\.(\w+)$/} @cond;
1338 my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
1340 # Get the related result source for this relationship
1341 my $othertable = $self->related_source($rel);
1343 # Get all the relationships for that source that related to this source
1344 # whose foreign column set are our self columns on $rel and whose self
1345 # columns are our foreign columns on $rel.
1346 my @otherrels = $othertable->relationships();
1347 my $otherrelationship;
1348 foreach my $otherrel (@otherrels) {
1349 my $otherrel_info = $othertable->relationship_info($otherrel);
1351 my $back = $othertable->related_source($otherrel);
1352 next unless $back->source_name eq $self->source_name;
1356 if (ref $otherrel_info->{cond} eq 'HASH') {
1357 @othertestconds = ($otherrel_info->{cond});
1359 elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1360 @othertestconds = @{$otherrel_info->{cond}};
1366 foreach my $othercond (@othertestconds) {
1367 my @other_cond = keys(%$othercond);
1368 my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1369 my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1370 next if (!$self->_compare_relationship_keys(\@refkeys, \@other_keys) ||
1371 !$self->_compare_relationship_keys(\@other_refkeys, \@keys));
1372 $ret->{$otherrel} = $otherrel_info;
1378 sub compare_relationship_keys {
1379 carp 'compare_relationship_keys is a private method, stop calling it';
1381 $self->_compare_relationship_keys (@_);
1384 # Returns true if both sets of keynames are the same, false otherwise.
1385 sub _compare_relationship_keys {
1386 my ($self, $keys1, $keys2) = @_;
1388 # Make sure every keys1 is in keys2
1390 foreach my $key (@$keys1) {
1392 foreach my $prim (@$keys2) {
1393 if ($prim eq $key) {
1401 # Make sure every key2 is in key1
1403 foreach my $prim (@$keys2) {
1405 foreach my $key (@$keys1) {
1406 if ($prim eq $key) {
1418 # Returns the {from} structure used to express JOIN conditions
1420 my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1422 # we need a supplied one, because we do in-place modifications, no returns
1423 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1424 unless ref $seen eq 'HASH';
1426 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1427 unless ref $jpath eq 'ARRAY';
1429 $jpath = [@$jpath]; # copy
1431 if (not defined $join) {
1434 elsif (ref $join eq 'ARRAY') {
1437 $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
1440 elsif (ref $join eq 'HASH') {
1443 for my $rel (keys %$join) {
1445 my $rel_info = $self->relationship_info($rel)
1446 or $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1448 my $force_left = $parent_force_left;
1449 $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1451 # the actual seen value will be incremented by the recursion
1452 my $as = $self->storage->relname_to_table_alias(
1453 $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1457 $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1458 $self->related_source($rel)->_resolve_join(
1459 $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
1467 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1470 my $count = ++$seen->{$join};
1471 my $as = $self->storage->relname_to_table_alias(
1472 $join, ($count > 1 && $count)
1475 my $rel_info = $self->relationship_info($join)
1476 or $self->throw_exception("No such relationship $join on " . $self->source_name);
1478 my $rel_src = $self->related_source($join);
1479 return [ { $as => $rel_src->from,
1481 -join_type => $parent_force_left
1483 : $rel_info->{attrs}{join_type}
1485 -join_path => [@$jpath, { $join => $as } ],
1487 $rel_info->{attrs}{accessor}
1489 first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
1492 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1494 $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
1499 carp 'pk_depends_on is a private method, stop calling it';
1501 $self->_pk_depends_on (@_);
1504 # Determines whether a relation is dependent on an object from this source
1505 # having already been inserted. Takes the name of the relationship and a
1506 # hashref of columns of the related object.
1507 sub _pk_depends_on {
1508 my ($self, $relname, $rel_data) = @_;
1510 my $relinfo = $self->relationship_info($relname);
1512 # don't assume things if the relationship direction is specified
1513 return $relinfo->{attrs}{is_foreign_key_constraint}
1514 if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1516 my $cond = $relinfo->{cond};
1517 return 0 unless ref($cond) eq 'HASH';
1519 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1520 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1522 # assume anything that references our PK probably is dependent on us
1523 # rather than vice versa, unless the far side is (a) defined or (b)
1525 my $rel_source = $self->related_source($relname);
1527 foreach my $p ($self->primary_columns) {
1528 if (exists $keyhash->{$p}) {
1529 unless (defined($rel_data->{$keyhash->{$p}})
1530 || $rel_source->column_info($keyhash->{$p})
1531 ->{is_auto_increment}) {
1540 sub resolve_condition {
1541 carp 'resolve_condition is a private method, stop calling it';
1543 $self->_resolve_condition (@_);
1546 # Resolves the passed condition to a concrete query fragment. If given an alias,
1547 # returns a join condition; if given an object, inverts that object to produce
1548 # a related conditional from that object.
1549 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1551 sub _resolve_condition {
1552 my ($self, $cond, $as, $for) = @_;
1553 if (ref $cond eq 'HASH') {
1555 foreach my $k (keys %{$cond}) {
1556 my $v = $cond->{$k};
1557 # XXX should probably check these are valid columns
1558 $k =~ s/^foreign\.// ||
1559 $self->throw_exception("Invalid rel cond key ${k}");
1560 $v =~ s/^self\.// ||
1561 $self->throw_exception("Invalid rel cond val ${v}");
1562 if (ref $for) { # Object
1563 #warn "$self $k $for $v";
1564 unless ($for->has_column_loaded($v)) {
1565 if ($for->in_storage) {
1566 $self->throw_exception(sprintf
1567 "Unable to resolve relationship '%s' from object %s: column '%s' not "
1568 . 'loaded from storage (or not passed to new() prior to insert()). You '
1569 . 'probably need to call ->discard_changes to get the server-side defaults '
1570 . 'from the database.',
1576 return $UNRESOLVABLE_CONDITION;
1578 $ret{$k} = $for->get_column($v);
1579 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1581 } elsif (!defined $for) { # undef, i.e. "no object"
1583 } elsif (ref $as eq 'HASH') { # reverse hashref
1584 $ret{$v} = $as->{$k};
1585 } elsif (ref $as) { # reverse object
1586 $ret{$v} = $as->get_column($k);
1587 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1590 $ret{"${as}.${k}"} = "${for}.${v}";
1594 } elsif (ref $cond eq 'ARRAY') {
1595 return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
1597 die("Can't handle condition $cond yet :(");
1602 # Accepts one or more relationships for the current source and returns an
1603 # array of column names for each of those relationships. Column names are
1604 # prefixed relative to the current source, in accordance with where they appear
1605 # in the supplied relationships.
1607 sub _resolve_prefetch {
1608 my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1611 if (not defined $pre) {
1614 elsif( ref $pre eq 'ARRAY' ) {
1616 map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
1619 elsif( ref $pre eq 'HASH' ) {
1622 $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1623 $self->related_source($_)->_resolve_prefetch(
1624 $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
1629 $self->throw_exception(
1630 "don't know how to resolve prefetch reftype ".ref($pre));
1634 $p = $p->{$_} for (@$pref_path, $pre);
1636 $self->throw_exception (
1637 "Unable to resolve prefetch '$pre' - join alias map does not contain an entry for path: "
1638 . join (' -> ', @$pref_path, $pre)
1639 ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
1641 my $as = shift @{$p->{-join_aliases}};
1643 my $rel_info = $self->relationship_info( $pre );
1644 $self->throw_exception( $self->source_name . " has no such relationship '$pre'" )
1646 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1647 my $rel_source = $self->related_source($pre);
1649 if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') {
1650 $self->throw_exception(
1651 "Can't prefetch has_many ${pre} (join cond too complex)")
1652 unless ref($rel_info->{cond}) eq 'HASH';
1653 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1654 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1655 keys %{$collapse}) {
1656 my ($last) = ($fail =~ /([^\.]+)$/);
1658 "Prefetching multiple has_many rels ${last} and ${pre} "
1659 .(length($as_prefix)
1660 ? "at the same level (${as_prefix}) "
1663 . 'will explode the number of row objects retrievable via ->next or ->all. '
1664 . 'Use at your own risk.'
1667 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1668 # values %{$rel_info->{cond}};
1669 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->_pri_cols ];
1670 # action at a distance. prepending the '.' allows simpler code
1671 # in ResultSet->_collapse_result
1672 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1673 keys %{$rel_info->{cond}};
1674 push @$order, map { "${as}.$_" } @key;
1676 if (my $rel_order = $rel_info->{attrs}{order_by}) {
1677 # this is kludgy and incomplete, I am well aware
1678 # but the parent method is going away entirely anyway
1680 my $sql_maker = $self->storage->sql_maker;
1681 my ($orig_ql, $orig_qr) = $sql_maker->_quote_chars;
1682 my $sep = $sql_maker->name_sep;
1684 # install our own quoter, so we can catch unqualified stuff
1685 local $sql_maker->{quote_char} = ["\x00", "\xFF"];
1687 my $quoted_prefix = "\x00${as}\xFF";
1689 for my $chunk ( $sql_maker->_order_by_chunks ($rel_order) ) {
1691 ($chunk, @bind) = @$chunk if ref $chunk;
1693 $chunk = "${quoted_prefix}${sep}${chunk}"
1694 unless $chunk =~ /\Q$sep/;
1696 $chunk =~ s/\x00/$orig_ql/g;
1697 $chunk =~ s/\xFF/$orig_qr/g;
1698 push @$order, \[$chunk, @bind];
1703 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1704 $rel_source->columns;
1708 =head2 related_source
1712 =item Arguments: $relname
1714 =item Return value: $source
1718 Returns the result source object for the given relationship.
1722 sub related_source {
1723 my ($self, $rel) = @_;
1724 if( !$self->has_relationship( $rel ) ) {
1725 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1727 return $self->schema->source($self->relationship_info($rel)->{source});
1730 =head2 related_class
1734 =item Arguments: $relname
1736 =item Return value: $classname
1740 Returns the class name for objects in the given relationship.
1745 my ($self, $rel) = @_;
1746 if( !$self->has_relationship( $rel ) ) {
1747 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1749 return $self->schema->class($self->relationship_info($rel)->{source});
1756 =item Arguments: None
1758 =item Return value: $source_handle
1762 Obtain a new L<result source handle instance|DBIx::Class::ResultSourceHandle>
1763 for this source. Used as a serializable pointer to this resultsource, as it is not
1764 easy (nor advisable) to serialize CODErefs which may very well be present in e.g.
1765 relationship definitions.
1770 return DBIx::Class::ResultSourceHandle->new({
1771 source_moniker => $_[0]->source_name,
1773 # so that a detached thaw can be re-frozen
1774 $_[0]->{_detached_thaw}
1775 ? ( _detached_source => $_[0] )
1776 : ( schema => $_[0]->schema )
1782 my $global_phase_destroy;
1784 END { $global_phase_destroy++ }
1787 return if $global_phase_destroy;
1793 # Under no circumstances shall $_[0] be stored anywhere else (like copied to
1794 # a lexical variable, or shifted, or anything else). Doing so will mess up
1795 # the refcount of this particular result source, and will allow the $schema
1796 # we are trying to save to reattach back to the source we are destroying.
1797 # The relevant code checking refcounts is in ::Schema::DESTROY()
1799 # if we are not a schema instance holder - we don't matter
1801 ! ref $_[0]->{schema}
1803 isweak $_[0]->{schema}
1806 # weaken our schema hold forcing the schema to find somewhere else to live
1807 weaken $_[0]->{schema};
1809 # if schema is still there reintroduce ourselves with strong refs back
1810 if ($_[0]->{schema}) {
1811 my $srcregs = $_[0]->{schema}->source_registrations;
1812 for (keys %$srcregs) {
1813 $srcregs->{$_} = $_[0] if $srcregs->{$_} == $_[0];
1819 sub STORABLE_freeze { nfreeze($_[0]->handle) }
1822 my ($self, $cloning, $ice) = @_;
1823 %$self = %{ (thaw $ice)->resolve };
1826 =head2 throw_exception
1828 See L<DBIx::Class::Schema/"throw_exception">.
1832 sub throw_exception {
1836 ? $self->{schema}->throw_exception(@_)
1837 : DBIx::Class::Exception->throw(@_)
1843 Stores a hashref of per-source metadata. No specific key names
1844 have yet been standardized, the examples below are purely hypothetical
1845 and don't actually accomplish anything on their own:
1847 __PACKAGE__->source_info({
1848 "_tablespace" => 'fast_disk_array_3',
1849 "_engine" => 'InnoDB',
1856 $class->new({attribute_name => value});
1858 Creates a new ResultSource object. Not normally called directly by end users.
1860 =head2 column_info_from_storage
1864 =item Arguments: 1/0 (default: 0)
1866 =item Return value: 1/0
1870 __PACKAGE__->column_info_from_storage(1);
1872 Enables the on-demand automatic loading of the above column
1873 metadata from storage as necessary. This is *deprecated*, and
1874 should not be used. It will be removed before 1.0.
1879 Matt S. Trout <mst@shadowcatsystems.co.uk>
1883 You may distribute this code under the same terms as Perl itself.