DBIx-Class
view release on metacpan or search on metacpan
lib/DBIx/Class/Row.pm view on Meta::CPAN
are invoked.
Creating a result object using L<DBIx::Class::ResultSet/new_result>, or
calling L</delete> on one, sets it to false.
=head2 update
$result->update(\%columns?)
=over
=item Arguments: none or a hashref
=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
=back
Throws an exception if the result object is not yet in the database,
according to L</in_storage>. Returns the object itself.
This method issues an SQL UPDATE query to commit any changes to the
object to the database if required (see L</get_dirty_columns>).
It throws an exception if a proper WHERE clause uniquely identifying
the database row can not be constructed (see
L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
for more details).
Also takes an optional hashref of C<< column_name => value >> pairs
to update on the object first. Be aware that the hashref will be
passed to C<set_inflated_columns>, which might edit it in place, so
don't rely on it being the same after a call to C<update>. If you
need to preserve the hashref, it is sufficient to pass a shallow copy
to C<update>, e.g. ( { %{ $href } } )
If the values passed or any of the column values set on the object
contain scalar references, e.g.:
$result->last_modified(\'NOW()')->update();
# OR
$result->update({ last_modified => \'NOW()' });
The update will pass the values verbatim into SQL. (See
L<SQL::Abstract::Classic> docs). The values in your Result object will NOT
change as a result of the update call, if you want the object to be updated
with the actual values from the database, call L</discard_changes> after the
update.
$result->update()->discard_changes();
To determine before calling this method, which column values have
changed and will be updated, call L</get_dirty_columns>.
To check if any columns will be updated, call L</is_changed>.
To force a column to be updated, call L</make_column_dirty> before
this method.
=cut
sub update {
my ($self, $upd) = @_;
$self->set_inflated_columns($upd) if $upd;
my %to_update = $self->get_dirty_columns
or return $self;
$self->throw_exception( "Not in database" ) unless $self->in_storage;
my $rows = $self->result_source->storage->update(
$self->result_source, \%to_update, $self->_storage_ident_condition
);
if ($rows == 0) {
$self->throw_exception( "Can't update ${self}: row not found" );
} elsif ($rows > 1) {
$self->throw_exception("Can't update ${self}: updated more than one row");
}
$self->{_dirty_columns} = {};
$self->{related_resultsets} = {};
delete $self->{_column_data_in_storage};
return $self;
}
=head2 delete
$result->delete
=over
=item Arguments: none
=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
=back
Throws an exception if the object is not in the database according to
L</in_storage>. Also throws an exception if a proper WHERE clause
uniquely identifying the database row can not be constructed (see
L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
for more details).
The object is still perfectly usable, but L</in_storage> will
now return 0 and the object must be reinserted using L</insert>
before it can be used to L</update> the row again.
If you delete an object in a class with a C<has_many> relationship, an
attempt is made to delete all the related objects as well. To turn
this behaviour off, pass C<< cascade_delete => 0 >> in the C<$attr>
hashref of the relationship, see L<DBIx::Class::Relationship>. Any
database-level cascade or restrict will take precedence over a
DBIx-Class-based cascading delete, since DBIx-Class B<deletes the
main row first> and only then attempts to delete any remaining related
rows.
If you delete an object within a txn_do() (see L<DBIx::Class::Storage/txn_do>)
and the transaction subsequently fails, the result object will remain marked as
not being in storage. If you know for a fact that the object is still in
storage (i.e. by inspecting the cause of the transaction's failure), you can
use C<< $obj->in_storage(1) >> to restore consistency between the object and
the database. This would allow a subsequent C<< $obj->delete >> to work
lib/DBIx/Class/Row.pm view on Meta::CPAN
and
ref($prefetch->{$rel_name}) ne $DBIx::Class::ResultSource::RowParser::Util::null_branch_class
) {
if (ref $prefetch->{$rel_name}[0] eq 'ARRAY') {
my $rel_rsrc = $rel_rs->result_source;
my $rel_class = $rel_rs->result_class;
my $rel_inflator = $rel_class->can('inflate_result');
@rel_objects = map
{ $rel_class->$rel_inflator ( $rel_rsrc, @$_ ) }
@{$prefetch->{$rel_name}}
;
}
else {
@rel_objects = $rel_rs->result_class->inflate_result(
$rel_rs->result_source, @{$prefetch->{$rel_name}}
);
}
}
if ($relinfo->{attrs}{accessor} eq 'single') {
$new->{_relationship_data}{$rel_name} = $rel_objects[0];
}
elsif ($relinfo->{attrs}{accessor} eq 'filter') {
$new->{_inflated_column}{$rel_name} = $rel_objects[0];
}
$rel_rs->set_cache(\@rel_objects);
}
}
$new->in_storage (1);
return $new;
}
=head2 update_or_insert
$result->update_or_insert
=over
=item Arguments: none
=item Return Value: Result of update or insert operation
=back
L</update>s the object if it's already in the database, according to
L</in_storage>, else L</insert>s it.
=head2 insert_or_update
$obj->insert_or_update
Alias for L</update_or_insert>
=cut
sub insert_or_update { shift->update_or_insert(@_) }
sub update_or_insert {
my $self = shift;
return ($self->in_storage ? $self->update : $self->insert);
}
=head2 is_changed
my @changed_col_names = $result->is_changed();
if ($result->is_changed()) { ... }
=over
=item Arguments: none
=item Return Value: 0|1 or @columnnames
=back
In list context returns a list of columns with uncommited changes, or
in scalar context returns a true value if there are uncommitted
changes.
=cut
sub is_changed {
return keys %{shift->{_dirty_columns} || {}};
}
=head2 is_column_changed
if ($result->is_column_changed('col')) { ... }
=over
=item Arguments: $columname
=item Return Value: 0|1
=back
Returns a true value if the column has uncommitted changes.
=cut
sub is_column_changed {
my( $self, $col ) = @_;
return exists $self->{_dirty_columns}->{$col};
}
=head2 result_source
my $resultsource = $result->result_source;
=over
=item Arguments: L<$result_source?|DBIx::Class::ResultSource>
=item Return Value: L<$result_source|DBIx::Class::ResultSource>
=back
( run in 0.565 second using v1.01-cache-2.11-cpan-39bf76dae61 )