Let SQLMaker rs_attr 'for' support string literals
Matt Phillips [Fri, 19 Oct 2012 18:49:46 +0000 (14:49 -0400)]
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

Changes
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/SQLMaker.pm
t/sqlmaker/core.t

diff --git a/Changes b/Changes
index 52f4247..59eba7a 100644 (file)
--- 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
 
index 1a444d4..3e629ec 100644 (file)
@@ -4324,12 +4324,13 @@ L<DBIx::Class::Manual::Cookbook>.
 
 =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
 
index 705c569..02b44f0 100644 (file)
@@ -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";
 }
 
index 2cf88ba..7312c98 100644 (file)
@@ -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 {