From f895cdd0f7e3ea79214bc58808b7ecc665f8edfc Mon Sep 17 00:00:00 2001 From: Andrew Ruder Date: Mon, 6 Nov 2017 14:47:46 -0600 Subject: [PATCH] clear inflated in update({column => deflated}) If you access an inflated column and then change it with update({column => deflated_value}), the cached inflated column isn't cleared out and returns stale values. Added a small test exhibiting the problem with a datetime field. --- AUTHORS | 1 + lib/DBIx/Class/Row.pm | 1 + t/inflate/datetime.t | 94 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 t/inflate/datetime.t diff --git a/AUTHORS b/AUTHORS index 9e4a9626b..dbafa528a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,6 +16,7 @@ abraxxa: Alexander Hartmaier acca: Alexander Kuznetsov +aeruder: Andrew Ruder aherzog: Adam Herzog Alexander Keusch alexrj: Alessandro Ranellucci diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 8b8f5fb08..34d81e8f5 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -986,6 +986,7 @@ sub set_column { delete $self->{_inflated_column}{$rel_name}; } } + delete $self->{_inflated_column}{$column}; if ( # value change from something (even if NULL) diff --git a/t/inflate/datetime.t b/t/inflate/datetime.t new file mode 100644 index 000000000..763eef05b --- /dev/null +++ b/t/inflate/datetime.t @@ -0,0 +1,94 @@ +BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) } + +use strict; +use warnings; +use DateTime; + +use Test::More; + +use DBIx::Class::_Util 'modver_gt_or_eq_and_lt'; +use base(); +BEGIN { + plan skip_all => 'base.pm 2.20 (only present in perl 5.19.7) is known to break this test' + if modver_gt_or_eq_and_lt( 'base', '2.19_01', '2.21' ); +} + +use Test::Exception; + +use DBICTest; +my $schema = DBICTest->init_schema(); + +my $created; + +my %required_create_args = ( + starts_at => "2012-01-01", + created_on => "2012-01-01", +); + +subtest "create with DateTime" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => DateTime->new(year => 2016, month => 01, day => 01) + }); + $created->varchar_datetime; # make sure inflated + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2016-01-01", "varchar_datetime has correct datetime"; +}; + +subtest "create with scalar" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => "2016-01-01", + }); + $created->varchar_datetime; # make sure inflated + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2016-01-01", "varchar_datetime has correct datetime"; +}; + +subtest "update with column datetime" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => DateTime->new(year => 2016, month => 01, day => 01) + }); + $created->varchar_datetime; # make sure inflated + $created->varchar_datetime(DateTime->new(year => 2017, month => 01, day => 01)); + $created->update; + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2017-01-01", "varchar_datetime has correct datetime"; +}; + +subtest "update with column scalar" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => DateTime->new(year => 2016, month => 01, day => 01) + }); + $created->varchar_datetime; # make sure inflated + $created->varchar_datetime("2017-01-01"); + $created->update; + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2017-01-01", "varchar_datetime has correct datetime"; +}; + +subtest "update with datetime" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => DateTime->new(year => 2016, month => 01, day => 01) + }); + $created->varchar_datetime; # make sure inflated + $created->update({varchar_datetime => DateTime->new(year => 2017, month => 01, day => 01)}); + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2017-01-01", "varchar_datetime has correct datetime"; +}; + +subtest "update with scalar" => sub { + $created = $schema->resultset('Event')->create({ + %required_create_args, + varchar_datetime => DateTime->new(year => 2016, month => 01, day => 01) + }); + $created->varchar_datetime; # make sure inflated + $created->update({varchar_datetime => "2017-01-01"}); + is ref($created->varchar_datetime), "DateTime", "varchar_datetime accessor is a datetime"; + is $created->varchar_datetime->date, "2017-01-01", "varchar_datetime has correct datetime"; +}; + +done_testing;