From: Matt Phillips Date: Fri, 19 Oct 2012 18:49:46 +0000 (-0400) Subject: Let SQLMaker rs_attr 'for' support string literals X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8249c09bde719b24cd6784dca75405073db40a1a;p=dbsrgits%2FDBIx-Class-Historic.git Let SQLMaker rs_attr 'for' support string literals SQLMaker previously only allowed hardcoded values with the 'for' attr, overriding in storage specific subclasses. Rather than attempt to provide an exhaustive list of possible options, the base class can now take \$scalaras an override that is embedded directly in the returned $sql --- diff --git a/Changes b/Changes index 52f4247..59eba7a 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for DBIx::Class -0.08203_01 2012-10-18 13:57 (UTC) + * New Features / Changes + - SQLMaker now accepts \'literal' with the 'for' rs attribute as an + override to the builtin FOR options * Fixes - Fix test failure on perl 5.8 diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 1a444d4..3e629ec 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -4324,12 +4324,13 @@ L. =over 4 -=item Value: ( 'update' | 'shared' ) +=item Value: ( 'update' | 'shared' | \$scalar ) =back Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT -... FOR SHARED. +... FOR SHARED. If \$scalar is passed, this is taken directly and embedded in the +query. =cut diff --git a/lib/DBIx/Class/SQLMaker.pm b/lib/DBIx/Class/SQLMaker.pm index 705c569..02b44f0 100644 --- a/lib/DBIx/Class/SQLMaker.pm +++ b/lib/DBIx/Class/SQLMaker.pm @@ -238,7 +238,15 @@ my $for_syntax = { }; sub _lock_select { my ($self, $type) = @_; - my $sql = $for_syntax->{$type} || $self->throw_exception( "Unknown SELECT .. FOR type '$type' requested" ); + + my $sql; + if (ref($type) eq 'SCALAR') { + $sql = "FOR $$type"; + } + else { + $sql = $for_syntax->{$type} || $self->throw_exception( "Unknown SELECT .. FOR type '$type' requested" ); + } + return " $sql"; } diff --git a/t/sqlmaker/core.t b/t/sqlmaker/core.t index 2cf88ba..7312c98 100644 --- a/t/sqlmaker/core.t +++ b/t/sqlmaker/core.t @@ -69,6 +69,36 @@ my $sql_maker = $schema->storage->sql_maker; ); } +# Tests base class for => \'FOO' actually generates proper query. for => +# 'READ'|'SHARE' is tested in db-specific subclasses +# we have to instantiate base because SQLMaker::SQLite disables _lock_select +{ + require DBIx::Class::SQLMaker; + my $sa = DBIx::Class::SQLMaker->new; + { + my ($sql, @bind) = $sa->select('foo', '*', {}, { for => 'update' } ); + is_same_sql_bind( + $sql, + \@bind, + 'SELECT * FROM foo FOR UPDATE', + [], + ); + } + + { + my ($sql, @bind) = $sa->select('bar', '*', {}, { for => \'baz' } ); + is_same_sql_bind( + $sql, + \@bind, + 'SELECT * FROM bar FOR baz', + [], + ); + } + +} + + + # Make sure the carp/croak override in SQLA works (via SQLMaker) my $file = quotemeta (__FILE__); throws_ok (sub {