DBIx-NinjaORM
view release on metacpan or search on metacpan
lib/DBIx/NinjaORM.pm view on Meta::CPAN
);
This method supports the following optional arguments:
=over 4
=item * skip_modified_update (default 0)
Do not update the 'modified' field. This is useful if you're using 'modified' to
record when was the last time a human changed the row, but you want to exclude
automated changes.
=item * dbh
A different database handle than the default one specified in
C<static_class_info()>, but it has to be writable.
=item * restrictions
The update statement is limited using the primary key. This parameter however
allows adding extra restrictions on the update. Additional clauses passed here
are joined with AND.
$book->update(
{
author_id => 1234,
},
restrictions =>
{
where_clauses => [ 'status != ?' ],
where_values => [ 'protected' ],
},
);
=item * set
\%data contains the data to update the row with "SET field = value". It is
however sometimes necessary to use more complex SETs, such as
"SET field = field + value", which is what this parameter allows.
Important: you will need to subclass C<update()> in your model classes and
update manually the values upon success (or reload the object), as
L<DBIx::NinjaORM> cannot determine the end result of those complex sets on the
database side.
$book->update(
{
name => 'Learning Perl',
},
set =>
{
placeholders => [ 'edits = edits + ?' ],
values => [ 1 ],
}
);
=back
=cut
sub update ## no critic (Subroutines::RequireArgUnpacking)
{
croak 'The first argument passed must be a hashref'
if !Data::Validate::Type::is_hashref( $_[1] );
my ( $self, $data, %args ) = @_;
# Allow using a different DB handle.
my $dbh = $self->assert_dbh( $args{'dbh'} );
# Clean input
my $clean_data = $self->validate_data( $data, %args );
return 0
if !defined( $clean_data );
# Set defaults
$clean_data->{'modified'} = $self->get_current_time()
if !$args{'skip_modified_update'} && $self->get_info('has_modified_field');
# If there's nothing to update, bail out.
if ( scalar( keys %$clean_data ) == 0 )
{
$log->debug( 'No data left to update after validation, skipping SQL update' )
if $self->is_verbose();
return;
}
# Retrieve the meta-data for that table.
my $class = ref( $self );
my $table_name = $self->get_info('table_name');
croak "The table name for class '$class' is not defined"
if ! defined( $table_name );
my $primary_key_name = $self->get_info('primary_key_name');
croak "Missing primary key name for class '$class', cannot force primary key value"
if !defined( $primary_key_name ) && defined( $args{'generated_primary_key_value'} );
croak "The object of class '$class' does not have a primary key value, cannot update"
if ! defined( $self->id() );
# Prepare the SQL request elements.
my $where_clauses = $args{'restrictions'}->{'where_clauses'} || [];
my $where_values = $args{'restrictions'}->{'where_values'} || [];
push( @$where_clauses, $primary_key_name . ' = ?' );
push( @$where_values, [ $self->id() ] );
# Prepare the values to set.
my @set_placeholders = ();
my @set_values = ();
foreach my $key ( keys %$clean_data )
{
if ( $key eq 'modified' )
{
# 'created' supports SQL keywords and is quoted by get_current_time() if
# needed, so we don't use placeholders.
push( @set_placeholders, $dbh->quote_identifier( $key ) . ' = ' . $clean_data->{ $key } );
}
else
{
# All the other data need to be inserted using placeholders, for
( run in 0.516 second using v1.01-cache-2.11-cpan-5a3173703d6 )