From: moltar Date: Mon, 26 Mar 2012 00:18:15 +0000 (-0400) Subject: Converted two private methods to public ones in I:DT. These methods add functionality... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6c1a058cf69058f5b49dfac52f836e4ce7641ee7;p=dbsrgits%2FDBIx-Class.git Converted two private methods to public ones in I:DT. These methods add functionality for end user to be able to overload them and set time zone and locale dynamically. This includes modifications for testing. --- diff --git a/lib/DBIx/Class/InflateColumn/DateTime.pm b/lib/DBIx/Class/InflateColumn/DateTime.pm index 0e2d058..ad80785 100644 --- a/lib/DBIx/Class/InflateColumn/DateTime.pm +++ b/lib/DBIx/Class/InflateColumn/DateTime.pm @@ -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 +object. The first argument is the DateTime object, and the second argument +is the column definition passed to L 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 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, and subsequently diff --git a/t/inflate/datetime_pre_post_inflate.t b/t/inflate/datetime_pre_post_inflate.t new file mode 100644 index 0000000..f71fe80 --- /dev/null +++ b/t/inflate/datetime_pre_post_inflate.t @@ -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; diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm index d2d41d0..147da16 100644 --- a/t/lib/DBICTest/Schema.pm +++ b/t/lib/DBICTest/Schema.pm @@ -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 index 0000000..73eebe5 --- /dev/null +++ b/t/lib/DBICTest/Schema/EventPrePostInflate.pm @@ -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; diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index 9d49210..4f8e65a 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -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 (