putting IC::DateTime locale, timezone or floating_tz_ok attributes into extra =>...
Johannes Plunien [Tue, 17 Mar 2009 15:31:08 +0000 (15:31 +0000)]
Changes
lib/DBIx/Class/InflateColumn/DateTime.pm
t/89inflate_datetime.t
t/lib/DBICTest/Schema/EventTZ.pm
t/lib/DBICTest/Schema/EventTZDeprecated.pm [new file with mode: 0644]

diff --git a/Changes b/Changes
index 3d84205..96f8cde 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,9 @@
 Revision history for DBIx::Class
 
 0.08099_07 2009-02-27 02:00:00 (UTC)
+        - putting IC::DateTime locale, timezone or floating_tz_ok attributes into
+          extra => {} has been deprecated. The new way is to put these things
+          directly into the columns definition
         - multi-create using find_or_create rather than _related for post-insert
         - fix get_inflated_columns to check has_column_loaded
         - Add DBIC_MULTICREATE_DEBUG env var (undocumented, quasi-internal)
index 3024241..afd118d 100644 (file)
@@ -30,7 +30,7 @@ Then you can treat the specified column as a L<DateTime> object.
 If you want to set a specific timezone and locale for that field, use:
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => "de_DE" } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago", locale => "de_DE" }
   );
 
 If you want to inflate no matter what data_type your column is,
