Added handling for implicit inflate/deflate of CDBI has_a relationships
Mike Francis [Fri, 18 Jul 2014 13:45:51 +0000 (14:45 +0100)]
Changes
lib/DBIx/Class.pm
lib/DBIx/Class/CDBICompat/Relationships.pm
t/cdbi/70_implicit_inflate.t [new file with mode: 0644]
t/cdbi/testlib/ImplicitInflate.pm [new file with mode: 0644]

diff --git a/Changes b/Changes
index b05ea3d..e1876f3 100644 (file)
--- 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
index b1a0270..119979b 100644 (file)
@@ -456,6 +456,8 @@ mithaldu: Christian Walde <walde.christian@gmail.com>
 
 mjemmeson: Michael Jemmeson <michael.jemmeson@gmail.com>
 
+mrf: Mike Francis <ungrim97@gmail.com>
+
 mstratman: Mark A. Stratman <stratman@gmail.com>
 
 ned: Neil de Carteret
index 66fe973..64bcc3c 100644 (file)
@@ -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 (file)
index 0000000..df7cb5e
--- /dev/null
@@ -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 (file)
index 0000000..610e835
--- /dev/null
@@ -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;