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 )