X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRow.pm;h=a6dcbeba5dffa94f5b0fd9756a4bd71b1e91efd2;hb=322ac74746c0ec7bb03f9241241ce7d0b928f929;hp=1d9c56dad853264c32233a1709c2c69fa00cb749;hpb=d4fe33d0eaa12ce9706b246ebd46492d96bef4c5;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 1d9c56d..a6dcbeb 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -4,9 +4,9 @@ use strict; use warnings; use base qw/DBIx::Class/; -use Carp::Clan qw/^DBIx::Class/; + +use DBIx::Class::Exception; use Scalar::Util (); -use Scope::Guard; ### ### Internal method @@ -155,7 +155,7 @@ sub new { $new->result_source($source); } - if (my $related = delete $attrs->{-from_resultset}) { + if (my $related = delete $attrs->{-cols_from_relations}) { @{$new->{_ignore_at_insert}={}}{@$related} = (); } @@ -168,7 +168,8 @@ sub new { foreach my $key (keys %$attrs) { if (ref $attrs->{$key}) { ## Can we extract this lot to use with update(_or .. ) ? - confess "Can't do multi-create without result source" unless $source; + $new->throw_exception("Can't do multi-create without result source") + unless $source; my $info = $source->relationship_info($key); if ($info && $info->{attrs}{accessor} && $info->{attrs}{accessor} eq 'single') @@ -354,18 +355,17 @@ sub insert { $self->{related_resultsets} = {}; foreach my $relname (keys %related_stuff) { - my $rel_obj = $related_stuff{$relname}; - my @cands; - if (Scalar::Util::blessed($rel_obj) - && $rel_obj->isa('DBIx::Class::Row')) - { - @cands = ($rel_obj); - } - elsif (ref $rel_obj eq 'ARRAY') { - @cands = @$rel_obj; - } + next unless $source->has_relationship ($relname); - if (@cands) { + my @cands = ref $related_stuff{$relname} eq 'ARRAY' + ? @{$related_stuff{$relname}} + : $related_stuff{$relname} + ; + + if (@cands + && Scalar::Util::blessed($cands[0]) + && $cands[0]->isa('DBIx::Class::Row') + ) { my $reverse = $source->reverse_relationship_info($relname); foreach my $obj (@cands) { $obj->set_from_related($_, $self) for keys %$reverse; @@ -424,7 +424,7 @@ L on one, sets it to false. sub in_storage { my ($self, $val) = @_; $self->{_in_storage} = $val if @_ > 1; - return $self->{_in_storage}; + return $self->{_in_storage} ? 1 : 0; } =head2 update @@ -751,10 +751,27 @@ See L for how to setup inflation. sub get_inflated_columns { my $self = shift; - return map { - my $accessor = $self->column_info($_)->{'accessor'} || $_; - ($_ => $self->$accessor); - } grep $self->has_column_loaded($_), $self->columns; + + my %loaded_colinfo = (map + { $_ => $self->column_info($_) } + (grep { $self->has_column_loaded($_) } $self->columns) + ); + + my %inflated; + for my $col (keys %loaded_colinfo) { + if (exists $loaded_colinfo{$col}{accessor}) { + my $acc = $loaded_colinfo{$col}{accessor}; + if (defined $acc) { + $inflated{$col} = $self->$acc; + } + } + else { + $inflated{$col} = $self->$col; + } + } + + # return all loaded columns with the inflations overlayed on top + return ($self->get_columns, %inflated); } =head2 set_column @@ -1278,12 +1295,51 @@ sub get_from_storage { my $resultset = $self->result_source->resultset; if(defined $attrs) { - $resultset = $resultset->search(undef, $attrs); + $resultset = $resultset->search(undef, $attrs); } return $resultset->find($self->{_orig_ident} || $self->ident_condition); } +=head2 discard_changes ($attrs) + +Re-selects the row from the database, losing any changes that had +been made. + +This method can also be used to refresh from storage, retrieving any +changes made since the row was last read from storage. + +$attrs is expected to be a hashref of attributes suitable for passing as the +second argument to $resultset->search($cond, $attrs); + +=cut + +sub discard_changes { + my ($self, $attrs) = @_; + delete $self->{_dirty_columns}; + return unless $self->in_storage; # Don't reload if we aren't real! + + # add a replication default to read from the master only + $attrs = { force_pool => 'master', %{$attrs||{}} }; + + if( my $current_storage = $self->get_from_storage($attrs)) { + + # Set $self to the current. + %$self = %$current_storage; + + # Avoid a possible infinite loop with + # sub DESTROY { $_[0]->discard_changes } + bless $current_storage, 'Do::Not::Exist'; + + return $self; + } + else { + $self->in_storage(0); + return $self; + } +} + + =head2 throw_exception See L. @@ -1292,10 +1348,12 @@ See L. sub throw_exception { my $self=shift; + if (ref $self && ref $self->result_source && $self->result_source->schema) { - $self->result_source->schema->throw_exception(@_); - } else { - croak(@_); + $self->result_source->schema->throw_exception(@_) + } + else { + DBIx::Class::Exception->throw(@_); } }