| Fey documentation | Contained in the Fey distribution. |
Fey::SQL::Update - Represents a UPDATE query
version 0.40
my $sql = Fey::SQL->new_update(); # UPDATE Part # SET quantity = 10 # WHERE part_id IN (1, 5) $sql->update($Part); $sql->set( $quantity, 10 ); $sql->where( $part_id, 'IN', 1, 5 ); print $sql->sql($dbh);
This class represents a UPDATE query.
This class provides the following methods:
To construct an object of this class, call $query->update() on
a Fey::SQL object.
This method specifies the UPDATE clause of the query. It expects
one or more Fey::Table objects (not aliases). Most RDBMS
implementations only allow for a single table here, but some (like
MySQL) do allow for multi-table updates.
This method takes a list of key/value pairs. The keys should be column objects, and the value can be one of the following:
This will be passed to Fey::Literal->new_from_scalar().
Fey::Literal objectFey::Column objectA column alias cannot be used.
Fey::Placeholder objectSee the Fey::SQL section on WHERE Clauses for more details.
See the Fey::SQL section on ORDER BY Clauses for more details.
See the Fey::SQL section on LIMIT Clauses for more details.
Returns the full SQL statement which this object represents. A DBI handle must be passed so that identifiers can be properly quoted.
See the Fey::SQL section on Bind Parameters for more details.
Returns the UPDATE clause portion of the SQL statement as a string.
Returns the SET clause portion of the SQL statement as a string.
Returns the WHERE clause portion of the SQL statement as a string.
Returns the ORDER BY clause portion of the SQL statement as a
string.
Returns the LIMIT clause portion of the SQL statement as a string.
See Fey for details on how to report bugs.
Dave Rolsky <autarch@urth.org>
This software is Copyright (c) 2011 by Dave Rolsky.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
| Fey documentation | Contained in the Fey distribution. |
package Fey::SQL::Update; BEGIN { $Fey::SQL::Update::VERSION = '0.40'; } use strict; use warnings; use namespace::autoclean; use Fey::Exceptions qw( param_error ); use Fey::Literal; use Fey::Types qw( ArrayRef CanQuote ColumnWithTable NonNullableUpdateValue NullableUpdateValue Table ); use overload (); use Scalar::Util qw( blessed ); use Moose; use MooseX::Params::Validate qw( pos_validated_list ); use MooseX::SemiAffordanceAccessor; use MooseX::StrictConstructor; with 'Fey::Role::SQL::HasOrderByClause', 'Fey::Role::SQL::HasLimitClause'; with 'Fey::Role::SQL::HasWhereClause' => { -excludes => 'bind_params', -alias => { bind_params => '_where_clause_bind_params' }, }; with 'Fey::Role::SQL::HasBindParams' => { -excludes => 'bind_params', -alias => { bind_params => '_update_bind_params' }, }; has '_update' => ( is => 'rw', isa => ArrayRef, default => sub { [] }, init_arg => undef, ); has '_set_pairs' => ( traits => ['Array'], is => 'bare', isa => ArrayRef[ArrayRef], default => sub { [] }, handles => { _add_set_pair => 'push', _set_pairs => 'elements', }, init_arg => undef, ); with 'Fey::Role::SQL::Cloneable'; sub update { my $self = shift; my $count = @_ ? @_ : 1; my (@tables) = pos_validated_list( \@_, ( ( { isa => Table } ) x $count ), MX_PARAMS_VALIDATE_NO_CACHE => 1, ); $self->_set_update( \@tables ); return $self; } sub set { my $self = shift; if ( !@_ || @_ % 2 ) { my $count = @_; param_error "The set method expects a list of paired column objects and values but you passed $count parameters"; } my @spec; for ( my $x = 0; $x < @_; $x += 2 ) { push @spec, { isa => ColumnWithTable }; push @spec, blessed $_[$x] && $_[$x]->is_nullable() ? { isa => NullableUpdateValue } : { isa => NonNullableUpdateValue }; } my @set = pos_validated_list( \@_, @spec, MX_PARAMS_VALIDATE_NO_CACHE => 1 ); for ( my $x = 0; $x < @_; $x += 2 ) { my $val = $_[ $x + 1 ]; $val .= '' if blessed $val && overload::Overloaded($val); if ( !blessed $val ) { if ( defined $val && $self->auto_placeholders() ) { $self->_add_bind_param($val); $val = Fey::Placeholder->new(); } else { $val = Fey::Literal->new_from_scalar($val); } } $self->_add_set_pair( [ $_[$x], $val ] ); } return $self; } sub sql { my $self = shift; my ($dbh) = pos_validated_list( \@_, { isa => CanQuote } ); return ( join ' ', $self->update_clause($dbh), $self->set_clause($dbh), $self->where_clause($dbh), $self->order_by_clause($dbh), $self->limit_clause($dbh), ); } sub update_clause { return 'UPDATE ' . $_[0]->_tables_subclause( $_[1] ); } sub _tables_subclause { return ( join ', ', map { $_[1]->quote_identifier( $_->name() ) } @{ $_[0]->_update() } ); } sub set_clause { my $self = shift; my $dbh = shift; # SQLite objects when the table name is provided ("User"."email") # on the LHS of the set. I'm hoping that a DBMS which allows a # multi-table update also allows the table name in the LHS. my $col_quote = @{ $self->_update() } > 1 ? '_name_and_table' : '_name'; return ( 'SET ' . ( join ', ', map { my $val = $_->[1]; my $val_sql = $val->sql($dbh); $val_sql = "($val_sql)" if blessed $val && $val->can('does') && $val->does('Fey::Role::SQL::ReturnsData'); $self->$col_quote( $_->[0], $dbh ) . ' = ' . $val_sql; } $self->_set_pairs() ) ); } sub _name_and_table { return $_[1]->sql( $_[2] ); } sub _name { return $_[2]->quote_identifier( $_[1]->name() ); } sub bind_params { my $self = shift; return ( $self->_update_bind_params(), $self->_where_clause_bind_params(), ); } __PACKAGE__->meta()->make_immutable(); 1; # ABSTRACT: Represents a UPDATE query
__END__