From: Mike Francis Date: Fri, 18 Jul 2014 13:45:51 +0000 (+0100) Subject: Added handling for implicit inflate/deflate of CDBI has_a relationships X-Git-Tag: v0.082800~112 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=2040ad7310898ed82cbd23ccf21fdb2a4cb4e102 Added handling for implicit inflate/deflate of CDBI has_a relationships --- diff --git a/Changes b/Changes index b05ea3d..e1876f3 100644 --- a/Changes +++ b/Changes @@ -40,6 +40,9 @@ Revision history for DBIx::Class additional codepath (missed in 0.08260) - Fix inability to handle multiple consecutive transactions with savepoints on DBD::SQLite < 1.39 + - Fix CDBICompat to match Class::DBI behavior handling non-result + blessed has_a (implicit deflate via stringification and inflate via + blind new) (GH#51) * Misc - Ensure source metadata calls always take place on the result source diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index b1a0270..119979b 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -456,6 +456,8 @@ mithaldu: Christian Walde mjemmeson: Michael Jemmeson +mrf: Mike Francis + mstratman: Mark A. Stratman ned: Neil de Carteret diff --git a/lib/DBIx/Class/CDBICompat/Relationships.pm b/lib/DBIx/Class/CDBICompat/Relationships.pm index 66fe973..64bcc3c 100644 --- a/lib/DBIx/Class/CDBICompat/Relationships.pm +++ b/lib/DBIx/Class/CDBICompat/Relationships.pm @@ -40,6 +40,13 @@ sub _declare_has_a { my $rel_info; + # Class::DBI allows Non database has_a with implicit deflate and inflate + # Hopefully the following will catch Non-database tables. + if( !$f_class->isa('DBIx::Class::Row') and !$f_class->isa('Class::DBI::Row') ) { + $args{'inflate'} ||= sub { $f_class->new(shift) }; # implicit inflate by calling new + $args{'deflate'} ||= sub { shift() . '' }; # implicit deflate by stringification + } + if ($args{'inflate'} || $args{'deflate'}) { # Non-database has_a if (!ref $args{'inflate'}) { my $meth = $args{'inflate'}; diff --git a/t/cdbi/70_implicit_inflate.t b/t/cdbi/70_implicit_inflate.t new file mode 100644 index 0000000..df7cb5e --- /dev/null +++ b/t/cdbi/70_implicit_inflate.t @@ -0,0 +1,36 @@ +use strict; +use warnings; + +# Class::DBI in its infinate wisdom allows implicit inflation +# and deflation of foriegn clas looups in has_a relationships. +# for inflate it would call ->new on the foreign_class and for +# deflate it would "" the column value and allow for overloading +# of the "" operator. + +use Test::More; +use DBIx::Class::Optional::Dependencies; + +BEGIN { + plan skip_all => "Test needs ".DBIx::Class::Optional::Dependencies->req_missing_for('test_dt_sqlite') + unless DBIx::Class::Optional::Dependencies->req_ok_for('test_dt_sqlite'); +} + +use lib 't/cdbi/testlib'; +use ImplicitInflate; + +ok(ImplicitInflate->can('db_Main'), 'set_db()'); +is(ImplicitInflate->__driver, "SQLite", 'Driver set correctly'); + +my $now = DateTime->now; + +ImplicitInflate->create({ + update_datetime => $now, + text => "Test Data", +}); + +my $implicit_inflate = ImplicitInflate->retrieve(text => 'Test Data'); + +ok($implicit_inflate->update_datetime->isa('DateTime'), 'Date column inflated correctly'); +is($implicit_inflate->update_datetime => $now, 'Date has correct year'); + +done_testing; diff --git a/t/cdbi/testlib/ImplicitInflate.pm b/t/cdbi/testlib/ImplicitInflate.pm new file mode 100644 index 0000000..610e835 --- /dev/null +++ b/t/cdbi/testlib/ImplicitInflate.pm @@ -0,0 +1,42 @@ +package # Hide from PAUSE + ImplicitInflate; + +# Test class for the testing of Implicit inflation +# in CDBI Classes using Compat layer +# See t/cdbi/70-implicit_inflate.t + +use strict; +use warnings; + +use base 'DBIC::Test::SQLite'; + +__PACKAGE__->set_table('Date'); + +__PACKAGE__->columns( Primary => 'id' ); +__PACKAGE__->columns( All => qw/ update_datetime text/); + +__PACKAGE__->has_a( + update_datetime => 'MyDateStamp', +); + +sub create_sql { + # SQLite doesn't support Datetime datatypes. + return qq{ + id INTEGER PRIMARY KEY, + update_datetime TEXT, + text VARCHAR(20) + } +} + +{ + package MyDateStamp; + + use DateTime::Format::SQLite; + + sub new { + my ($self, $value) = @_; + return DateTime::Format::SQLite->parse_datetime($value); + } +} + +1;