[Dbix-class] Tests for MySQL's illustrious 0000-00-00

J. Shirley jshirley at gmail.com
Fri Jul 18 17:01:35 BST 2008


Ok, we all hate MySQL.  That's a given, but some of us have to work
with it so lets make it better.  There's been several threads on the
mailing list about how MySQL handles undef dates (and the default
idiom is to use 0000-00-00)

Here's a patch I wrote that will simply return undef if there is an
exception inflating the date.  I'm not fully convinced that eating the
error is a good thing, but I also don't want a ton of pollution in the
logs.  Because of that, I'm thinking that also adding in:
            my $dt = eval { $obj->_datetime_parser->$parse($value); };
            warn $@ if $@ and $value !~ /^00(?:00)?-00-00$/;

I don't like this at all, which is one reason why I didn't put it in
the patch, but throwing that out because I'm sure someone has better
ideas.

I have a commit bit, so if you guys approve just holler and I'll check
in the patch.

=== lib/DBIx/Class/InflateColumn/DateTime.pm
==================================================================
--- lib/DBIx/Class/InflateColumn/DateTime.pm    (revision 14362)
+++ lib/DBIx/Class/InflateColumn/DateTime.pm    (local)
@@ -73,8 +73,8 @@
         {
           inflate => sub {
             my ($value, $obj) = @_;
-            my $dt = $obj->_datetime_parser->$parse($value);
-            $dt->set_time_zone($timezone) if $timezone;
+            my $dt = eval { $obj->_datetime_parser->$parse($value); };
+            $dt->set_time_zone($timezone) if $dt and $timezone;
             return $dt;
           },
           deflate => sub {
=== t/89inflate_datetime.t
==================================================================
--- t/89inflate_datetime.t      (revision 14362)
+++ t/89inflate_datetime.t      (local)
@@ -10,7 +10,7 @@
 eval { require DateTime::Format::MySQL };
 plan skip_all => "Need DateTime::Format::MySQL for inflation tests" if $@;

-plan tests => 17;
+plan tests => 20;

 # inflation test
 my $event = $schema->resultset("Event")->find(1);
@@ -70,3 +70,15 @@
 is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp
using timezone');
 is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone');

+# This should fail to set
+my $prev_str = "$created_on";
+$loaded_event->update({ created_on => '0000-00-00' });
+is("$created_on", $prev_str, "Don't update invalid dates");
+
+my $invalid = $schema->resultset('Event')->create({
+    starts_at  => '0000-00-00',
+    created_on => '0000-00-00'
+});
+
+is( $invalid->get_column('created_on'), '0000-00-00', "Invalid date stored" );
+is( $invalid->created_on, undef, "Inflate to undef" );



More information about the DBIx-Class mailing list