Teach FC about literals
Peter Rabbitson [Wed, 4 Jun 2014 12:53:48 +0000 (14:53 +0200)]
Changes
lib/DBIx/Class/FilterColumn.pm
t/row/filter_column.t

diff --git a/Changes b/Changes
index 0b971bd..d1f8cdd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
 Revision history for DBIx::Class
 
+    * Notable Changes and Deprecations
+        - DBIC::FilterColumn now properly bypasses \'' and \[] literals, just
+          like the rest of DBIC
+
     * Fixes
         - Fix on_connect_* not always firing in some cases - a race condition
           existed between storage accessor setters and the determine_driver
index 6d7e48c..6fdf1ad 100644 (file)
@@ -2,7 +2,9 @@ package DBIx::Class::FilterColumn;
 use strict;
 use warnings;
 
-use base qw/DBIx::Class::Row/;
+use base 'DBIx::Class::Row';
+use DBIx::Class::_Util 'is_literal_value';
+use namespace::clean;
 
 sub filter_column {
   my ($self, $col, $attrs) = @_;
@@ -30,7 +32,11 @@ sub filter_column {
 sub _column_from_storage {
   my ($self, $col, $value) = @_;
 
-  return $value unless defined $value;
+  return $value if (
+    ! defined $value
+      or
+    is_literal_value($value)
+  );
 
   my $info = $self->column_info($col)
     or $self->throw_exception("No column info for $col");
@@ -45,6 +51,8 @@ sub _column_from_storage {
 sub _column_to_storage {
   my ($self, $col, $value) = @_;
 
+  return $value if is_literal_value($value);
+
   my $info = $self->column_info($col) or
     $self->throw_exception("No column info for $col");
 
index fb8dd00..785206d 100644 (file)
@@ -140,6 +140,33 @@ for my $artist_maker (
   is( $artist->get_column('rank'), 21, 'Proper filtered value' );
 }
 
+# test literals
+for my $v ( \ '16', \[ '?', '16' ] ) {
+  my $art = $schema->resultset('Artist')->new({ rank => 10 });
+  $art->rank($v);
+
+  is_deeply( $art->rank, $v);
+  is_deeply( $art->get_filtered_column("rank"), $v);
+  is_deeply( $art->get_column("rank"), $v);
+
+  $art->insert;
+  $art->discard_changes;
+
+  is ($art->get_column("rank"), 16, "Literal inserted into database properly");
+  is ($art->rank, 32, "filtering still works");
+
+  $art->update({ rank => $v });
+
+  is_deeply( $art->rank, $v);
+  is_deeply( $art->get_filtered_column("rank"), $v);
+  is_deeply( $art->get_column("rank"), $v);
+
+  $art->discard_changes;
+
+  is ($art->get_column("rank"), 16, "Literal inserted into database properly");
+  is ($art->rank, 32, "filtering still works");
+}
+
 IC_DIE: {
   throws_ok {
      DBICTest::Schema::Artist->inflate_column(rank =>