X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRow.pm;h=1e11805bd71c76e21395b93517fb85c4d13a40d7;hb=937114227af35f69796b19606cd87083b2a9ae68;hp=ea6ea0924df33f887f9ff9c99df543091453df45;hpb=867f1b28c4934e62ad3545c8607b2bf4c145b34a;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index ea6ea09..1e11805 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -43,6 +43,23 @@ L or L) relationship accessors of L objects. +=head1 NOTE + +All "Row objects" derived from a Schema-attached L +object (such as a typical C<< L->L >> call) are actually Result +instances, based on your application's +L. + +L implements most of the row-based communication with the +underlying storage, but a Result class B. +Usually, Result classes inherit from L, which in turn +combines the methods from several classes, one of them being +L. Therefore, while many of the methods available to a +L-derived Result class are described in the following +documentation, it does not detail all of the methods available to Result +objects. Refer to L for more info. + =head1 METHODS =head2 new @@ -55,7 +72,7 @@ relationship accessors of L objects. =item Arguments: \%attrs or \%colsandvalues -=item Returns: A Row object +=item Returns: A DBIx::Class::Row object =back @@ -255,6 +272,39 @@ sub new { return $new; } +=head2 $column_accessor + + # Each pair does the same thing + + # (un-inflated, regular column) + my $val = $row->get_column('first_name'); + my $val = $row->first_name; + + $row->set_column('first_name' => $val); + $row->first_name($val); + + # (inflated column via DBIx::Class::InflateColumn::DateTime) + my $val = $row->get_inflated_column('last_modified'); + my $val = $row->last_modified; + + $row->set_inflated_column('last_modified' => $val); + $row->last_modified($val); + +=over + +=item Arguments: $value? + +=item Returns: $value + +=back + +A column accessor method is created for each column, which is used for +getting/setting the value for that column. + +The actual method name is based on the L +name given in the table definition. Like L, this will +not store the data until L or L is called on the row. + =head2 insert $row->insert; @@ -357,9 +407,11 @@ sub insert { # this ensures we fire store_column only once # (some asshats like overriding it) if ( - (! defined $current_rowdata{$_}) + (!exists $current_rowdata{$_}) + or + (defined $current_rowdata{$_} xor defined $returned_cols->{$_}) or - ( $current_rowdata{$_} ne $returned_cols->{$_}) + (defined $current_rowdata{$_} and $current_rowdata{$_} ne $returned_cols->{$_}) ); } @@ -466,7 +518,7 @@ to C, e.g. ( { %{ $href } } ) If the values passed or any of the column values set on the object contain scalar references, e.g.: - $row->last_modified(\'NOW()'); + $row->last_modified(\'NOW()')->update(); # OR $row->update({ last_modified => \'NOW()' }); @@ -591,7 +643,7 @@ sub delete { =back Throws an exception if the column name given doesn't exist according -to L. +to L. Returns a raw column value from the row object, if it has already been fetched from the database or set by an accessor. @@ -822,7 +874,7 @@ the column is marked as dirty for when you next call L. If passed an object or reference as a value, this method will happily attempt to store it, and a later L or L will try and stringify/numify as appropriate. To set an object to be deflated -instead, see L. +instead, see L, or better yet, use L. =cut @@ -1137,23 +1189,38 @@ sub inflate_result { foreach my $pre (keys %{$prefetch||{}}) { - my $pre_source = $source->related_source($pre) - or $class->throw_exception("Can't prefetch non-existent relationship ${pre}"); - - my $accessor = $source->relationship_info($pre)->{attrs}{accessor} - or $class->throw_exception("No accessor for prefetched $pre"); - - my @pre_vals; + my (@pre_vals, $is_multi); if (ref $prefetch->{$pre}[0] eq 'ARRAY') { + $is_multi = 1; @pre_vals = @{$prefetch->{$pre}}; } - elsif ($accessor eq 'multi') { - $class->throw_exception("Implicit prefetch (via select/columns) not supported with accessor 'multi'"); - } else { @pre_vals = $prefetch->{$pre}; } + my $pre_source = try { + $source->related_source($pre) + } + catch { + $class->throw_exception(sprintf + + "Can't inflate manual prefetch into non-existent relationship '%s' from '%s', " + . "check the inflation specification (columns/as) ending in '%s.%s'.", + + $pre, + $source->source_name, + $pre, + (keys %{$pre_vals[0][0]})[0] || 'something.something...', + ); + }; + + my $accessor = $source->relationship_info($pre)->{attrs}{accessor} + or $class->throw_exception("No accessor type declared for prefetched $pre"); + + if (! $is_multi and $accessor eq 'multi') { + $class->throw_exception("Manual prefetch (via select/columns) not supported with accessor 'multi'"); + } + my @pre_objects; for my $me_pref (@pre_vals) { @@ -1373,7 +1440,7 @@ sub get_from_storage { return $resultset->find($self->_storage_ident_condition); } -=head2 discard_changes ($attrs?) +=head2 discard_changes $row->discard_changes @@ -1430,7 +1497,6 @@ sub discard_changes { } } - =head2 throw_exception See L. @@ -1463,9 +1529,9 @@ sub throw_exception { Returns the primary key(s) for a row. Can't be called as a class method. Actually implemented in L -=head1 AUTHORS +=head1 AUTHOR AND CONTRIBUTORS -Matt S. Trout +See L and L in DBIx::Class =head1 LICENSE