X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=bdf01f12e9d5627b5de85e73d05a9b0a8334e8c3;hb=aa1088bf7ed82084a2d4b2ca957650a15a294ab4;hp=22cbdf1e9e3630768f44cdd54c9161279fea78f7;hpb=5a5bec6c01bda57e0f09e77b4e36ce84edeb5fa2;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 22cbdf1..bdf01f1 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -5,16 +5,17 @@ use warnings; use DBIx::Class::ResultSet; use Carp::Clan qw/^DBIx::Class/; - use Storable; -use Scalar::Util qw/weaken/; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/AccessorGroup/); -__PACKAGE__->mk_group_accessors('simple' => - qw/_ordered_columns _columns _primaries _unique_constraints name resultset_attributes schema from _relationships/); -__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class result_class/); +__PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns + _columns _primaries _unique_constraints name resultset_attributes + schema from _relationships/); + +__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class + result_class/); =head1 NAME @@ -93,7 +94,8 @@ If the column is allowed to contain NULL values, set a true value =item is_auto_increment Set this to a true value if this is a column that is somehow -automatically filled. This is currently not used by DBIx::Class. +automatically filled. This is used to determine which columns to empty +when cloning objects using C. =item is_foreign_key @@ -108,11 +110,9 @@ currently not used by DBIx::Class. =item sequence -If your column is using a sequence to create it's values, set the name -of the sequence here, to allow the values to be retrieved -automatically by the L module. PK::Auto will -attempt to retrieve the sequence name from the database, if this value -is left unset. +Sets the name of the sequence to use to generate values. If not +specified, L will attempt to retrieve the +name of the sequence from the database automatically. =back @@ -126,18 +126,15 @@ Convenience alias to add_columns sub add_columns { my ($self, @cols) = @_; - $self->_ordered_columns( \@cols ) - if !$self->_ordered_columns; + $self->_ordered_columns(\@cols) unless $self->_ordered_columns; + my @added; my $columns = $self->_columns; while (my $col = shift @cols) { - + # If next entry is { ... } use that for the column info, if not + # use an empty hashref my $column_info = ref $cols[0] ? shift(@cols) : {}; - # If next entry is { ... } use that for the column info, if not - # use an empty hashref - push(@added, $col) unless exists $columns->{$col}; - $columns->{$col} = $column_info; } push @{ $self->_ordered_columns }, @added; @@ -173,22 +170,21 @@ sub column_info { $self->throw_exception("No such column $column") unless exists $self->_columns->{$column}; #warn $self->{_columns_info_loaded}, "\n"; - if ( ! $self->_columns->{$column}->{data_type} - && ! $self->{_columns_info_loaded} - && $self->schema && $self->storage() ){ - $self->{_columns_info_loaded}++; - my $info; -############ eval for the case of storage without table - eval{ - $info = $self->storage->columns_info_for ( $self->from() ); - }; - if ( ! $@ ){ - for my $col ( keys %{$self->_columns} ){ - for my $i ( keys %{$info->{$col}} ){ - $self->_columns()->{$col}->{$i} = $info->{$col}->{$i}; - } - } + if ( ! $self->_columns->{$column}{data_type} + and ! $self->{_columns_info_loaded} + and $self->schema and $self->storage ) + { + $self->{_columns_info_loaded}++; + my $info; + # eval for the case of storage without table + eval { $info = $self->storage->columns_info_for($self->from) }; + unless ($@) { + foreach my $col ( keys %{$self->_columns} ) { + foreach my $i ( keys %{$info->{$col}} ) { + $self->_columns->{$col}{$i} = $info->{$col}{$i}; + } } + } } return $self->_columns->{$column}; } @@ -202,8 +198,10 @@ Returns all column names in the order they were declared to add_columns =cut sub columns { - my $self=shift; - $self->throw_exception("columns() is a read-only accessor, did you mean add_columns()?") if (@_ > 1); + my $self = shift; + $self->throw_exception( + "columns() is a read-only accessor, did you mean add_columns()?" + ) if (@_ > 1); return @{$self->{_ordered_columns}||[]}; } @@ -224,9 +222,9 @@ retrieve automatically created values from the database. sub set_primary_key { my ($self, @cols) = @_; # check if primary key columns are valid columns - for (@cols) { - $self->throw_exception("No such column $_ on table ".$self->name) - unless $self->has_column($_); + foreach my $col (@cols) { + $self->throw_exception("No such column $col on table " . $self->name) + unless $self->has_column($col); } $self->_primaries(\@cols); @@ -257,9 +255,9 @@ L, only columns in the constraint are searched, sub add_unique_constraint { my ($self, $name, $cols) = @_; - for (@$cols) { - $self->throw_exception("No such column $_ on table ".$self->name) - unless $self->has_column($_); + foreach my $col (@$cols) { + $self->throw_exception("No such column $col on table " . $self->name) + unless $self->has_column($col); } my %unique_constraints = $self->unique_constraints; @@ -299,13 +297,18 @@ sub storage { shift->schema->storage; } $source->add_relationship('relname', 'related_source', $cond, $attrs); -The relation name can be arbitrary, but must be unique for each relationship -attached to this result source. 'related_source' should be the name with -which the related result source was registered with the current schema -(for simple schemas this is usally either Some::Namespace::Foo or just Foo) +The relationship name can be arbitrary, but must be unique for each +relationship attached to this result source. 'related_source' should +be the name with which the related result source was registered with +the current schema. For example: + + $schema->source('Book')->add_relationship('reviews', 'Review', { + 'foreign.book_id' => 'self.id', + }); -The condition needs to be an SQL::Abstract-style representation of the join -between the tables. For example, if you're creating a rel from Author to Book, +The condition C<$cond> needs to be an SQL::Abstract-style +representation of the join between the tables. For example, if you're +creating a rel from Author to Book, { 'foreign.author_id' => 'self.id' } @@ -327,15 +330,18 @@ the SQL command immediately before C. =item proxy -An arrayref containing a list of accessors in the foreign class to -proxy in the main class. If, for example, you do the following: - - __PACKAGE__->might_have(bar => 'Bar', undef, { proxy => [ qw/margle/] }); +An arrayref containing a list of accessors in the foreign class to proxy in +the main class. If, for example, you do the following: + + CD->might_have(liner_notes => 'LinerNotes', undef, { + proxy => [ qw/notes/ ], + }); + +Then, assuming LinerNotes has an accessor named notes, you can do: -Then, assuming Bar has an accessor named margle, you can do: - - my $obj = Foo->find(1); - $obj->margle(10); # set margle; Bar object is created if it doesn't exist + my $cd = CD->find(1); + $cd->notes('Notes go here'); # set notes -- LinerNotes object is + # created if it doesn't exist =item accessor @@ -547,7 +553,6 @@ in the supplied relationships. Examples: sub resolve_prefetch { my ($self, $pre, $alias, $seen, $order, $collapse) = @_; $seen ||= {}; - use Data::Dumper; #$alias ||= $self->name; #warn $alias, Dumper $pre; if( ref $pre eq 'ARRAY' ) { @@ -575,7 +580,7 @@ sub resolve_prefetch { my $rel_info = $self->relationship_info( $pre ); $self->throw_exception( $self->name . " has no such relationship '$pre'" ) unless $rel_info; - my $as_prefix = ($alias =~ /^.*?\.(.*)$/ ? $1.'.' : ''); + my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : ''); my $rel_source = $self->related_source($pre); if (exists $rel_info->{attrs}{accessor} @@ -583,7 +588,7 @@ sub resolve_prefetch { $self->throw_exception( "Can't prefetch has_many ${pre} (join cond too complex)") unless ref($rel_info->{cond}) eq 'HASH'; - my @key = map { (/^foreign\.(.*)$/ ? ($1) : ()); } + my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); } keys %{$rel_info->{cond}}; $collapse->{"${as_prefix}${pre}"} = \@key; my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY' @@ -617,12 +622,31 @@ sub related_source { return $self->schema->source($self->relationship_info($rel)->{source}); } +=head2 related_class + +=head3 Arguments: ($relname) + +Returns the class object for the given relationship + +=cut + +sub related_class { + my ($self, $rel) = @_; + if( !$self->has_relationship( $rel ) ) { + $self->throw_exception("No such relationship '$rel'"); + } + return $self->schema->class($self->relationship_info($rel)->{source}); +} + =head2 resultset -Returns a resultset for the given source, by calling: +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 Set the class of the resultset, this is useful if you want to create your @@ -639,11 +663,7 @@ 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} if ref $self->{_resultset} eq $self->resultset_class; - return $self->{_resultset} = do { - my $rs = $self->resultset_class->new($self, $self->{resultset_attributes}); - weaken $rs->result_source; - $rs; - }; + return $self->{_resultset} = $self->resultset_class->new($self, $self->{resultset_attributes}); } =head2 throw_exception