@@ -111,13 +111,20 @@ sub register_column {
 
   my $timezone;
   if ( defined $info->{extra}{timezone} ) {
+    warn "Putting timezone into extra => { timezone => '...' } has been deprecated, ".
+         "please put it directly into the columns definition.";
     $timezone = $info->{extra}{timezone};
   }
 
   my $locale;
   if ( defined $info->{extra}{locale} ) {
+    warn "Putting locale into extra => { locale => '...' } has been deprecated, ".
+         "please put it directly into the columns definition.";
     $locale = $info->{extra}{locale};
   }
+  
+  $locale   = $info->{locale}   if defined $info->{locale};
+  $timezone = $info->{timezone} if defined $info->{timezone};
 
   my $undef_if_invalid = $info->{datetime_undef_if_invalid};
 
@@ -137,7 +144,13 @@ sub register_column {
     #     closure &G, $info => $H
     #     $H => %E
     #
-    my $floating_tz_ok = $info->{extra}{floating_tz_ok};
+    my $floating_tz_ok;
+    if (defined $info->{extra}{floating_tz_ok}) {
+      warn "Putting floating_tz_ok into extra => { floating_tz_ok => 1 } has been deprecated, ".
+           "please put it directly into the columns definition.";
+      $floating_tz_ok = $info->{extra}{floating_tz_ok};
+    }
+    $floating_tz_ok = $info->{floating_tz_ok} if defined $info->{floating_tz_ok};
 
     $self->inflate_column(
       $column =>
@@ -189,7 +202,7 @@ timezone, you will get a warning (as there is a very good chance this will not h
 result you expect). For example:
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago" } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago" }
   );
 
   my $event = $schema->resultset('EventTZ')->create({
@@ -213,7 +226,7 @@ to be supply explicit times to the database:
 =item Suppress the check on per-column basis
 
   __PACKAGE__->add_columns(
-    starts_when => { data_type => 'datetime', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } }
+    starts_when => { data_type => 'datetime', timezone => "America/Chicago", floating_tz_ok => 1 }
   );
 
 =item Suppress the check globally
@@ -222,7 +235,10 @@ Set the environment variable DBIC_FLOATING_TZ_OK to some true value.
 
 =back
 
-
+Putting extra attributes like timezone, locale or floating_tz_ok into extra => {} has been
+B<DEPRECATED> because this gets you into trouble using L<DBIx::Class::Schema::Versioned>.
+Instead put it directly into the columns definition like in the examples above. If you still
+use the old way you'll see a warning - please fix your code then!
 
 =head1 SEE ALSO
 
index baf8ef8..91bbd2a 100644 (file)
@@ -5,12 +5,14 @@ use Test::More;
 use lib qw(t/lib);
 use DBICTest;
 
+DBICTest::Schema->load_classes('EventTZDeprecated');
+
 my $schema = DBICTest->init_schema();
 
 eval { require DateTime::Format::MySQL };
 plan skip_all => "Need DateTime::Format::MySQL for inflation tests" if $@;
 
-plan tests => 32;
+plan tests => 50;
 
 # inflation test
 my $event = $schema->resultset("Event")->find(1);
@@ -52,75 +54,78 @@ is("$created_cron", '2006-06-23T00:00:00', 'Correct date/time');
 
 
 # Test "timezone" parameter
-my $event_tz = $schema->resultset('EventTZ')->create({
-    starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ),
-    created_on => DateTime->new(year=>2006, month=>1, day=>31,
-        hour => 13, minute => 34, second => 56, time_zone => "America/New_York" ),
-});
-
-is ($event_tz->starts_at->day_name, "Montag", 'Locale de_DE loaded: day_name');
-is ($event_tz->starts_at->month_name, "Dezember", 'Locale de_DE loaded: month_name');
-is ($event_tz->created_on->day_name, "Tuesday", 'Default locale loaded: day_name');
-is ($event_tz->created_on->month_name, "January", 'Default locale loaded: month_name');
-
-my $starts_at = $event_tz->starts_at;
-is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone');
-
-my $created_on = $event_tz->created_on;
-is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone');
-is($event_tz->created_on->time_zone->name, "America/Chicago", "Correct timezone");
-
-my $loaded_event = $schema->resultset('EventTZ')->find( $event_tz->id );
-
-isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned');
-$starts_at = $loaded_event->starts_at;
-is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using timezone');
-is($starts_at->time_zone->name, 'America/Chicago', 'Correct timezone');
-
-isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned');
-$created_on = $loaded_event->created_on;
-is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using timezone');
-is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone');
-
-# Test floating timezone warning
-# We expect one warning
-SKIP: {
-    skip "ENV{DBIC_FLOATING_TZ_OK} was set, skipping", 1 if $ENV{DBIC_FLOATING_TZ_OK};
-    local $SIG{__WARN__} = sub {
-        like(
-            shift,
-            qr/You're using a floating timezone, please see the documentation of DBIx::Class::InflateColumn::DateTime for an explanation/,
-            'Floating timezone warning'
-        );
-    };
-    my $event_tz_floating = $schema->resultset('EventTZ')->create({
-        starts_at => DateTime->new(year=>2007, month=>12, day=>31, ),
-        created_on => DateTime->new(year=>2006, month=>1, day=>31,
-            hour => 13, minute => 34, second => 56, ),
-    });
-    delete $SIG{__WARN__};
-};
-
-# 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 => $created_on
-});
-
-is( $invalid->get_column('starts_at'), '0000-00-00', "Invalid date stored" );
-is( $invalid->starts_at, undef, "Inflate to undef" );
-
-$invalid->created_on('0000-00-00');
-$invalid->update;
 
