X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=bb178fc16eb1adf0e11028a8d247fd0ce889386b;hb=a4fcda000aa9833874693ea9bc940a92abbe1b6f;hp=41d55622c641e27544f33feed32a4384987144cb;hpb=391ccf38fb53560c1eee1012fc3e483f42fe607b;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 41d5562..bb178fc 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -13,7 +13,7 @@ use base qw/DBIx::Class/; __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns _columns _primaries _unique_constraints name resultset_attributes schema from _relationships column_info_from_storage source_info - source_name/); + source_name sqlt_deploy_callback/); __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class result_class/); @@ -29,18 +29,12 @@ DBIx::Class::ResultSource - Result source object A ResultSource is a component of a schema from which results can be directly retrieved, most usually a table (see L) +Basic view support also exists, see L<. + =head1 METHODS =pod -=head2 new - - $class->new(); - - $class->new({attribute_name => value}); - -Creates a new ResultSource object. Not normally called directly by end users. - =cut sub new { @@ -55,22 +49,12 @@ sub new { $new->{_relationships} = { %{$new->{_relationships}||{}} }; $new->{name} ||= "!!NAME NOT SET!!"; $new->{_columns_info_loaded} ||= 0; + $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook"; return $new; } =pod -=head2 source_info - -Stores a hashref of per-source metadata. No specific key names -have yet been standardized, the examples below are purely hypothetical -and don't actually accomplish anything on their own: - - __PACKAGE__->source_info({ - "_tablespace" => 'fast_disk_array_3', - "_engine" => 'InnoDB', - }); - =head2 add_columns =over @@ -81,16 +65,16 @@ and don't actually accomplish anything on their own: =back - $table->add_columns(qw/col1 col2 col3/); + $source->add_columns(qw/col1 col2 col3/); - $table->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...); + $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...); Adds columns to the result source. If supplied key => hashref pairs, uses the hashref as the column_info for that column. Repeated calls of this method will add more columns, not replace them. The column names given will be created as accessor methods on your -L objects, you can change the name of the accessor +L objects. You can change the name of the accessor by supplying an L in the column_info hash. The contents of the column_info are not set in stone. The following @@ -141,8 +125,12 @@ L. =item default_value Set this to the default value which will be inserted into a column -by the database. Can contain either a value or a function. This is -currently only used by L. +by the database. Can contain either a value or a function (use a +reference to a scalar e.g. C<\'now()'> if you want a function). This +is currently only used by L. + +See the note on L for more information about possible +issues related to db-side default values. =item sequence @@ -154,7 +142,7 @@ automatically. =item auto_nextval Set this to a true value for a column whose value is retrieved -automatically from an oracle sequence. If you do not use an oracle +automatically from an oracle sequence. If you do not use an Oracle trigger to get the nextval, you have to set sequence as well. =item extra @@ -177,7 +165,7 @@ L. =back - $table->add_column('col' => \%info?); + $source->add_column('col' => \%info?); Add a single column and optional column info. Uses the same column info keys as L. @@ -213,7 +201,7 @@ sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB =back - if ($obj->has_column($colname)) { ... } + if ($source->has_column($colname)) { ... } Returns true if the source has a column of this name, false otherwise. @@ -234,7 +222,7 @@ sub has_column { =back - my $info = $obj->column_info($col); + my $info = $source->column_info($col); Returns the column metadata hashref for a column, as originally passed to L. See the description of L for information @@ -272,22 +260,6 @@ sub column_info { return $self->_columns->{$column}; } -=head2 column_info_from_storage - -=over - -=item Arguments: 1/0 (default: 0) - -=item Return value: 1/0 - -=back - -Enables the on-demand automatic loading of the above column -metadata from storage as neccesary. This is *deprecated*, and -should not be used. It will be removed before 1.0. - - __PACKAGE__->column_info_from_storage(1); - =head2 columns =over @@ -352,22 +324,18 @@ broken result source. =cut sub remove_columns { - my ($self, @cols) = @_; + my ($self, @to_remove) = @_; - return unless $self->_ordered_columns; + my $columns = $self->_columns + or return; - my $columns = $self->_columns; - my @remaining; - - foreach my $col (@{$self->_ordered_columns}) { - push @remaining, $col unless grep(/$col/, @cols); - } - - foreach (@cols) { + my %to_remove; + for (@to_remove) { delete $columns->{$_}; - }; + ++$to_remove{$_}; + } - $self->_ordered_columns(\@remaining); + $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]); } sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB @@ -582,6 +550,171 @@ sub unique_constraint_columns { return @{ $unique_constraints{$constraint_name} }; } +=head2 sqlt_deploy_callback + +=over + +=item Arguments: $callback + +=back + + __PACKAGE__->sqlt_deploy_callback('mycallbackmethod'); + +An accessor to set a callback to be called during deployment of +the schema via L or +L. + +The callback can be set as either a code reference or the name of a +method in the current result class. + +If not set, the L is called. + +Your callback will be passed the $source object representing the +ResultSource instance being deployed, and the +L object being created from it. The +callback can be used to manipulate the table object or add your own +customised indexes. If you need to manipulate a non-table object, use +the L. + +See L for examples. + +This sqlt deployment callback can only be used to manipulate +SQL::Translator objects as they get turned into SQL. To execute +post-deploy statements which SQL::Translator does not currently +handle, override L in your Schema class +and call L. + +=head2 default_sqlt_deploy_hook + +=over + +=item Arguments: $source, $sqlt_table + +=item Return value: undefined + +=back + +This is the sensible default for L. + +If a method named C exists in your Result class, it +will be called and passed the current C<$source> and the +C<$sqlt_table> being deployed. + +=cut + +sub default_sqlt_deploy_hook { + my $self = shift; + + my $class = $self->result_class; + + if ($class and $class->can('sqlt_deploy_hook')) { + $class->sqlt_deploy_hook(@_); + } +} + +sub _invoke_sqlt_deploy_hook { + my $self = shift; + if ( my $hook = $self->sqlt_deploy_callback) { + $self->$hook(@_); + } +} + +=head2 resultset + +=over 4 + +=item Arguments: None + +=item Return value: $resultset + +=back + +Returns a resultset for the given source. This will initially be created +on demand by calling + + $self->resultset_class->new($self, $self->resultset_attributes) + +but is cached from then on unless resultset_class changes. + +=head2 resultset_class + +=over 4 + +=item Arguments: $classname + +=item Return value: $classname + +=back + + package My::ResultSetClass; + use base 'DBIx::Class::ResultSet'; + ... + + $source->resultset_class('My::ResultSet::Class'); + +Set the class of the resultset. This is useful if you want to create your +own resultset methods. Create your own class derived from +L, and set it here. If called with no arguments, +this method returns the name of the existing resultset class, if one +exists. + +=head2 resultset_attributes + +=over 4 + +=item Arguments: \%attrs + +=item Return value: \%attrs + +=back + + $source->resultset_attributes({ order_by => [ 'id' ] }); + +Store a collection of resultset attributes, that will be set on every +L produced from this result source. For a full +list see L. + +=cut + +sub resultset { + my $self = shift; + $self->throw_exception( + 'resultset does not take any arguments. If you want another resultset, '. + 'call it on the schema instead.' + ) if scalar @_; + + return $self->resultset_class->new( + $self, + { + %{$self->{resultset_attributes}}, + %{$self->schema->default_resultset_attributes} + }, + ); +} + +=head2 source_name + +=over 4 + +=item Arguments: $source_name + +=item Result value: $source_name + +=back + +Set an alternate name for the result source when it is loaded into a schema. +This is useful if you want to refer to a result source by a name other than +its class name. + + package ArchivedBooks; + use base qw/DBIx::Class/; + __PACKAGE__->table('books_archive'); + __PACKAGE__->source_name('Books'); + + # from your schema... + $schema->resultset('Books')->find(1); + =head2 from =over 4 @@ -1067,7 +1200,11 @@ sub resolve_condition { #warn "$self $k $for $v"; unless ($for->has_column_loaded($v)) { if ($for->in_storage) { - $self->throw_exception("Column ${v} not loaded on ${for} trying to resolve relationship"); + $self->throw_exception( + "Column ${v} not loaded or not passed to new() prior to insert()" + ." on ${for} trying to resolve relationship (maybe you forgot " + ."to call ->reload_from_storage to get defaults from the db)" + ); } return $UNRESOLVABLE_CONDITION; } @@ -1262,101 +1399,6 @@ sub related_class { return $self->schema->class($self->relationship_info($rel)->{source}); } -=head2 resultset - -=over 4 - -=item Arguments: None - -=item Return value: $resultset - -=back - -Returns a resultset for the given source. This will initially be created -on demand by calling - - $self->resultset_class->new($self, $self->resultset_attributes) - -but is cached from then on unless resultset_class changes. - -=head2 resultset_class - -=over 4 - -=item Arguments: $classname - -=item Return value: $classname - -=back - - package My::ResultSetClass; - use base 'DBIx::Class::ResultSet'; - ... - - $source->resultset_class('My::ResultSet::Class'); - -Set the class of the resultset, this is useful if you want to create your -own resultset methods. Create your own class derived from -L, and set it here. If called with no arguments, -this method returns the name of the existing resultset class, if one -exists. - -=head2 resultset_attributes - -=over 4 - -=item Arguments: \%attrs - -=item Return value: \%attrs - -=back - - $source->resultset_attributes({ order_by => [ 'id' ] }); - -Store a collection of resultset attributes, that will be set on every -L produced from this result source. For a full -list see L. - -=cut - -sub resultset { - my $self = shift; - $self->throw_exception( - 'resultset does not take any arguments. If you want another resultset, '. - 'call it on the schema instead.' - ) if scalar @_; - - return $self->resultset_class->new( - $self, - { - %{$self->{resultset_attributes}}, - %{$self->schema->default_resultset_attributes} - }, - ); -} - -=head2 source_name - -=over 4 - -=item Arguments: $source_name - -=item Result value: $source_name - -=back - -Set an alternate name for the result source when it is loaded into a schema. -This is useful if you want to refer to a result source by a name other than -its class name. - - package ArchivedBooks; - use base qw/DBIx::Class/; - __PACKAGE__->table('books_archive'); - __PACKAGE__->source_name('Books'); - - # from your schema... - $schema->resultset('Books')->find(1); - =head2 handle Obtain a new handle to this source. Returns an instance of a @@ -1386,25 +1428,41 @@ sub throw_exception { } } -=head2 sqlt_deploy_hook($sqlt_table) +=head2 source_info -=over 4 +Stores a hashref of per-source metadata. No specific key names +have yet been standardized, the examples below are purely hypothetical +and don't actually accomplish anything on their own: -=item Arguments: $source, $sqlt_table + __PACKAGE__->source_info({ + "_tablespace" => 'fast_disk_array_3', + "_engine" => 'InnoDB', + }); -=item Return value: undefined +=head2 new + + $class->new(); + + $class->new({attribute_name => value}); + +Creates a new ResultSource object. Not normally called directly by end users. + +=head2 column_info_from_storage + +=over + +=item Arguments: 1/0 (default: 0) + +=item Return value: 1/0 =back -An optional sub which you can declare in your own Result class that will get -passed the L object when you deploy the schema -via L or L. + __PACKAGE__->column_info_from_storage(1); -This is useful to make L create non-unique indexes, -or set table options such as C. +Enables the on-demand automatic loading of the above column +metadata from storage as neccesary. This is *deprecated*, and +should not be used. It will be removed before 1.0. -For an example of what you can do with this, see -L. =head1 AUTHORS