X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FAbstract.pm;h=3adfc01b6dc5d72896c60106f24776e3cf080e79;hb=78536e8b84aa4fdab20f50fb2ca65d17319099af;hp=e9c06f732fd2ba29722f86e8adc37fc8cfa9a0ce;hpb=cfc7db76ab314a1aa301aefb4dc3017d9aa4c7ec;p=dbsrgits%2FSQL-Abstract.git diff --git a/lib/SQL/Abstract.pm b/lib/SQL/Abstract.pm index e9c06f7..3adfc01 100644 --- a/lib/SQL/Abstract.pm +++ b/lib/SQL/Abstract.pm @@ -27,7 +27,7 @@ BEGIN { # GLOBALS #====================================================================== -our $VERSION = '1.80'; +our $VERSION = '1.81'; # This would confuse some packagers $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases @@ -227,7 +227,10 @@ sub insert { return wantarray ? ($sql, @bind) : $sql; } -sub _insert_returning { +# Used by DBIx::Class::SQLMaker->insert +sub _insert_returning { shift->_returning(@_) } + +sub _returning { my ($self, $options) = @_; my $f = $options->{returning}; @@ -348,10 +351,11 @@ sub _insert_values { sub update { - my $self = shift; - my $table = $self->_table(shift); - my $data = shift || return; - my $where = shift; + my $self = shift; + my $table = $self->_table(shift); + my $data = shift || return; + my $where = shift; + my $options = shift; # first build the 'SET' part of the sql statement my (@set, @all_bind); @@ -414,6 +418,12 @@ sub update { push @all_bind, @where_bind; } + if ($options->{returning}) { + my ($returning_sql, @returning_bind) = $self->_returning ($options); + $sql .= $returning_sql; + push @all_bind, @returning_bind; + } + return wantarray ? ($sql, @all_bind) : $sql; } @@ -1242,8 +1252,29 @@ sub _where_field_IN { # adding them back in the corresponding method sub _open_outer_paren { my ($self, $sql) = @_; - $sql = $1 while $sql =~ /^ \s* \( (.*) \) \s* $/xs; - return $sql; + + while ( my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs ) { + + # there are closing parens inside, need the heavy duty machinery + # to reevaluate the extraction starting from $sql (full reevaluation) + if ( $inner =~ /\)/ ) { + require Text::Balanced; + + my (undef, $remainder) = do { + # idiotic design - writes to $@ but *DOES NOT* throw exceptions + local $@; + Text::Balanced::extract_bracketed( $sql, '()', qr/\s*/ ); + }; + + # the entire expression needs to be a balanced bracketed thing + # (after an extract no remainder sans trailing space) + last if defined $remainder and $remainder =~ /\S/; + } + + $sql = $inner; + } + + $sql; } @@ -2049,7 +2080,7 @@ be supported by all database engines. =back -=head2 update($table, \%fieldvals, \%where) +=head2 update($table, \%fieldvals, \%where, \%options) This takes a table, hashref of field/value pairs, and an optional hashref L. It returns an SQL UPDATE function and a list @@ -2058,6 +2089,19 @@ See the sections on L and L for information on how to insert with those data types. +The optional C<\%options> hash reference may contain additional +options to generate the update SQL. Currently supported options +are: + +=over 4 + +=item returning + +See the C option to +L. + +=back + =head2 select($source, $fields, $where, $order) This returns a SQL SELECT statement and associated list of bind values, as @@ -2602,10 +2646,16 @@ This difference in syntax is unfortunate but must be preserved for historical reasons. So be careful : the two examples below would seem algebraically equivalent, but they are not - {col => [-and => {-like => 'foo%'}, {-like => '%bar'}]} + { col => [ -and => + { -like => 'foo%' }, + { -like => '%bar' }, + ] } # yields : WHERE ( ( col LIKE ? AND col LIKE ? ) ) - [-and => {col => {-like => 'foo%'}, {col => {-like => '%bar'}}]] + [ -and => + { col => { -like => 'foo%' } }, + { col => { -like => '%bar' } }, + ] # yields : WHERE ( ( col LIKE ? OR col LIKE ? ) )