Converted two private methods to public ones in I:DT. These methods add functionality...
moltar [Mon, 26 Mar 2012 00:18:15 +0000 (20:18 -0400)]
lib/DBIx/Class/InflateColumn/DateTime.pm
t/inflate/datetime_pre_post_inflate.t [new file with mode: 0644]
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/EventPrePostInflate.pm [new file with mode: 0644]
t/lib/sqlite.sql

index 0e2d058..ad80785 100644 (file)
@@ -175,14 +175,14 @@ sub register_column {
           my $dt = $obj->_inflate_to_datetime( $value, $infcopy );
 
           return (defined $dt)
-            ? $obj->_post_inflate_datetime( $dt, $infcopy )
+            ? $obj->post_inflate_datetime( $dt, $infcopy )
             : undef
           ;
         },
         deflate => sub {
           my ($value, $obj) = @_;
 
-          $value = $obj->_pre_deflate_datetime( $value, $infcopy );
+          $value = $obj->pre_deflate_datetime( $value, $infcopy );
           $obj->_deflate_from_datetime( $value, $infcopy );
         },
       }
@@ -224,15 +224,30 @@ sub _datetime_parser {
 sub _post_inflate_datetime {
   my( $self, $dt, $info ) = @_;
 
+  if ((caller(0))[3] ne 'post_inflate_datetime') {
+    carp "Method _post_inflate_datetime is deprecated and should not be used."
+      . " Please use post_inflate_datetime method instead.";
+  }
+
   $dt->set_time_zone($info->{timezone}) if defined $info->{timezone};
   $dt->set_locale($info->{locale}) if defined $info->{locale};
 
   return $dt;
 }
 
+sub post_inflate_datetime {
+  my ($self, @args) = @_;
+  return $self->_post_inflate_datetime(@args);
+}
+
 sub _pre_deflate_datetime {
   my( $self, $dt, $info ) = @_;
 
+  if ((caller(0))[3] ne 'pre_deflate_datetime') {
+    carp "Method _pre_deflate_datetime is deprecated and should not be used."
+      . " Please use pre_deflate_datetime method instead.";
+  }
+
   if (defined $info->{timezone}) {
     carp "You're using a floating timezone, please see the documentation of"
       . " DBIx::Class::InflateColumn::DateTime for an explanation"
@@ -248,9 +263,67 @@ sub _pre_deflate_datetime {
   return $dt;
 }
 
+sub pre_deflate_datetime {
+  my ($self, @args) = @_;
+  return $self->_pre_deflate_datetime(@args);
+}
+
 1;
 __END__
 
+=head1 DYNAMIC TIME ZONE AND LOCALE SETTING
+
+If you do not want to hard code time zone information into each column
+definition, you can set it globally via method overloading.
+
+There are two methods that get called during the inflation/deflation process:
+
+=head2 post_inflate_datetime($datetime, $column_info)
+
+This method is called after the column has been inflated into a L<DateTime>
+object. The first argument is the DateTime object, and the second argument
+is the column definition passed to L<DBIx::Class::Row/register_column> method.
+
+=head2 pre_deflate_datetime($datetime, $column_info)
+
+This method is called before the DateTime object is deflated into a string
+format. The first argument is the DateTime object, and the second argument
+is the column definition passed to L<DBIx::Class::Row/register_column> method.
+
+=head3 Example
+
+  sub post_inflate_datetime {
+    my ($self, $datetime, $column_info) = @_;
+
+    $column_info->{timezone} = 'UTC';
+    $column_info->{locale}   = 'en_CA';
+
+    return $self->next::method($dt, $info);
+  }
+
+=head3 Advanced Example
+
+In your Schema class:
+
+  package MyApp::Schema;
+  use base qw/DBIx::Class::Schema/;
+  __PACKAGE__->mk_group_accessors(inherited => qw/time_zone/);
+  __PACKAGE__->time_zone('UTC'); ## sets default to UTC
+  
+In your Result class:
+
+  sub post_inflate_datetime {
+    my ($self, $datetime, $column_info) = @_;
+    $column_info->{timezone} = $self->result_source->schema->time_zone;
+    return $self->next::method($dt, $info);
+  }
+  
+In your application code:
+
+  use MyApp::Schema;
+  my $schema = MyApp::Schema->connect();
+  $schema->time_zone('America/Toronto'); ## set time zone dynamically
+
 =head1 USAGE NOTES
 
 If you have a datetime column with an associated C<timezone>, and subsequently
diff --git a/t/inflate/datetime_pre_post_inflate.t b/t/inflate/datetime_pre_post_inflate.t
new file mode 100644 (file)
index 0000000..f71fe80
--- /dev/null
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Warn;
+use lib qw(t/lib);
+use DBICTest;
+
+# so user's env doesn't screw us
+delete $ENV{DBIC_DT_SEARCH_OK};
+
+my $schema = DBICTest->init_schema();
+
+plan skip_all => 'DT inflation tests need ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_dt_sqlite')
+  unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_dt_sqlite');
+
+my $event_rs = $schema->resultset("EventPrePostInflate");
+my $event = $event_rs->new({});
+
+can_ok $event, qw/_post_inflate_datetime _pre_deflate_datetime post_inflate_datetime pre_deflate_datetime/;
+
+warning_like {
+    $event_rs->create({ starts_at => DateTime->now(time_zone => 'UTC') });
+} qr/deprecated/, 'Get warning for overloading _pre_deflate_datetime.';
+
+warning_like {
+    $event_rs->find(1)->starts_at;
+} qr/deprecated/, 'Get warning for overloading _post_inflate_datetime.';
+
+done_testing;
index d2d41d0..147da16 100644 (file)
@@ -59,7 +59,7 @@ __PACKAGE__->load_classes(qw/
   ),
   qw/SelfRefAlias TreeLike TwoKeyTreeLike Event EventTZ NoPrimaryKey/,
   qw/Collection CollectionObject TypedObject Owners BooksInLibrary/,
-  qw/ForceForeign Encoded/,
+  qw/ForceForeign Encoded EventPrePostInflate/,
 );
 
 sub sqlt_deploy_hook {
diff --git a/t/lib/DBICTest/Schema/EventPrePostInflate.pm b/t/lib/DBICTest/Schema/EventPrePostInflate.pm
new file mode 100644 (file)
index 0000000..73eebe5
--- /dev/null
@@ -0,0 +1,30 @@
+package DBICTest::Schema::EventPrePostInflate;
+
+use strict;
+use warnings;
+use base qw/DBICTest::BaseResult/;
+
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+
+__PACKAGE__->table('event_pre_post_inflate');
+
+__PACKAGE__->add_columns(
+  id => { data_type => 'integer', is_auto_increment => 1 },
+  starts_at => { data_type => 'datetime', is_nullable => 1 },
+);
+
+__PACKAGE__->set_primary_key('id');
+
+## expecting carp
+sub _post_inflate_datetime {
+    my ($self, @args) = @_;
+    return $self->next::method(@args);
+}
+
+## expecting carp
+sub _pre_deflate_datetime {
+    my ($self, @args) = @_;
+    return $self->next::method(@args);
+}
+
+1;
index 9d49210..4f8e65a 100644 (file)
@@ -60,6 +60,14 @@ CREATE TABLE event (
 );
 
 --
+-- Table: event_pre_post_inflate
+--
+CREATE TABLE event_pre_post_inflate (
+  id INTEGER PRIMARY KEY NOT NULL,
+  starts_at datetime NOT NULL
+);
+
+--
 -- Table: fourkeys
 --
 CREATE TABLE fourkeys (