-{
-    local $@;
-    eval { $invalid->created_on };
-    like( $@, qr/invalid date format/i, "Invalid date format exception");
+foreach my $tbl (qw/EventTZ EventTZDeprecated/) {
+  my $event_tz = $schema->resultset($tbl)->create({
+      starts_at => DateTime->new(year=>2007, month=>12, day=>31, time_zone => "America/Chicago" ),
+      created_on => DateTime->new(year=>2006, month=>1, day=>31,
+          hour => 13, minute => 34, second => 56, time_zone => "America/New_York" ),
+  });
+
+  is ($event_tz->starts_at->day_name, "Montag", 'Locale de_DE loaded: day_name');
+  is ($event_tz->starts_at->month_name, "Dezember", 'Locale de_DE loaded: month_name');
+  is ($event_tz->created_on->day_name, "Tuesday", 'Default locale loaded: day_name');
+  is ($event_tz->created_on->month_name, "January", 'Default locale loaded: month_name');
+
+  my $starts_at = $event_tz->starts_at;
+  is("$starts_at", '2007-12-31T00:00:00', 'Correct date/time using timezone');
+
+  my $created_on = $event_tz->created_on;
+  is("$created_on", '2006-01-31T12:34:56', 'Correct timestamp using timezone');
+  is($event_tz->created_on->time_zone->name, "America/Chicago", "Correct timezone");
+
+  my $loaded_event = $schema->resultset($tbl)->find( $event_tz->id );
+
+  isa_ok($loaded_event->starts_at, 'DateTime', 'DateTime returned');
+  $starts_at = $loaded_event->starts_at;
+  is("$starts_at", '2007-12-31T00:00:00', 'Loaded correct date/time using timezone');
+  is($starts_at->time_zone->name, 'America/Chicago', 'Correct timezone');
+
+  isa_ok($loaded_event->created_on, 'DateTime', 'DateTime returned');
+  $created_on = $loaded_event->created_on;
+  is("$created_on", '2006-01-31T12:34:56', 'Loaded correct timestamp using timezone');
+  is($created_on->time_zone->name, 'America/Chicago', 'Correct timezone');
+
+  # Test floating timezone warning
+  # We expect one warning
+  SKIP: {
+      skip "ENV{DBIC_FLOATING_TZ_OK} was set, skipping", 1 if $ENV{DBIC_FLOATING_TZ_OK};
+      local $SIG{__WARN__} = sub {
+          like(
+              shift,
+              qr/You're using a floating timezone, please see the documentation of DBIx::Class::InflateColumn::DateTime for an explanation/,
+              'Floating timezone warning'
+          );
+      };
+      my $event_tz_floating = $schema->resultset($tbl)->create({
+          starts_at => DateTime->new(year=>2007, month=>12, day=>31, ),
+          created_on => DateTime->new(year=>2006, month=>1, day=>31,
+              hour => 13, minute => 34, second => 56, ),
+      });
+      delete $SIG{__WARN__};
+  };
+
+  # 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 => $created_on
+  });
+
+  is( $invalid->get_column('starts_at'), '0000-00-00', "Invalid date stored" );
+  is( $invalid->starts_at, undef, "Inflate to undef" );
+
+  $invalid->created_on('0000-00-00');
+  $invalid->update;
+
+  {
+      local $@;
+      eval { $invalid->created_on };
+      like( $@, qr/invalid date format/i, "Invalid date format exception");
+  }
 }
 
 ## varchar field using inflate_date => 1
index d19980c..1d5c06b 100644 (file)
@@ -10,8 +10,8 @@ __PACKAGE__->table('event');
 
 __PACKAGE__->add_columns(
   id => { data_type => 'integer', is_auto_increment => 1 },
-  starts_at => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => 'de_DE' } },
-  created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } },
+  starts_at => { data_type => 'datetime', timezone => "America/Chicago", locale => 'de_DE' },
+  created_on => { data_type => 'timestamp', timezone => "America/Chicago", floating_tz_ok => 1 },
 );
 
 __PACKAGE__->set_primary_key('id');
diff --git a/t/lib/DBICTest/Schema/EventTZDeprecated.pm b/t/lib/DBICTest/Schema/EventTZDeprecated.pm
new file mode 100644 (file)
index 0000000..29695dd
--- /dev/null
@@ -0,0 +1,19 @@
+package DBICTest::Schema::EventTZDeprecated;
+
+use strict;
+use warnings;
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+
+__PACKAGE__->table('event');
+
+__PACKAGE__->add_columns(
+  id => { data_type => 'integer', is_auto_increment => 1 },
+  starts_at => { data_type => 'datetime', extra => { timezone => "America/Chicago", locale => 'de_DE' } },
+  created_on => { data_type => 'timestamp', extra => { timezone => "America/Chicago", floating_tz_ok => 1 } },
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;